Comparar commits

...

355 Commits

Autor SHA1 Mensagem Data
Kevin Sawicki 79c6badce8 Upgrade to gists@0.11.0 for spec fixes 2013-11-25 11:40:05 -08:00
Kevin Sawicki a48ef934eb Upgrade to gists@0.10.0 2013-11-25 11:31:53 -08:00
Kevin Sawicki 85d5968318 Remove consecutive comment blocks 2013-11-22 15:45:01 -08:00
Kevin Sawicki 9b4dd602be 📝 Tweak markdown in Atom comments 2013-11-22 15:40:50 -08:00
Kevin Sawicki 62d84e5d4b 📝 Doc Project::registerOpener 2013-11-22 15:40:50 -08:00
Ben Ogle 61ed5da1dc Upgrade themes for tooltips 2013-11-22 15:40:12 -08:00
Ben Ogle 32e25d4bb2 Don't override the default options! 2013-11-22 15:39:47 -08:00
Ben Ogle aae9614839 Upgrade to tabs@0.12.0 2013-11-22 15:33:03 -08:00
Kevin Sawicki 7fa4121227 📝 Mark PackageManager constructor as private 2013-11-22 15:19:23 -08:00
Kevin Sawicki 1d783826a2 📝 Doc Selection::compare 2013-11-22 15:19:23 -08:00
Ben Ogle bdb6e193de Upgrade find-and-replace@0.49.0 2013-11-22 15:18:43 -08:00
Ben Ogle 3f75512de2 Tooltips can now override the default options 2013-11-22 15:15:05 -08:00
Ben Ogle 5910b05344 Use my fork of bootstrap for now
I added some things to tooltips that we need. Namely, fitting them within the viewport.
2013-11-22 15:15:05 -08:00
Kevin Sawicki 7f039b3383 Update confirmSync references in specs 2013-11-22 15:09:47 -08:00
Kevin Sawicki ca35ced587 📝 Use markdown for example 2013-11-22 15:08:18 -08:00
Kevin Sawicki 734ef19f48 Upgrade to tree-view@0.39.0 2013-11-22 15:02:08 -08:00
Kevin Sawicki ef9ce1bf70 Consolidate Atom::confirm/confirmSync
Support both an array and hash of buttons to allow callbacks
optionally.
2013-11-22 15:00:32 -08:00
Kevin Sawicki c754b73b71 📝 Doc what paths are returned 2013-11-22 14:39:27 -08:00
Kevin Sawicki 21565332a4 Use fs-plus to get home directory path 2013-11-22 14:39:27 -08:00
Kevin Sawicki 8871d9cd2d Remove unused Atom::getTempDirPath 2013-11-22 14:39:26 -08:00
Kevin Sawicki 64f0fcc839 📝 Add docs to Atom class 2013-11-22 14:39:26 -08:00
Nathan Sobo 581d12b04f Upgrade to Telepath 0.45.0 for references and to debug #1153
I downgraded back to 0.38.0 after a brief period on 0.44.0 in which I
saw issues. 0.44.0 is a pretty big jump that introduces reference
semantics. I've since only seen issue #1153, which @mcolyer saw at
version 0.38.0 as well. 0.45.0 throws an exception at the moment I think
markers are getting into a bad state, so hopefully it should help us
debug the problem.
2013-11-22 16:52:10 -05:00
Kevin Sawicki 05a9ace3e6 📝 Add period to comment 2013-11-22 13:43:43 -08:00
Kevin Sawicki 03eac362f6 📝 Add missing colon to Private 2013-11-22 13:39:24 -08:00
Kevin Sawicki 8a05b0f51d 📝 Mark setDigest as private 2013-11-22 13:31:27 -08:00
Matt Colyer 4069d23d86 📝 Indicate how to access DeserializerManager 2013-11-22 14:53:08 -05:00
Kevin Sawicki 78b48345ac Update reference to renamed param 2013-11-22 11:52:21 -08:00
Matt Colyer 139e2f6de0 :note: Mark ContextMenu as private 2013-11-22 14:49:10 -05:00
Kevin Sawicki ed86b4a478 📝 Mark EditorView public 2013-11-22 11:48:00 -08:00
Kevin Sawicki f2352131cc 📝 Mark SiteShim private 2013-11-22 11:45:36 -08:00
Kevin Sawicki 56df435fb8 📝 Mark ::get as private and tweak comments 2013-11-22 11:43:52 -08:00
Kevin Sawicki 595ff19b5b 📝 Mark LessCompileCache class private 2013-11-22 11:40:52 -08:00
Kevin Sawicki 33eb0bae8f 📝 Add docs to all public methods 2013-11-22 11:37:29 -08:00
Kevin Sawicki fde1560377 📝 doc PackageManager as public 2013-11-22 10:59:43 -08:00
Kevin Sawicki a640d07599 Merge pull request #1151 from atom/ks-remove-global-functions
Remove global functions
2013-11-22 10:26:35 -08:00
Kevin Sawicki 45b65cd3aa Organize imports 2013-11-22 10:13:59 -08:00
Kevin Sawicki f217278001 Move editor window helpers to Atom class 2013-11-22 10:13:59 -08:00
Kevin Sawicki 3320176a0a Move atom/apm install helpers to CommandInstaller 2013-11-22 10:13:59 -08:00
Kevin Sawicki 754b5a6004 Remove unused requires 2013-11-22 10:13:59 -08:00
Kevin Sawicki 79b84b2433 Move window.deserializeEditorWindow to Atom class 2013-11-22 10:13:59 -08:00
Kevin Sawicki 17be036ff8 Move window.setUpEnvironment to Atom class 2013-11-22 10:13:59 -08:00
Ben Ogle 23deec833f Upgrade to bootstrap 3.0.2 2013-11-22 10:11:24 -08:00
Ben Ogle 6a8d0bef4a Merge branch 'master' of github.com:atom/atom 2013-11-22 10:03:06 -08:00
Ben Ogle d5ce1a0312 Add more chars to the shortcut parser 2013-11-22 10:02:52 -08:00
Kevin Sawicki 74decbd18a Upgrade to terminal@0.22.0 refs #1150 2013-11-22 09:33:17 -08:00
Matt Colyer 085806f97f Upgrade terminal@0.21.0 2013-11-22 10:12:19 -05:00
Matt Colyer ca8be83903 Upgrade terminal@0.20.0 2013-11-22 09:46:59 -05:00
Matt Colyer da713da311 Merge pull request #1147 from atom/pass-original-event
Pass originalEvent property on command events
2013-11-22 06:19:36 -08:00
Kevin Sawicki 7a6c75a83e Refresh cache when core.themes changes
Previously this wasn't needed because a new cache was created for each
stylesheet loaded.
2013-11-21 17:46:29 -08:00
Kevin Sawicki 3e7a517c25 Add missing @ before lessCache lazy initialization 2013-11-21 17:03:10 -08:00
Kevin Sawicki e623ef4232 Upgrade to exception-reporting@0.8.0 2013-11-21 16:56:24 -08:00
Ben Ogle 18399aa264 Replace keystrokes in tooltips 2013-11-21 16:53:38 -08:00
Kevin Sawicki 2a5f393712 Use resource path from atom.getLoadSettings() 2013-11-21 16:32:12 -08:00
Kevin Sawicki 27f779ec03 Merge pull request #1149 from atom/ks-user-dot-js
~/.atom/user.js
2013-11-21 16:26:18 -08:00
Kevin Sawicki 5d717eb7bd Load ~/.atom/user.js when available 2013-11-21 16:21:37 -08:00
Kevin Sawicki 0b457fd80a Merge pull request #1148 from atom/ks-remove-resource-path
🔥 window.resourcePath
2013-11-21 16:19:42 -08:00
Kevin Sawicki dd9aa2d02f 💄 Remove extra space 2013-11-21 16:08:27 -08:00
Kevin Sawicki 87b530140b Remove window.resourcePath 2013-11-21 16:08:27 -08:00
Kevin Sawicki 2f46fee1ca Use resource path from load settings 2013-11-21 16:08:27 -08:00
Kevin Sawicki fbb48e7807 Merge pull request #1146 from atom/ks-menu-selectors
Check selectors using webkitMatchesSelector
2013-11-21 16:07:04 -08:00
Ben Ogle 01c141eec6 Upgrade styleguide 2013-11-21 16:05:07 -08:00
Kevin Sawicki 7d9d0c715c 📝 Mention what testEditor simulates 2013-11-21 16:01:55 -08:00
Kevin Sawicki a9887b5007 Remove logging 2013-11-21 16:01:55 -08:00
Kevin Sawicki c4dec72dcd Return early when document.body matches selector 2013-11-21 16:01:55 -08:00
Kevin Sawicki d093d5cc06 Check selectors using webkitMatchesSelector 2013-11-21 16:01:55 -08:00
Ben Ogle 27c9e54538 Upgrade styleguide 2013-11-21 15:44:40 -08:00
Ben Ogle 3bbe6ee98c Merge branch 'master' of github.com:atom/atom 2013-11-21 15:30:13 -08:00
Matt Colyer 524d8e8e21 Merge remote-tracking branch 'origin/master' into pass-original-event 2013-11-21 17:54:54 -05:00
Kevin Sawicki c31211dc21 Full screen window after it is shown and focused
This prevents a blank menu bar from appearing when opening a window
that was previously closed when in full screen mode.

Closes #1144
2013-11-21 14:51:49 -08:00
Matt Colyer 6c1b63d352 Pass originalEvent property on command events
vim-mode needs access to the original keystroke that triggered the
event.
2013-11-21 17:49:07 -05:00
Ben Ogle 6fa7da79eb Provide a defualt 2013-11-21 14:34:49 -08:00
Ben Ogle c2371f3054 Allow passing an htmlElement into requireStylesheet 2013-11-21 14:32:48 -08:00
Kevin Sawicki 2349627e3c Tweak modifier order in spec 2013-11-21 13:56:12 -08:00
Kevin Sawicki 90d92a4c92 Upgrade to go-to-line@0.10.0 for atom prefix fixes 2013-11-21 13:46:54 -08:00
Matt Colyer 66171e0301 Modifiers need to be added in alphabetical order 2013-11-21 16:17:37 -05:00
Kevin Sawicki cdc7f70b22 Pass buffer from event to TextBuffer::removeBuffer
Previously only the last buffer would be destroyed since the buffer
from the loop variable was being used.
2013-11-21 13:04:47 -08:00
Matt Colyer e225dbe93d Merge pull request #1130 from atom/meta-to-command
Use `cmd` instead of `meta`
2013-11-21 12:41:31 -08:00
Kevin Sawicki 7dc18765ad Call serializeForPersistence instead of serialize 2013-11-21 11:29:05 -08:00
Matt Colyer c1d379fd6c Update packages for updated keymaps 2013-11-21 14:07:38 -05:00
Matt Colyer a754ac4da0 Revert "Alias meta to cmd in keymaps"
This reverts commit f0aa408b70.
2013-11-21 13:08:12 -05:00
Kevin Sawicki 21560df2f0 Add platform class to selectors array 2013-11-21 09:19:33 -08:00
Matt Colyer f0aa408b70 Alias meta to cmd in keymaps 2013-11-21 10:38:13 -05:00
Matt Colyer 161c9a62b5 Merge branch 'master' into meta-to-command
Conflicts:
	spec/keymap-spec.coffee
2013-11-21 09:59:49 -05:00
Nathan Sobo 2c5bbcbc22 Merge branch 'ns-fix-telepath' 2013-11-20 22:08:00 -07:00
Nathan Sobo eee72f7664 Drop back to telepath 0.38.0 until I figure out what's going on 2013-11-20 21:59:52 -07:00
Nathan Sobo 073d398e6f Upgrade telepath to 0.43.0 so we don't serialize orphans 2013-11-20 21:18:08 -07:00
Kevin Sawicki 2310e263a7 Upgrade to tabs@0.11.0 refs #1143 2013-11-20 19:30:50 -08:00
Kevin Sawicki de7b212d99 Change cancel to off for consistency with emissary 2013-11-20 19:07:56 -08:00
Kevin Sawicki 75873ef6b3 Upgrade apm for develop command running install 2013-11-20 18:58:44 -08:00
Kevin Sawicki 73855a49fc Merge pull request #1142 from atom/ks-remove-fs-shims
Remove fs-plus shims
2013-11-20 18:26:09 -08:00
Kevin Sawicki cae055fd3f Upgrade to tree-view@0.37.0 2013-11-20 18:21:09 -08:00
Kevin Sawicki 2aad31c4dc Upgrade to find-and-replace@0.47.0 2013-11-20 18:08:46 -08:00
Kevin Sawicki 93052ad611 Upgrade to fuzzy-finder@0.24.0 2013-11-20 18:06:31 -08:00
Kevin Sawicki 67733b8b05 Upgrade to git-diff@0.16.0 2013-11-20 18:04:07 -08:00
Kevin Sawicki 21543569ef Upgrade to package-generator@0.21.0 2013-11-20 18:01:42 -08:00
Kevin Sawicki 7371ebbf20 Upgrade to status-bar@0.22.0 2013-11-20 18:00:05 -08:00
Kevin Sawicki 73470cc294 Upgrade to symbols-view@0.23.0 2013-11-20 17:58:00 -08:00
Kevin Sawicki 1e60b5fa3b Upgrade to archive-view@0.14.0 2013-11-20 17:56:45 -08:00
Kevin Sawicki 172ecbd897 Upgrade to tree-view@0.36.0 2013-11-20 17:54:35 -08:00
Kevin Sawicki 289cc24b56 Remove fs shims 2013-11-20 17:48:10 -08:00
Kevin Sawicki a20483ccdb Merge pull request #1140 from atom/ks-remove-project-root-view-globals
Remove project/rootView globals
2013-11-20 17:34:44 -08:00
Kevin Sawicki b2ceaf3b8b Upgrade packages for missing atom prefix fixes 2013-11-20 17:29:01 -08:00
Kevin Sawicki 1c3c508985 Upgrade apm for new package templates 2013-11-20 17:23:48 -08:00
Kevin Sawicki 645f4ad907 📝 Add atom prefix package example 2013-11-20 17:23:48 -08:00
Kevin Sawicki 05dd6f8f17 Upgrade to fuzzy-finder@0.23.0 2013-11-20 17:23:48 -08:00
Kevin Sawicki b19390b519 Add missing atom prefix to rootView and project 2013-11-20 17:23:48 -08:00
Kevin Sawicki a3f339e0c3 Correct order of refresh steps 2013-11-20 17:23:48 -08:00
Kevin Sawicki 42040e14b3 Add atom prefix to rootView and project 2013-11-20 17:23:48 -08:00
Kevin Sawicki 91640f0886 Add atom prefix to project references 2013-11-20 17:23:47 -08:00
Kevin Sawicki 0377d64788 Assign to atom.project instead of window.project 2013-11-20 17:23:47 -08:00
Kevin Sawicki cd37caae96 Add atom prefix to rootView 2013-11-20 17:23:47 -08:00
Kevin Sawicki aab63c26e7 Add atom prefix to project 2013-11-20 17:23:47 -08:00
Kevin Sawicki 6da6101a52 Upgrade packages for project/rootView global fixes 2013-11-20 17:23:47 -08:00
Kevin Sawicki 87b33648dc Use project passed in via options hash 2013-11-20 17:23:47 -08:00
Kevin Sawicki d0b380e535 Add atom prefix to rootView and project references 2013-11-20 17:23:47 -08:00
Kevin Sawicki 99480901e2 Add missing atom prefix 2013-11-20 17:23:47 -08:00
Kevin Sawicki 6852720408 Add atom prefix to project references 2013-11-20 17:23:47 -08:00
Kevin Sawicki f9498732a5 Add atom prefix to rootView 2013-11-20 17:23:47 -08:00
Kevin Sawicki e4aa82fda1 Remove window.rootView shims 2013-11-20 17:23:47 -08:00
Kevin Sawicki bc1a743b2f Remove project and rootView from window 2013-11-20 17:23:47 -08:00
Ben Ogle 3fe22aa5c8 Set font sizes 2013-11-20 17:11:50 -08:00
Ben Ogle fe035d4d7c Merge pull request #1141 from atom/bo-jquery-extensions
Add setTooltip jquery function
2013-11-20 17:11:21 -08:00
Ben Ogle e8bfb7ca09 Fix up things for kevin 2013-11-20 17:10:57 -08:00
Ben Ogle 4bfd48b983 Add setTooltip jquery function 2013-11-20 16:55:50 -08:00
Nathan Sobo 5a1fadf7ce Merge branch 'ns-telepath-references' 2013-11-20 17:12:06 -07:00
Ben Ogle 819ac9ea68 Add keyBindingsForCommandMatchingElement to keymap 2013-11-20 15:43:02 -08:00
Nathan Sobo 6384841134 Upgrade to telepath 0.42.0 for references 2013-11-20 16:23:04 -07:00
Paul Betts a0fbec29c3 Merge pull request #1137 from atom/windows-fonts
Set up Windows font fallbacks
2013-11-20 15:14:21 -08:00
Ben Ogle 238fca2004 upgrade status-bar and grammar-selector
Use the status bar api in grammar-selector
2013-11-20 14:52:19 -08:00
Kevin Sawicki 014beda455 Merge pull request #1138 from atom/ks-remove-deserializer-shims
Remove deserializer shims
2013-11-20 14:51:03 -08:00
Kevin Sawicki 777df644ce Upgrade to markdown-preview@0.18.0 2013-11-20 14:40:04 -08:00
Kevin Sawicki f3ea3a3395 Add missing atom.deserializers prefix 2013-11-20 14:33:55 -08:00
Kevin Sawicki b82fdace61 Add missing atom.deserializers prefix 2013-11-20 14:26:56 -08:00
Kevin Sawicki 7195102a04 Upgrade to find-and-replace@0.45.0 2013-11-20 14:19:47 -08:00
Kevin Sawicki 5ec6a4a189 Use atom.deserializers directly 2013-11-20 14:18:38 -08:00
Kevin Sawicki e330b1a2e8 Use atom.deserializers directly 2013-11-20 14:16:38 -08:00
Kevin Sawicki 5334433bc2 Upgrade to tabs@0.10.0 2013-11-20 14:13:54 -08:00
Kevin Sawicki 366a12903a Deserialize using atom.deserializers 2013-11-20 14:13:13 -08:00
Kevin Sawicki 063cb04fb5 Upgrade to styleguide@0.11.0 2013-11-20 14:10:00 -08:00
Kevin Sawicki d9c2f07fbe Use atom.deserializers directly 2013-11-20 14:09:44 -08:00
Kevin Sawicki 5c1fa8e53d Upgrade to terminal@0.18.0 2013-11-20 14:07:08 -08:00
Kevin Sawicki a1f3540cb4 Call deserialize on deserializers ivar 2013-11-20 14:00:51 -08:00
Kevin Sawicki 2eeb399cf1 Remove deserializer shims on window 2013-11-20 13:51:12 -08:00
Kevin Sawicki 71e8e865f2 Merge pull request #1131 from atom/ks-remove-shims
Remove shims
2013-11-20 13:42:11 -08:00
Paul Betts 9f080be6e1 Add Courier New as a last-chance fallback 2013-11-20 13:21:30 -08:00
Kevin Sawicki 56f66f8578 Upgrade to release-notes@0.12.0 2013-11-20 12:49:16 -08:00
Kevin Sawicki 0b1dc704ea Upgrade to tabs@0.9.0 2013-11-20 12:49:16 -08:00
Kevin Sawicki 578d823118 Upgrade to find-and-replace@0.44.0 2013-11-20 12:49:16 -08:00
Kevin Sawicki 0196f2a2eb Upgrade to dev-live-reload@0.16.0 2013-11-20 12:49:16 -08:00
Kevin Sawicki 1e68a7266f Add atom prefix to keymap global 2013-11-20 12:49:16 -08:00
Kevin Sawicki 093143f7a9 Upgrade to symbols-view@0.21.0 2013-11-20 12:49:16 -08:00
Kevin Sawicki 4eeef9cfbd Upgrade packages for shim removal fixes 2013-11-20 12:49:15 -08:00
Kevin Sawicki ce3ec75c55 Remove remaining package manager shims 2013-11-20 12:49:15 -08:00
Kevin Sawicki bb09de9703 Upgrade to wrap-guide@0.6.0 for spec fixes 2013-11-20 12:48:50 -08:00
Kevin Sawicki e64ba18fe3 Upgrade to visual-bell@0.4.0 for atom global fixes 2013-11-20 12:48:50 -08:00
Kevin Sawicki 3908f81fc6 Upgrade to spell-check@0.14.0 for spec fixes 2013-11-20 12:48:06 -08:00
Kevin Sawicki fac46a295c Add shim for rootView on either atom or window 2013-11-20 12:48:06 -08:00
Kevin Sawicki b01470a738 Upgrade to settings-view@0.44.0 for config fixes 2013-11-20 12:48:06 -08:00
Kevin Sawicki f3be613662 Add atom prefix to config global 2013-11-20 12:48:06 -08:00
Kevin Sawicki ede29d99c1 Access package manager via atom.packages 2013-11-20 12:48:05 -08:00
Kevin Sawicki d2369e94c8 Add atom prefix to config reference 2013-11-20 12:48:05 -08:00
Kevin Sawicki dbe3399016 Upgrade to autoflow@0.6.0 for global fixes 2013-11-20 12:48:05 -08:00
Kevin Sawicki 3952423d99 Access package manager methods on atom.packages 2013-11-20 12:48:05 -08:00
Kevin Sawicki ffdcecc0f2 Remove unused package manager shims on atom 2013-11-20 12:48:05 -08:00
Kevin Sawicki 0069eb4d0d Remove atom.isPackageActive shim 2013-11-20 12:48:05 -08:00
Kevin Sawicki 5fa55026d5 Call loadPackage on atom.packages 2013-11-20 12:48:05 -08:00
Kevin Sawicki 6d04d57e74 Remove atom.loadPackage shim 2013-11-20 12:48:05 -08:00
Kevin Sawicki 3f0dca5a40 Remove unused package managers shims 2013-11-20 12:48:05 -08:00
Kevin Sawicki 8b14a66e2c Upgrade to settings-view@0.43.0 2013-11-20 12:48:05 -08:00
Kevin Sawicki 1607411df1 Upgrade to timecop@0.10.0 2013-11-20 12:48:05 -08:00
Kevin Sawicki dade9f6309 Upgrade to metrics@0.12.0 2013-11-20 12:48:05 -08:00
Kevin Sawicki 568aa1d396 Remove some package manager shims on atom global 2013-11-20 12:48:05 -08:00
Kevin Sawicki 9febe179fa Remove unused deserializer shims 2013-11-20 12:48:04 -08:00
Kevin Sawicki c9e68ab044 Remove window.config shim from spec helper 2013-11-20 12:48:04 -08:00
Kevin Sawicki 285186567a Upgrade to status-bar@0.18.0 for syntax global fixes 2013-11-20 12:48:04 -08:00
Kevin Sawicki 1c136f16e3 Upgrade to keybind-resolve@0.4.0 for rootView fix 2013-11-20 12:48:04 -08:00
Kevin Sawicki 534a2d4565 Upgrade to markdown-preview@0.17.0 for atom prefix on globals 2013-11-20 12:48:04 -08:00
Kevin Sawicki 9e814de969 Remove window.config shim 2013-11-20 12:48:04 -08:00
Kevin Sawicki 7202ba274a Upgrade to status-bar@0.17.0 for atom.syntax usage 2013-11-20 12:48:04 -08:00
Kevin Sawicki 46e85fac87 Remove window.syntax shim 2013-11-20 12:48:04 -08:00
Kevin Sawicki d1f1b494cf Remove window.keymap shim 2013-11-20 12:48:04 -08:00
Kevin Sawicki f11803df60 Remove window.site shim 2013-11-20 12:48:04 -08:00
Paul Betts f094a86ae7 Initial hack of proper Windows fonts 2013-11-20 12:47:32 -08:00
Ben Ogle a6c791ce39 Upgrade to tree-view@0.34.0 2013-11-20 11:40:08 -08:00
Matt Colyer dfa870f514 Merge branch 'master' into meta-to-command
Conflicts:
	keymaps/win32.cson
2013-11-20 10:19:12 -08:00
Corey Johnson a98377b899 Merge pull request #1132 from atom/cj-editor-rename
Editor & EditSession rename
2013-11-20 10:11:09 -08:00
probablycorey c3de3d8eea Update documentation 2013-11-20 10:04:28 -08:00
probablycorey 2d15f5e49a Remove pathForRepositoryUrl from atom exports 2013-11-20 10:03:06 -08:00
Matt Colyer 56386cb06a Upgrade atom-shell@0.6.11 2013-11-20 08:48:03 -08:00
Ben Ogle 986a7ad5c3 Merge pull request #1135 from atom/workspace-class
Use `.workspace` rather than `body` for keybindings
2013-11-19 18:50:43 -08:00
Kevin Sawicki 9a01b5a6bf Use Date.now() 2013-11-19 17:15:25 -08:00
Matt Colyer ccafda6f7f Keep .platform-<platform> rather than .workspace-<platform> 2013-11-19 17:03:16 -08:00
Matt Colyer 33538a5ed7 Use .workspace rather than body for keybindings 2013-11-19 16:57:10 -08:00
Ben Ogle aae85cd7c1 Upgrade to find-and-replace@0.43.0 2013-11-19 16:56:32 -08:00
Matt Colyer ce098e587f Reduce specificity of platform keybindings 2013-11-19 16:46:46 -08:00
Kevin Sawicki 233d819e04 Add atom prefix to syntax global 2013-11-19 16:37:50 -08:00
Kevin Sawicki fbbf3d177a Upgrade to whitespace@0.9.0 2013-11-19 16:33:46 -08:00
probablycorey c33bd34996 Add reverse compatability for Editor creation 2013-11-19 16:22:29 -08:00
probablycorey 34cdb23d71 Remove file
I didn't mean to check this file in.
2013-11-19 15:57:41 -08:00
probablycorey fcedcd117d Merge remote-tracking branch 'origin/master' into cj-editor-rename 2013-11-19 15:55:20 -08:00
Matt Colyer 3d7de21d6c Replicate command keybindings on windows 2013-11-19 15:53:43 -08:00
Matt Colyer 2278ee742a Merge remote-tracking branch 'origin/master' into meta-to-command 2013-11-19 15:35:31 -08:00
Matt Colyer 55e90f8ae1 Use cmd instead of command 2013-11-19 15:29:37 -08:00
probablycorey 2ca738453b Update benchmarks 2013-11-19 15:24:50 -08:00
probablycorey 31a9bb83cf Replace editSession variables with editor 2013-11-19 15:22:47 -08:00
Matt Colyer 1e4504e7f3 Use command instead of meta 2013-11-19 15:16:55 -08:00
probablycorey bf05ddb958 🔫
I screwed up a rebase, this nasty commit is the result.
2013-11-19 15:15:12 -08:00
probablycorey 756c2be64a Replace editor instance variables with editorView 2013-11-19 14:57:35 -08:00
probablycorey 6fdd4f775b Rename TextEditor and TextEditorView to Editor and EditorView 2013-11-19 14:57:35 -08:00
probablycorey 625fcaffc8 Update TextEditor specs 2013-11-19 14:57:31 -08:00
probablycorey 955d379e0e Rename EditSession to TextEditor 2013-11-19 14:56:09 -08:00
Kevin Sawicki 0d71f20073 Upgrade to gists@0.8.0 for pasteboard fix 2013-11-19 14:43:28 -08:00
Kevin Sawicki 42c40e8c7a Upgrade to to-the-hubs@0.11.0 for pasteboard fix 2013-11-19 14:39:44 -08:00
probablycorey 89212e599f Update requires 2013-11-19 14:34:26 -08:00
probablycorey 95e4ac903c Use Range literals 2013-11-19 14:34:26 -08:00
probablycorey 311155ac0d Rename editor-spec to text-editor-view-spec 2013-11-19 14:34:26 -08:00
probablycorey aaa82e23da Rename Editor to TextEditorView 2013-11-19 14:34:20 -08:00
Kevin Sawicki 8e46bc5241 Add shim for atom.rootView vs. window.rootView 2013-11-19 14:15:47 -08:00
Matt Colyer 37a5a6f501 Merge pull request #1117 from atom/platform-keybindings
Platform keybindings
2013-11-19 14:10:53 -08:00
Kevin Sawicki 83f14c137c Remove window.pasteboard shim 2013-11-19 14:03:44 -08:00
Matt Colyer b0b458b1f6 Review remaining global bindings 2013-11-19 13:53:10 -08:00
Kevin Sawicki f4de124aa6 Add atom prefix to rootView reference 2013-11-19 13:34:01 -08:00
Kevin Sawicki 4b0eaf05a5 Remove Emitter::trigger shim 2013-11-19 13:24:29 -08:00
Kevin Sawicki 03e8bc6f19 Remove Emitter::one shim 2013-11-19 12:58:56 -08:00
Kevin Sawicki 13186fcf7a Remove Emitter::subscriptionCount shim 2013-11-19 12:55:18 -08:00
Kevin Sawicki fea0f1f90a 📝 atom.project instead of global.project 2013-11-19 12:30:05 -08:00
Matt Colyer b449bb4444 Fix update-atom-shell task when using the keychain 2013-11-19 12:21:12 -08:00
Matt Colyer fe6b40fc5d Merge branch 'master' into platform-keybindings 2013-11-19 11:58:48 -08:00
Matt Colyer 82e3935ae3 Guard against undefined labels 2013-11-19 11:57:59 -08:00
Matt Colyer 32a3b6302c Use document.body to be concise 2013-11-19 11:21:50 -08:00
Matt Colyer 6157fcaf73 Merge branch 'master' into platform-keybindings 2013-11-19 11:11:32 -08:00
Matt Colyer ab74d8be38 Merge pull request #1115 from atom/refine-paste-normalization
Don't normalize indents on paste if there are preceding characters, fixes #1112
2013-11-19 10:54:44 -08:00
Kevin Sawicki 886a2aa867 Remove pathForRepositoryUrl from exports 2013-11-19 10:26:33 -08:00
Kevin Sawicki aeaa76a9e1 Remove Site from exports 2013-11-19 10:25:42 -08:00
Kevin Sawicki 6a7bcb6f52 Prepare next release 2013-11-19 09:31:13 -08:00
Kevin Sawicki ee1ec4670d Listen for destroyed events on deserialized buffers 2013-11-19 09:08:24 -08:00
Kevin Sawicki 7e0af4c575 Prepare next release 2013-11-18 18:49:23 -08:00
Kevin Sawicki f55a200591 Return emissary subscription directly 2013-11-18 18:41:43 -08:00
Kevin Sawicki 89d8eac091 Remove console.log statement 2013-11-18 16:09:25 -08:00
probablycorey 5011b6e78f Remove atom argument from activate 2013-11-18 15:50:36 -08:00
probablycorey d6e67c5b32 Update find-and-replace 2013-11-18 15:10:13 -08:00
Ben Ogle de547e20c2 Oops 2013-11-18 15:07:49 -08:00
Ben Ogle 2b79b19330 Upgrade ui themes and style guide to style progress bars 2013-11-18 15:05:52 -08:00
Matt Colyer 2b234545b5 Merge pull request #1116 from atom/windows-menus
Make Windows menus more Native(tm), fixes #1085
2013-11-18 11:08:04 -08:00
Kevin Sawicki a66543048b Include buffer in emitted events 2013-11-18 10:06:14 -08:00
Kevin Sawicki ca96aa2804 📝 doc what DisplayBuffer::getGrammar returns 2013-11-18 09:30:56 -08:00
Kevin Sawicki 316571308a Remove unused ws dependency 2013-11-15 15:34:52 -08:00
Matt Colyer b323d9ce18 Rename hasNoPrecedingCharacters => hasPrecedingCharactersOnLine 2013-11-15 15:32:24 -08:00
Corey Johnson 0e1c757cd0 Merge pull request #1119 from atom/cj-keymap-cleanup
Keymap cleanup
2013-11-15 14:42:20 -08:00
probablycorey 084bbb1578 Use skinny arrow 2013-11-15 14:35:02 -08:00
probablycorey 7c348ee478 Update packages 2013-11-15 14:25:48 -08:00
probablycorey a0c6a94409 Added documentation for Keymap's public classes 2013-11-15 14:23:52 -08:00
probablycorey 80cdf61fa4 Update remove spec 2013-11-15 14:09:24 -08:00
probablycorey 29c3fadb6f Move public methods to top of file 2013-11-15 14:07:01 -08:00
probablycorey 1ae3806c69 Use source instead of name 2013-11-15 14:06:03 -08:00
probablycorey 98b509441c Move methods into KeyBinding class 2013-11-15 14:05:35 -08:00
probablycorey 02f40688e2 Merge remote-tracking branch 'origin/master' into cj-keymap-cleanup 2013-11-15 13:53:42 -08:00
probablycorey cb8e378af6 Use keyBinding in place of binding in method names 2013-11-15 13:49:17 -08:00
Kevin Sawicki babc4732b8 Merge pull request #1111 from atom/ks-extend-model
Extend telepath.Model
2013-11-15 13:43:23 -08:00
probablycorey dcccde8f3f Clone default keybindings in specs 2013-11-15 13:32:31 -08:00
probablycorey 8ed4923e58 Replace binding-set with key-binding 2013-11-15 13:32:09 -08:00
probablycorey 529c829438 💄 2013-11-15 11:54:18 -08:00
probablycorey 809a02ca10 Clone keyBindings by default 2013-11-15 11:54:09 -08:00
probablycorey b9902cb6f2 Add specs 2013-11-15 11:50:55 -08:00
Kevin Sawicki de4d3dbbe9 Create new project when state doesn't return a Project 2013-11-15 11:37:25 -08:00
Kevin Sawicki 3fe88c4df1 💄 Add period to comment 2013-11-15 11:17:35 -08:00
Kevin Sawicki 20811a9f52 📝 Mention which methods are telepath hooks 2013-11-15 11:17:35 -08:00
Kevin Sawicki b137f1a3e3 Upgrade to emissary@0.17.0 2013-11-15 11:17:35 -08:00
Kevin Sawicki 0b12f01206 Use Project::bufferForPathSync instead of buildBufferSync 2013-11-15 11:17:35 -08:00
Kevin Sawicki 1d7b4c5f9a Updating places still using Buffer instead of TextBuffer 2013-11-15 11:17:35 -08:00
Kevin Sawicki e2d4b58d5f Remove unused Range 2013-11-15 11:17:35 -08:00
Kevin Sawicki 1c8df2c0b5 💄 Organize imports in TextBuffer 2013-11-15 11:17:35 -08:00
Kevin Sawicki 9067c65a41 Use Atom::replicate to test serialization 2013-11-15 11:17:35 -08:00
Kevin Sawicki 1d4f2fba8b Use id provide by telepath.Model 2013-11-15 11:17:34 -08:00
Kevin Sawicki 12dd412439 Restore relative path as uri of TextBuffer 2013-11-15 11:17:34 -08:00
Kevin Sawicki 19d680544b Use Atom::replicate to obtain second project 2013-11-15 11:17:34 -08:00
Kevin Sawicki a45dd3fe37 Register deepest model classes first 2013-11-15 11:17:34 -08:00
Kevin Sawicki f6c8a435ae Upgrade to telepath@0.37.0 2013-11-15 11:17:34 -08:00
Kevin Sawicki 93bfe0edf6 Store path when set in project 2013-11-15 11:17:34 -08:00
Kevin Sawicki d3fed57cb3 Only serialize project state for persistence 2013-11-15 11:17:34 -08:00
Kevin Sawicki 8372adb38a Remove spec for removed TextBuffer::getRelativePath 2013-11-15 11:17:34 -08:00
Kevin Sawicki e4b3d3a83c Call getValues() when iterating over buffers 2013-11-15 11:17:34 -08:00
Kevin Sawicki 11f1ef9d8b Destroy unretained buffers in beforePersistence 2013-11-15 11:17:34 -08:00
Kevin Sawicki 7d87ae00ff Use Atom::replicate for second project 2013-11-15 11:17:34 -08:00
Kevin Sawicki 3ec2378242 Access project from atom global 2013-11-15 11:17:34 -08:00
Kevin Sawicki 28943a35da Use getWindowState instead of referencing window state directly 2013-11-15 11:17:34 -08:00
Kevin Sawicki 7b43c8a860 Use Atom::replicate in git spec to simulate project serialization 2013-11-15 11:17:33 -08:00
Kevin Sawicki 8b17b7eca9 Remove unused repoUrl property 2013-11-15 11:17:33 -08:00
Kevin Sawicki 6432cda691 Upgrade to telepath@0.35.0 2013-11-15 11:17:33 -08:00
Kevin Sawicki cf0bdb9c94 Remove unused property 2013-11-15 11:17:33 -08:00
Kevin Sawicki 34f1472653 Use getValues() when iterating over buffers 2013-11-15 11:17:33 -08:00
Kevin Sawicki a475e27cd4 Call createAsRoot for mini editor's buffer 2013-11-15 11:17:33 -08:00
Kevin Sawicki abc1f23516 Remove unused relative path from Editor/EditSession/TextBuffer 2013-11-15 11:17:33 -08:00
Kevin Sawicki dc7e7f9ed0 Listen for buffer destroyed in Project 2013-11-15 11:17:33 -08:00
Kevin Sawicki 5fdec4dc7b Move checkoutHead implementation to Editor 2013-11-15 11:17:33 -08:00
Kevin Sawicki 618d281d6c Restore buffer.release() call to previously location 2013-11-15 11:17:33 -08:00
Kevin Sawicki 055ec8cb9c Implement beforePersistence in TextBuffer 2013-11-15 11:17:33 -08:00
Kevin Sawicki df3fe90c89 Upgrade to telepath@0.33.0 2013-11-15 11:17:33 -08:00
Kevin Sawicki 21e0e95a7a Add model property for disk contents digest 2013-11-15 11:17:33 -08:00
Kevin Sawicki 6caed6e918 Add model property for relative path 2013-11-15 11:17:32 -08:00
Kevin Sawicki 7dd84636ba Use Project::addBuffer instead of window.deserialize 2013-11-15 11:17:32 -08:00
Kevin Sawicki b12954760d Use Project::addBuffer instead of ::openSync 2013-11-15 11:17:32 -08:00
Kevin Sawicki 4bb21fd9ec Use project.addBuffer instead of window.deserialize 2013-11-15 11:17:32 -08:00
Kevin Sawicki 11787e5a5d Return added buffer from Project::addBufferAtIndex 2013-11-15 11:17:32 -08:00
Kevin Sawicki 276e63611a Register buffer with project 2013-11-15 11:17:32 -08:00
Kevin Sawicki 957374eb40 Call telepath.Array::getValues() during clone 2013-11-15 11:17:32 -08:00
Kevin Sawicki fe9f1373c1 Cancel stopped changing timeout when destroyed 2013-11-15 11:17:32 -08:00
Kevin Sawicki 6290c19264 Set up spec Project as telepath model 2013-11-15 11:17:32 -08:00
Kevin Sawicki 913bb82d6e Remove debug logging 2013-11-15 11:17:32 -08:00
Kevin Sawicki ffc936ca4d Use telepath.Document::registerModelClasses 2013-11-15 11:17:32 -08:00
Kevin Sawicki 1808e5f991 Initial 🔪 at extending telepath.Model in Project/TextBuffer 2013-11-15 11:17:32 -08:00
Kevin Sawicki 62feefd28d Upgrade to emissary@0.15.0 2013-11-15 11:17:31 -08:00
Kevin Sawicki ada992be4d Upgrade to telepath@0.29.0 2013-11-15 11:17:31 -08:00
Kevin Sawicki f8933cfeab Upgrade to pathwatcher@0.10.0, refs atom/tree-view#17 2013-11-15 11:14:52 -08:00
probablycorey 0878d7ab6a Update specs 2013-11-15 10:45:21 -08:00
probablycorey bd8e19bce7 Update keymap in spec-helper 2013-11-15 10:43:20 -08:00
probablycorey 4852ba6d95 Don't store binding sets, instead store a keyBinding array 2013-11-15 10:21:38 -08:00
Kevin Sawicki caffcafe2e 🙉 Ignore stdout from installation of apm 2013-11-15 09:54:36 -08:00
probablycorey c7a1205ca6 Remove Editor:bindToKeyedEvent 2013-11-15 09:39:26 -08:00
probablycorey 2c4f94c319 Merge remote-tracking branch 'origin/master' into cj-keymap-cleanup 2013-11-15 09:24:45 -08:00
Corey Johnson 941fc97e79 Merge pull request #1118 from atom/cj-less-verbose-grunt
Less verbose grunt
2013-11-15 09:05:11 -08:00
probablycorey 8788b2a51c Add keybinding-resolver to default package list 2013-11-14 16:49:09 -08:00
probablycorey ca8ae9ad61 Remove bindingsForElement 2013-11-14 16:45:09 -08:00
probablycorey 2fb00af255 Rename keyMapping to keyBinding 2013-11-14 16:20:35 -08:00
probablycorey 94a8d16664 Update specs 2013-11-14 16:05:17 -08:00
probablycorey fc0a46d6b2 Add mappingsForKeystrokeMatchingElement 2013-11-14 16:05:10 -08:00
probablycorey fd443a8b68 Reorder args 2013-11-14 16:05:01 -08:00
probablycorey c43f277c5b Remove getAllKeyMappings 2013-11-14 14:46:21 -08:00
probablycorey dd0938dca6 Merge remote-tracking branch 'origin/master' into cj-keymap-cleanup 2013-11-14 14:43:37 -08:00
probablycorey e90f19da97 Rename keystrokeByCommmand to keystrokesByCommmand 2013-11-14 14:26:25 -08:00
probablycorey c3aea1d149 Remove keymap.keystrokeByCommmandForSelector 2013-11-14 14:18:54 -08:00
Paul Betts 569c3116a8 Add keyboard accelerators 2013-11-14 13:25:58 -08:00
probablycorey 8bdc1d2418 Better error messages 2013-11-14 13:10:31 -08:00
Matt Colyer 6a1e83205f Merge branch 'master' into refine-paste-normalization 2013-11-14 11:23:45 -08:00
Matt Colyer 33891b51f2 Split keybindings by platform 2013-11-14 11:20:40 -08:00
Matt Colyer 1ef821f4e7 Add CSS class indicating platform on body 2013-11-14 11:20:34 -08:00
probablycorey ed030a54c3 Output which package failed 2013-11-14 10:54:49 -08:00
probablycorey 6bb3a69410 Only show stderr if the process fails 2013-11-14 10:54:25 -08:00
probablycorey 53f5e9fbc6 Quite some grunt.log.write 2013-11-14 10:53:19 -08:00
Matt Colyer 1dac1f375c Provide keyboard navigation for base windows menus 2013-11-14 10:39:31 -08:00
Matt Colyer cfab5c619d Use fat arrow when necessary 2013-11-14 10:39:09 -08:00
Matt Colyer b6afc415f8 Merge menu items without regard to platform decorations 2013-11-14 10:31:20 -08:00
Matt Colyer 5454e93168 Make base menus platform dependent
This fixes the most egrerious errors on Windows but there's still room
for improvement.

Refs #1085
2013-11-14 10:15:23 -08:00
probablycorey 389b2bd8d6 Remove spec suite measuring.
This may be a bit aggressive, so we can add it back if people think it
has benifits.
2013-11-14 09:03:58 -08:00
probablycorey 8ea011597c Don't log start time when running specs 2013-11-14 09:01:54 -08:00
probablycorey 21060ae85a Update public keymap interface 2013-11-14 08:33:23 -08:00
probablycorey f67e9b6e03 Treat all calls to grunt.log.writeln as grunt.verbose.writeln 2013-11-13 17:52:22 -08:00
Matt Colyer 64f2cdb795 💄 2013-11-13 17:35:21 -08:00
probablycorey a996597d49 Call grunt.verbose.writeln instead of grunt.log.writeln 2013-11-13 17:24:49 -08:00
Matt Colyer 52680bd63f Don't normalize indents on paste if there are preceding characters 2013-11-13 17:18:43 -08:00
probablycorey 8f9f5ed0ed Update specs 2013-11-11 15:46:17 -08:00
probablycorey d71e58ec33 Use keystroke even when referring to multiKeystrokes
The use of keystroke and keystrokes was becoming confusing. When I 
started thinking of a keystroke as a set of keys that trigger a
command it became easier to think about.
2013-11-11 14:05:48 -08:00
probablycorey 8c8f1bc048 Make keymap changes backwards compatible 2013-11-11 11:42:11 -08:00
probablycorey 94bc4ce737 Update clear-cut 2013-11-11 11:42:10 -08:00
probablycorey 9914085ead Simplify keymap selector matching 2013-11-11 11:42:10 -08:00
94 arquivos alterados com 11246 adições e 10927 exclusões
+4
Ver Arquivo
@@ -8,6 +8,10 @@ _ = require 'underscore-plus'
packageJson = require './package.json'
module.exports = (grunt) ->
if not grunt.option('verbose')
grunt.log.writeln = (args...) -> grunt.log
grunt.log.write = (args...) -> grunt.log
[major, minor, patch] = packageJson.version.split('.')
if process.platform is 'win32'
appName = 'Atom'
+7 -7
Ver Arquivo
@@ -73,8 +73,8 @@ window.clickEvent = (properties={}) ->
window.mouseEvent = (type, properties) ->
if properties.point
{point, editor} = properties
{top, left} = @pagePixelPositionForPoint(editor, point)
{point, editorView} = properties
{top, left} = @pagePixelPositionForPoint(editorView, point)
properties.pageX = left + 1
properties.pageY = top + 1
properties.originalEvent ?= {detail: 1}
@@ -86,14 +86,14 @@ window.mousedownEvent = (properties={}) ->
window.mousemoveEvent = (properties={}) ->
window.mouseEvent('mousemove', properties)
window.pagePixelPositionForPoint = (editor, point) ->
window.pagePixelPositionForPoint = (editorView, point) ->
point = Point.fromObject point
top = editor.lines.offset().top + point.row * editor.lineHeight
left = editor.lines.offset().left + point.column * editor.charWidth - editor.lines.scrollLeft()
top = editorView.lines.offset().top + point.row * editorView.lineHeight
left = editorView.lines.offset().left + point.column * editorView.charWidth - editorView.lines.scrollLeft()
{ top, left }
window.setEditorWidthInChars = (editor, widthInChars, charWidth=editor.charWidth) ->
editor.width(charWidth * widthInChars + editor.lines.position().left)
window.seteditorViewWidthInChars = (editorView, widthInChars, charWidth=editorView.charWidth) ->
editorView.width(charWidth * widthInChars + editorView.lines.position().left)
$.fn.resultOfTrigger = (type) ->
event = $.Event(type)
+68 -68
Ver Arquivo
@@ -2,8 +2,8 @@ require './benchmark-helper'
{$, _, RootView} = require 'atom'
TokenizedBuffer = require '../src/tokenized-buffer'
describe "editor.", ->
editor = null
describe "editorView.", ->
editorView = null
beforeEach ->
window.rootViewParentSelector = '#jasmine-content'
@@ -12,19 +12,19 @@ describe "editor.", ->
rootView.width(1024)
rootView.height(768)
rootView.openSync() # open blank editor
editor = rootView.getActiveView()
rootView.openSync()
editorView = rootView.getActiveView()
afterEach ->
if editor.pendingDisplayUpdate
if editorView.pendingDisplayUpdate
waitsFor "editor to finish rendering", (done) ->
editor.on 'editor:display-updated', done
editorView.on 'editor:display-updated', done
describe "keymap.", ->
event = null
beforeEach ->
event = keydownEvent('x', target: editor.hiddenInput[0])
event = keydownEvent('x', target: editorView.hiddenInput[0])
benchmark "keydown-event-with-no-binding", 10, ->
keymap.handleKeyEvent(event)
@@ -35,8 +35,8 @@ describe "editor.", ->
describe "empty-file.", ->
benchmark "insert-delete", ->
editor.insertText('x')
editor.backspace()
editorView.insertText('x')
editorView.backspace()
describe "300-line-file.", ->
beforeEach ->
@@ -44,81 +44,81 @@ describe "editor.", ->
describe "at-begining.", ->
benchmark "insert-delete", ->
editor.insertText('x')
editor.backspace()
editorView.insertText('x')
editorView.backspace()
benchmark "insert-delete-rehighlight", ->
editor.insertText('"')
editor.backspace()
editorView.insertText('"')
editorView.backspace()
describe "at-end.", ->
beforeEach ->
editor.moveCursorToBottom()
editorView.moveCursorToBottom()
benchmark "insert-delete", ->
editor.insertText('"')
editor.backspace()
editorView.insertText('"')
editorView.backspace()
describe "empty-vs-set-innerHTML.", ->
[firstRow, lastRow] = []
beforeEach ->
firstRow = editor.getFirstVisibleScreenRow()
lastRow = editor.getLastVisibleScreenRow()
firstRow = editorView.getFirstVisibleScreenRow()
lastRow = editorView.getLastVisibleScreenRow()
benchmark "build-gutter-html.", 1000, ->
editor.gutter.renderLineNumbers(null, firstRow, lastRow)
editorView.gutter.renderLineNumbers(null, firstRow, lastRow)
benchmark "set-innerHTML.", 1000, ->
editor.gutter.renderLineNumbers(null, firstRow, lastRow)
editor.gutter.lineNumbers[0].innerHtml = ''
editorView.gutter.renderLineNumbers(null, firstRow, lastRow)
editorView.gutter.lineNumbers[0].innerHtml = ''
benchmark "empty.", 1000, ->
editor.gutter.renderLineNumbers(null, firstRow, lastRow)
editor.gutter.lineNumbers.empty()
editorView.gutter.renderLineNumbers(null, firstRow, lastRow)
editorView.gutter.lineNumbers.empty()
describe "positionLeftForLineAndColumn.", ->
line = null
beforeEach ->
editor.scrollTop(2000)
editor.resetDisplay()
line = editor.lineElementForScreenRow(106)[0]
editorView.scrollTop(2000)
editorView.resetDisplay()
line = editorView.lineElementForScreenRow(106)[0]
describe "one-line.", ->
beforeEach ->
editor.clearCharacterWidthCache()
editorView.clearCharacterWidthCache()
benchmark "uncached", 5000, ->
editor.positionLeftForLineAndColumn(line, 106, 82)
editor.clearCharacterWidthCache()
editorView.positionLeftForLineAndColumn(line, 106, 82)
editorView.clearCharacterWidthCache()
benchmark "cached", 5000, ->
editor.positionLeftForLineAndColumn(line, 106, 82)
editorView.positionLeftForLineAndColumn(line, 106, 82)
describe "multiple-lines.", ->
[firstRow, lastRow] = []
beforeEach ->
firstRow = editor.getFirstVisibleScreenRow()
lastRow = editor.getLastVisibleScreenRow()
firstRow = editorView.getFirstVisibleScreenRow()
lastRow = editorView.getLastVisibleScreenRow()
benchmark "cache-entire-visible-area", 100, ->
for i in [firstRow..lastRow]
line = editor.lineElementForScreenRow(i)[0]
editor.positionLeftForLineAndColumn(line, i, Math.max(0, editor.lineLengthForBufferRow(i)))
line = editorView.lineElementForScreenRow(i)[0]
editorView.positionLeftForLineAndColumn(line, i, Math.max(0, editorView.lineLengthForBufferRow(i)))
describe "text-rendering.", ->
beforeEach ->
editor.scrollTop(2000)
editorView.scrollTop(2000)
benchmark "resetDisplay", 50, ->
editor.resetDisplay()
editorView.resetDisplay()
benchmark "htmlForScreenRows", 1000, ->
lastRow = editor.getLastScreenRow()
editor.htmlForScreenRows(0, lastRow)
lastRow = editorView.getLastScreenRow()
editorView.htmlForScreenRows(0, lastRow)
benchmark "htmlForScreenRows.htmlParsing", 50, ->
lastRow = editor.getLastScreenRow()
html = editor.htmlForScreenRows(0, lastRow)
lastRow = editorView.getLastScreenRow()
html = editorView.htmlForScreenRows(0, lastRow)
div = document.createElement('div')
div.innerHTML = html
@@ -126,44 +126,44 @@ describe "editor.", ->
describe "gutter-api.", ->
describe "getLineNumberElementsForClass.", ->
beforeEach ->
editor.gutter.addClassToLine(20, 'omgwow')
editor.gutter.addClassToLine(40, 'omgwow')
editorView.gutter.addClassToLine(20, 'omgwow')
editorView.gutter.addClassToLine(40, 'omgwow')
benchmark "DOM", 20000, ->
editor.gutter.getLineNumberElementsForClass('omgwow')
editorView.gutter.getLineNumberElementsForClass('omgwow')
benchmark "getLineNumberElement.DOM", 20000, ->
editor.gutter.getLineNumberElement(12)
editorView.gutter.getLineNumberElement(12)
benchmark "toggle-class", 2000, ->
editor.gutter.addClassToLine(40, 'omgwow')
editor.gutter.removeClassFromLine(40, 'omgwow')
editorView.gutter.addClassToLine(40, 'omgwow')
editorView.gutter.removeClassFromLine(40, 'omgwow')
describe "find-then-unset.", ->
classes = ['one', 'two', 'three', 'four']
benchmark "single-class", 200, ->
editor.gutter.addClassToLine(30, 'omgwow')
editor.gutter.addClassToLine(40, 'omgwow')
editor.gutter.removeClassFromAllLines('omgwow')
editorView.gutter.addClassToLine(30, 'omgwow')
editorView.gutter.addClassToLine(40, 'omgwow')
editorView.gutter.removeClassFromAllLines('omgwow')
benchmark "multiple-class", 200, ->
editor.gutter.addClassToLine(30, 'one')
editor.gutter.addClassToLine(30, 'two')
editorView.gutter.addClassToLine(30, 'one')
editorView.gutter.addClassToLine(30, 'two')
editor.gutter.addClassToLine(40, 'two')
editor.gutter.addClassToLine(40, 'three')
editor.gutter.addClassToLine(40, 'four')
editorView.gutter.addClassToLine(40, 'two')
editorView.gutter.addClassToLine(40, 'three')
editorView.gutter.addClassToLine(40, 'four')
for klass in classes
editor.gutter.removeClassFromAllLines(klass)
editorView.gutter.removeClassFromAllLines(klass)
describe "line-htmlification.", ->
div = null
html = null
beforeEach ->
lastRow = editor.getLastScreenRow()
html = editor.htmlForScreenRows(0, lastRow)
lastRow = editorView.getLastScreenRow()
html = editorView.htmlForScreenRows(0, lastRow)
div = document.createElement('div')
benchmark "setInnerHTML", 1, ->
@@ -178,40 +178,40 @@ describe "editor.", ->
rootView.openSync('huge.js')
benchmark "moving-to-eof.", 1, ->
editor.moveCursorToBottom()
editorView.moveCursorToBottom()
describe "on-first-line.", ->
benchmark "inserting-newline", 5, ->
editor.insertNewline()
editorView.insertNewline()
describe "on-last-visible-line.", ->
beforeEach ->
editor.setCursorScreenPosition([editor.getLastVisibleScreenRow(), 0])
editorView.setCursorScreenPosition([editorView.getLastVisibleScreenRow(), 0])
benchmark "move-down-and-scroll", 300, ->
editor.trigger 'move-down'
editorView.trigger 'move-down'
describe "at-eof.", ->
endPosition = null
beforeEach ->
editor.moveCursorToBottom()
endPosition = editor.getCursorScreenPosition()
editorView.moveCursorToBottom()
endPosition = editorView.getCursorScreenPosition()
benchmark "move-to-beginning-of-word", ->
editor.moveCursorToBeginningOfWord()
editor.setCursorScreenPosition(endPosition)
editorView.moveCursorToBeginningOfWord()
editorView.setCursorScreenPosition(endPosition)
benchmark "insert", ->
editor.insertText('x')
editorView.insertText('x')
describe "TokenizedBuffer.", ->
describe "coffee-script-grammar.", ->
[languageMode, buffer] = []
beforeEach ->
editSession = benchmarkFixturesProject.openSync('medium.coffee')
{ languageMode, buffer } = editSession
editor = benchmarkFixturesProject.openSync('medium.coffee')
{ languageMode, buffer } = editor
benchmark "construction", 20, ->
new TokenizedBuffer(buffer, { languageMode, tabLength: 2})
+1 -1
Ver Arquivo
@@ -245,7 +245,7 @@ $('ol.entries li.file.status-modified span.name').each (i, el) ->
parents.each (i, el) ->
filePath.unshift($(el).find('div.header span.name').eq(0).text())
modifiedFilePath = path.join(project.rootDirectory.path, filePath.join(path.sep))
modifiedFilePath = path.join(atom.project.rootDirectory.path, filePath.join(path.sep))
modifiedFiles.push modifiedFilePath
```
+2 -4
Ver Arquivo
@@ -1,4 +1,4 @@
{Document, Point, Range, Site} = require 'telepath'
{Document, Point, Range} = require 'telepath'
module.exports =
_: require 'underscore-plus'
@@ -11,7 +11,6 @@ module.exports =
Git: require '../src/git'
Point: Point
Range: Range
Site: Site
# The following classes can't be used from a Task handler and should therefore
# only be exported when not running as a child node process
@@ -21,8 +20,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
module.exports.$ = $
module.exports.$$ = $$
module.exports.$$$ = $$$
module.exports.Editor = require '../src/editor'
module.exports.pathForRepositoryUrl = require('../src/project').pathForRepositoryUrl
module.exports.Editor = require '../src/editor-view'
module.exports.RootView = require '../src/root-view'
module.exports.SelectList = require '../src/select-list'
module.exports.ScrollView = require '../src/scroll-view'
+52
Ver Arquivo
@@ -0,0 +1,52 @@
'.editor':
# Platform Bindings
'alt-left': 'editor:move-to-previous-word-boundary'
'alt-right': 'editor:move-to-next-word-boundary'
'alt-shift-left': 'editor:select-to-previous-word-boundary'
'alt-shift-right': 'editor:select-to-next-word-boundary'
'home': 'editor:move-to-first-character-of-line'
'end': 'editor:move-to-end-of-line'
'shift-home': 'editor:select-to-first-character-of-line'
'shift-end': 'editor:select-to-end-of-line'
# Sublime Parity
'ctrl-t': 'editor:transpose'
'.editor:not(.mini)':
# Atom Specific
'ctrl-C': 'editor:copy-path'
# Sublime Parity
'tab': 'editor:indent'
'enter': 'editor:newline'
'shift-tab': 'editor:outdent-selected-rows'
'ctrl-K': 'editor:delete-line'
'ctrl-shift-up': 'editor:add-selection-above'
'ctrl-shift-down': 'editor:add-selection-below'
'.tool-panel':
'escape': 'core:close'
'.tool-panel.panel-left, .tool-panel.panel-right':
'escape': 'tool-panel:unfocus'
'.editor !important, .editor.mini !important':
'escape': 'editor:consolidate-selections'
# allow standard input fields to work correctly
'input:not(.hidden-input), .native-key-bindings':
'tab': 'core:focus-next'
'shift-tab': 'core:focus-previous'
'left': 'native!'
'right': 'native!'
'shift-left': 'native!'
'shift-right': 'native!'
'backspace': 'native!'
'shift-backspace': 'native!'
'delete': 'native!'
'ctrl-b': 'native!'
'ctrl-f': 'native!'
'ctrl-F': 'native!'
'ctrl-B': 'native!'
'ctrl-h': 'native!'
'ctrl-d': 'native!'
+154
Ver Arquivo
@@ -0,0 +1,154 @@
'.platform-darwin':
# Apple specific
'cmd-q': 'application:quit'
'cmd-h': 'application:hide'
'cmd-H': 'application:hide-other-applications'
'cmd-m': 'application:minimize'
'alt-cmd-ctrl-m': 'application:zoom'
'ctrl-p': 'core:move-up'
'ctrl-n': 'core:move-down'
'ctrl-b': 'core:move-left'
'ctrl-f': 'core:move-right'
'ctrl-P': 'core:select-up'
'ctrl-N': 'core:select-down'
'ctrl-F': 'core:select-right'
'ctrl-B': 'core:select-left'
'ctrl-h': 'core:backspace'
'ctrl-d': 'core:delete'
# Atom Specific
'cmd-O': 'application:open-dev'
'cmd-alt-ctrl-s': 'application:run-all-specs'
'enter': 'core:confirm'
'escape': 'core:cancel'
'up': 'core:move-up'
'down': 'core:move-down'
'left': 'core:move-left'
'right': 'core:move-right'
'ctrl-alt-cmd-r': 'window:reload'
'alt-cmd-i': 'window:toggle-dev-tools'
'cmd-alt-ctrl-p': 'window:run-package-specs'
# Sublime Parity
'cmd-,': 'application:show-settings'
'cmd-N': 'application:new-window'
'cmd-W': 'window:close'
'cmd-o': 'application:open'
'cmd-T': 'pane:reopen-closed-item'
'cmd-n': 'application:new-file'
'cmd-s': 'core:save'
'cmd-S': 'core:save-as'
'cmd-alt-s': 'window:save-all'
'cmd-w': 'core:close'
'cmd-ctrl-f': 'window:toggle-full-screen'
'cmd-z': 'core:undo'
'cmd-Z': 'core:redo'
'cmd-y': 'core:redo'
'cmd-x': 'core:cut'
'cmd-c': 'core:copy'
'cmd-v': 'core:paste'
'shift-up': 'core:select-up'
'shift-down': 'core:select-down'
'shift-left': 'core:select-left'
'shift-right': 'core:select-right'
'delete': 'core:delete'
'pageup': 'core:page-up'
'pagedown': 'core:page-down'
'backspace': 'core:backspace'
'shift-backspace': 'core:backspace'
'cmd-up': 'core:move-to-top'
'cmd-down': 'core:move-to-bottom'
'cmd-shift-up': 'core:select-to-top'
'cmd-shift-down': 'core:select-to-bottom'
'cmd-{': 'pane:show-previous-item'
'cmd-}': 'pane:show-next-item'
'cmd-alt-left': 'pane:show-previous-item'
'cmd-alt-right': 'pane:show-next-item'
'cmd-=': 'window:increase-font-size'
'cmd-+': 'window:increase-font-size'
'cmd--': 'window:decrease-font-size'
'cmd-k up': 'pane:split-up' # Atom Specific
'cmd-k down': 'pane:split-down' # Atom Specific
'cmd-k left': 'pane:split-left' # Atom Specific
'cmd-k right': 'pane:split-right' # Atom Specific
'cmd-k cmd-w': 'pane:close' # Atom Specific
'cmd-k alt-cmd-w': 'pane:close-other-items' # Atom Specific
'cmd-k cmd-left': 'window:focus-previous-pane'
'cmd-k cmd-right': 'window:focus-next-pane'
'cmd-1': 'pane:show-item-1'
'cmd-2': 'pane:show-item-2'
'cmd-3': 'pane:show-item-3'
'cmd-4': 'pane:show-item-4'
'cmd-5': 'pane:show-item-5'
'cmd-6': 'pane:show-item-6'
'cmd-7': 'pane:show-item-7'
'cmd-8': 'pane:show-item-8'
'cmd-9': 'pane:show-item-9'
'.platform-darwin .editor':
# Apple Specific
'cmd-backspace': 'editor:backspace-to-beginning-of-line'
'cmd-delete': 'editor:backspace-to-beginning-of-line'
'ctrl-A': 'editor:select-to-first-character-of-line'
'ctrl-E': 'editor:select-to-end-of-line'
'cmd-left': 'editor:move-to-first-character-of-line'
'cmd-right': 'editor:move-to-end-of-line'
'cmd-shift-left': 'editor:select-to-first-character-of-line'
'cmd-shift-right': 'editor:select-to-end-of-line'
'alt-backspace': 'editor:backspace-to-beginning-of-word'
'alt-delete': 'editor:delete-to-end-of-word'
'ctrl-a': 'editor:move-to-first-character-of-line'
'ctrl-e': 'editor:move-to-end-of-line'
'ctrl-k': 'editor:cut-to-end-of-line'
# Atom Specific
'ctrl-W': 'editor:select-word'
# Sublime Parity
'cmd-a': 'core:select-all'
'cmd-alt-p': 'editor:log-cursor-scope'
'cmd-k cmd-u': 'editor:upper-case'
'cmd-k cmd-l': 'editor:lower-case'
'body.platform-darwin .editor:not(.mini)':
# Atom specific
'alt-cmd-z': 'editor:checkout-head-revision'
'cmd-<': 'editor:scroll-to-cursor'
'alt-cmd-ctrl-f': 'editor:fold-selection'
'cmd-=': 'editor:auto-indent'
# Sublime Parity
'cmd-enter': 'editor:newline-below'
'cmd-shift-enter': 'editor:newline-above'
'cmd-]': 'editor:indent-selected-rows'
'cmd-[': 'editor:outdent-selected-rows'
'ctrl-cmd-up': 'editor:move-line-up'
'ctrl-cmd-down': 'editor:move-line-down'
'cmd-/': 'editor:toggle-line-comments'
'cmd-j': 'editor:join-line'
'cmd-D': 'editor:duplicate-line'
'cmd-alt-[': 'editor:fold-current-row'
'cmd-alt-]': 'editor:unfold-current-row'
'cmd-alt-{': 'editor:fold-all' # Atom Specific
'cmd-alt-}': 'editor:unfold-all' # Atom Specific
'cmd-k cmd-0': 'editor:unfold-all'
'cmd-k cmd-1': 'editor:fold-at-indent-level-1'
'cmd-k cmd-2': 'editor:fold-at-indent-level-2'
'cmd-k cmd-3': 'editor:fold-at-indent-level-3'
'cmd-k cmd-4': 'editor:fold-at-indent-level-4'
'cmd-k cmd-5': 'editor:fold-at-indent-level-5'
'cmd-k cmd-6': 'editor:fold-at-indent-level-6'
'cmd-k cmd-7': 'editor:fold-at-indent-level-7'
'cmd-k cmd-8': 'editor:fold-at-indent-level-8'
'cmd-k cmd-9': 'editor:fold-at-indent-level-9'
# allow standard input fields to work correctly
'body.platform-darwin input:not(.hidden-input), body.platform-darwin .native-key-bindings':
'cmd-z': 'native!'
'cmd-Z': 'native!'
'cmd-x': 'native!'
'cmd-c': 'native!'
'cmd-v': 'native!'
-194
Ver Arquivo
@@ -1,194 +0,0 @@
'body':
# Apple specific
'meta-q': 'application:quit'
'meta-h': 'application:hide'
'meta-H': 'application:hide-other-applications'
'meta-m': 'application:minimize'
'alt-meta-ctrl-m': 'application:zoom'
'ctrl-p': 'core:move-up'
'ctrl-n': 'core:move-down'
'ctrl-b': 'core:move-left'
'ctrl-f': 'core:move-right'
'ctrl-P': 'core:select-up'
'ctrl-N': 'core:select-down'
'ctrl-F': 'core:select-right'
'ctrl-B': 'core:select-left'
'ctrl-h': 'core:backspace'
'ctrl-d': 'core:delete'
# Atom Specific
'meta-O': 'application:open-dev'
'meta-alt-ctrl-s': 'application:run-all-specs'
'enter': 'core:confirm'
'escape': 'core:cancel'
'up': 'core:move-up'
'down': 'core:move-down'
'left': 'core:move-left'
'right': 'core:move-right'
'ctrl-alt-meta-r': 'window:reload'
'alt-meta-i': 'window:toggle-dev-tools'
'meta-alt-ctrl-p': 'window:run-package-specs'
# Sublime Parity
'meta-,': 'application:show-settings'
'meta-N': 'application:new-window'
'meta-W': 'window:close'
'meta-o': 'application:open'
'meta-T': 'pane:reopen-closed-item'
'meta-n': 'application:new-file'
'meta-s': 'core:save'
'meta-S': 'core:save-as'
'meta-alt-s': 'window:save-all'
'meta-w': 'core:close'
'meta-ctrl-f': 'window:toggle-full-screen'
'meta-z': 'core:undo'
'meta-Z': 'core:redo'
'meta-y': 'core:redo'
'meta-x': 'core:cut'
'meta-c': 'core:copy'
'meta-v': 'core:paste'
'shift-up': 'core:select-up'
'shift-down': 'core:select-down'
'shift-left': 'core:select-left'
'shift-right': 'core:select-right'
'delete': 'core:delete'
'pageup': 'core:page-up'
'pagedown': 'core:page-down'
'backspace': 'core:backspace'
'shift-backspace': 'core:backspace'
'meta-up': 'core:move-to-top'
'meta-down': 'core:move-to-bottom'
'meta-shift-up': 'core:select-to-top'
'meta-shift-down': 'core:select-to-bottom'
'meta-{': 'pane:show-previous-item'
'meta-}': 'pane:show-next-item'
'meta-alt-left': 'pane:show-previous-item'
'meta-alt-right': 'pane:show-next-item'
'meta-=': 'window:increase-font-size'
'meta-+': 'window:increase-font-size'
'meta--': 'window:decrease-font-size'
'meta-k up': 'pane:split-up' # Atom Specific
'meta-k down': 'pane:split-down' # Atom Specific
'meta-k left': 'pane:split-left' # Atom Specific
'meta-k right': 'pane:split-right' # Atom Specific
'meta-k meta-w': 'pane:close' # Atom Specific
'meta-k alt-meta-w': 'pane:close-other-items' # Atom Specific
'meta-k meta-left': 'window:focus-previous-pane'
'meta-k meta-right': 'window:focus-next-pane'
'meta-1': 'pane:show-item-1'
'meta-2': 'pane:show-item-2'
'meta-3': 'pane:show-item-3'
'meta-4': 'pane:show-item-4'
'meta-5': 'pane:show-item-5'
'meta-6': 'pane:show-item-6'
'meta-7': 'pane:show-item-7'
'meta-8': 'pane:show-item-8'
'meta-9': 'pane:show-item-9'
'.editor':
# Apple Specific
'alt-left': 'editor:move-to-previous-word-boundary'
'alt-right': 'editor:move-to-next-word-boundary'
'alt-shift-left': 'editor:select-to-previous-word-boundary'
'alt-shift-right': 'editor:select-to-next-word-boundary'
'meta-backspace': 'editor:backspace-to-beginning-of-line'
'meta-delete': 'editor:backspace-to-beginning-of-line'
'ctrl-A': 'editor:select-to-first-character-of-line'
'ctrl-E': 'editor:select-to-end-of-line'
'meta-left': 'editor:move-to-first-character-of-line'
'meta-right': 'editor:move-to-end-of-line'
'meta-shift-left': 'editor:select-to-first-character-of-line'
'meta-shift-right': 'editor:select-to-end-of-line'
'home': 'editor:move-to-first-character-of-line'
'end': 'editor:move-to-end-of-line'
'shift-home': 'editor:select-to-first-character-of-line'
'shift-end': 'editor:select-to-end-of-line'
'alt-backspace': 'editor:backspace-to-beginning-of-word'
'alt-delete': 'editor:delete-to-end-of-word'
'ctrl-a': 'editor:move-to-first-character-of-line'
'ctrl-e': 'editor:move-to-end-of-line'
'ctrl-k': 'editor:cut-to-end-of-line'
# Atom Specific
'ctrl-W': 'editor:select-word'
# Sublime Parity
'meta-a': 'core:select-all'
'meta-alt-p': 'editor:log-cursor-scope'
'ctrl-t': 'editor:transpose'
'meta-k meta-u': 'editor:upper-case'
'meta-k meta-l': 'editor:lower-case'
'.editor:not(.mini)':
# Atom Specific
'alt-meta-z': 'editor:checkout-head-revision'
'meta-<': 'editor:scroll-to-cursor'
'ctrl-C': 'editor:copy-path'
'alt-meta-ctrl-f': 'editor:fold-selection'
'meta-=': 'editor:auto-indent'
# Sublime Parity
'tab': 'editor:indent'
'enter': 'editor:newline'
'meta-enter': 'editor:newline-below'
'meta-shift-enter': 'editor:newline-above'
'meta-]': 'editor:indent-selected-rows'
'meta-[': 'editor:outdent-selected-rows'
'shift-tab': 'editor:outdent-selected-rows'
'ctrl-meta-up': 'editor:move-line-up'
'ctrl-meta-down': 'editor:move-line-down'
'meta-/': 'editor:toggle-line-comments'
'meta-j': 'editor:join-line'
'meta-D': 'editor:duplicate-line'
'ctrl-K': 'editor:delete-line'
'ctrl-shift-up': 'editor:add-selection-above'
'ctrl-shift-down': 'editor:add-selection-below'
'meta-alt-[': 'editor:fold-current-row'
'meta-alt-]': 'editor:unfold-current-row'
'meta-alt-{': 'editor:fold-all' # Atom Specific
'meta-alt-}': 'editor:unfold-all' # Atom Specific
'meta-k meta-0': 'editor:unfold-all'
'meta-k meta-1': 'editor:fold-at-indent-level-1'
'meta-k meta-2': 'editor:fold-at-indent-level-2'
'meta-k meta-3': 'editor:fold-at-indent-level-3'
'meta-k meta-4': 'editor:fold-at-indent-level-4'
'meta-k meta-5': 'editor:fold-at-indent-level-5'
'meta-k meta-6': 'editor:fold-at-indent-level-6'
'meta-k meta-7': 'editor:fold-at-indent-level-7'
'meta-k meta-8': 'editor:fold-at-indent-level-8'
'meta-k meta-9': 'editor:fold-at-indent-level-9'
'.tool-panel':
'escape': 'core:close'
'.tool-panel.panel-left, .tool-panel.panel-right':
'escape': 'tool-panel:unfocus'
'.editor !important, .editor.mini !important':
'escape': 'editor:consolidate-selections'
# allow standard input fields to work correctly
'input:not(.hidden-input), .native-key-bindings':
'tab': 'core:focus-next'
'shift-tab': 'core:focus-previous'
'left': 'native!'
'right': 'native!'
'shift-left': 'native!'
'shift-right': 'native!'
'backspace': 'native!'
'shift-backspace': 'native!'
'delete': 'native!'
'meta-z': 'native!'
'meta-Z': 'native!'
'meta-x': 'native!'
'meta-c': 'native!'
'meta-v': 'native!'
'ctrl-b': 'native!'
'ctrl-f': 'native!'
'ctrl-F': 'native!'
'ctrl-B': 'native!'
'ctrl-h': 'native!'
'ctrl-d': 'native!'
+102
Ver Arquivo
@@ -0,0 +1,102 @@
'.platform-win32':
# Atom Specific
'enter': 'core:confirm'
'escape': 'core:cancel'
'up': 'core:move-up'
'down': 'core:move-down'
'left': 'core:move-left'
'right': 'core:move-right'
'ctrl-alt-r': 'window:reload'
'ctrl-alt-i': 'window:toggle-dev-tools'
'ctrl-alt-p': 'window:run-package-specs'
'ctrl-alt-s': 'application:run-all-specs'
# Sublime Parity
'ctrl-N': 'application:new-window'
'ctrl-W': 'window:close'
'ctrl-o': 'application:open'
'ctrl-T': 'pane:reopen-closed-item'
'ctrl-n': 'application:new-file'
'ctrl-s': 'core:save'
'ctrl-S': 'core:save-as'
'ctrl-w': 'core:close'
'ctrl-z': 'core:undo'
'ctrl-y': 'core:redo'
'ctrl-x': 'core:cut'
'ctrl-c': 'core:copy'
'ctrl-v': 'core:paste'
'shift-up': 'core:select-up'
'shift-down': 'core:select-down'
'shift-left': 'core:select-left'
'shift-right': 'core:select-right'
'delete': 'core:delete'
'pageup': 'core:page-up'
'pagedown': 'core:page-down'
'backspace': 'core:backspace'
'ctrl-tab': 'pane:show-next-item'
'ctrl-shift-tab': 'pane:show-previous-item'
'ctrl-shift-up': 'core:move-up'
'ctrl-shift-down': 'core:move-down'
'ctrl-=': 'window:increase-font-size'
'ctrl-+': 'window:increase-font-size'
'ctrl--': 'window:decrease-font-size'
'ctrl-k up': 'pane:split-up' # Atom Specific
'ctrl-k down': 'pane:split-down' # Atom Specific
'ctrl-k left': 'pane:split-left' # Atom Specific
'ctrl-k right': 'pane:split-right' # Atom Specific
'ctrl-k ctrl-w': 'pane:close' # Atom Specific
'ctrl-k alt-ctrl-w': 'pane:close-other-items' # Atom Specific
'ctrl-k ctrl-left': 'window:focus-previous-pane'
'ctrl-k ctrl-right': 'window:focus-next-pane'
'.platform-win32 .editor':
# Windows specific
'ctrl-delete': 'editor:backspace-to-beginning-of-word'
# Sublime Parity
'ctrl-a': 'core:select-all'
'ctrl-alt-p': 'editor:log-cursor-scope'
'ctrl-k ctrl-u': 'editor:upper-case'
'ctrl-k ctrl-l': 'editor:lower-case'
'.platform-win32 .editor:not(.mini)':
# Atom specific
'alt-ctrl-z': 'editor:checkout-head-revision'
'ctrl-<': 'editor:scroll-to-cursor'
'alt-ctrl-f': 'editor:fold-selection'
'ctrl-=': 'editor:auto-indent'
# Sublime Parity
'ctrl-enter': 'editor:newline-below'
'ctrl-shift-enter': 'editor:newline-above'
'ctrl-]': 'editor:indent-selected-rows'
'ctrl-[': 'editor:outdent-selected-rows'
'ctrl-up': 'editor:move-line-up'
'ctrl-down': 'editor:move-line-down'
'ctrl-/': 'editor:toggle-line-comments'
'ctrl-j': 'editor:join-line'
'ctrl-D': 'editor:duplicate-line'
'ctrl-alt-[': 'editor:fold-current-row'
'ctrl-alt-]': 'editor:unfold-current-row'
'ctrl-alt-{': 'editor:fold-all' # Atom Specific
'ctrl-alt-}': 'editor:unfold-all' # Atom Specific
'ctrl-k ctrl-0': 'editor:unfold-all'
'ctrl-k ctrl-1': 'editor:fold-at-indent-level-1'
'ctrl-k ctrl-2': 'editor:fold-at-indent-level-2'
'ctrl-k ctrl-3': 'editor:fold-at-indent-level-3'
'ctrl-k ctrl-4': 'editor:fold-at-indent-level-4'
'ctrl-k ctrl-5': 'editor:fold-at-indent-level-5'
'ctrl-k ctrl-6': 'editor:fold-at-indent-level-6'
'ctrl-k ctrl-7': 'editor:fold-at-indent-level-7'
'ctrl-k ctrl-8': 'editor:fold-at-indent-level-8'
'ctrl-k ctrl-9': 'editor:fold-at-indent-level-9'
# allow standard input fields to work correctly
'.platform-win32 input:not(.hidden-input), .platform-win32 .native-key-bindings':
'ctrl-z': 'native!'
'ctrl-Z': 'native!'
'ctrl-x': 'native!'
'ctrl-c': 'native!'
'ctrl-v': 'native!'
Ver Arquivo
+172
Ver Arquivo
@@ -0,0 +1,172 @@
'menu': [
{
label: '&File'
submenu: [
{ label: 'New &Window', command: 'application:new-window' }
{ label: '&New File', command: 'application:new-file' }
{ label: '&Open...', command: 'application:open' }
{ label: 'Reopen Last &Item', command: 'pane:reopen-closed-item' }
{ type: 'separator' }
{ label: '&Preferences...', command: 'application:show-settings' }
{ type: 'separator' }
{ label: '&Save', command: 'core:save' }
{ label: 'Save &As...', command: 'core:save-as' }
{ label: 'Save A&ll', command: 'window:save-all' }
{ type: 'separator' }
{ label: '&Close Buffer', command: 'core:close' }
{ label: 'Close All &Buffers', command: 'pane:close' }
{ label: 'Clos&e Window', command: 'window:close' }
{ type: 'separator' }
{ label: 'E&xit', command: 'application:quit' }
]
}
{
label: '&Edit'
submenu: [
{ label: '&Undo', command: 'core:undo' }
{ label: '&Redo', command: 'core:redo' }
{ type: 'separator' }
{ label: '&Cut', command: 'core:cut' }
{ label: 'C&opy', command: 'core:copy' }
{ label: 'Copy Pat&h', command: 'editor:copy-path' }
{ label: '&Paste', command: 'core:paste' }
{ label: 'Select &All', command: 'core:select-all' }
{ type: 'separator' }
{ label: '&Toggle Comments', command: 'editor:toggle-line-comments' }
{
label: 'Lines',
submenu: [
{ label: '&Indent', command: 'editor:indent-selected-rows' }
{ label: '&Outdent', command: 'editor:outdent-selected-rows' }
{ label: '&Auto Indent', command: 'editor:auto-indent' }
{ type: 'separator' }
{ label: 'Move Line &Up', command: 'editor:move-line-up' }
{ label: 'Move Line &Down', command: 'editor:move-line-down' }
{ label: 'Du&plicate Line', command: 'editor:duplicate-line' }
{ label: 'D&elete Line', command: 'editor:delete-line' }
{ label: '&Join Lines', command: 'editor:join-line' }
]
}
{
label: 'Text',
submenu: [
{ label: '&Upper Case', command: 'editor:upper-case' }
{ label: '&Lower Case', command: 'editor:lower-case' }
{ type: 'separator' }
{ label: 'Delete to End of &Word', command: 'editor:delete-to-end-of-word' }
{ label: '&Delete Line', command: 'editor:delete-line' }
{ type: 'separator' }
{ label: '&Transpose', command: 'editor:transpose' }
]
}
{
label: 'Folding',
submenu: [
{ label: '&Fold', command: 'editor:fold-current-row' }
{ label: '&Unfold', command: 'editor:unfold-current-row' }
{ label: 'Unfold &All', command: 'editor:unfold-all' }
{ type: 'separator' }
{ label: 'Fol&d All', command: 'editor:fold-all' }
{ label: 'Fold Level 1', command: 'editor:fold-at-indent-level-1' }
{ label: 'Fold Level 2', command: 'editor:fold-at-indent-level-2' }
{ label: 'Fold Level 3', command: 'editor:fold-at-indent-level-3' }
{ label: 'Fold Level 4', command: 'editor:fold-at-indent-level-4' }
{ label: 'Fold Level 5', command: 'editor:fold-at-indent-level-5' }
{ label: 'Fold Level 6', command: 'editor:fold-at-indent-level-6' }
{ label: 'Fold Level 7', command: 'editor:fold-at-indent-level-7' }
{ label: 'Fold Level 8', command: 'editor:fold-at-indent-level-8' }
{ label: 'Fold Level 9', command: 'editor:fold-at-indent-level-9' }
]
}
]
}
{
label: '&View'
submenu: [
{ label: '&Reload', command: 'window:reload' }
{ label: 'Toggle &Full Screen', command: 'window:toggle-full-screen' }
{
label: 'Developer'
submenu: [
{ label: 'Open In &Dev Mode...', command: 'application:open-dev' }
{ label: 'Run &Atom Specs', command: 'application:run-all-specs' }
{ label: 'Run Package &Specs', command: 'window:run-package-specs' }
{ label: 'Toggle Developer &Tools', command: 'window:toggle-dev-tools' }
]
}
{ type: 'separator' }
{ label: 'Toggle Soft &Wrap', command: 'editor:toggle-soft-wrap' }
]
}
{
label: '&Selection'
submenu: [
{ label: 'Add Selection &Above', command: 'editor:add-selection-above' }
{ label: 'Add Selection &Below', command: 'editor:add-selection-below' }
{ type: 'separator' }
{ label: 'Select to &Top', command: 'core:select-to-top' }
{ label: 'Select to Botto&m', command: 'core:select-to-bottom' }
{ type: 'separator' }
{ label: 'Select &Line', command: 'editor:select-line' }
{ label: 'Select &Word', command: 'editor:select-word' }
{ label: 'Select to Beginning of W&ord', command: 'editor:select-to-beginning-of-word' }
{ label: 'Select to Beginning of L&ine', command: 'editor:select-to-beginning-of-line' }
{ label: 'Select to First &Character of Line', command: 'editor:select-to-first-character-of-line' }
{ label: 'Select to End of Wor&d', command: 'editor:select-to-end-of-word' }
{ label: 'Select to End of Lin&e', command: 'editor:select-to-end-of-line' }
]
}
{
label: '&Movement'
submenu: [
{ label: 'Move to &Top', command: 'core:move-to-top' }
{ label: 'Move to &Bottom', command: 'core:move-to-bottom' }
{ type: 'separator' }
{ label: 'Move to Beginning of &Line', command: 'editor:move-to-beginning-of-line' }
{ label: 'Move to &First Character of Line', command: 'editor:move-to-first-character-of-line' }
{ label: 'Move to &End of Line', command: 'editor:move-to-end-of-line' }
{ type: 'separator' }
{ label: 'Move to Beginning of &Word', command: 'editor:move-to-beginning-of-word' }
{ label: 'Move to End of Wor&d', command: 'editor:move-to-end-of-word' }
{ label: 'Move to &Next Word', command: 'editor:move-to-next-word-boundary' }
{ label: 'Move to &Previous Word', command: 'editor:move-to-previous-word-boundary' }
]
}
{
label: 'F&ind'
submenu: []
}
{
label: '&Packages'
submenu: []
}
{
label: '&Window'
submenu: [
{ label: 'Mi&nimize', command: 'application:minimize' }
{ label: 'Ma&ximize', command: 'application:zoom' }
{ type: 'separator' }
{ label: 'Bring &All to Front', command: 'application:bring-all-windows-to-front' }
]
}
{
label: '&Help'
submenu: [
{ label: '&About Atom...', command: 'application:about' }
{ label: "VERSION", enabled: false }
{ label: "Install &update", command: 'application:install-update', visible: false }
{ type: 'separator' }
{ label: '&Documentation', command: 'application:open-documentation' }
{ label: 'Report an &Issue', command: 'application:report-issue' }
{ type: 'separator' }
]
}
]
+50 -50
Ver Arquivo
@@ -1,6 +1,6 @@
{
"name": "atom",
"version": "36.0.0",
"version": "39.0.0",
"main": "./src/browser/main.js",
"repository": {
"type": "git",
@@ -9,14 +9,14 @@
"bugs": {
"url": "https://github.com/atom/atom/issues"
},
"atomShellVersion": "0.6.10",
"atomShellVersion": "0.6.11",
"dependencies": {
"async": "0.2.6",
"bootstrap": "git://github.com/twbs/bootstrap.git#v3.0.0",
"clear-cut": "0.1.0",
"bootstrap": "git://github.com/benogle/bootstrap.git",
"clear-cut": "0.2.0",
"coffee-script": "1.6.3",
"coffeestack": "0.6.0",
"emissary": "0.9.0",
"emissary": "0.19.0",
"first-mate": "0.5.0",
"fs-plus": "0.9.0",
"fuzzaldrin": "0.1.0",
@@ -28,14 +28,14 @@
"nslog": "0.1.0",
"oniguruma": "0.24.0",
"optimist": "0.4.0",
"pathwatcher": "0.9.0",
"pathwatcher": "0.10.0",
"pegjs": "0.7.0",
"q": "0.9.7",
"scandal": "0.8.0",
"season": "0.14.0",
"semver": "1.1.4",
"space-pen": "2.0.0",
"telepath": "0.23.0",
"telepath": "0.45.0",
"temp": "0.5.0",
"underscore-plus": "0.3.0"
},
@@ -52,7 +52,6 @@
"grunt-contrib-coffee": "~0.7.0",
"grunt-contrib-less": "~0.8.0",
"walkdir": "0.0.7",
"ws": "0.4.27",
"js-yaml": "~2.1.0",
"grunt-markdown": "~0.4.0",
"json-front-matter": "~0.1.3",
@@ -65,55 +64,56 @@
"rimraf": "~2.2.2"
},
"packageDependencies": {
"atom-light-ui": "0.6.0",
"atom-light-ui": "0.8.0",
"atom-light-syntax": "0.6.0",
"atom-dark-ui": "0.6.0",
"atom-dark-ui": "0.8.0",
"atom-dark-syntax": "0.6.0",
"base16-tomorrow-dark-theme": "0.6.0",
"solarized-dark-syntax": "0.4.0",
"archive-view": "0.11.0",
"autocomplete": "0.12.0",
"autoflow": "0.5.0",
"autosave": "0.6.0",
"bookmarks": "0.10.0",
"bracket-matcher": "0.11.0",
"command-logger": "0.6.0",
"command-palette": "0.7.0",
"dev-live-reload": "0.15.0",
"editor-stats": "0.5.0",
"exception-reporting": "0.7.0",
"find-and-replace": "0.40.0",
"fuzzy-finder": "0.20.0",
"gists": "0.6.0",
"git-diff": "0.13.0",
"github-sign-in": "0.9.0",
"go-to-line": "0.8.0",
"grammar-selector": "0.8.0",
"image-view": "0.7.0",
"link": "0.7.0",
"markdown-preview": "0.15.0",
"metrics": "0.11.0",
"package-generator": "0.19.0",
"release-notes": "0.11.0",
"settings-view": "0.39.0",
"snippets": "0.13.0",
"spell-check": "0.13.0",
"status-bar": "0.16.0",
"styleguide": "0.9.0",
"symbols-view": "0.19.0",
"tabs": "0.8.0",
"terminal": "0.16.0",
"timecop": "0.9.0",
"to-the-hubs": "0.9.0",
"tree-view": "0.30.0",
"visual-bell": "0.3.0",
"whitespace": "0.8.0",
"wrap-guide": "0.5.0",
"archive-view": "0.14.0",
"autocomplete": "0.15.0",
"autoflow": "0.9.0",
"autosave": "0.7.0",
"bookmarks": "0.13.0",
"bracket-matcher": "0.12.0",
"command-logger": "0.7.0",
"command-palette": "0.10.0",
"dev-live-reload": "0.17.0",
"editor-stats": "0.7.0",
"exception-reporting": "0.8.0",
"find-and-replace": "0.49.0",
"fuzzy-finder": "0.25.0",
"gists": "0.11.0",
"git-diff": "0.16.0",
"github-sign-in": "0.11.0",
"go-to-line": "0.10.0",
"grammar-selector": "0.11.0",
"image-view": "0.9.0",
"keybinding-resolver": "0.5.0",
"link": "0.9.0",
"markdown-preview": "0.19.0",
"metrics": "0.12.0",
"package-generator": "0.21.0",
"release-notes": "0.12.0",
"settings-view": "0.47.0",
"snippets": "0.15.0",
"spell-check": "0.15.0",
"status-bar": "0.22.0",
"styleguide": "0.15.0",
"symbols-view": "0.24.0",
"tabs": "0.12.0",
"terminal": "0.22.0",
"timecop": "0.10.0",
"to-the-hubs": "0.13.0",
"tree-view": "0.39.0",
"visual-bell": "0.4.0",
"whitespace": "0.9.0",
"wrap-guide": "0.6.0",
"language-c": "0.2.0",
"language-clojure": "0.1.0",
"language-coffee-script": "0.3.0",
"language-css": "0.2.0",
"language-gfm": "0.8.0",
"language-gfm": "0.9.0",
"language-git": "0.3.0",
"language-go": "0.2.0",
"language-html": "0.2.0",
@@ -139,7 +139,7 @@
"language-sql": "0.2.0",
"language-text": "0.2.0",
"language-todo": "0.2.0",
"language-toml": "0.6.0",
"language-toml": "0.7.0",
"language-xml": "0.2.0",
"language-yaml": "0.1.0"
},
+11 -5
Ver Arquivo
@@ -5,9 +5,15 @@ var path = require('path');
// Executes an array of commands one by one.
function executeCommands(commands, done, index) {
index = (index == undefined ? 0 : index);
if (index < commands.length)
safeExec(commands[index], executeCommands.bind(this, commands, done, index + 1));
else
if (index < commands.length) {
var command = commands[index];
var options = null;
if (typeof command !== 'string') {
options = command.options;
command = command.command;
}
safeExec(command, options, executeCommands.bind(this, commands, done, index + 1));
} else
done(null);
}
@@ -21,8 +27,8 @@ var echoNewLine = process.platform == 'win32' ? 'echo.' : 'echo';
var commands = [
'git submodule --quiet sync',
'git submodule --quiet update --recursive --init',
joinCommands('cd vendor/apm', 'npm install --silent .'),
'npm install --silent vendor/apm',
{command: joinCommands('cd vendor/apm', 'npm install --silent .'), options: {ignoreStdout: true}},
{command: 'npm install --silent vendor/apm', options: {ignoreStdout: true}},
echoNewLine,
'node node_modules/atom-package-manager/bin/apm clean',
'node node_modules/atom-package-manager/bin/apm install --silent',
+3 -2
Ver Arquivo
@@ -10,7 +10,7 @@ exports.safeExec = function(command, options, callback) {
if (!options)
options = {};
// This needed to be increase for `apm test` runs that generate tons of failures
// This needed to be increased for `apm test` runs that generate many failures
// The default is 200KB.
options.maxBuffer = 1024 * 1024;
@@ -21,7 +21,8 @@ exports.safeExec = function(command, options, callback) {
callback(null);
});
child.stderr.pipe(process.stderr);
child.stdout.pipe(process.stdout);
if (!options.ignoreStdout)
child.stdout.pipe(process.stdout);
}
// Same with safeExec but call child_process.spawn instead.
+6 -6
Ver Arquivo
@@ -15,14 +15,14 @@ describe "AtomPackage", ->
describe "when the theme contains a single style file", ->
it "loads and applies css", ->
expect($(".editor").css("padding-bottom")).not.toBe "1234px"
themePath = project.resolve('packages/theme-with-index-css')
themePath = atom.project.resolve('packages/theme-with-index-css')
theme = Package.load(themePath)
theme.activate()
expect($(".editor").css("padding-top")).toBe "1234px"
it "parses, loads and applies less", ->
expect($(".editor").css("padding-bottom")).not.toBe "1234px"
themePath = project.resolve('packages/theme-with-index-less')
themePath = atom.project.resolve('packages/theme-with-index-less')
theme = Package.load(themePath)
theme.activate()
expect($(".editor").css("padding-top")).toBe "4321px"
@@ -33,7 +33,7 @@ describe "AtomPackage", ->
expect($(".editor").css("padding-right")).not.toBe("102px")
expect($(".editor").css("padding-bottom")).not.toBe("103px")
themePath = project.resolve('packages/theme-with-package-file')
themePath = atom.project.resolve('packages/theme-with-package-file')
theme = Package.load(themePath)
theme.activate()
expect($(".editor").css("padding-top")).toBe("101px")
@@ -46,7 +46,7 @@ describe "AtomPackage", ->
expect($(".editor").css("padding-right")).not.toBe "20px"
expect($(".editor").css("padding-bottom")).not.toBe "30px"
themePath = project.resolve('packages/theme-without-package-file')
themePath = atom.project.resolve('packages/theme-without-package-file')
theme = Package.load(themePath)
theme.activate()
expect($(".editor").css("padding-top")).toBe "10px"
@@ -55,7 +55,7 @@ describe "AtomPackage", ->
describe "reloading a theme", ->
beforeEach ->
themePath = project.resolve('packages/theme-with-package-file')
themePath = atom.project.resolve('packages/theme-with-package-file')
theme = Package.load(themePath)
theme.activate()
@@ -66,7 +66,7 @@ describe "AtomPackage", ->
describe "events", ->
beforeEach ->
themePath = project.resolve('packages/theme-with-package-file')
themePath = atom.project.resolve('packages/theme-with-package-file')
theme = Package.load(themePath)
theme.activate()
+83 -82
Ver Arquivo
@@ -5,16 +5,16 @@ ThemeManager = require '../src/theme-manager'
describe "the `atom` global", ->
beforeEach ->
window.rootView = new RootView
atom.rootView = new RootView
describe "package lifecycle methods", ->
describe ".loadPackage(name)", ->
describe "when the package has deferred deserializers", ->
it "requires the package's main module if one of its deferred deserializers is referenced", ->
pack = atom.loadPackage('package-with-activation-events')
pack = atom.packages.loadPackage('package-with-activation-events')
spyOn(pack, 'activateStylesheets').andCallThrough()
expect(pack.mainModule).toBeNull()
object = deserialize({deserializer: 'Foo', data: 5})
object = atom.deserializers.deserialize({deserializer: 'Foo', data: 5})
expect(pack.mainModule).toBeDefined()
expect(object.constructor.name).toBe 'Foo'
expect(object.data).toBe 5
@@ -23,34 +23,34 @@ describe "the `atom` global", ->
it "continues if the package has an invalid package.json", ->
spyOn(console, 'warn')
atom.config.set("core.disabledPackages", [])
expect(-> atom.loadPackage("package-with-broken-package-json")).not.toThrow()
expect(-> atom.packages.loadPackage("package-with-broken-package-json")).not.toThrow()
it "continues if the package has an invalid keymap", ->
atom.config.set("core.disabledPackages", [])
expect(-> atom.loadPackage("package-with-broken-keymap")).not.toThrow()
expect(-> atom.packages.loadPackage("package-with-broken-keymap")).not.toThrow()
describe ".unloadPackage(name)", ->
describe "when the package is active", ->
it "throws an error", ->
pack = atom.activatePackage('package-with-main')
expect(atom.isPackageLoaded(pack.name)).toBeTruthy()
expect(atom.isPackageActive(pack.name)).toBeTruthy()
expect( -> atom.unloadPackage(pack.name)).toThrow()
expect(atom.isPackageLoaded(pack.name)).toBeTruthy()
expect(atom.isPackageActive(pack.name)).toBeTruthy()
pack = atom.packages.activatePackage('package-with-main')
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
expect(atom.packages.isPackageActive(pack.name)).toBeTruthy()
expect( -> atom.packages.unloadPackage(pack.name)).toThrow()
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
expect(atom.packages.isPackageActive(pack.name)).toBeTruthy()
describe "when the package is not loaded", ->
it "throws an error", ->
expect(atom.isPackageLoaded('unloaded')).toBeFalsy()
expect( -> atom.unloadPackage('unloaded')).toThrow()
expect(atom.isPackageLoaded('unloaded')).toBeFalsy()
expect(atom.packages.isPackageLoaded('unloaded')).toBeFalsy()
expect( -> atom.packages.unloadPackage('unloaded')).toThrow()
expect(atom.packages.isPackageLoaded('unloaded')).toBeFalsy()
describe "when the package is loaded", ->
it "no longers reports it as being loaded", ->
pack = atom.loadPackage('package-with-main')
expect(atom.isPackageLoaded(pack.name)).toBeTruthy()
atom.unloadPackage(pack.name)
expect(atom.isPackageLoaded(pack.name)).toBeFalsy()
pack = atom.packages.loadPackage('package-with-main')
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
atom.packages.unloadPackage(pack.name)
expect(atom.packages.isPackageLoaded(pack.name)).toBeFalsy()
describe ".activatePackage(id)", ->
describe "atom packages", ->
@@ -59,7 +59,7 @@ describe "the `atom` global", ->
it "requires the module at the specified path", ->
mainModule = require('./fixtures/packages/package-with-main/main-module')
spyOn(mainModule, 'activate')
pack = atom.activatePackage('package-with-main')
pack = atom.packages.activatePackage('package-with-main')
expect(mainModule.activate).toHaveBeenCalled()
expect(pack.mainModule).toBe mainModule
@@ -67,13 +67,13 @@ describe "the `atom` global", ->
it "requires index.coffee", ->
indexModule = require('./fixtures/packages/package-with-index/index')
spyOn(indexModule, 'activate')
pack = atom.activatePackage('package-with-index')
pack = atom.packages.activatePackage('package-with-index')
expect(indexModule.activate).toHaveBeenCalled()
expect(pack.mainModule).toBe indexModule
it "assigns config defaults from the module", ->
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
atom.activatePackage('package-with-config-defaults')
atom.packages.activatePackage('package-with-config-defaults')
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
@@ -85,24 +85,24 @@ describe "the `atom` global", ->
spyOn(mainModule, 'activate').andCallThrough()
AtomPackage = require '../src/atom-package'
spyOn(AtomPackage.prototype, 'requireMainModule').andCallThrough()
pack = atom.activatePackage('package-with-activation-events')
pack = atom.packages.activatePackage('package-with-activation-events')
it "defers requiring/activating the main module until an activation event bubbles to the root view", ->
expect(pack.requireMainModule).not.toHaveBeenCalled()
expect(mainModule.activate).not.toHaveBeenCalled()
rootView.trigger 'activation-event'
atom.rootView.trigger 'activation-event'
expect(mainModule.activate).toHaveBeenCalled()
it "triggers the activation event on all handlers registered during activation", ->
rootView.openSync()
editor = rootView.getActiveView()
atom.rootView.openSync()
editorView = atom.rootView.getActiveView()
eventHandler = jasmine.createSpy("activation-event")
editor.command 'activation-event', eventHandler
editor.trigger 'activation-event'
editorView.command 'activation-event', eventHandler
editorView.trigger 'activation-event'
expect(mainModule.activate.callCount).toBe 1
expect(mainModule.activationEventCallCount).toBe 1
expect(eventHandler.callCount).toBe 1
editor.trigger 'activation-event'
editorView.trigger 'activation-event'
expect(mainModule.activationEventCallCount).toBe 2
expect(eventHandler.callCount).toBe 2
expect(mainModule.activate.callCount).toBe 1
@@ -111,23 +111,23 @@ describe "the `atom` global", ->
it "does not throw an exception", ->
spyOn(console, "error")
spyOn(console, "warn").andCallThrough()
expect(-> atom.activatePackage('package-without-module')).not.toThrow()
expect(-> atom.packages.activatePackage('package-without-module')).not.toThrow()
expect(console.error).not.toHaveBeenCalled()
expect(console.warn).not.toHaveBeenCalled()
it "passes the activate method the package's previously serialized state if it exists", ->
pack = atom.activatePackage("package-with-serialization")
pack = atom.packages.activatePackage("package-with-serialization")
expect(pack.mainModule.someNumber).not.toBe 77
pack.mainModule.someNumber = 77
atom.deactivatePackage("package-with-serialization")
atom.packages.deactivatePackage("package-with-serialization")
spyOn(pack.mainModule, 'activate').andCallThrough()
atom.activatePackage("package-with-serialization")
atom.packages.activatePackage("package-with-serialization")
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
it "logs warning instead of throwing an exception if the package fails to load", ->
atom.config.set("core.disabledPackages", [])
spyOn(console, "warn")
expect(-> atom.activatePackage("package-that-throws-an-exception")).not.toThrow()
expect(-> atom.packages.activatePackage("package-that-throws-an-exception")).not.toThrow()
expect(console.warn).toHaveBeenCalled()
describe "keymap loading", ->
@@ -137,28 +137,28 @@ describe "the `atom` global", ->
element2 = $$ -> @div class: 'test-2'
element3 = $$ -> @div class: 'test-3'
expect(atom.keymap.bindingsForElement(element1)['ctrl-z']).toBeUndefined()
expect(atom.keymap.bindingsForElement(element2)['ctrl-z']).toBeUndefined()
expect(atom.keymap.bindingsForElement(element3)['ctrl-z']).toBeUndefined()
expect(atom.keymap.keyBindingsForKeystrokeMatchingElement('ctrl-z', element1)).toHaveLength 0
expect(atom.keymap.keyBindingsForKeystrokeMatchingElement('ctrl-z', element2)).toHaveLength 0
expect(atom.keymap.keyBindingsForKeystrokeMatchingElement('ctrl-z', element3)).toHaveLength 0
atom.activatePackage("package-with-keymaps")
atom.packages.activatePackage("package-with-keymaps")
expect(atom.keymap.bindingsForElement(element1)['ctrl-z']).toBe "test-1"
expect(atom.keymap.bindingsForElement(element2)['ctrl-z']).toBe "test-2"
expect(atom.keymap.bindingsForElement(element3)['ctrl-z']).toBeUndefined()
expect(atom.keymap.keyBindingsForKeystrokeMatchingElement('ctrl-z', element1)[0].command).toBe "test-1"
expect(atom.keymap.keyBindingsForKeystrokeMatchingElement('ctrl-z', element2)[0].command).toBe "test-2"
expect(atom.keymap.keyBindingsForKeystrokeMatchingElement('ctrl-z', element3)).toHaveLength 0
describe "when the metadata contains a 'keymaps' manifest", ->
it "loads only the keymaps specified by the manifest, in the specified order", ->
element1 = $$ -> @div class: 'test-1'
element3 = $$ -> @div class: 'test-3'
expect(atom.keymap.bindingsForElement(element1)['ctrl-z']).toBeUndefined()
expect(atom.keymap.keyBindingsForKeystrokeMatchingElement('ctrl-z', element1)).toHaveLength 0
atom.activatePackage("package-with-keymaps-manifest")
atom.packages.activatePackage("package-with-keymaps-manifest")
expect(atom.keymap.bindingsForElement(element1)['ctrl-z']).toBe 'keymap-1'
expect(atom.keymap.bindingsForElement(element1)['ctrl-n']).toBe 'keymap-2'
expect(atom.keymap.bindingsForElement(element3)['ctrl-y']).toBeUndefined()
expect(atom.keymap.keyBindingsForKeystrokeMatchingElement('ctrl-z', element1)[0].command).toBe 'keymap-1'
expect(atom.keymap.keyBindingsForKeystrokeMatchingElement('ctrl-n', element1)[0].command).toBe 'keymap-2'
expect(atom.keymap.keyBindingsForKeystrokeMatchingElement('ctrl-y', element3)).toHaveLength 0
describe "menu loading", ->
beforeEach ->
@@ -171,7 +171,7 @@ describe "the `atom` global", ->
expect(atom.contextMenu.definitionsForElement(element)).toEqual []
atom.activatePackage("package-with-menus")
atom.packages.activatePackage("package-with-menus")
expect(atom.menu.template.length).toBe 2
expect(atom.menu.template[0].label).toBe "Second to Last"
@@ -186,7 +186,7 @@ describe "the `atom` global", ->
expect(atom.contextMenu.definitionsForElement(element)).toEqual []
atom.activatePackage("package-with-menus-manifest")
atom.packages.activatePackage("package-with-menus-manifest")
expect(atom.menu.template[0].label).toBe "Second to Last"
expect(atom.menu.template[1].label).toBe "Last"
@@ -209,7 +209,7 @@ describe "the `atom` global", ->
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
atom.activatePackage("package-with-stylesheets-manifest")
atom.packages.activatePackage("package-with-stylesheets-manifest")
expect(atom.themes.stylesheetElementForId(one)).toExist()
expect(atom.themes.stylesheetElementForId(two)).toExist()
@@ -231,7 +231,7 @@ describe "the `atom` global", ->
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
atom.activatePackage("package-with-stylesheets")
atom.packages.activatePackage("package-with-stylesheets")
expect(atom.themes.stylesheetElementForId(one)).toExist()
expect(atom.themes.stylesheetElementForId(two)).toExist()
expect(atom.themes.stylesheetElementForId(three)).toExist()
@@ -239,90 +239,91 @@ describe "the `atom` global", ->
describe "grammar loading", ->
it "loads the package's grammars", ->
atom.activatePackage('package-with-grammars')
atom.packages.activatePackage('package-with-grammars')
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Alot'
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Alittle'
describe "scoped-property loading", ->
it "loads the scoped properties", ->
atom.activatePackage("package-with-scoped-properties")
atom.packages.activatePackage("package-with-scoped-properties")
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
describe "textmate packages", ->
it "loads the package's grammars", ->
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
atom.activatePackage('language-ruby', sync: true)
atom.packages.activatePackage('language-ruby', sync: true)
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
it "translates the package's scoped properties to Atom terms", ->
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
atom.activatePackage('language-ruby', sync: true)
atom.packages.activatePackage('language-ruby', sync: true)
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBe '# '
describe "when the package has no grammars but does have preferences", ->
it "loads the package's preferences as scoped properties", ->
jasmine.unspy(window, 'setTimeout')
spyOn(syntax, 'addProperties').andCallThrough()
spyOn(atom.syntax, 'addProperties').andCallThrough()
atom.activatePackage('package-with-preferences-tmbundle')
atom.packages.activatePackage('package-with-preferences-tmbundle')
waitsFor ->
atom.syntax.addProperties.callCount > 0
runs ->
expect(atom.syntax.getProperty(['.source.pref'], 'editor.increaseIndentPattern')).toBe '^abc$'
describe ".deactivatePackage(id)", ->
describe "atom packages", ->
it "calls `deactivate` on the package's main module if activate was successful", ->
pack = atom.activatePackage("package-with-deactivate")
expect(atom.isPackageActive("package-with-deactivate")).toBeTruthy()
pack = atom.packages.activatePackage("package-with-deactivate")
expect(atom.packages.isPackageActive("package-with-deactivate")).toBeTruthy()
spyOn(pack.mainModule, 'deactivate').andCallThrough()
atom.deactivatePackage("package-with-deactivate")
atom.packages.deactivatePackage("package-with-deactivate")
expect(pack.mainModule.deactivate).toHaveBeenCalled()
expect(atom.isPackageActive("package-with-module")).toBeFalsy()
expect(atom.packages.isPackageActive("package-with-module")).toBeFalsy()
spyOn(console, 'warn')
badPack = atom.activatePackage("package-that-throws-on-activate")
expect(atom.isPackageActive("package-that-throws-on-activate")).toBeTruthy()
badPack = atom.packages.activatePackage("package-that-throws-on-activate")
expect(atom.packages.isPackageActive("package-that-throws-on-activate")).toBeTruthy()
spyOn(badPack.mainModule, 'deactivate').andCallThrough()
atom.deactivatePackage("package-that-throws-on-activate")
atom.packages.deactivatePackage("package-that-throws-on-activate")
expect(badPack.mainModule.deactivate).not.toHaveBeenCalled()
expect(atom.isPackageActive("package-that-throws-on-activate")).toBeFalsy()
expect(atom.packages.isPackageActive("package-that-throws-on-activate")).toBeFalsy()
it "does not serialize packages that have not been activated called on their main module", ->
spyOn(console, 'warn')
badPack = atom.activatePackage("package-that-throws-on-activate")
badPack = atom.packages.activatePackage("package-that-throws-on-activate")
spyOn(badPack.mainModule, 'serialize').andCallThrough()
atom.deactivatePackage("package-that-throws-on-activate")
atom.packages.deactivatePackage("package-that-throws-on-activate")
expect(badPack.mainModule.serialize).not.toHaveBeenCalled()
it "absorbs exceptions that are thrown by the package module's serialize methods", ->
spyOn(console, 'error')
atom.activatePackage('package-with-serialize-error', immediate: true)
atom.activatePackage('package-with-serialization', immediate: true)
atom.deactivatePackages()
atom.packages.activatePackage('package-with-serialize-error', immediate: true)
atom.packages.activatePackage('package-with-serialization', immediate: true)
atom.packages.deactivatePackages()
expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined()
expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1
expect(console.error).toHaveBeenCalled()
it "removes the package's grammars", ->
atom.activatePackage('package-with-grammars')
atom.deactivatePackage('package-with-grammars')
atom.packages.activatePackage('package-with-grammars')
atom.packages.deactivatePackage('package-with-grammars')
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Null Grammar'
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Null Grammar'
it "removes the package's keymaps", ->
atom.activatePackage('package-with-keymaps')
atom.deactivatePackage('package-with-keymaps')
expect(atom.keymap.bindingsForElement($$ -> @div class: 'test-1')['ctrl-z']).toBeUndefined()
expect(atom.keymap.bindingsForElement($$ -> @div class: 'test-2')['ctrl-z']).toBeUndefined()
atom.packages.activatePackage('package-with-keymaps')
atom.packages.deactivatePackage('package-with-keymaps')
expect(atom.keymap.keyBindingsForKeystrokeMatchingElement('ctrl-z', $$ -> @div class: 'test-1')).toHaveLength 0
expect(atom.keymap.keyBindingsForKeystrokeMatchingElement('ctrl-z', $$ -> @div class: 'test-2')).toHaveLength 0
it "removes the package's stylesheets", ->
atom.activatePackage('package-with-stylesheets')
atom.deactivatePackage('package-with-stylesheets')
atom.packages.activatePackage('package-with-stylesheets')
atom.packages.deactivatePackage('package-with-stylesheets')
one = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css")
two = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less")
three = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css")
@@ -331,22 +332,22 @@ describe "the `atom` global", ->
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
it "removes the package's scoped-properties", ->
atom.activatePackage("package-with-scoped-properties")
atom.packages.activatePackage("package-with-scoped-properties")
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
atom.deactivatePackage("package-with-scoped-properties")
atom.packages.deactivatePackage("package-with-scoped-properties")
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBeUndefined()
describe "textmate packages", ->
it "removes the package's grammars", ->
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
atom.activatePackage('language-ruby', sync: true)
atom.packages.activatePackage('language-ruby', sync: true)
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
atom.deactivatePackage('language-ruby')
atom.packages.deactivatePackage('language-ruby')
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
it "removes the package's scoped properties", ->
atom.activatePackage('language-ruby', sync: true)
atom.deactivatePackage('language-ruby')
atom.packages.activatePackage('language-ruby', sync: true)
atom.packages.deactivatePackage('language-ruby')
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
describe ".activate()", ->
+9 -3
Ver Arquivo
@@ -112,7 +112,7 @@ describe "Config", ->
beforeEach ->
spyOn(nodeFs, 'writeFileSync')
jasmine.unspy config, 'save'
jasmine.unspy atom.config, 'save'
describe "when ~/.atom/config.json exists", ->
it "writes any non-default properties to ~/.atom/config.json", ->
@@ -158,12 +158,12 @@ describe "Config", ->
expect(atom.config.get("foo.quux.y")).toBe 1
describe ".observe(keyPath)", ->
observeHandler = null
[observeHandler, observeSubscription] = []
beforeEach ->
observeHandler = jasmine.createSpy("observeHandler")
atom.config.set("foo.bar.baz", "value 1")
atom.config.observe "foo.bar.baz", observeHandler
observeSubscription = atom.config.observe "foo.bar.baz", observeHandler
it "fires the given callback with the current value at the keypath", ->
expect(observeHandler).toHaveBeenCalledWith("value 1")
@@ -192,6 +192,12 @@ describe "Config", ->
atom.config.set("foo.bar.baz", "i'm back")
expect(observeHandler).toHaveBeenCalledWith("i'm back", {previous: undefined})
it "does not fire the callback once the observe subscription is off'ed", ->
observeHandler.reset() # clear the initial call
observeSubscription.off()
atom.config.set('foo.bar.baz', "value 2")
expect(observeHandler).not.toHaveBeenCalled()
describe ".initializeConfigDirectory()", ->
beforeEach ->
atom.config.configDirPath = dotAtomPath
+6 -6
Ver Arquivo
@@ -5,8 +5,8 @@ describe "DisplayBuffer", ->
[displayBuffer, buffer, changeHandler, tabLength] = []
beforeEach ->
tabLength = 2
atom.activatePackage('language-javascript', sync: true)
buffer = project.bufferForPathSync('sample.js')
atom.packages.activatePackage('language-javascript', sync: true)
buffer = atom.project.bufferForPathSync('sample.js')
displayBuffer = new DisplayBuffer({buffer, tabLength})
changeHandler = jasmine.createSpy 'changeHandler'
displayBuffer.on 'changed', changeHandler
@@ -20,7 +20,7 @@ describe "DisplayBuffer", ->
displayBuffer.setTabLength(4)
displayBuffer.setEditorWidthInChars(64)
displayBuffer.createFold(2, 4)
displayBuffer2 = deserialize(displayBuffer.serialize())
displayBuffer2 = atom.deserializers.deserialize(displayBuffer.serialize())
expect(displayBuffer2.id).toBe displayBuffer.id
expect(displayBuffer2.buffer).toBe displayBuffer.buffer
expect(displayBuffer2.tokenizedBuffer.buffer).toBe displayBuffer.tokenizedBuffer.buffer
@@ -154,7 +154,7 @@ describe "DisplayBuffer", ->
describe "when a newline is inserted, deleted, and re-inserted at the end of a wrapped line (regression)", ->
it "correctly renders the original wrapped line", ->
buffer = project.buildBufferSync(null, '')
buffer = atom.project.buildBufferSync(null, '')
displayBuffer = new DisplayBuffer({buffer, tabLength, editorWidthInChars: 30, softWrap: true})
buffer.insert([0, 0], "the quick brown fox jumps over the lazy dog.")
@@ -206,7 +206,7 @@ describe "DisplayBuffer", ->
beforeEach ->
displayBuffer.destroy()
buffer.release()
buffer = project.bufferForPathSync('two-hundred.txt')
buffer = atom.project.bufferForPathSync('two-hundred.txt')
displayBuffer = new DisplayBuffer({buffer, tabLength})
displayBuffer.on 'changed', changeHandler
@@ -600,7 +600,7 @@ describe "DisplayBuffer", ->
it "unsubscribes all display buffer markers from their underlying buffer marker (regression)", ->
marker = displayBuffer.markBufferPosition([12, 2])
displayBuffer.destroy()
expect(marker.bufferMarker.subscriptionCount()).toBe 0
expect(marker.bufferMarker.getSubscriptionCount()).toBe 0
expect( -> buffer.insert([12, 2], '\n')).not.toThrow()
describe "markers", ->
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+2613 -2773
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
@@ -1,5 +1,5 @@
class Foo
registerDeserializer(this)
atom.deserializers.add(this)
@deserialize: ({data}) -> new Foo(data)
constructor: (@data) ->
@@ -9,5 +9,5 @@ module.exports =
activate: ->
@activateCallCount++
rootView.getActiveView()?.command 'activation-event', =>
atom.rootView.getActiveView()?.command 'activation-event', =>
@activationEventCallCount++
+24 -23
Ver Arquivo
@@ -182,10 +182,10 @@ describe "Git", ->
beforeEach ->
repo = new Git(path.join(__dirname, 'fixtures', 'git', 'working-dir'))
modifiedPath = project.resolve('git/working-dir/file.txt')
modifiedPath = atom.project.resolve('git/working-dir/file.txt')
originalModifiedPathText = fs.readFileSync(modifiedPath, 'utf8')
newPath = project.resolve('git/working-dir/untracked.txt')
cleanPath = project.resolve('git/working-dir/other.txt')
newPath = atom.project.resolve('git/working-dir/untracked.txt')
cleanPath = atom.project.resolve('git/working-dir/other.txt')
fs.writeFileSync(newPath, '')
afterEach ->
@@ -208,44 +208,44 @@ describe "Git", ->
expect(repo.isStatusModified(statuses[modifiedPath])).toBeTruthy()
describe "buffer events", ->
[originalContent, editSession] = []
[originalContent, editor] = []
beforeEach ->
editSession = project.openSync('sample.js')
originalContent = editSession.getText()
editor = atom.project.openSync('sample.js')
originalContent = editor.getText()
afterEach ->
fs.writeFileSync(editSession.getPath(), originalContent)
fs.writeFileSync(editor.getPath(), originalContent)
it "emits a status-changed event when a buffer is saved", ->
editSession.insertNewline()
editor.insertNewline()
statusHandler = jasmine.createSpy('statusHandler')
project.getRepo().on 'status-changed', statusHandler
editSession.save()
atom.project.getRepo().on 'status-changed', statusHandler
editor.save()
expect(statusHandler.callCount).toBe 1
expect(statusHandler).toHaveBeenCalledWith editSession.getPath(), 256
expect(statusHandler).toHaveBeenCalledWith editor.getPath(), 256
it "emits a status-changed event when a buffer is reloaded", ->
fs.writeFileSync(editSession.getPath(), 'changed')
fs.writeFileSync(editor.getPath(), 'changed')
statusHandler = jasmine.createSpy('statusHandler')
project.getRepo().on 'status-changed', statusHandler
editSession.getBuffer().reload()
atom.project.getRepo().on 'status-changed', statusHandler
editor.getBuffer().reload()
expect(statusHandler.callCount).toBe 1
expect(statusHandler).toHaveBeenCalledWith editSession.getPath(), 256
editSession.getBuffer().reload()
expect(statusHandler).toHaveBeenCalledWith editor.getPath(), 256
editor.getBuffer().reload()
expect(statusHandler.callCount).toBe 1
it "emits a status-changed event when a buffer's path changes", ->
fs.writeFileSync(editSession.getPath(), 'changed')
fs.writeFileSync(editor.getPath(), 'changed')
statusHandler = jasmine.createSpy('statusHandler')
project.getRepo().on 'status-changed', statusHandler
editSession.getBuffer().trigger 'path-changed'
atom.project.getRepo().on 'status-changed', statusHandler
editor.getBuffer().emit 'path-changed'
expect(statusHandler.callCount).toBe 1
expect(statusHandler).toHaveBeenCalledWith editSession.getPath(), 256
editSession.getBuffer().trigger 'path-changed'
expect(statusHandler).toHaveBeenCalledWith editor.getPath(), 256
editor.getBuffer().emit 'path-changed'
expect(statusHandler.callCount).toBe 1
describe "when a project is deserialized", ->
@@ -256,8 +256,9 @@ describe "Git", ->
project2?.destroy()
it "subscribes to all the serialized buffers in the project", ->
project.openSync('sample.js')
project2 = deserialize(project.serialize())
atom.project.openSync('sample.js')
#TODO Replace with atom.replicate().project when Atom is a telepath model
project2 = atom.replicate().get('project')
buffer = project2.getBuffers()[0]
waitsFor ->
+73 -109
Ver Arquivo
@@ -21,25 +21,19 @@ describe "Keymap", ->
describe ".handleKeyEvent(event)", ->
deleteCharHandler = null
insertCharHandler = null
commandZHandler = null
beforeEach ->
keymap.bindKeys '.command-mode', 'x': 'deleteChar'
keymap.bindKeys '.insert-mode', 'x': 'insertChar'
keymap.bindKeys 'name', '.command-mode', 'x': 'deleteChar'
keymap.bindKeys 'name', '.insert-mode', 'x': 'insertChar'
keymap.bindKeys 'name', '.command-mode', 'cmd-z': 'commandZPressed'
deleteCharHandler = jasmine.createSpy('deleteCharHandler')
insertCharHandler = jasmine.createSpy('insertCharHandler')
commandZHandler = jasmine.createSpy('commandZHandler')
fragment.on 'deleteChar', deleteCharHandler
fragment.on 'insertChar', insertCharHandler
it "adds a 'keystrokes' string to the event object", ->
event = keydownEvent('x', altKey: true, metaKey: true)
keymap.handleKeyEvent(event)
expect(event.keystrokes).toBe 'alt-meta-x'
event = keydownEvent(',', metaKey: true)
event.which = 188
keymap.handleKeyEvent(event)
expect(event.keystrokes).toBe 'meta-,'
fragment.on 'commandZPressed', commandZHandler
describe "when no binding matches the event's keystroke", ->
it "does not return false so the event continues to propagate", ->
@@ -47,10 +41,11 @@ describe "Keymap", ->
describe "when a non-English keyboard language is used", ->
it "uses the physical character pressed instead of the character it maps to in the current language", ->
event = keydownEvent('U+03B6', metaKey: true) # This is the 'z' key using the Greek keyboard layout
event.which = 122
keymap.handleKeyEvent(event)
expect(event.keystrokes).toBe 'meta-z'
event = keydownEvent('U+03B6', metaKey: true, which: 122, target: fragment[0]) # This is the 'z' key using the Greek keyboard layout
result = keymap.handleKeyEvent(event)
expect(result).toBe(false)
expect(commandZHandler).toHaveBeenCalled()
describe "when at least one binding fully matches the event's keystroke", ->
describe "when the event's target node matches a selector with a matching binding", ->
@@ -67,9 +62,6 @@ describe "Keymap", ->
keymap.handleKeyEvent(event)
expect(deleteCharHandler).not.toHaveBeenCalled()
expect(insertCharHandler).toHaveBeenCalled()
commandEvent = insertCharHandler.argsForCall[0][0]
expect(commandEvent.keyEvent).toBe event
expect(event.keystrokes).toBe 'x'
describe "when the event's target node *descends* from a selector with a matching binding", ->
it "triggers the command event associated with that binding on the target node and returns false", ->
@@ -88,7 +80,7 @@ describe "Keymap", ->
describe "when the event's target node descends from multiple nodes that match selectors with a binding", ->
beforeEach ->
keymap.bindKeys '.child-node', 'x': 'foo'
keymap.bindKeys 'name', '.child-node', 'x': 'foo'
it "only triggers bindings on selectors associated with the closest ancestor node", ->
fooHandler = jasmine.createSpy 'fooHandler'
@@ -125,10 +117,10 @@ describe "Keymap", ->
describe "when the event bubbles to a node that matches multiple selectors", ->
describe "when the matching selectors differ in specificity", ->
it "triggers the binding for the most specific selector", ->
keymap.bindKeys 'div .child-node', 'x': 'foo'
keymap.bindKeys '.command-mode .child-node !important', 'x': 'baz'
keymap.bindKeys '.command-mode .child-node', 'x': 'quux'
keymap.bindKeys '.child-node', 'x': 'bar'
keymap.bindKeys 'name', 'div .child-node', 'x': 'foo'
keymap.bindKeys 'name', '.command-mode .child-node !important', 'x': 'baz'
keymap.bindKeys 'name', '.command-mode .child-node', 'x': 'quux'
keymap.bindKeys 'name', '.child-node', 'x': 'bar'
fooHandler = jasmine.createSpy 'fooHandler'
barHandler = jasmine.createSpy 'barHandler'
@@ -146,8 +138,8 @@ describe "Keymap", ->
describe "when the matching selectors have the same specificity", ->
it "triggers the bindings for the most recently declared selector", ->
keymap.bindKeys '.child-node', 'x': 'foo', 'y': 'baz'
keymap.bindKeys '.child-node', 'x': 'bar'
keymap.bindKeys 'name', '.child-node', 'x': 'foo', 'y': 'baz'
keymap.bindKeys 'name', '.child-node', 'x': 'bar'
fooHandler = jasmine.createSpy 'fooHandler'
barHandler = jasmine.createSpy 'barHandler'
@@ -167,10 +159,11 @@ describe "Keymap", ->
describe "when the event's target is the document body", ->
it "triggers the mapped event on the rootView", ->
window.rootView = new RootView
keymap.bindKeys 'body', 'x': 'foo'
atom.rootView = new RootView
atom.rootView.attachToDom()
keymap.bindKeys 'name', 'body', 'x': 'foo'
fooHandler = jasmine.createSpy("fooHandler")
rootView.on 'foo', fooHandler
atom.rootView.on 'foo', fooHandler
result = keymap.handleKeyEvent(keydownEvent('x', target: document.body))
expect(result).toBe(false)
@@ -180,7 +173,7 @@ describe "Keymap", ->
describe "when the event matches a 'native!' binding", ->
it "returns true, allowing the browser's native key handling to process the event", ->
keymap.bindKeys '.grandchild-node', 'x': 'native!'
keymap.bindKeys 'name', '.grandchild-node', 'x': 'native!'
nativeHandler = jasmine.createSpy("nativeHandler")
fragment.on 'native!', nativeHandler
expect(keymap.handleKeyEvent(keydownEvent('x', target: fragment.find('.grandchild-node')[0]))).toBe true
@@ -190,7 +183,7 @@ describe "Keymap", ->
[quitHandler, closeOtherWindowsHandler] = []
beforeEach ->
keymap.bindKeys "*",
keymap.bindKeys 'name', "*",
'ctrl-x ctrl-c': 'quit'
'ctrl-x 1': 'close-other-windows'
@@ -220,7 +213,7 @@ describe "Keymap", ->
expect(closeOtherWindowsHandler).toHaveBeenCalled()
describe "when a second keystroke added to the first doesn't match any bindings", ->
it "clears the queued keystrokes without triggering any events", ->
it "clears the queued keystroke without triggering any events", ->
expect(keymap.handleKeyEvent(keydownEvent('x', target: fragment[0], ctrlKey: true))).toBe false
expect(keymap.handleKeyEvent(keydownEvent('c', target: fragment[0]))).toBe false
expect(quitHandler).not.toHaveBeenCalled()
@@ -230,7 +223,7 @@ describe "Keymap", ->
describe "when the event's target node descends from multiple nodes that match selectors with a partial binding match", ->
it "allows any of the bindings to be triggered upon a second keystroke, favoring the most specific selector", ->
keymap.bindKeys ".grandchild-node", 'ctrl-x ctrl-c': 'more-specific-quit'
keymap.bindKeys 'name', ".grandchild-node", 'ctrl-x ctrl-c': 'more-specific-quit'
grandchildNode = fragment.find('.grandchild-node')[0]
moreSpecificQuitHandler = jasmine.createSpy('moreSpecificQuitHandler')
fragment.on 'more-specific-quit', moreSpecificQuitHandler
@@ -254,39 +247,17 @@ describe "Keymap", ->
describe "when there is a complete binding with a more specific selector", ->
it "favors the more specific complete match", ->
describe "when a tab keystroke does not match any bindings", ->
it "returns false to prevent the browser from transferring focus", ->
expect(keymap.handleKeyEvent(keydownEvent('U+0009', target: fragment[0]))).toBe false
describe ".keystrokesByCommandForSelector(selector)", ->
it "returns a hash of all commands and their keybindings", ->
keymap.bindKeys 'body', 'a': 'letter'
keymap.bindKeys '.editor', 'b': 'letter'
keymap.bindKeys '.editor', '1': 'number'
keymap.bindKeys '.editor', 'meta-alt-1': 'number-with-modifiers'
expect(keymap.keystrokesByCommandForSelector()).toEqual
'letter': ['b', 'a']
'number': ['1']
'number-with-modifiers': ['alt-meta-1']
expect(keymap.keystrokesByCommandForSelector('.editor')).toEqual
'letter': ['b']
'number': ['1']
'number-with-modifiers': ['alt-meta-1']
describe ".bindKeys(selector, bindings)", ->
describe ".bindKeys(name, selector, bindings)", ->
it "normalizes the key patterns in the hash to put the modifiers in alphabetical order", ->
fooHandler = jasmine.createSpy('fooHandler')
fragment.on 'foo', fooHandler
keymap.bindKeys '*', 'ctrl-alt-delete': 'foo'
keymap.bindKeys 'name', '*', 'ctrl-alt-delete': 'foo'
result = keymap.handleKeyEvent(keydownEvent('delete', ctrlKey: true, altKey: true, target: fragment[0]))
expect(result).toBe(false)
expect(fooHandler).toHaveBeenCalled()
fooHandler.reset()
keymap.bindKeys '*', 'ctrl-alt--': 'foo'
keymap.bindKeys 'name', '*', 'ctrl-alt--': 'foo'
result = keymap.handleKeyEvent(keydownEvent('-', ctrlKey: true, altKey: true, target: fragment[0]))
expect(result).toBe(false)
expect(fooHandler).toHaveBeenCalled()
@@ -299,15 +270,17 @@ describe "Keymap", ->
'.brown':
'ctrl-h': 'harvest'
expect(keymap.bindingsForElement($$ -> @div class: 'green')).toEqual { 'ctrl-c': 'cultivate' }
expect(keymap.bindingsForElement($$ -> @div class: 'brown')).toEqual { 'ctrl-h': 'harvest' }
keymap.add 'medical',
'.green':
'ctrl-v': 'vomit'
expect(keymap.keyBindingsMatchingElement($$ -> @div class: 'green')).toHaveLength 2
expect(keymap.keyBindingsMatchingElement($$ -> @div class: 'brown')).toHaveLength 1
keymap.remove('nature')
expect(keymap.bindingsForElement($$ -> @div class: 'green')).toEqual {}
expect(keymap.bindingsForElement($$ -> @div class: 'brown')).toEqual {}
expect(keymap.bindingSetsByFirstKeystroke['ctrl-c']).toEqual []
expect(keymap.bindingSetsByFirstKeystroke['ctrl-h']).toEqual []
expect(keymap.keyBindingsMatchingElement($$ -> @div class: 'green')).toHaveLength 1
expect(keymap.keyBindingsMatchingElement($$ -> @div class: 'brown')).toEqual []
describe ".keystrokeStringForEvent(event)", ->
describe "when no modifiers are pressed", ->
@@ -318,12 +291,12 @@ describe "Keymap", ->
expect(keymap.keystrokeStringForEvent(keydownEvent('left'))).toBe 'left'
expect(keymap.keystrokeStringForEvent(keydownEvent('\b'))).toBe 'backspace'
describe "when ctrl, alt or meta is pressed with a non-modifier key", ->
describe "when ctrl, alt or command is pressed with a non-modifier key", ->
it "returns a string that identifies the key pressed", ->
expect(keymap.keystrokeStringForEvent(keydownEvent('a', altKey: true))).toBe 'alt-a'
expect(keymap.keystrokeStringForEvent(keydownEvent('[', metaKey: true))).toBe 'meta-['
expect(keymap.keystrokeStringForEvent(keydownEvent('[', metaKey: true))).toBe 'cmd-['
expect(keymap.keystrokeStringForEvent(keydownEvent('*', ctrlKey: true))).toBe 'ctrl-*'
expect(keymap.keystrokeStringForEvent(keydownEvent('left', ctrlKey: true, metaKey: true, altKey: true))).toBe 'alt-ctrl-meta-left'
expect(keymap.keystrokeStringForEvent(keydownEvent('left', ctrlKey: true, metaKey: true, altKey: true))).toBe 'alt-cmd-ctrl-left'
describe "when shift is pressed when a non-modifer key", ->
it "returns a string that identifies the key pressed", ->
@@ -332,54 +305,45 @@ describe "Keymap", ->
expect(keymap.keystrokeStringForEvent(keydownEvent('left', shiftKey: true))).toBe 'shift-left'
expect(keymap.keystrokeStringForEvent(keydownEvent('Left', shiftKey: true))).toBe 'shift-left'
describe ".bindingsForElement(element)", ->
describe ".keyBindingsMatchingElement(element)", ->
it "returns the matching bindings for the element", ->
keymap.bindKeys '.command-mode', 'c': 'c'
keymap.bindKeys '.grandchild-node', 'g': 'g'
keymap.bindKeys 'name', '.command-mode', 'c': 'c'
keymap.bindKeys 'name', '.grandchild-node', 'g': 'g'
bindings = keymap.bindingsForElement(fragment.find('.grandchild-node'))
expect(Object.keys(bindings).length).toBe 2
expect(bindings['c']).toEqual "c"
expect(bindings['g']).toEqual "g"
bindings = keymap.keyBindingsMatchingElement(fragment.find('.grandchild-node'))
expect(bindings).toHaveLength 2
expect(bindings[0].command).toEqual "g"
expect(bindings[1].command).toEqual "c"
describe "when multiple bindings match a keystroke", ->
it "only returns bindings that match the most specific selector", ->
keymap.bindKeys '.command-mode', 'g': 'command-mode'
keymap.bindKeys '.command-mode .grandchild-node', 'g': 'command-and-grandchild-node'
keymap.bindKeys '.grandchild-node', 'g': 'grandchild-node'
keymap.bindKeys 'name', '.command-mode', 'g': 'cmd-mode'
keymap.bindKeys 'name', '.command-mode .grandchild-node', 'g': 'cmd-and-grandchild-node'
keymap.bindKeys 'name', '.grandchild-node', 'g': 'grandchild-node'
bindings = keymap.bindingsForElement(fragment.find('.grandchild-node'))
expect(Object.keys(bindings).length).toBe 1
expect(bindings['g']).toEqual "command-and-grandchild-node"
bindings = keymap.keyBindingsMatchingElement(fragment.find('.grandchild-node'))
expect(bindings).toHaveLength 3
expect(bindings[0].command).toEqual "cmd-and-grandchild-node"
describe ".getAllKeyMappings", ->
it "returns the all bindings", ->
keymap.bindKeys path.join('~', '.atom', 'packages', 'dummy', 'keymaps', 'a.cson'), '.command-mode', 'k': 'c'
describe ".keyBindingsForCommandMatchingElement(element)", ->
beforeEach ->
keymap.add 'nature',
'.green':
'ctrl-c': 'cultivate'
'.green-2':
'ctrl-o': 'cultivate'
'.brown':
'ctrl-h': 'harvest'
'.blue':
'ctrl-c': 'fly'
mappings = keymap.getAllKeyMappings()
expect(mappings.length).toBe 1
expect(mappings[0].source).toEqual 'dummy'
expect(mappings[0].keystrokes).toEqual 'k'
expect(mappings[0].command).toEqual 'c'
expect(mappings[0].selector).toEqual '.command-mode'
it "finds a keymap for an element", ->
el = $$ -> @div class: 'green'
bindings = keymap.keyBindingsForCommandMatchingElement('cultivate', el)
expect(bindings).toHaveLength 1
expect(bindings[0].keystroke).toEqual "ctrl-c"
describe ".determineSource", ->
describe "for a package", ->
it "returns '<package-name>'", ->
expect(keymap.determineSource(path.join('~', '.atom', 'packages', 'dummy', 'keymaps', 'a.cson'))).toEqual 'dummy'
describe "for a linked package", ->
it "returns '<package-name>'", ->
expect(keymap.determineSource(path.join('Users', 'john', 'github', 'dummy', 'keymaps', 'a.cson'))).toEqual 'dummy'
describe "for a user defined keymap", ->
it "returns 'User'", ->
expect(keymap.determineSource(path.join('~', '.atom', 'keymaps', 'a.cson'))).toEqual 'User'
describe "for a core keymap", ->
it "returns 'Core'", ->
expect(keymap.determineSource(path.join('Applications', 'Atom.app', '..', 'node_modules', 'dummy', 'keymaps', 'a.cson'))).toEqual 'Core'
describe "for a linked core keymap", ->
it "returns 'Core'", ->
expect(keymap.determineSource(path.join('Users', 'john', 'github', 'atom', 'keymaps', 'a.cson'))).toEqual 'Core'
it "no keymap an element without that map", ->
el = $$ -> @div class: 'brown'
bindings = keymap.keyBindingsForCommandMatchingElement('cultivate', el)
expect(bindings).toHaveLength 0
+56 -56
Ver Arquivo
@@ -1,14 +1,14 @@
describe "LanguageMode", ->
[editSession, buffer, languageMode] = []
[editor, buffer, languageMode] = []
afterEach ->
editSession.destroy()
editor.destroy()
describe "javascript", ->
beforeEach ->
atom.activatePackage('language-javascript', sync: true)
editSession = project.openSync('sample.js', autoIndent: false)
{buffer, languageMode} = editSession
atom.packages.activatePackage('language-javascript', sync: true)
editor = atom.project.openSync('sample.js', autoIndent: false)
{buffer, languageMode} = editor
describe ".minIndentLevelForRowRange(startRow, endRow)", ->
it "returns the minimum indent level for the given row range", ->
@@ -109,9 +109,9 @@ describe "LanguageMode", ->
describe "coffeescript", ->
beforeEach ->
atom.activatePackage('language-coffee-script', sync: true)
editSession = project.openSync('coffee.coffee', autoIndent: false)
{buffer, languageMode} = editSession
atom.packages.activatePackage('language-coffee-script', sync: true)
editor = atom.project.openSync('coffee.coffee', autoIndent: false)
{buffer, languageMode} = editor
describe ".toggleLineCommentsForBufferRows(start, end)", ->
it "comments/uncomments lines in the given range", ->
@@ -156,9 +156,9 @@ describe "LanguageMode", ->
describe "css", ->
beforeEach ->
atom.activatePackage('language-css', sync: true)
editSession = project.openSync('css.css', autoIndent: false)
{buffer, languageMode} = editSession
atom.packages.activatePackage('language-css', sync: true)
editor = atom.project.openSync('css.css', autoIndent: false)
{buffer, languageMode} = editor
describe ".toggleLineCommentsForBufferRows(start, end)", ->
it "comments/uncomments lines in the given range", ->
@@ -197,10 +197,10 @@ describe "LanguageMode", ->
describe "less", ->
beforeEach ->
atom.activatePackage('language-less', sync: true)
atom.activatePackage('language-css', sync: true)
editSession = project.openSync('sample.less', autoIndent: false)
{buffer, languageMode} = editSession
atom.packages.activatePackage('language-less', sync: true)
atom.packages.activatePackage('language-css', sync: true)
editor = atom.project.openSync('sample.less', autoIndent: false)
{buffer, languageMode} = editor
describe "when commenting lines", ->
it "only uses the `commentEnd` pattern if it comes from the same grammar as the `commentStart`", ->
@@ -209,68 +209,68 @@ describe "LanguageMode", ->
describe "folding", ->
beforeEach ->
atom.activatePackage('language-javascript', sync: true)
editSession = project.openSync('sample.js', autoIndent: false)
{buffer, languageMode} = editSession
atom.packages.activatePackage('language-javascript', sync: true)
editor = atom.project.openSync('sample.js', autoIndent: false)
{buffer, languageMode} = editor
it "maintains cursor buffer position when a folding/unfolding", ->
editSession.setCursorBufferPosition([5,5])
editor.setCursorBufferPosition([5,5])
languageMode.foldAll()
expect(editSession.getCursorBufferPosition()).toEqual([5,5])
expect(editor.getCursorBufferPosition()).toEqual([5,5])
describe ".unfoldAll()", ->
it "unfolds every folded line", ->
initialScreenLineCount = editSession.getScreenLineCount()
initialScreenLineCount = editor.getScreenLineCount()
languageMode.foldBufferRow(0)
languageMode.foldBufferRow(1)
expect(editSession.getScreenLineCount()).toBeLessThan initialScreenLineCount
expect(editor.getScreenLineCount()).toBeLessThan initialScreenLineCount
languageMode.unfoldAll()
expect(editSession.getScreenLineCount()).toBe initialScreenLineCount
expect(editor.getScreenLineCount()).toBe initialScreenLineCount
describe ".foldAll()", ->
it "folds every foldable line", ->
languageMode.foldAll()
fold1 = editSession.lineForScreenRow(0).fold
fold1 = editor.lineForScreenRow(0).fold
expect([fold1.getStartRow(), fold1.getEndRow()]).toEqual [0, 12]
fold1.destroy()
fold2 = editSession.lineForScreenRow(1).fold
fold2 = editor.lineForScreenRow(1).fold
expect([fold2.getStartRow(), fold2.getEndRow()]).toEqual [1, 9]
fold2.destroy()
fold3 = editSession.lineForScreenRow(4).fold
fold3 = editor.lineForScreenRow(4).fold
expect([fold3.getStartRow(), fold3.getEndRow()]).toEqual [4, 7]
describe ".foldBufferRow(bufferRow)", ->
describe "when bufferRow can be folded", ->
it "creates a fold based on the syntactic region starting at the given row", ->
languageMode.foldBufferRow(1)
fold = editSession.lineForScreenRow(1).fold
fold = editor.lineForScreenRow(1).fold
expect(fold.getStartRow()).toBe 1
expect(fold.getEndRow()).toBe 9
describe "when bufferRow can't be folded", ->
it "searches upward for the first row that begins a syntatic region containing the given buffer row (and folds it)", ->
languageMode.foldBufferRow(8)
fold = editSession.lineForScreenRow(1).fold
fold = editor.lineForScreenRow(1).fold
expect(fold.getStartRow()).toBe 1
expect(fold.getEndRow()).toBe 9
describe "when the bufferRow is already folded", ->
it "searches upward for the first row that begins a syntatic region containing the folded row (and folds it)", ->
languageMode.foldBufferRow(2)
expect(editSession.lineForScreenRow(1).fold).toBeDefined()
expect(editSession.lineForScreenRow(0).fold).not.toBeDefined()
expect(editor.lineForScreenRow(1).fold).toBeDefined()
expect(editor.lineForScreenRow(0).fold).not.toBeDefined()
languageMode.foldBufferRow(1)
expect(editSession.lineForScreenRow(0).fold).toBeDefined()
expect(editor.lineForScreenRow(0).fold).toBeDefined()
describe "when the bufferRow is in a multi-line comment", ->
it "searches upward and downward for surrounding comment lines and folds them as a single fold", ->
buffer.insert([1,0], " //this is a comment\n // and\n //more docs\n\n//second comment")
languageMode.foldBufferRow(1)
fold = editSession.lineForScreenRow(1).fold
fold = editor.lineForScreenRow(1).fold
expect(fold.getStartRow()).toBe 1
expect(fold.getEndRow()).toBe 3
@@ -278,7 +278,7 @@ describe "LanguageMode", ->
it "searches upward for the first row that begins a syntatic region containing the folded row (and folds it)", ->
buffer.insert([1,0], " //this is a single line comment\n")
languageMode.foldBufferRow(1)
fold = editSession.lineForScreenRow(0).fold
fold = editor.lineForScreenRow(0).fold
expect(fold.getStartRow()).toBe 0
expect(fold.getEndRow()).toBe 13
@@ -286,77 +286,77 @@ describe "LanguageMode", ->
describe "when bufferRow can be unfolded", ->
it "destroys a fold based on the syntactic region starting at the given row", ->
languageMode.foldBufferRow(1)
expect(editSession.lineForScreenRow(1).fold).toBeDefined()
expect(editor.lineForScreenRow(1).fold).toBeDefined()
languageMode.unfoldBufferRow(1)
expect(editSession.lineForScreenRow(1).fold).toBeUndefined()
expect(editor.lineForScreenRow(1).fold).toBeUndefined()
describe "when bufferRow can't be unfolded", ->
it "does not throw an error", ->
expect(editSession.lineForScreenRow(1).fold).toBeUndefined()
expect(editor.lineForScreenRow(1).fold).toBeUndefined()
languageMode.unfoldBufferRow(1)
expect(editSession.lineForScreenRow(1).fold).toBeUndefined()
expect(editor.lineForScreenRow(1).fold).toBeUndefined()
describe "folding with comments", ->
beforeEach ->
atom.activatePackage('language-javascript', sync: true)
editSession = project.openSync('sample-with-comments.js', autoIndent: false)
{buffer, languageMode} = editSession
atom.packages.activatePackage('language-javascript', sync: true)
editor = atom.project.openSync('sample-with-comments.js', autoIndent: false)
{buffer, languageMode} = editor
describe ".unfoldAll()", ->
it "unfolds every folded line", ->
initialScreenLineCount = editSession.getScreenLineCount()
initialScreenLineCount = editor.getScreenLineCount()
languageMode.foldBufferRow(0)
languageMode.foldBufferRow(5)
expect(editSession.getScreenLineCount()).toBeLessThan initialScreenLineCount
expect(editor.getScreenLineCount()).toBeLessThan initialScreenLineCount
languageMode.unfoldAll()
expect(editSession.getScreenLineCount()).toBe initialScreenLineCount
expect(editor.getScreenLineCount()).toBe initialScreenLineCount
describe ".foldAll()", ->
it "folds every foldable line", ->
languageMode.foldAll()
fold1 = editSession.lineForScreenRow(0).fold
fold1 = editor.lineForScreenRow(0).fold
expect([fold1.getStartRow(), fold1.getEndRow()]).toEqual [0, 19]
fold1.destroy()
fold2 = editSession.lineForScreenRow(1).fold
fold2 = editor.lineForScreenRow(1).fold
expect([fold2.getStartRow(), fold2.getEndRow()]).toEqual [1, 4]
fold3 = editSession.lineForScreenRow(2).fold.destroy()
fold3 = editor.lineForScreenRow(2).fold.destroy()
fold4 = editSession.lineForScreenRow(3).fold
fold4 = editor.lineForScreenRow(3).fold
expect([fold4.getStartRow(), fold4.getEndRow()]).toEqual [6, 8]
describe ".foldAllAtIndentLevel()", ->
it "folds every foldable range at a given indentLevel", ->
languageMode.foldAllAtIndentLevel(2)
fold1 = editSession.lineForScreenRow(6).fold
fold1 = editor.lineForScreenRow(6).fold
expect([fold1.getStartRow(), fold1.getEndRow()]).toEqual [6, 8]
fold1.destroy()
fold2 = editSession.lineForScreenRow(11).fold
fold2 = editor.lineForScreenRow(11).fold
expect([fold2.getStartRow(), fold2.getEndRow()]).toEqual [11, 14]
fold2.destroy()
it "does not fold anything but the indentLevel", ->
languageMode.foldAllAtIndentLevel(0)
fold1 = editSession.lineForScreenRow(0).fold
fold1 = editor.lineForScreenRow(0).fold
expect([fold1.getStartRow(), fold1.getEndRow()]).toEqual [0, 19]
fold1.destroy()
fold2 = editSession.lineForScreenRow(5).fold
fold2 = editor.lineForScreenRow(5).fold
expect(fold2).toBeFalsy()
describe "css", ->
beforeEach ->
atom.activatePackage('language-source', sync: true)
atom.activatePackage('language-css', sync: true)
editSession = project.openSync('css.css', autoIndent: true)
atom.packages.activatePackage('language-source', sync: true)
atom.packages.activatePackage('language-css', sync: true)
editor = atom.project.openSync('css.css', autoIndent: true)
describe "suggestedIndentForBufferRow", ->
it "does not return negative values (regression)", ->
editSession.setText('.test {\npadding: 0;\n}')
expect(editSession.suggestedIndentForBufferRow(2)).toBe 0
editor.setText('.test {\npadding: 0;\n}')
expect(editor.suggestedIndentForBufferRow(2)).toBe 0
+13 -13
Ver Arquivo
@@ -9,7 +9,7 @@ describe "PaneContainer", ->
beforeEach ->
class TestView extends View
registerDeserializer(this)
atom.deserializers.add(this)
@deserialize: ({name}) -> new TestView(name)
@content: -> @div tabindex: -1
initialize: (@name) -> @text(@name)
@@ -25,7 +25,7 @@ describe "PaneContainer", ->
pane3 = pane2.splitDown(new TestView('3'))
afterEach ->
unregisterDeserializer(TestView)
atom.deserializers.remove(TestView)
describe ".focusNextPane()", ->
it "focuses the pane following the focused pane or the first pane if no pane has focus", ->
@@ -84,7 +84,7 @@ describe "PaneContainer", ->
expect(panes).toEqual [pane4]
panes = []
subscription.cancel()
subscription.off()
pane4.splitDown()
expect(panes).toEqual []
@@ -111,11 +111,11 @@ describe "PaneContainer", ->
describe "when the last-closed pane item is an edit session", ->
it "reopens the edit session (regression)", ->
editSession = project.openSync('sample.js')
pane3.showItem(editSession)
pane3.destroyItem(editSession)
editor = atom.project.openSync('sample.js')
pane3.showItem(editor)
pane3.destroyItem(editor)
expect(container.reopenItem()).toBeTruthy()
expect(pane3.activeItem.getPath()).toBe editSession.getPath()
expect(pane3.activeItem.getPath()).toBe editor.getPath()
expect(container.reopenItem()).toBeFalsy()
describe "when there is no active pane", ->
@@ -169,28 +169,28 @@ describe "PaneContainer", ->
it "returns true after modified files are saved", ->
pane1.itemAtIndex(0).shouldPromptToSave = -> true
pane2.itemAtIndex(0).shouldPromptToSave = -> true
spyOn(atom, "confirmSync").andReturn(0)
spyOn(atom, "confirm").andReturn(0)
saved = container.confirmClose()
runs ->
expect(saved).toBeTruthy()
expect(atom.confirmSync).toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
it "returns false if the user cancels saving", ->
pane1.itemAtIndex(0).shouldPromptToSave = -> true
pane2.itemAtIndex(0).shouldPromptToSave = -> true
spyOn(atom, "confirmSync").andReturn(1)
spyOn(atom, "confirm").andReturn(1)
saved = container.confirmClose()
runs ->
expect(saved).toBeFalsy()
expect(atom.confirmSync).toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
describe "serialization", ->
it "can be serialized and deserialized, and correctly adjusts dimensions of deserialized panes after attach", ->
newContainer = deserialize(container.serialize())
newContainer = atom.deserializers.deserialize(container.serialize())
expect(newContainer.find('.row > :contains(1)')).toExist()
expect(newContainer.find('.row > .column > :contains(2)')).toExist()
expect(newContainer.find('.row > .column > :contains(3)')).toExist()
@@ -202,7 +202,7 @@ describe "PaneContainer", ->
xit "removes empty panes on deserialization", ->
# only deserialize pane 1's view successfully
TestView.deserialize = ({name}) -> new TestView(name) if name is '1'
newContainer = deserialize(container.serialize())
newContainer = atom.deserializers.deserialize(container.serialize())
expect(newContainer.find('.row, .column')).not.toExist()
expect(newContainer.find('> :contains(1)')).toExist()
+121 -121
Ver Arquivo
@@ -5,7 +5,7 @@ path = require 'path'
temp = require 'temp'
describe "Pane", ->
[container, view1, view2, editSession1, editSession2, pane] = []
[container, view1, view2, editor1, editor2, pane] = []
class TestView extends View
@deserialize: ({id, text}) -> new TestView({id, text})
@@ -16,17 +16,17 @@ describe "Pane", ->
isEqual: (other) -> @id == other.id and @text == other.text
beforeEach ->
registerDeserializer(TestView)
atom.deserializers.add(TestView)
container = new PaneContainer
view1 = new TestView(id: 'view-1', text: 'View 1')
view2 = new TestView(id: 'view-2', text: 'View 2')
editSession1 = project.openSync('sample.js')
editSession2 = project.openSync('sample.txt')
pane = new Pane(view1, editSession1, view2, editSession2)
editor1 = atom.project.openSync('sample.js')
editor2 = atom.project.openSync('sample.txt')
pane = new Pane(view1, editor1, view2, editor2)
container.setRoot(pane)
afterEach ->
unregisterDeserializer(TestView)
atom.deserializers.remove(TestView)
describe ".initialize(items...)", ->
it "displays the first item in the pane", ->
@@ -52,9 +52,9 @@ describe "Pane", ->
expect(itemChangedHandler.argsForCall[0][1]).toBe view2
itemChangedHandler.reset()
pane.showItem(editSession1)
pane.showItem(editor1)
expect(itemChangedHandler).toHaveBeenCalled()
expect(itemChangedHandler.argsForCall[0][1]).toBe editSession1
expect(itemChangedHandler.argsForCall[0][1]).toBe editor1
itemChangedHandler.reset()
describe "if the pane's active view is focused before calling showItem", ->
@@ -70,12 +70,12 @@ describe "Pane", ->
view3 = null
beforeEach ->
view3 = new TestView(id: 'view-3', text: "View 3")
pane.showItem(editSession1)
pane.showItem(editor1)
expect(pane.getActiveItemIndex()).toBe 1
it "adds it to the items list after the active item", ->
pane.showItem(view3)
expect(pane.getItems()).toEqual [view1, editSession1, view3, view2, editSession2]
expect(pane.getItems()).toEqual [view1, editor1, view3, view2, editor2]
expect(pane.activeItem).toBe view3
expect(pane.getActiveItemIndex()).toBe 2
@@ -89,19 +89,19 @@ describe "Pane", ->
describe "when showing a model item", ->
describe "when no view has yet been appended for that item", ->
it "appends and shows a view to display the item based on its `.getViewClass` method", ->
pane.showItem(editSession1)
editor = pane.activeView
expect(editor.css('display')).not.toBe 'none'
expect(editor.activeEditSession).toBe editSession1
pane.showItem(editor1)
editorView = pane.activeView
expect(editorView.css('display')).not.toBe 'none'
expect(editorView.activeEditSession).toBe editor1
describe "when a valid view has already been appended for another item", ->
it "multiple views are created for multiple items", ->
pane.showItem(editSession1)
pane.showItem(editSession2)
pane.showItem(editor1)
pane.showItem(editor2)
expect(pane.itemViews.find('.editor').length).toBe 2
editor = pane.activeView
expect(editor.css('display')).not.toBe 'none'
expect(editor.activeEditSession).toBe editSession2
editorView = pane.activeView
expect(editorView.css('display')).not.toBe 'none'
expect(editorView.activeEditSession).toBe editor2
it "creates a new view with the item", ->
initialViewCount = pane.itemViews.find('.test-view').length
@@ -141,77 +141,77 @@ describe "Pane", ->
describe ".destroyItem(item)", ->
describe "if the item is not modified", ->
it "removes the item and tries to call destroy on it", ->
pane.destroyItem(editSession2)
expect(pane.getItems().indexOf(editSession2)).toBe -1
expect(editSession2.destroyed).toBeTruthy()
pane.destroyItem(editor2)
expect(pane.getItems().indexOf(editor2)).toBe -1
expect(editor2.destroyed).toBeTruthy()
describe "if the item is modified", ->
beforeEach ->
spyOn(editSession2, 'save')
spyOn(editSession2, 'saveAs')
spyOn(editor2, 'save')
spyOn(editor2, 'saveAs')
editSession2.insertText('a')
expect(editSession2.isModified()).toBeTruthy()
editor2.insertText('a')
expect(editor2.isModified()).toBeTruthy()
describe "if the [Save] option is selected", ->
describe "when the item has a uri", ->
it "saves the item before removing and destroying it", ->
spyOn(atom, 'confirmSync').andReturn(0)
pane.destroyItem(editSession2)
spyOn(atom, 'confirm').andReturn(0)
pane.destroyItem(editor2)
expect(editSession2.save).toHaveBeenCalled()
expect(pane.getItems().indexOf(editSession2)).toBe -1
expect(editSession2.destroyed).toBeTruthy()
expect(editor2.save).toHaveBeenCalled()
expect(pane.getItems().indexOf(editor2)).toBe -1
expect(editor2.destroyed).toBeTruthy()
describe "when the item has no uri", ->
it "presents a save-as dialog, then saves the item with the given uri before removing and destroying it", ->
editSession2.buffer.setPath(undefined)
editor2.buffer.setPath(undefined)
spyOn(atom, 'showSaveDialogSync').andReturn("/selected/path")
spyOn(atom, 'confirmSync').andReturn(0)
pane.destroyItem(editSession2)
spyOn(atom, 'confirm').andReturn(0)
pane.destroyItem(editor2)
expect(atom.showSaveDialogSync).toHaveBeenCalled()
expect(editSession2.saveAs).toHaveBeenCalledWith("/selected/path")
expect(pane.getItems().indexOf(editSession2)).toBe -1
expect(editSession2.destroyed).toBeTruthy()
expect(editor2.saveAs).toHaveBeenCalledWith("/selected/path")
expect(pane.getItems().indexOf(editor2)).toBe -1
expect(editor2.destroyed).toBeTruthy()
describe "if the [Don't Save] option is selected", ->
it "removes and destroys the item without saving it", ->
spyOn(atom, 'confirmSync').andReturn(2)
pane.destroyItem(editSession2)
spyOn(atom, 'confirm').andReturn(2)
pane.destroyItem(editor2)
expect(editSession2.save).not.toHaveBeenCalled()
expect(pane.getItems().indexOf(editSession2)).toBe -1
expect(editSession2.destroyed).toBeTruthy()
expect(editor2.save).not.toHaveBeenCalled()
expect(pane.getItems().indexOf(editor2)).toBe -1
expect(editor2.destroyed).toBeTruthy()
describe "if the [Cancel] option is selected", ->
it "does not save, remove, or destroy the item", ->
spyOn(atom, 'confirmSync').andReturn(1)
pane.destroyItem(editSession2)
spyOn(atom, 'confirm').andReturn(1)
pane.destroyItem(editor2)
expect(editSession2.save).not.toHaveBeenCalled()
expect(pane.getItems().indexOf(editSession2)).not.toBe -1
expect(editSession2.destroyed).toBeFalsy()
expect(editor2.save).not.toHaveBeenCalled()
expect(pane.getItems().indexOf(editor2)).not.toBe -1
expect(editor2.destroyed).toBeFalsy()
describe ".removeItem(item)", ->
it "removes the item from the items list and shows the next item if it was showing", ->
pane.removeItem(view1)
expect(pane.getItems()).toEqual [editSession1, view2, editSession2]
expect(pane.activeItem).toBe editSession1
expect(pane.getItems()).toEqual [editor1, view2, editor2]
expect(pane.activeItem).toBe editor1
pane.showItem(editSession2)
pane.removeItem(editSession2)
expect(pane.getItems()).toEqual [editSession1, view2]
expect(pane.activeItem).toBe editSession1
pane.showItem(editor2)
pane.removeItem(editor2)
expect(pane.getItems()).toEqual [editor1, view2]
expect(pane.activeItem).toBe editor1
it "triggers 'pane:item-removed' with the item and its former index", ->
itemRemovedHandler = jasmine.createSpy("itemRemovedHandler")
pane.on 'pane:item-removed', itemRemovedHandler
pane.removeItem(editSession1)
pane.removeItem(editor1)
expect(itemRemovedHandler).toHaveBeenCalled()
expect(itemRemovedHandler.argsForCall[0][1..2]).toEqual [editSession1, 1]
expect(itemRemovedHandler.argsForCall[0][1..2]).toEqual [editor1, 1]
describe "when removing the last item", ->
it "removes the pane", ->
@@ -236,11 +236,11 @@ describe "Pane", ->
describe "when the item is a model", ->
it "removes the associated view only when all items that require it have been removed", ->
pane.showItem(editSession1)
pane.showItem(editSession2)
pane.removeItem(editSession2)
pane.showItem(editor1)
pane.showItem(editor2)
pane.removeItem(editor2)
expect(pane.itemViews.find('.editor')).toExist()
pane.removeItem(editSession1)
pane.removeItem(editor1)
expect(pane.itemViews.find('.editor')).not.toExist()
describe ".moveItem(item, index)", ->
@@ -249,21 +249,21 @@ describe "Pane", ->
pane.on 'pane:item-moved', itemMovedHandler
pane.moveItem(view1, 2)
expect(pane.getItems()).toEqual [editSession1, view2, view1, editSession2]
expect(pane.getItems()).toEqual [editor1, view2, view1, editor2]
expect(itemMovedHandler).toHaveBeenCalled()
expect(itemMovedHandler.argsForCall[0][1..2]).toEqual [view1, 2]
itemMovedHandler.reset()
pane.moveItem(editSession1, 3)
expect(pane.getItems()).toEqual [view2, view1, editSession2, editSession1]
pane.moveItem(editor1, 3)
expect(pane.getItems()).toEqual [view2, view1, editor2, editor1]
expect(itemMovedHandler).toHaveBeenCalled()
expect(itemMovedHandler.argsForCall[0][1..2]).toEqual [editSession1, 3]
expect(itemMovedHandler.argsForCall[0][1..2]).toEqual [editor1, 3]
itemMovedHandler.reset()
pane.moveItem(editSession1, 1)
expect(pane.getItems()).toEqual [view2, editSession1, view1, editSession2]
pane.moveItem(editor1, 1)
expect(pane.getItems()).toEqual [view2, editor1, view1, editor2]
expect(itemMovedHandler).toHaveBeenCalled()
expect(itemMovedHandler.argsForCall[0][1..2]).toEqual [editSession1, 1]
expect(itemMovedHandler.argsForCall[0][1..2]).toEqual [editor1, 1]
itemMovedHandler.reset()
describe ".moveItemToPane(item, pane, index)", ->
@@ -275,21 +275,21 @@ describe "Pane", ->
it "moves the item to the given pane at the given index", ->
pane.moveItemToPane(view1, pane2, 1)
expect(pane.getItems()).toEqual [editSession1, view2, editSession2]
expect(pane.getItems()).toEqual [editor1, view2, editor2]
expect(pane2.getItems()).toEqual [view3, view1]
describe "when it is the last item on the source pane", ->
it "removes the source pane, but does not destroy the item", ->
pane.removeItem(view1)
pane.removeItem(view2)
pane.removeItem(editSession2)
pane.removeItem(editor2)
expect(pane.getItems()).toEqual [editSession1]
pane.moveItemToPane(editSession1, pane2, 1)
expect(pane.getItems()).toEqual [editor1]
pane.moveItemToPane(editor1, pane2, 1)
expect(pane.hasParent()).toBeFalsy()
expect(pane2.getItems()).toEqual [view3, editSession1]
expect(editSession1.destroyed).toBeFalsy()
expect(pane2.getItems()).toEqual [view3, editor1]
expect(editor1.destroyed).toBeFalsy()
describe "when the item is a jQuery object", ->
it "preserves data by detaching instead of removing", ->
@@ -303,37 +303,37 @@ describe "Pane", ->
containerCloseHandler = jasmine.createSpy("containerCloseHandler")
container.on 'core:close', containerCloseHandler
pane.showItem(editSession1)
pane.showItem(editor1)
initialItemCount = pane.getItems().length
pane.trigger 'core:close'
expect(pane.getItems().length).toBe initialItemCount - 1
expect(editSession1.destroyed).toBeTruthy()
expect(editor1.destroyed).toBeTruthy()
expect(containerCloseHandler).not.toHaveBeenCalled()
describe "pane:close", ->
it "destroys all items and removes the pane", ->
pane.showItem(editSession1)
pane.showItem(editor1)
pane.trigger 'pane:close'
expect(pane.hasParent()).toBeFalsy()
expect(editSession2.destroyed).toBeTruthy()
expect(editSession1.destroyed).toBeTruthy()
expect(editor2.destroyed).toBeTruthy()
expect(editor1.destroyed).toBeTruthy()
describe "pane:close-other-items", ->
it "destroys all items except the current", ->
pane.showItem(editSession1)
pane.showItem(editor1)
pane.trigger 'pane:close-other-items'
expect(editSession2.destroyed).toBeTruthy()
expect(pane.getItems()).toEqual [editSession1]
expect(editor2.destroyed).toBeTruthy()
expect(pane.getItems()).toEqual [editor1]
describe "core:save", ->
describe "when the current item has a uri", ->
describe "when the current item has a save method", ->
it "saves the current item", ->
spyOn(editSession2, 'save')
pane.showItem(editSession2)
spyOn(editor2, 'save')
pane.showItem(editor2)
pane.trigger 'core:save'
expect(editSession2.save).toHaveBeenCalled()
expect(editor2.save).toHaveBeenCalled()
describe "when the current item has no save method", ->
it "does nothing", ->
@@ -347,14 +347,14 @@ describe "Pane", ->
describe "when the current item has a saveAs method", ->
it "opens a save dialog and saves the current item as the selected path", ->
spyOn(editSession2, 'saveAs')
editSession2.buffer.setPath(undefined)
pane.showItem(editSession2)
spyOn(editor2, 'saveAs')
editor2.buffer.setPath(undefined)
pane.showItem(editor2)
pane.trigger 'core:save'
expect(atom.showSaveDialogSync).toHaveBeenCalled()
expect(editSession2.saveAs).toHaveBeenCalledWith('/selected/path')
expect(editor2.saveAs).toHaveBeenCalledWith('/selected/path')
describe "when the current item has no saveAs method", ->
it "does nothing", ->
@@ -368,13 +368,13 @@ describe "Pane", ->
describe "when the current item has a saveAs method", ->
it "opens the save dialog and calls saveAs on the item with the selected path", ->
spyOn(editSession2, 'saveAs')
pane.showItem(editSession2)
spyOn(editor2, 'saveAs')
pane.showItem(editor2)
pane.trigger 'core:save-as'
expect(atom.showSaveDialogSync).toHaveBeenCalledWith(path.dirname(editSession2.getPath()))
expect(editSession2.saveAs).toHaveBeenCalledWith('/selected/path')
expect(atom.showSaveDialogSync).toHaveBeenCalledWith(path.dirname(editor2.getPath()))
expect(editor2.saveAs).toHaveBeenCalledWith('/selected/path')
describe "when the current item does not have a saveAs method", ->
it "does nothing", ->
@@ -386,11 +386,11 @@ describe "Pane", ->
it "advances forward/backward through the pane's items, looping around at either end", ->
expect(pane.activeItem).toBe view1
pane.trigger 'pane:show-previous-item'
expect(pane.activeItem).toBe editSession2
expect(pane.activeItem).toBe editor2
pane.trigger 'pane:show-previous-item'
expect(pane.activeItem).toBe view2
pane.trigger 'pane:show-next-item'
expect(pane.activeItem).toBe editSession2
expect(pane.activeItem).toBe editor2
pane.trigger 'pane:show-next-item'
expect(pane.activeItem).toBe view1
@@ -424,8 +424,8 @@ describe "Pane", ->
describe ".remove()", ->
it "destroys all the pane's items", ->
pane.remove()
expect(editSession1.destroyed).toBeTruthy()
expect(editSession2.destroyed).toBeTruthy()
expect(editor1.destroyed).toBeTruthy()
expect(editor2.destroyed).toBeTruthy()
it "triggers a 'pane:removed' event with the pane", ->
removedHandler = jasmine.createSpy("removedHandler")
@@ -438,7 +438,7 @@ describe "Pane", ->
[paneToLeft, paneToRight] = []
beforeEach ->
pane.showItem(editSession1)
pane.showItem(editor1)
paneToLeft = pane.splitLeft(pane.copyActiveItem())
paneToRight = pane.splitRight(pane.copyActiveItem())
container.attachToDom()
@@ -475,24 +475,24 @@ describe "Pane", ->
describe "when it is the last pane", ->
beforeEach ->
expect(container.getPanes().length).toBe 1
window.rootView = focus: jasmine.createSpy("rootView.focus")
atom.rootView = focus: jasmine.createSpy("rootView.focus")
describe "when the removed pane is focused", ->
it "calls focus on rootView so we don't lose focus", ->
container.attachToDom()
pane.focus()
pane.remove()
expect(rootView.focus).toHaveBeenCalled()
expect(atom.rootView.focus).toHaveBeenCalled()
describe "when the removed pane is not focused", ->
it "does not call focus on root view", ->
expect(pane).not.toMatchSelector ':has(:focus)'
pane.remove()
expect(rootView.focus).not.toHaveBeenCalled()
expect(atom.rootView.focus).not.toHaveBeenCalled()
describe ".getNextPane()", ->
it "returns the next pane if one exists, wrapping around from the last pane to the first", ->
pane.showItem(editSession1)
pane.showItem(editor1)
expect(pane.getNextPane()).toBeUndefined
pane2 = pane.splitRight(pane.copyActiveItem())
expect(pane.getNextPane()).toBe pane2
@@ -538,7 +538,7 @@ describe "Pane", ->
[pane1, view3, view4] = []
beforeEach ->
pane1 = pane
pane.showItem(editSession1)
pane.showItem(editor1)
view3 = new TestView(id: 'view-3', text: 'View 3')
view4 = new TestView(id: 'view-4', text: 'View 4')
@@ -547,8 +547,8 @@ describe "Pane", ->
# creates the new pane with a copy of the active item if none are given
pane2 = pane1.splitRight(pane1.copyActiveItem())
expect(container.find('.row .pane').toArray()).toEqual [pane1[0], pane2[0]]
expect(pane2.items).toEqual [editSession1]
expect(pane2.activeItem).not.toBe editSession1 # it's a copy
expect(pane2.items).toEqual [editor1]
expect(pane2.activeItem).not.toBe editor1 # it's a copy
pane3 = pane2.splitRight(view3, view4)
expect(pane3.getItems()).toEqual [view3, view4]
@@ -571,8 +571,8 @@ describe "Pane", ->
# creates the new pane with a copy of the active item if none are given
pane2 = pane.splitLeft(pane1.copyActiveItem())
expect(container.find('.row .pane').toArray()).toEqual [pane2[0], pane[0]]
expect(pane2.items).toEqual [editSession1]
expect(pane2.activeItem).not.toBe editSession1 # it's a copy
expect(pane2.items).toEqual [editor1]
expect(pane2.activeItem).not.toBe editor1 # it's a copy
pane3 = pane2.splitLeft(view3, view4)
expect(pane3.getItems()).toEqual [view3, view4]
@@ -583,8 +583,8 @@ describe "Pane", ->
# creates the new pane with a copy of the active item if none are given
pane2 = pane.splitDown(pane1.copyActiveItem())
expect(container.find('.column .pane').toArray()).toEqual [pane[0], pane2[0]]
expect(pane2.items).toEqual [editSession1]
expect(pane2.activeItem).not.toBe editSession1 # it's a copy
expect(pane2.items).toEqual [editor1]
expect(pane2.activeItem).not.toBe editor1 # it's a copy
pane3 = pane2.splitDown(view3, view4)
expect(pane3.getItems()).toEqual [view3, view4]
@@ -595,8 +595,8 @@ describe "Pane", ->
# creates the new pane with a copy of the active item if none are given
pane2 = pane.splitUp(pane1.copyActiveItem())
expect(container.find('.column .pane').toArray()).toEqual [pane2[0], pane[0]]
expect(pane2.items).toEqual [editSession1]
expect(pane2.activeItem).not.toBe editSession1 # it's a copy
expect(pane2.items).toEqual [editor1]
expect(pane2.activeItem).not.toBe editor1 # it's a copy
pane3 = pane2.splitUp(view3, view4)
expect(pane3.getItems()).toEqual [view3, view4]
@@ -673,18 +673,18 @@ describe "Pane", ->
describe ".itemForUri(uri)", ->
it "returns the item for which a call to .getUri() returns the given uri", ->
expect(pane.itemForUri(editSession1.getUri())).toBe editSession1
expect(pane.itemForUri(editSession2.getUri())).toBe editSession2
expect(pane.itemForUri(editor1.getUri())).toBe editor1
expect(pane.itemForUri(editor2.getUri())).toBe editor2
describe "serialization", ->
it "can serialize and deserialize the pane and all its items", ->
newPane = deserialize(pane.serialize())
expect(newPane.getItems()).toEqual [view1, editSession1, view2, editSession2]
newPane = atom.deserializers.deserialize(pane.serialize())
expect(newPane.getItems()).toEqual [view1, editor1, view2, editor2]
it "restores the active item on deserialization", ->
pane.showItem(editSession2)
newPane = deserialize(pane.serialize())
expect(newPane.activeItem).toEqual editSession2
pane.showItem(editor2)
newPane = atom.deserializers.deserialize(pane.serialize())
expect(newPane.activeItem).toEqual editor2
it "does not show items that cannot be deserialized", ->
spyOn(console, 'warn')
@@ -693,18 +693,18 @@ describe "Pane", ->
paneState = pane.serialize()
paneState.get('items').set(pane.items.indexOf(view2), {deserializer: 'Bogus'}) # nuke serialized state of active item
newPane = deserialize(paneState)
newPane = atom.deserializers.deserialize(paneState)
expect(newPane.activeItem).toEqual pane.items[0]
expect(newPane.items.length).toBe pane.items.length - 1
it "focuses the pane after attach only if had focus when serialized", ->
reloadContainer = ->
projectState = project.serialize()
projectReplica = atom.replicate().get('project')
containerState = container.serialize()
container.remove()
project.destroy()
window.project = deserialize(projectState)
container = deserialize(containerState)
atom.project = projectReplica
atom.project.destroy()
container = atom.deserializers.deserialize(containerState)
pane = container.getRoot()
container.attachToDom()
+167 -154
Ver Arquivo
@@ -8,7 +8,7 @@ BufferedProcess = require '../src/buffered-process'
describe "Project", ->
beforeEach ->
project.setPath(project.resolve('dir'))
atom.project.setPath(atom.project.resolve('dir'))
describe "serialization", ->
deserializedProject = null
@@ -17,121 +17,134 @@ describe "Project", ->
deserializedProject?.destroy()
it "destroys unretained buffers and does not include them in the serialized state", ->
project.bufferForPathSync('a')
expect(project.getBuffers().length).toBe 1
deserializedProject = deserialize(project.serialize())
atom.project.bufferForPathSync('a')
expect(atom.project.getBuffers().length).toBe 1
atom.project.getState().serializeForPersistence()
deserializedProject = atom.replicate().get('project')
expect(deserializedProject.getBuffers().length).toBe 0
expect(atom.project.getBuffers().length).toBe 0
it "listens for destroyed events on deserialized buffers and removes them when they are destroyed", ->
atom.project.openSync('a')
expect(atom.project.getBuffers().length).toBe 1
atom.project.getState().serializeForPersistence()
deserializedProject = atom.replicate().get('project')
expect(deserializedProject.getBuffers().length).toBe 1
deserializedProject.getBuffers()[0].destroy()
expect(deserializedProject.getBuffers().length).toBe 0
expect(project.getBuffers().length).toBe 0
describe "when an edit session is destroyed", ->
it "removes edit session and calls destroy on buffer (if buffer is not referenced by other edit sessions)", ->
editSession = project.openSync("a")
anotherEditSession = project.openSync("a")
editor = atom.project.openSync("a")
anotherEditSession = atom.project.openSync("a")
expect(project.editSessions.length).toBe 2
expect(editSession.buffer).toBe anotherEditSession.buffer
expect(atom.project.editors.length).toBe 2
expect(editor.buffer).toBe anotherEditSession.buffer
editSession.destroy()
expect(project.editSessions.length).toBe 1
editor.destroy()
expect(atom.project.editors.length).toBe 1
anotherEditSession.destroy()
expect(project.editSessions.length).toBe 0
expect(atom.project.editors.length).toBe 0
describe "when an edit session is saved and the project has no path", ->
it "sets the project's path to the saved file's parent directory", ->
tempFile = temp.openSync().path
project.setPath(undefined)
expect(project.getPath()).toBeUndefined()
editSession = project.openSync()
editSession.saveAs(tempFile)
expect(project.getPath()).toBe path.dirname(tempFile)
atom.project.setPath(undefined)
expect(atom.project.getPath()).toBeUndefined()
editor = atom.project.openSync()
editor.saveAs(tempFile)
expect(atom.project.getPath()).toBe path.dirname(tempFile)
describe "when an edit session is deserialized", ->
it "emits an 'edit-session-created' event and stores the edit session", ->
handler = jasmine.createSpy('editSessionCreatedHandler')
project.on 'edit-session-created', handler
it "emits an 'editor-created' event and stores the edit session", ->
handler = jasmine.createSpy('editorCreatedHandler')
atom.project.on 'editor-created', handler
editSession1 = project.openSync("a")
editor1 = atom.project.openSync("a")
expect(handler.callCount).toBe 1
expect(project.getEditSessions().length).toBe 1
expect(project.getEditSessions()[0]).toBe editSession1
expect(atom.project.getEditSessions().length).toBe 1
expect(atom.project.getEditSessions()[0]).toBe editor1
editSession2 = deserialize(editSession1.serialize())
editor2 = atom.deserializers.deserialize(editor1.serialize())
expect(handler.callCount).toBe 2
expect(project.getEditSessions().length).toBe 2
expect(project.getEditSessions()[0]).toBe editSession1
expect(project.getEditSessions()[1]).toBe editSession2
expect(atom.project.getEditSessions().length).toBe 2
expect(atom.project.getEditSessions()[0]).toBe editor1
expect(atom.project.getEditSessions()[1]).toBe editor2
describe "when an edit session is copied", ->
it "emits an 'edit-session-created' event and stores the edit session", ->
handler = jasmine.createSpy('editSessionCreatedHandler')
project.on 'edit-session-created', handler
it "emits an 'editor-created' event and stores the edit session", ->
handler = jasmine.createSpy('editorCreatedHandler')
atom.project.on 'editor-created', handler
editSession1 = project.openSync("a")
editor1 = atom.project.openSync("a")
expect(handler.callCount).toBe 1
expect(project.getEditSessions().length).toBe 1
expect(project.getEditSessions()[0]).toBe editSession1
expect(atom.project.getEditSessions().length).toBe 1
expect(atom.project.getEditSessions()[0]).toBe editor1
editSession2 = editSession1.copy()
editor2 = editor1.copy()
expect(handler.callCount).toBe 2
expect(project.getEditSessions().length).toBe 2
expect(project.getEditSessions()[0]).toBe editSession1
expect(project.getEditSessions()[1]).toBe editSession2
expect(atom.project.getEditSessions().length).toBe 2
expect(atom.project.getEditSessions()[0]).toBe editor1
expect(atom.project.getEditSessions()[1]).toBe editor2
describe ".openSync(path)", ->
[fooOpener, barOpener, absolutePath, newBufferHandler, newEditSessionHandler] = []
beforeEach ->
absolutePath = require.resolve('./fixtures/dir/a')
newBufferHandler = jasmine.createSpy('newBufferHandler')
project.on 'buffer-created', newBufferHandler
atom.project.on 'buffer-created', newBufferHandler
newEditSessionHandler = jasmine.createSpy('newEditSessionHandler')
project.on 'edit-session-created', newEditSessionHandler
atom.project.on 'editor-created', newEditSessionHandler
fooOpener = (pathToOpen, options) -> { foo: pathToOpen, options } if pathToOpen?.match(/\.foo/)
barOpener = (pathToOpen) -> { bar: pathToOpen } if pathToOpen?.match(/^bar:\/\//)
project.registerOpener(fooOpener)
project.registerOpener(barOpener)
atom.project.registerOpener(fooOpener)
atom.project.registerOpener(barOpener)
afterEach ->
project.unregisterOpener(fooOpener)
project.unregisterOpener(barOpener)
atom.project.unregisterOpener(fooOpener)
atom.project.unregisterOpener(barOpener)
describe "when passed a path that doesn't match a custom opener", ->
describe "when given an absolute path that hasn't been opened previously", ->
it "returns a new edit session for the given path and emits 'buffer-created' and 'edit-session-created' events", ->
editSession = project.openSync(absolutePath)
expect(editSession.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editSession.buffer
expect(newEditSessionHandler).toHaveBeenCalledWith editSession
it "returns a new edit session for the given path and emits 'buffer-created' and 'editor-created' events", ->
editor = atom.project.openSync(absolutePath)
expect(editor.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
expect(newEditSessionHandler).toHaveBeenCalledWith editor
describe "when given a relative path that hasn't been opened previously", ->
it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created' and 'edit-session-created' events", ->
editSession = project.openSync('a')
expect(editSession.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editSession.buffer
expect(newEditSessionHandler).toHaveBeenCalledWith editSession
it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created' and 'editor-created' events", ->
editor = atom.project.openSync('a')
expect(editor.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
expect(newEditSessionHandler).toHaveBeenCalledWith editor
describe "when passed the path to a buffer that has already been opened", ->
it "returns a new edit session containing previously opened buffer and emits a 'edit-session-created' event", ->
editSession = project.openSync(absolutePath)
it "returns a new edit session containing previously opened buffer and emits a 'editor-created' event", ->
editor = atom.project.openSync(absolutePath)
newBufferHandler.reset()
expect(project.openSync(absolutePath).buffer).toBe editSession.buffer
expect(project.openSync('a').buffer).toBe editSession.buffer
expect(atom.project.openSync(absolutePath).buffer).toBe editor.buffer
expect(atom.project.openSync('a').buffer).toBe editor.buffer
expect(newBufferHandler).not.toHaveBeenCalled()
expect(newEditSessionHandler).toHaveBeenCalledWith editSession
expect(newEditSessionHandler).toHaveBeenCalledWith editor
describe "when not passed a path", ->
it "returns a new edit session and emits 'buffer-created' and 'edit-session-created' events", ->
editSession = project.openSync()
expect(editSession.buffer.getPath()).toBeUndefined()
expect(newBufferHandler).toHaveBeenCalledWith(editSession.buffer)
expect(newEditSessionHandler).toHaveBeenCalledWith editSession
it "returns a new edit session and emits 'buffer-created' and 'editor-created' events", ->
editor = atom.project.openSync()
expect(editor.buffer.getPath()).toBeUndefined()
expect(newBufferHandler).toHaveBeenCalledWith(editor.buffer)
expect(newEditSessionHandler).toHaveBeenCalledWith editor
describe "when passed a path that matches a custom opener", ->
it "returns the resource returned by the custom opener", ->
pathToOpen = project.resolve('a.foo')
expect(project.openSync(pathToOpen, hey: "there")).toEqual { foo: pathToOpen, options: {hey: "there"} }
expect(project.openSync("bar://baz")).toEqual { bar: "bar://baz" }
pathToOpen = atom.project.resolve('a.foo')
expect(atom.project.openSync(pathToOpen, hey: "there")).toEqual { foo: pathToOpen, options: {hey: "there"} }
expect(atom.project.openSync("bar://baz")).toEqual { bar: "bar://baz" }
describe ".open(path)", ->
[fooOpener, barOpener, absolutePath, newBufferHandler, newEditSessionHandler] = []
@@ -139,81 +152,81 @@ describe "Project", ->
beforeEach ->
absolutePath = require.resolve('./fixtures/dir/a')
newBufferHandler = jasmine.createSpy('newBufferHandler')
project.on 'buffer-created', newBufferHandler
atom.project.on 'buffer-created', newBufferHandler
newEditSessionHandler = jasmine.createSpy('newEditSessionHandler')
project.on 'edit-session-created', newEditSessionHandler
atom.project.on 'editor-created', newEditSessionHandler
fooOpener = (pathToOpen, options) -> { foo: pathToOpen, options } if pathToOpen?.match(/\.foo/)
barOpener = (pathToOpen) -> { bar: pathToOpen } if pathToOpen?.match(/^bar:\/\//)
project.registerOpener(fooOpener)
project.registerOpener(barOpener)
atom.project.registerOpener(fooOpener)
atom.project.registerOpener(barOpener)
afterEach ->
project.unregisterOpener(fooOpener)
project.unregisterOpener(barOpener)
atom.project.unregisterOpener(fooOpener)
atom.project.unregisterOpener(barOpener)
describe "when passed a path that doesn't match a custom opener", ->
describe "when given an absolute path that isn't currently open", ->
it "returns a new edit session for the given path and emits 'buffer-created' and 'edit-session-created' events", ->
editSession = null
it "returns a new edit session for the given path and emits 'buffer-created' and 'editor-created' events", ->
editor = null
waitsForPromise ->
project.open(absolutePath).then (o) -> editSession = o
atom.project.open(absolutePath).then (o) -> editor = o
runs ->
expect(editSession.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editSession.buffer
expect(newEditSessionHandler).toHaveBeenCalledWith editSession
expect(editor.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
expect(newEditSessionHandler).toHaveBeenCalledWith editor
describe "when given a relative path that isn't currently opened", ->
it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created' and 'edit-session-created' events", ->
editSession = null
it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created' and 'editor-created' events", ->
editor = null
waitsForPromise ->
project.open(absolutePath).then (o) -> editSession = o
atom.project.open(absolutePath).then (o) -> editor = o
runs ->
expect(editSession.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editSession.buffer
expect(newEditSessionHandler).toHaveBeenCalledWith editSession
expect(editor.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
expect(newEditSessionHandler).toHaveBeenCalledWith editor
describe "when passed the path to a buffer that is currently opened", ->
it "returns a new edit session containing currently opened buffer and emits a 'edit-session-created' event", ->
editSession = null
it "returns a new edit session containing currently opened buffer and emits a 'editor-created' event", ->
editor = null
waitsForPromise ->
project.open(absolutePath).then (o) -> editSession = o
atom.project.open(absolutePath).then (o) -> editor = o
runs ->
newBufferHandler.reset()
expect(project.openSync(absolutePath).buffer).toBe editSession.buffer
expect(project.openSync('a').buffer).toBe editSession.buffer
expect(atom.project.openSync(absolutePath).buffer).toBe editor.buffer
expect(atom.project.openSync('a').buffer).toBe editor.buffer
expect(newBufferHandler).not.toHaveBeenCalled()
expect(newEditSessionHandler).toHaveBeenCalledWith editSession
expect(newEditSessionHandler).toHaveBeenCalledWith editor
describe "when not passed a path", ->
it "returns a new edit session and emits 'buffer-created' and 'edit-session-created' events", ->
editSession = null
it "returns a new edit session and emits 'buffer-created' and 'editor-created' events", ->
editor = null
waitsForPromise ->
project.open().then (o) -> editSession = o
atom.project.open().then (o) -> editor = o
runs ->
expect(editSession.buffer.getPath()).toBeUndefined()
expect(newBufferHandler).toHaveBeenCalledWith(editSession.buffer)
expect(newEditSessionHandler).toHaveBeenCalledWith editSession
expect(editor.buffer.getPath()).toBeUndefined()
expect(newBufferHandler).toHaveBeenCalledWith(editor.buffer)
expect(newEditSessionHandler).toHaveBeenCalledWith editor
describe "when passed a path that matches a custom opener", ->
it "returns the resource returned by the custom opener", ->
waitsForPromise ->
pathToOpen = project.resolve('a.foo')
project.open(pathToOpen, hey: "there").then (item) ->
pathToOpen = atom.project.resolve('a.foo')
atom.project.open(pathToOpen, hey: "there").then (item) ->
expect(item).toEqual { foo: pathToOpen, options: {hey: "there"} }
waitsForPromise ->
project.open("bar://baz").then (item) ->
atom.project.open("bar://baz").then (item) ->
expect(item).toEqual { bar: "bar://baz" }
it "returns number of read bytes as progress indicator", ->
filePath = project.resolve 'a'
filePath = atom.project.resolve 'a'
totalBytes = 0
promise = project.open(filePath)
promise = atom.project.open(filePath)
promise.progress (bytesRead) -> totalBytes = bytesRead
waitsForPromise ->
@@ -225,22 +238,22 @@ describe "Project", ->
describe ".bufferForPathSync(path)", ->
describe "when opening a previously opened path", ->
it "does not create a new buffer", ->
buffer = project.bufferForPathSync("a").retain()
expect(project.bufferForPathSync("a")).toBe buffer
buffer = atom.project.bufferForPathSync("a").retain()
expect(atom.project.bufferForPathSync("a")).toBe buffer
alternativeBuffer = project.bufferForPathSync("b").retain().release()
alternativeBuffer = atom.project.bufferForPathSync("b").retain().release()
expect(alternativeBuffer).not.toBe buffer
buffer.release()
it "creates a new buffer if the previous buffer was destroyed", ->
buffer = project.bufferForPathSync("a").retain().release()
expect(project.bufferForPathSync("a").retain().release()).not.toBe buffer
buffer = atom.project.bufferForPathSync("a").retain().release()
expect(atom.project.bufferForPathSync("a").retain().release()).not.toBe buffer
describe ".bufferForPath(path)", ->
[buffer] = []
beforeEach ->
waitsForPromise ->
project.bufferForPath("a").then (o) ->
atom.project.bufferForPath("a").then (o) ->
buffer = o
buffer.retain()
@@ -250,60 +263,60 @@ describe "Project", ->
describe "when opening a previously opened path", ->
it "does not create a new buffer", ->
waitsForPromise ->
project.bufferForPath("a").then (anotherBuffer) ->
atom.project.bufferForPath("a").then (anotherBuffer) ->
expect(anotherBuffer).toBe buffer
waitsForPromise ->
project.bufferForPath("b").then (anotherBuffer) ->
atom.project.bufferForPath("b").then (anotherBuffer) ->
expect(anotherBuffer).not.toBe buffer
it "creates a new buffer if the previous buffer was destroyed", ->
buffer.release()
waitsForPromise ->
project.bufferForPath("b").then (anotherBuffer) ->
atom.project.bufferForPath("b").then (anotherBuffer) ->
expect(anotherBuffer).not.toBe buffer
describe ".resolve(uri)", ->
describe "when passed an absolute or relative path", ->
it "returns an absolute path based on the project's root", ->
it "returns an absolute path based on the atom.project's root", ->
absolutePath = require.resolve('./fixtures/dir/a')
expect(project.resolve('a')).toBe absolutePath
expect(project.resolve(absolutePath + '/../a')).toBe absolutePath
expect(project.resolve('a/../a')).toBe absolutePath
expect(atom.project.resolve('a')).toBe absolutePath
expect(atom.project.resolve(absolutePath + '/../a')).toBe absolutePath
expect(atom.project.resolve('a/../a')).toBe absolutePath
describe "when passed a uri with a scheme", ->
it "does not modify uris that begin with a scheme", ->
expect(project.resolve('http://zombo.com')).toBe 'http://zombo.com'
expect(atom.project.resolve('http://zombo.com')).toBe 'http://zombo.com'
describe ".setPath(path)", ->
describe "when path is a file", ->
it "sets its path to the files parent directory and updates the root directory", ->
project.setPath(require.resolve('./fixtures/dir/a'))
expect(project.getPath()).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
expect(project.getRootDirectory().path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
atom.project.setPath(require.resolve('./fixtures/dir/a'))
expect(atom.project.getPath()).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
expect(atom.project.getRootDirectory().path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
describe "when path is a directory", ->
it "sets its path to the directory and updates the root directory", ->
directory = fs.absolute(path.join(__dirname, 'fixtures', 'dir', 'a-dir'))
project.setPath(directory)
expect(project.getPath()).toEqual directory
expect(project.getRootDirectory().path).toEqual directory
atom.project.setPath(directory)
expect(atom.project.getPath()).toEqual directory
expect(atom.project.getRootDirectory().path).toEqual directory
describe "when path is null", ->
it "sets its path and root directory to null", ->
project.setPath(null)
expect(project.getPath()?).toBeFalsy()
expect(project.getRootDirectory()?).toBeFalsy()
atom.project.setPath(null)
expect(atom.project.getPath()?).toBeFalsy()
expect(atom.project.getRootDirectory()?).toBeFalsy()
describe ".replace()", ->
[filePath, commentFilePath, sampleContent, sampleCommentContent] = []
beforeEach ->
project.setPath(project.resolve('../'))
atom.project.setPath(atom.project.resolve('../'))
filePath = project.resolve('sample.js')
commentFilePath = project.resolve('sample-with-comments.js')
filePath = atom.project.resolve('sample.js')
commentFilePath = atom.project.resolve('sample-with-comments.js')
sampleContent = fs.readFileSync(filePath).toString()
sampleCommentContent = fs.readFileSync(commentFilePath).toString()
@@ -315,7 +328,7 @@ describe "Project", ->
it "replaces properly", ->
results = []
waitsForPromise ->
project.replace /items/gi, 'items', [filePath], (result) ->
atom.project.replace /items/gi, 'items', [filePath], (result) ->
results.push(result)
runs ->
@@ -325,12 +338,12 @@ describe "Project", ->
describe "when a buffer is already open", ->
it "replaces properly and saves when not modified", ->
editSession = project.openSync('sample.js')
expect(editSession.isModified()).toBeFalsy()
editor = atom.project.openSync('sample.js')
expect(editor.isModified()).toBeFalsy()
results = []
waitsForPromise ->
project.replace /items/gi, 'items', [filePath], (result) ->
atom.project.replace /items/gi, 'items', [filePath], (result) ->
results.push(result)
runs ->
@@ -338,16 +351,16 @@ describe "Project", ->
expect(results[0].filePath).toBe filePath
expect(results[0].replacements).toBe 6
expect(editSession.isModified()).toBeFalsy()
expect(editor.isModified()).toBeFalsy()
it "does NOT save when modified", ->
editSession = project.openSync('sample.js')
editSession.buffer.change([[0,0],[0,0]], 'omg')
expect(editSession.isModified()).toBeTruthy()
editor = atom.project.openSync('sample.js')
editor.buffer.change([[0,0],[0,0]], 'omg')
expect(editor.isModified()).toBeTruthy()
results = []
waitsForPromise ->
project.replace /items/gi, 'okthen', [filePath], (result) ->
atom.project.replace /items/gi, 'okthen', [filePath], (result) ->
results.push(result)
runs ->
@@ -355,19 +368,19 @@ describe "Project", ->
expect(results[0].filePath).toBe filePath
expect(results[0].replacements).toBe 6
expect(editSession.isModified()).toBeTruthy()
expect(editor.isModified()).toBeTruthy()
describe ".scan(options, callback)", ->
describe "when called with a regex", ->
it "calls the callback with all regex results in all files in the project", ->
results = []
waitsForPromise ->
project.scan /(a)+/, (result) ->
atom.project.scan /(a)+/, (result) ->
results.push(result)
runs ->
expect(results).toHaveLength(3)
expect(results[0].filePath).toBe project.resolve('a')
expect(results[0].filePath).toBe atom.project.resolve('a')
expect(results[0].matches).toHaveLength(3)
expect(results[0].matches[0]).toEqual
matchText: 'aaa'
@@ -378,13 +391,13 @@ describe "Project", ->
it "works with with escaped literals (like $ and ^)", ->
results = []
waitsForPromise ->
project.scan /\$\w+/, (result) -> results.push(result)
atom.project.scan /\$\w+/, (result) -> results.push(result)
runs ->
expect(results.length).toBe 1
{filePath, matches} = results[0]
expect(filePath).toBe project.resolve('a')
expect(filePath).toBe atom.project.resolve('a')
expect(matches).toHaveLength 1
expect(matches[0]).toEqual
matchText: '$bill'
@@ -393,11 +406,11 @@ describe "Project", ->
range: [[2, 6], [2, 11]]
it "works on evil filenames", ->
project.setPath(path.join(__dirname, 'fixtures', 'evil-files'))
atom.project.setPath(path.join(__dirname, 'fixtures', 'evil-files'))
paths = []
matches = []
waitsForPromise ->
project.scan /evil/, (result) ->
atom.project.scan /evil/, (result) ->
paths.push(result.filePath)
matches = matches.concat(result.matches)
@@ -420,7 +433,7 @@ describe "Project", ->
it "ignores case if the regex includes the `i` flag", ->
results = []
waitsForPromise ->
project.scan /DOLLAR/i, (result) -> results.push(result)
atom.project.scan /DOLLAR/i, (result) -> results.push(result)
runs ->
expect(results).toHaveLength 1
@@ -448,11 +461,11 @@ describe "Project", ->
fs.removeSync(projectPath) if fs.existsSync(projectPath)
it "excludes ignored files", ->
project.setPath(projectPath)
atom.project.setPath(projectPath)
atom.config.set('core.excludeVcsIgnoredPaths', true)
resultHandler = jasmine.createSpy("result found")
waitsForPromise ->
project.scan /match/, (results) ->
atom.project.scan /match/, (results) ->
resultHandler()
runs ->
@@ -460,14 +473,14 @@ describe "Project", ->
it "includes only files when a directory filter is specified", ->
projectPath = path.join(path.join(__dirname, 'fixtures', 'dir'))
project.setPath(projectPath)
atom.project.setPath(projectPath)
filePath = path.join(projectPath, 'a-dir', 'oh-git')
paths = []
matches = []
waitsForPromise ->
project.scan /aaa/, paths: ["a-dir#{path.sep}"], (result) ->
atom.project.scan /aaa/, paths: ["a-dir#{path.sep}"], (result) ->
paths.push(result.filePath)
matches = matches.concat(result.matches)
@@ -480,11 +493,11 @@ describe "Project", ->
projectPath = temp.mkdirSync()
filePath = path.join(projectPath, '.text')
fs.writeFileSync(filePath, 'match this')
project.setPath(projectPath)
atom.project.setPath(projectPath)
paths = []
matches = []
waitsForPromise ->
project.scan /match this/, (result) ->
atom.project.scan /match this/, (result) ->
paths.push(result.filePath)
matches = matches.concat(result.matches)
@@ -501,18 +514,18 @@ describe "Project", ->
resultHandler = jasmine.createSpy("result found")
waitsForPromise ->
project.scan /dollar/, (results) ->
atom.project.scan /dollar/, (results) ->
resultHandler()
runs ->
expect(resultHandler).not.toHaveBeenCalled()
it "scans buffer contents if the buffer is modified", ->
editSession = project.openSync("a")
editSession.setText("Elephant")
editor = atom.project.openSync("a")
editor.setText("Elephant")
results = []
waitsForPromise ->
project.scan /a|Elephant/, (result) -> results.push result
atom.project.scan /a|Elephant/, (result) -> results.push result
runs ->
expect(results).toHaveLength 3
+196 -195
Ver Arquivo
@@ -8,67 +8,68 @@ describe "RootView", ->
pathToOpen = null
beforeEach ->
project.setPath(project.resolve('dir'))
pathToOpen = project.resolve('a')
window.rootView = new RootView
rootView.enableKeymap()
rootView.openSync(pathToOpen)
rootView.focus()
atom.project.setPath(atom.project.resolve('dir'))
pathToOpen = atom.project.resolve('a')
atom.rootView = new RootView
atom.rootView.enableKeymap()
atom.rootView.openSync(pathToOpen)
atom.rootView.focus()
describe "@deserialize()", ->
viewState = null
refreshRootViewAndProject = ->
rootViewState = rootView.serialize()
projectState = project.serialize()
rootView.remove()
project.destroy()
window.project = deserialize(projectState)
window.rootView = deserialize(rootViewState)
rootView.attachToDom()
rootViewState = atom.rootView.serialize()
atom.project.getState().serializeForPersistence()
project2 = atom.replicate().get('project')
atom.rootView.remove()
atom.project.destroy()
atom.project = project2
atom.rootView = atom.deserializers.deserialize(rootViewState)
atom.rootView.attachToDom()
describe "when the serialized RootView has an unsaved buffer", ->
it "constructs the view with the same panes", ->
rootView.attachToDom()
rootView.openSync()
editor1 = rootView.getActiveView()
atom.rootView.attachToDom()
atom.rootView.openSync()
editor1 = atom.rootView.getActiveView()
buffer = editor1.getBuffer()
editor1.splitRight()
expect(rootView.getActiveView()).toBe rootView.getEditors()[2]
expect(atom.rootView.getActiveView()).toBe atom.rootView.getEditors()[2]
refreshRootViewAndProject()
expect(rootView.getEditors().length).toBe 2
expect(rootView.getActiveView()).toBe rootView.getEditors()[1]
expect(rootView.title).toBe "untitled - #{project.getPath()}"
expect(atom.rootView.getEditors().length).toBe 2
expect(atom.rootView.getActiveView()).toBe atom.rootView.getEditors()[1]
expect(atom.rootView.title).toBe "untitled - #{atom.project.getPath()}"
describe "when there are open editors", ->
it "constructs the view with the same panes", ->
rootView.attachToDom()
pane1 = rootView.getActivePane()
atom.rootView.attachToDom()
pane1 = atom.rootView.getActivePane()
pane2 = pane1.splitRight()
pane3 = pane2.splitRight()
pane4 = pane2.splitDown()
pane2.showItem(project.openSync('b'))
pane3.showItem(project.openSync('../sample.js'))
pane2.showItem(atom.project.openSync('b'))
pane3.showItem(atom.project.openSync('../sample.js'))
pane3.activeItem.setCursorScreenPosition([2, 4])
pane4.showItem(project.openSync('../sample.txt'))
pane4.showItem(atom.project.openSync('../sample.txt'))
pane4.activeItem.setCursorScreenPosition([0, 2])
pane2.focus()
refreshRootViewAndProject()
expect(rootView.getEditors().length).toBe 4
editor1 = rootView.panes.find('.row > .pane .editor:eq(0)').view()
editor3 = rootView.panes.find('.row > .pane .editor:eq(1)').view()
editor2 = rootView.panes.find('.row > .column > .pane .editor:eq(0)').view()
editor4 = rootView.panes.find('.row > .column > .pane .editor:eq(1)').view()
expect(atom.rootView.getEditors().length).toBe 4
editor1 = atom.rootView.panes.find('.row > .pane .editor:eq(0)').view()
editor3 = atom.rootView.panes.find('.row > .pane .editor:eq(1)').view()
editor2 = atom.rootView.panes.find('.row > .column > .pane .editor:eq(0)').view()
editor4 = atom.rootView.panes.find('.row > .column > .pane .editor:eq(1)').view()
expect(editor1.getPath()).toBe project.resolve('a')
expect(editor2.getPath()).toBe project.resolve('b')
expect(editor3.getPath()).toBe project.resolve('../sample.js')
expect(editor1.getPath()).toBe atom.project.resolve('a')
expect(editor2.getPath()).toBe atom.project.resolve('b')
expect(editor3.getPath()).toBe atom.project.resolve('../sample.js')
expect(editor3.getCursorScreenPosition()).toEqual [2, 4]
expect(editor4.getPath()).toBe project.resolve('../sample.txt')
expect(editor4.getPath()).toBe atom.project.resolve('../sample.txt')
expect(editor4.getCursorScreenPosition()).toEqual [0, 2]
# ensure adjust pane dimensions is called
@@ -83,184 +84,184 @@ describe "RootView", ->
expect(editor3.isFocused).toBeFalsy()
expect(editor4.isFocused).toBeFalsy()
expect(rootView.title).toBe "#{path.basename(editor2.getPath())} - #{project.getPath()}"
expect(atom.rootView.title).toBe "#{path.basename(editor2.getPath())} - #{atom.project.getPath()}"
describe "where there are no open editors", ->
it "constructs the view with no open editors", ->
rootView.getActivePane().remove()
expect(rootView.getEditors().length).toBe 0
atom.rootView.getActivePane().remove()
expect(atom.rootView.getEditors().length).toBe 0
refreshRootViewAndProject()
expect(rootView.getEditors().length).toBe 0
expect(atom.rootView.getEditors().length).toBe 0
describe "focus", ->
beforeEach ->
rootView.attachToDom()
atom.rootView.attachToDom()
describe "when there is an active view", ->
it "hands off focus to the active view", ->
editor = rootView.getActiveView()
editor.isFocused = false
rootView.focus()
expect(editor.isFocused).toBeTruthy()
editorView = atom.rootView.getActiveView()
editorView.isFocused = false
atom.rootView.focus()
expect(editorView.isFocused).toBeTruthy()
describe "when there is no active view", ->
beforeEach ->
rootView.getActivePane().remove()
expect(rootView.getActiveView()).toBeUndefined()
rootView.attachToDom()
atom.rootView.getActivePane().remove()
expect(atom.rootView.getActiveView()).toBeUndefined()
atom.rootView.attachToDom()
expect(document.activeElement).toBe document.body
describe "when are visible focusable elements (with a -1 tabindex)", ->
it "passes focus to the first focusable element", ->
focusable1 = $$ -> @div "One", id: 'one', tabindex: -1
focusable2 = $$ -> @div "Two", id: 'two', tabindex: -1
rootView.horizontal.append(focusable1, focusable2)
atom.rootView.horizontal.append(focusable1, focusable2)
expect(document.activeElement).toBe document.body
rootView.focus()
atom.rootView.focus()
expect(document.activeElement).toBe focusable1[0]
describe "when there are no visible focusable elements", ->
it "surrenders focus to the body", ->
focusable = $$ -> @div "One", id: 'one', tabindex: -1
rootView.horizontal.append(focusable)
atom.rootView.horizontal.append(focusable)
focusable.hide()
expect(document.activeElement).toBe document.body
rootView.focus()
atom.rootView.focus()
expect(document.activeElement).toBe document.body
describe "keymap wiring", ->
commandHandler = null
beforeEach ->
commandHandler = jasmine.createSpy('commandHandler')
rootView.on('foo-command', commandHandler)
atom.rootView.on('foo-command', commandHandler)
atom.keymap.bindKeys('*', 'x': 'foo-command')
atom.keymap.bindKeys('name', '*', 'x': 'foo-command')
describe "when a keydown event is triggered in the RootView", ->
it "triggers matching keybindings for that event", ->
event = keydownEvent 'x', target: rootView[0]
event = keydownEvent 'x', target: atom.rootView[0]
rootView.trigger(event)
atom.rootView.trigger(event)
expect(commandHandler).toHaveBeenCalled()
describe "window title", ->
describe "when the project has no path", ->
it "sets the title to 'untitled'", ->
project.setPath(undefined)
expect(rootView.title).toBe 'untitled'
atom.project.setPath(undefined)
expect(atom.rootView.title).toBe 'untitled'
describe "when the project has a path", ->
beforeEach ->
rootView.openSync('b')
atom.rootView.openSync('b')
describe "when there is an active pane item", ->
it "sets the title to the pane item's title plus the project path", ->
item = rootView.getActivePaneItem()
expect(rootView.title).toBe "#{item.getTitle()} - #{project.getPath()}"
item = atom.rootView.getActivePaneItem()
expect(atom.rootView.title).toBe "#{item.getTitle()} - #{atom.project.getPath()}"
describe "when the title of the active pane item changes", ->
it "updates the window title based on the item's new title", ->
editSession = rootView.getActivePaneItem()
editSession.buffer.setPath(path.join(temp.dir, 'hi'))
expect(rootView.title).toBe "#{editSession.getTitle()} - #{project.getPath()}"
editor = atom.rootView.getActivePaneItem()
editor.buffer.setPath(path.join(temp.dir, 'hi'))
expect(atom.rootView.title).toBe "#{editor.getTitle()} - #{atom.project.getPath()}"
describe "when the active pane's item changes", ->
it "updates the title to the new item's title plus the project path", ->
rootView.getActivePane().showNextItem()
item = rootView.getActivePaneItem()
expect(rootView.title).toBe "#{item.getTitle()} - #{project.getPath()}"
atom.rootView.getActivePane().showNextItem()
item = atom.rootView.getActivePaneItem()
expect(atom.rootView.title).toBe "#{item.getTitle()} - #{atom.project.getPath()}"
describe "when the last pane item is removed", ->
it "updates the title to contain the project's path", ->
rootView.getActivePane().remove()
expect(rootView.getActivePaneItem()).toBeUndefined()
expect(rootView.title).toBe project.getPath()
atom.rootView.getActivePane().remove()
expect(atom.rootView.getActivePaneItem()).toBeUndefined()
expect(atom.rootView.title).toBe atom.project.getPath()
describe "when an inactive pane's item changes", ->
it "does not update the title", ->
pane = rootView.getActivePane()
pane = atom.rootView.getActivePane()
pane.splitRight()
initialTitle = rootView.title
initialTitle = atom.rootView.title
pane.showNextItem()
expect(rootView.title).toBe initialTitle
expect(atom.rootView.title).toBe initialTitle
describe "when the root view is deserialized", ->
it "updates the title to contain the project's path", ->
rootView2 = atom.deserializers.deserialize(rootView.serialize())
item = rootView.getActivePaneItem()
expect(rootView2.title).toBe "#{item.getTitle()} - #{project.getPath()}"
rootView2 = atom.deserializers.deserialize(atom.rootView.serialize())
item = atom.rootView.getActivePaneItem()
expect(rootView2.title).toBe "#{item.getTitle()} - #{atom.project.getPath()}"
rootView2.remove()
describe "font size adjustment", ->
it "increases/decreases font size when increase/decrease-font-size events are triggered", ->
fontSizeBefore = atom.config.get('editor.fontSize')
rootView.trigger 'window:increase-font-size'
atom.rootView.trigger 'window:increase-font-size'
expect(atom.config.get('editor.fontSize')).toBe fontSizeBefore + 1
rootView.trigger 'window:increase-font-size'
atom.rootView.trigger 'window:increase-font-size'
expect(atom.config.get('editor.fontSize')).toBe fontSizeBefore + 2
rootView.trigger 'window:decrease-font-size'
atom.rootView.trigger 'window:decrease-font-size'
expect(atom.config.get('editor.fontSize')).toBe fontSizeBefore + 1
rootView.trigger 'window:decrease-font-size'
atom.rootView.trigger 'window:decrease-font-size'
expect(atom.config.get('editor.fontSize')).toBe fontSizeBefore
it "does not allow the font size to be less than 1", ->
atom.config.set("editor.fontSize", 1)
rootView.trigger 'window:decrease-font-size'
atom.rootView.trigger 'window:decrease-font-size'
expect(atom.config.get('editor.fontSize')).toBe 1
describe ".openSync(filePath, options)", ->
describe "when there is no active pane", ->
beforeEach ->
spyOn(Pane.prototype, 'focus')
rootView.getActivePane().remove()
expect(rootView.getActivePane()).toBeUndefined()
atom.rootView.getActivePane().remove()
expect(atom.rootView.getActivePane()).toBeUndefined()
describe "when called with no path", ->
it "creates a empty edit session as an item on a new pane, and focuses the pane", ->
editSession = rootView.openSync()
expect(rootView.getActivePane().activeItem).toBe editSession
expect(editSession.getPath()).toBeUndefined()
expect(rootView.getActivePane().focus).toHaveBeenCalled()
editor = atom.rootView.openSync()
expect(atom.rootView.getActivePane().activeItem).toBe editor
expect(editor.getPath()).toBeUndefined()
expect(atom.rootView.getActivePane().focus).toHaveBeenCalled()
it "can create multiple empty edit sessions as an item on a new pane", ->
editSession = rootView.openSync()
editSession2 = rootView.openSync()
expect(rootView.getActivePane().getItems().length).toBe 2
expect(editSession).not.toBe editSession2
editor = atom.rootView.openSync()
editor2 = atom.rootView.openSync()
expect(atom.rootView.getActivePane().getItems().length).toBe 2
expect(editor).not.toBe editor2
describe "when called with a path", ->
it "creates an edit session for the given path as an item on a new pane, and focuses the pane", ->
editSession = rootView.openSync('b')
expect(rootView.getActivePane().activeItem).toBe editSession
expect(editSession.getPath()).toBe require.resolve('./fixtures/dir/b')
expect(rootView.getActivePane().focus).toHaveBeenCalled()
editor = atom.rootView.openSync('b')
expect(atom.rootView.getActivePane().activeItem).toBe editor
expect(editor.getPath()).toBe require.resolve('./fixtures/dir/b')
expect(atom.rootView.getActivePane().focus).toHaveBeenCalled()
describe "when the changeFocus option is false", ->
it "does not focus the new pane", ->
editSession = rootView.openSync('b', changeFocus: false)
expect(rootView.getActivePane().focus).not.toHaveBeenCalled()
editor = atom.rootView.openSync('b', changeFocus: false)
expect(atom.rootView.getActivePane().focus).not.toHaveBeenCalled()
describe "when the split option is 'right'", ->
it "creates a new pane and opens the file in said pane", ->
editSession = rootView.openSync('b', split: 'right')
expect(rootView.getActivePane().activeItem).toBe editSession
expect(editSession.getPath()).toBe require.resolve('./fixtures/dir/b')
editor = atom.rootView.openSync('b', split: 'right')
expect(atom.rootView.getActivePane().activeItem).toBe editor
expect(editor.getPath()).toBe require.resolve('./fixtures/dir/b')
describe "when there is an active pane", ->
[activePane, initialItemCount] = []
beforeEach ->
activePane = rootView.getActivePane()
activePane = atom.rootView.getActivePane()
spyOn(activePane, 'focus')
initialItemCount = activePane.getItems().length
describe "when called with no path", ->
it "opens an edit session with an empty buffer as an item in the active pane and focuses it", ->
editSession = rootView.openSync()
editor = atom.rootView.openSync()
expect(activePane.getItems().length).toBe initialItemCount + 1
expect(activePane.activeItem).toBe editSession
expect(editSession.getPath()).toBeUndefined()
expect(activePane.activeItem).toBe editor
expect(editor.getPath()).toBeUndefined()
expect(activePane.focus).toHaveBeenCalled()
describe "when called with a path", ->
@@ -268,97 +269,97 @@ describe "RootView", ->
it "shows the existing edit session in the pane", ->
previousEditSession = activePane.activeItem
editSession = rootView.openSync('b')
expect(activePane.activeItem).toBe editSession
expect(editSession).not.toBe previousEditSession
editor = atom.rootView.openSync('b')
expect(activePane.activeItem).toBe editor
expect(editor).not.toBe previousEditSession
editSession = rootView.openSync(previousEditSession.getPath())
expect(editSession).toBe previousEditSession
expect(activePane.activeItem).toBe editSession
editor = atom.rootView.openSync(previousEditSession.getPath())
expect(editor).toBe previousEditSession
expect(activePane.activeItem).toBe editor
expect(activePane.focus).toHaveBeenCalled()
describe "when the active pane does not have an edit session item for the path being opened", ->
it "creates a new edit session for the given path in the active editor", ->
editSession = rootView.openSync('b')
editor = atom.rootView.openSync('b')
expect(activePane.items.length).toBe 2
expect(activePane.activeItem).toBe editSession
expect(activePane.activeItem).toBe editor
expect(activePane.focus).toHaveBeenCalled()
describe "when the changeFocus option is false", ->
it "does not focus the active pane", ->
editSession = rootView.openSync('b', changeFocus: false)
editor = atom.rootView.openSync('b', changeFocus: false)
expect(activePane.focus).not.toHaveBeenCalled()
describe "when the split option is 'right'", ->
it "creates a new pane and opens the file in said pane", ->
pane1 = rootView.getActivePane()
pane1 = atom.rootView.getActivePane()
editSession = rootView.openSync('b', split: 'right')
pane2 = rootView.getActivePane()
editor = atom.rootView.openSync('b', split: 'right')
pane2 = atom.rootView.getActivePane()
expect(pane2[0]).not.toBe pane1[0]
expect(editSession.getPath()).toBe require.resolve('./fixtures/dir/b')
expect(editor.getPath()).toBe require.resolve('./fixtures/dir/b')
expect(rootView.panes.find('.row .pane').toArray()).toEqual [pane1[0], pane2[0]]
expect(atom.rootView.panes.find('.row .pane').toArray()).toEqual [pane1[0], pane2[0]]
editSession = rootView.openSync('file1', split: 'right')
pane3 = rootView.getActivePane()
editor = atom.rootView.openSync('file1', split: 'right')
pane3 = atom.rootView.getActivePane()
expect(pane3[0]).toBe pane2[0]
expect(editSession.getPath()).toBe require.resolve('./fixtures/dir/file1')
expect(editor.getPath()).toBe require.resolve('./fixtures/dir/file1')
expect(rootView.panes.find('.row .pane').toArray()).toEqual [pane1[0], pane2[0]]
expect(atom.rootView.panes.find('.row .pane').toArray()).toEqual [pane1[0], pane2[0]]
describe ".openSingletonSync(filePath, options)", ->
describe "when there is an active pane", ->
[pane1] = []
beforeEach ->
spyOn(Pane.prototype, 'focus').andCallFake -> @makeActive()
pane1 = rootView.getActivePane()
pane1 = atom.rootView.getActivePane()
it "creates a new pane and reuses the file when already open", ->
rootView.openSingletonSync('b', split: 'right')
pane2 = rootView.getActivePane()
atom.rootView.openSingletonSync('b', split: 'right')
pane2 = atom.rootView.getActivePane()
expect(pane2[0]).not.toBe pane1[0]
expect(pane1.itemForUri('b')).toBeFalsy()
expect(pane2.itemForUri('b')).not.toBeFalsy()
expect(rootView.panes.find('.row .pane').toArray()).toEqual [pane1[0], pane2[0]]
expect(atom.rootView.panes.find('.row .pane').toArray()).toEqual [pane1[0], pane2[0]]
pane1.focus()
expect(rootView.getActivePane()[0]).toBe pane1[0]
expect(atom.rootView.getActivePane()[0]).toBe pane1[0]
rootView.openSingletonSync('b', split: 'right')
pane3 = rootView.getActivePane()
atom.rootView.openSingletonSync('b', split: 'right')
pane3 = atom.rootView.getActivePane()
expect(pane3[0]).toBe pane2[0]
expect(pane1.itemForUri('b')).toBeFalsy()
expect(pane2.itemForUri('b')).not.toBeFalsy()
expect(rootView.panes.find('.row .pane').toArray()).toEqual [pane1[0], pane2[0]]
expect(atom.rootView.panes.find('.row .pane').toArray()).toEqual [pane1[0], pane2[0]]
it "handles split: left by opening to the left pane when necessary", ->
rootView.openSingletonSync('b', split: 'right')
pane2 = rootView.getActivePane()
atom.rootView.openSingletonSync('b', split: 'right')
pane2 = atom.rootView.getActivePane()
expect(pane2[0]).not.toBe pane1[0]
rootView.openSingletonSync('file1', split: 'left')
atom.rootView.openSingletonSync('file1', split: 'left')
activePane = rootView.getActivePane()
activePane = atom.rootView.getActivePane()
expect(activePane[0]).toBe pane1[0]
expect(pane1.itemForUri('file1')).toBeTruthy()
expect(pane2.itemForUri('file1')).toBeFalsy()
expect(rootView.panes.find('.row .pane').toArray()).toEqual [pane1[0], pane2[0]]
expect(atom.rootView.panes.find('.row .pane').toArray()).toEqual [pane1[0], pane2[0]]
pane2.focus()
expect(rootView.getActivePane()[0]).toBe pane2[0]
expect(atom.rootView.getActivePane()[0]).toBe pane2[0]
rootView.openSingletonSync('file1', split: 'left')
activePane = rootView.getActivePane()
atom.rootView.openSingletonSync('file1', split: 'left')
activePane = atom.rootView.getActivePane()
expect(activePane[0]).toBe pane1[0]
expect(rootView.panes.find('.row .pane').toArray()).toEqual [pane1[0], pane2[0]]
expect(atom.rootView.panes.find('.row .pane').toArray()).toEqual [pane1[0], pane2[0]]
it "reuses the file when already open", ->
rootView.openSync('b')
rootView.openSingletonSync('b', split: 'right')
expect(rootView.panes.find('.pane').toArray()).toEqual [pane1[0]]
atom.rootView.openSync('b')
atom.rootView.openSingletonSync('b', split: 'right')
expect(atom.rootView.panes.find('.pane').toArray()).toEqual [pane1[0]]
describe ".open(filePath)", ->
beforeEach ->
@@ -366,65 +367,65 @@ describe "RootView", ->
describe "when there is no active pane", ->
beforeEach ->
rootView.getActivePane().remove()
expect(rootView.getActivePane()).toBeUndefined()
atom.rootView.getActivePane().remove()
expect(atom.rootView.getActivePane()).toBeUndefined()
describe "when called with no path", ->
it "creates a empty edit session as an item on a new pane, and focuses the pane", ->
editSession = null
editor = null
waitsForPromise ->
rootView.open().then (o) -> editSession = o
atom.rootView.open().then (o) -> editor = o
runs ->
expect(rootView.getActivePane().activeItem).toBe editSession
expect(editSession.getPath()).toBeUndefined()
expect(rootView.getActivePane().focus).toHaveBeenCalled()
expect(atom.rootView.getActivePane().activeItem).toBe editor
expect(editor.getPath()).toBeUndefined()
expect(atom.rootView.getActivePane().focus).toHaveBeenCalled()
it "can create multiple empty edit sessions as items on a pane", ->
editSession1 = null
editSession2 = null
editor1 = null
editor2 = null
waitsForPromise ->
rootView.open()
atom.rootView.open()
.then (o) ->
editSession1 = o
rootView.open()
editor1 = o
atom.rootView.open()
.then (o) ->
editSession2 = o
editor2 = o
runs ->
expect(rootView.getActivePane().getItems().length).toBe 2
expect(editSession1).not.toBe editSession2
expect(atom.rootView.getActivePane().getItems().length).toBe 2
expect(editor1).not.toBe editor2
describe "when called with a path", ->
it "creates an edit session for the given path as an item on a new pane, and focuses the pane", ->
editSession = null
editor = null
waitsForPromise ->
rootView.open('b').then (o) -> editSession = o
atom.rootView.open('b').then (o) -> editor = o
runs ->
expect(rootView.getActivePane().activeItem).toBe editSession
expect(editSession.getPath()).toBe require.resolve('./fixtures/dir/b')
expect(rootView.getActivePane().focus).toHaveBeenCalled()
expect(atom.rootView.getActivePane().activeItem).toBe editor
expect(editor.getPath()).toBe require.resolve('./fixtures/dir/b')
expect(atom.rootView.getActivePane().focus).toHaveBeenCalled()
describe "when there is an active pane", ->
[activePane] = []
beforeEach ->
activePane = rootView.getActivePane()
activePane = atom.rootView.getActivePane()
describe "when called with no path", ->
it "opens an edit session with an empty buffer as an item in the active pane and focuses it", ->
editSession = null
editor = null
waitsForPromise ->
rootView.open().then (o) -> editSession = o
atom.rootView.open().then (o) -> editor = o
runs ->
expect(activePane.getItems().length).toBe 2
expect(activePane.activeItem).toBe editSession
expect(editSession.getPath()).toBeUndefined()
expect(activePane.activeItem).toBe editor
expect(editor.getPath()).toBeUndefined()
expect(activePane.focus).toHaveBeenCalled()
describe "when called with a path", ->
@@ -432,39 +433,39 @@ describe "RootView", ->
it "shows the existing edit session in the pane", ->
previousEditSession = activePane.activeItem
editSession = null
editor = null
waitsForPromise ->
rootView.open('b').then (o) -> editSession = o
atom.rootView.open('b').then (o) -> editor = o
runs ->
expect(activePane.activeItem).toBe editSession
expect(editSession).not.toBe previousEditSession
expect(activePane.activeItem).toBe editor
expect(editor).not.toBe previousEditSession
waitsForPromise ->
rootView.open(previousEditSession.getPath()).then (o) -> editSession = o
atom.rootView.open(previousEditSession.getPath()).then (o) -> editor = o
runs ->
expect(editSession).toBe previousEditSession
expect(activePane.activeItem).toBe editSession
expect(editor).toBe previousEditSession
expect(activePane.activeItem).toBe editor
expect(activePane.focus).toHaveBeenCalled()
describe "when the active pane does not have an existing item for the given path", ->
it "creates a new edit session for the given path in the active pane", ->
editSession = null
editor = null
waitsForPromise ->
rootView.open('b').then (o) -> editSession = o
atom.rootView.open('b').then (o) -> editor = o
runs ->
expect(activePane.activeItem).toBe editSession
expect(activePane.activeItem).toBe editor
expect(activePane.getItems().length).toBe 2
expect(activePane.focus).toHaveBeenCalled()
describe "window:toggle-invisibles event", ->
it "shows/hides invisibles in all open and future editors", ->
rootView.height(200)
rootView.attachToDom()
rightEditor = rootView.getActiveView()
atom.rootView.height(200)
atom.rootView.attachToDom()
rightEditor = atom.rootView.getActiveView()
rightEditor.setText(" \t ")
leftEditor = rightEditor.splitLeft()
expect(rightEditor.find(".line:first").text()).toBe " "
@@ -472,14 +473,14 @@ describe "RootView", ->
withInvisiblesShowing = "#{rightEditor.invisibles.space}#{rightEditor.invisibles.tab} #{rightEditor.invisibles.space}#{rightEditor.invisibles.eol}"
rootView.trigger "window:toggle-invisibles"
atom.rootView.trigger "window:toggle-invisibles"
expect(rightEditor.find(".line:first").text()).toBe withInvisiblesShowing
expect(leftEditor.find(".line:first").text()).toBe withInvisiblesShowing
lowerLeftEditor = leftEditor.splitDown()
expect(lowerLeftEditor.find(".line:first").text()).toBe withInvisiblesShowing
rootView.trigger "window:toggle-invisibles"
atom.rootView.trigger "window:toggle-invisibles"
expect(rightEditor.find(".line:first").text()).toBe " "
expect(leftEditor.find(".line:first").text()).toBe " "
@@ -488,7 +489,7 @@ describe "RootView", ->
describe ".eachEditor(callback)", ->
beforeEach ->
rootView.attachToDom()
atom.rootView.attachToDom()
it "invokes the callback for existing editor", ->
count = 0
@@ -496,9 +497,9 @@ describe "RootView", ->
callback = (editor) ->
callbackEditor = editor
count++
rootView.eachEditor(callback)
atom.rootView.eachEditor(callback)
expect(count).toBe 1
expect(callbackEditor).toBe rootView.getActiveView()
expect(callbackEditor).toBe atom.rootView.getActiveView()
it "invokes the callback for new editor", ->
count = 0
@@ -507,28 +508,28 @@ describe "RootView", ->
callbackEditor = editor
count++
rootView.eachEditor(callback)
atom.rootView.eachEditor(callback)
count = 0
callbackEditor = null
rootView.getActiveView().splitRight()
atom.rootView.getActiveView().splitRight()
expect(count).toBe 1
expect(callbackEditor).toBe rootView.getActiveView()
expect(callbackEditor).toBe atom.rootView.getActiveView()
it "returns a subscription that can be disabled", ->
count = 0
callback = (editor) -> count++
subscription = rootView.eachEditor(callback)
subscription = atom.rootView.eachEditor(callback)
expect(count).toBe 1
rootView.getActiveView().splitRight()
atom.rootView.getActiveView().splitRight()
expect(count).toBe 2
subscription.off()
rootView.getActiveView().splitRight()
atom.rootView.getActiveView().splitRight()
expect(count).toBe 2
describe ".eachBuffer(callback)", ->
beforeEach ->
rootView.attachToDom()
atom.rootView.attachToDom()
it "invokes the callback for existing buffer", ->
count = 0
@@ -537,9 +538,9 @@ describe "RootView", ->
callback = (buffer) ->
callbackBuffer = buffer
count++
rootView.eachBuffer(callback)
atom.rootView.eachBuffer(callback)
expect(count).toBe 1
expect(callbackBuffer).toBe rootView.getActiveView().getBuffer()
expect(callbackBuffer).toBe atom.rootView.getActiveView().getBuffer()
it "invokes the callback for new buffer", ->
count = 0
@@ -548,9 +549,9 @@ describe "RootView", ->
callbackBuffer = buffer
count++
rootView.eachBuffer(callback)
atom.rootView.eachBuffer(callback)
count = 0
callbackBuffer = null
rootView.openSync(require.resolve('./fixtures/sample.txt'))
atom.rootView.openSync(require.resolve('./fixtures/sample.txt'))
expect(count).toBe 1
expect(callbackBuffer).toBe rootView.getActiveView().getBuffer()
expect(callbackBuffer).toBe atom.rootView.getActiveView().getBuffer()
+5 -5
Ver Arquivo
@@ -1,12 +1,12 @@
EditSession = require '../src/edit-session'
Editor = require '../src/editor'
describe "Selection", ->
[buffer, editSession, selection] = []
[buffer, editor, selection] = []
beforeEach ->
buffer = project.buildBufferSync('sample.js')
editSession = new EditSession(buffer: buffer, tabLength: 2)
selection = editSession.getSelection()
buffer = atom.project.bufferForPathSync('sample.js')
editor = new Editor(buffer: buffer, tabLength: 2)
selection = editor.getSelection()
afterEach ->
buffer.destroy()
+15 -1
Ver Arquivo
@@ -1,4 +1,4 @@
{View, $$} = require 'atom'
{View, $, $$} = require 'atom'
describe "SpacePen extensions", ->
class TestView extends View
@@ -51,3 +51,17 @@ describe "SpacePen extensions", ->
it "subscribes to the given event emitter and unsubscribes when unsubscribe is called", ->
emitter.trigger "foo"
expect(eventHandler).toHaveBeenCalled()
describe "tooltips", ->
describe "replaceModifiers", ->
replaceModifiers = $.fn.setTooltip.replaceModifiers
it "replaces single keystroke", ->
expect(replaceModifiers('cmd-O')).toEqual '⌘⇧O'
expect(replaceModifiers('cmd-shift-up')).toEqual '⌘⇧↑'
expect(replaceModifiers('cmd-option-down')).toEqual '⌘⌥↓'
expect(replaceModifiers('cmd-option-left')).toEqual '⌘⌥←'
expect(replaceModifiers('cmd-option-right')).toEqual '⌘⌥→'
it "replaces multiple keystroke", ->
expect(replaceModifiers('cmd-o ctrl-2')).toEqual '⌘O ⌃2'
+26 -39
Ver Arquivo
@@ -1,5 +1,5 @@
require '../src/window'
window.setUpEnvironment('spec')
atom.setUpEnvironment('spec')
atom.restoreDimensions()
require '../vendor/jasmine-jquery'
@@ -9,7 +9,7 @@ Keymap = require '../src/keymap'
Config = require '../src/config'
{Point} = require 'telepath'
Project = require '../src/project'
Editor = require '../src/editor'
EditorView = require '../src/editor-view'
TokenizedBuffer = require '../src/tokenized-buffer'
pathwatcher = require 'pathwatcher'
platform = require './spec-helper-platform'
@@ -23,7 +23,7 @@ atom.themes.requireStylesheet '../static/jasmine'
fixturePackagesPath = path.resolve(__dirname, './fixtures/packages')
atom.packages.packageDirPaths.unshift(fixturePackagesPath)
atom.keymap.loadBundledKeymaps()
[bindingSetsToRestore, bindingSetsByFirstKeystrokeToRestore] = []
keyBindingsToRestore = atom.keymap.getKeyBindings()
$(window).on 'core:close', -> window.close()
$(window).on 'unload', ->
@@ -39,7 +39,9 @@ specPackageName = null
specPackagePath = null
specProjectPath = null
if specDirectory = atom.getLoadSettings().specDirectory
{specDirectory, resourcePath} = atom.getLoadSettings()
if specDirectory
specPackagePath = path.resolve(specDirectory, '..')
try
specPackageName = fs.readObjectSync(path.join(specPackagePath, 'package.json'))?.name
@@ -47,11 +49,9 @@ if specDirectory = atom.getLoadSettings().specDirectory
beforeEach ->
$.fx.off = true
if specProjectPath
atom.project = new Project(specProjectPath)
else
atom.project = new Project(path.join(@specDirectory, 'fixtures'))
window.project = atom.project
projectPath = specProjectPath ? path.join(@specDirectory, 'fixtures')
atom.project = atom.getWindowState().set('project', new Project(path: projectPath))
atom.keymap.keyBindings = _.clone(keyBindingsToRestore)
window.resetTimeouts()
atom.packages.packageStates = {}
@@ -66,21 +66,15 @@ beforeEach ->
resolvePackagePath(packageName)
resolvePackagePath = _.bind(spy.originalValue, atom.packages)
# used to reset keymap after each spec
bindingSetsToRestore = _.clone(atom.keymap.bindingSets)
bindingSetsByFirstKeystrokeToRestore = _.clone(atom.keymap.bindingSetsByFirstKeystroke)
# prevent specs from modifying Atom's menus
spyOn(atom.menu, 'sendToBrowserProcess')
# reset config before each spec; don't load or save from/to `config.json`
config = new Config
resourcePath: window.resourcePath
configDirPath: atom.getConfigDirPath()
config = new Config({resourcePath, configDirPath: atom.getConfigDirPath()})
spyOn(config, 'load')
spyOn(config, 'save')
config.setDefaults('core', RootView.configDefaults)
config.setDefaults('editor', Editor.configDefaults)
config.setDefaults('editor', EditorView.configDefaults)
config.set "editor.fontFamily", "Courier"
config.set "editor.fontSize", 16
config.set "editor.autoIndent", false
@@ -88,10 +82,9 @@ beforeEach ->
"package-with-broken-package-json", "package-with-broken-keymap"]
config.save.reset()
atom.config = config
window.config = config
# make editor display updates synchronous
spyOn(Editor.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
spyOn(EditorView.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
spyOn(RootView.prototype, 'setTitle').andCallFake (@title) ->
spyOn(window, "setTimeout").andCallFake window.fakeSetTimeout
spyOn(window, "clearTimeout").andCallFake window.fakeClearTimeout
@@ -108,19 +101,13 @@ beforeEach ->
addCustomMatchers(this)
afterEach ->
atom.keymap.bindingSets = bindingSetsToRestore
atom.keymap.bindingSetsByFirstKeystroke = bindingSetsByFirstKeystrokeToRestore
atom.deactivatePackages()
atom.packages.deactivatePackages()
atom.menu.template = []
window.rootView?.remove?()
atom.rootView?.remove?() if atom.rootView isnt window.rootView
window.rootView = null
atom.rootView?.remove?()
atom.rootView = null
window.project?.destroy?()
atom.project?.destroy?() if atom.project isnt window.project
window.project = null
atom.project?.destroy?()
atom.project = null
$('#jasmine-content').empty() unless window.debugContent
@@ -181,8 +168,8 @@ window.keydownEvent = (key, properties={}) ->
window.mouseEvent = (type, properties) ->
if properties.point
{point, editor} = properties
{top, left} = @pagePixelPositionForPoint(editor, point)
{point, editorView} = properties
{top, left} = @pagePixelPositionForPoint(editorView, point)
properties.pageX = left + 1
properties.pageY = top + 1
properties.originalEvent ?= {detail: 1}
@@ -243,22 +230,22 @@ window.advanceClock = (delta=1) ->
callback() for callback in callbacks
window.pagePixelPositionForPoint = (editor, point) ->
window.pagePixelPositionForPoint = (editorView, point) ->
point = Point.fromObject point
top = editor.renderedLines.offset().top + point.row * editor.lineHeight
left = editor.renderedLines.offset().left + point.column * editor.charWidth - editor.renderedLines.scrollLeft()
top = editorView.renderedLines.offset().top + point.row * editorView.lineHeight
left = editorView.renderedLines.offset().left + point.column * editorView.charWidth - editorView.renderedLines.scrollLeft()
{ top, left }
window.tokensText = (tokens) ->
_.pluck(tokens, 'value').join('')
window.setEditorWidthInChars = (editor, widthInChars, charWidth=editor.charWidth) ->
editor.width(charWidth * widthInChars + editor.gutter.outerWidth())
$(window).trigger 'resize' # update width of editor's on-screen lines
window.setEditorWidthInChars = (editorView, widthInChars, charWidth=editorView.charWidth) ->
editorView.width(charWidth * widthInChars + editorView.gutter.outerWidth())
$(window).trigger 'resize' # update width of editor view's on-screen lines
window.setEditorHeightInLines = (editor, heightInChars, charHeight=editor.lineHeight) ->
editor.height(charHeight * heightInChars + editor.renderedLines.position().top)
$(window).trigger 'resize' # update editor's on-screen lines
window.setEditorHeightInLines = (editorView, heightInChars, charHeight=editorView.lineHeight) ->
editorView.height(charHeight * heightInChars + editorView.renderedLines.position().top)
$(window).trigger 'resize' # update editor view's on-screen lines
$.fn.resultOfTrigger = (type) ->
event = $.Event(type)
+45 -44
Ver Arquivo
@@ -1,54 +1,55 @@
measure 'spec suite require time', ->
{_, fs, Git} = require 'atom'
path = require 'path'
require './spec-helper'
{_, fs, Git} = require 'atom'
path = require 'path'
require './spec-helper'
requireSpecs = (specDirectory, specType) ->
for specFilePath in fs.listTreeSync(specDirectory) when /-spec\.coffee$/.test specFilePath
require specFilePath
requireSpecs = (specDirectory, specType) ->
for specFilePath in fs.listTreeSync(specDirectory) when /-spec\.coffee$/.test specFilePath
require specFilePath
# Set spec directory on spec for setting up the project in spec-helper
setSpecDirectory(specDirectory)
# Set spec directory on spec for setting up the project in spec-helper
setSpecDirectory(specDirectory)
setSpecField = (name, value) ->
specs = jasmine.getEnv().currentRunner().specs()
return if specs.length is 0
for index in [specs.length-1..0]
break if specs[index][name]?
specs[index][name] = value
setSpecField = (name, value) ->
specs = jasmine.getEnv().currentRunner().specs()
return if specs.length is 0
for index in [specs.length-1..0]
break if specs[index][name]?
specs[index][name] = value
setSpecType = (specType) ->
setSpecField('specType', specType)
setSpecType = (specType) ->
setSpecField('specType', specType)
setSpecDirectory = (specDirectory) ->
setSpecField('specDirectory', specDirectory)
setSpecDirectory = (specDirectory) ->
setSpecField('specDirectory', specDirectory)
runAllSpecs = ->
# Only run core specs when resource path is the Atom repository
if Git.exists(window.resourcePath)
requireSpecs(path.join(window.resourcePath, 'spec'))
setSpecType('core')
runAllSpecs = ->
{resourcePath} = atom.getLoadSettings()
# Only run core specs when resource path is the Atom repository
if Git.exists(resourcePath)
requireSpecs(path.join(resourcePath, 'spec'))
setSpecType('core')
fixturesPackagesPath = path.join(__dirname, 'fixtures', 'packages')
packagePaths = atom.getAvailablePackageNames().map (packageName) -> atom.resolvePackagePath(packageName)
packagePaths = _.groupBy packagePaths, (packagePath) ->
if packagePath.indexOf("#{fixturesPackagesPath}#{path.sep}") is 0
'fixtures'
else if packagePath.indexOf("#{window.resourcePath}#{path.sep}") is 0
'bundled'
else
'user'
fixturesPackagesPath = path.join(__dirname, 'fixtures', 'packages')
packagePaths = atom.packages.getAvailablePackageNames().map (packageName) ->
atom.packages.resolvePackagePath(packageName)
packagePaths = _.groupBy packagePaths, (packagePath) ->
if packagePath.indexOf("#{fixturesPackagesPath}#{path.sep}") is 0
'fixtures'
else if packagePath.indexOf("#{resourcePath}#{path.sep}") is 0
'bundled'
else
'user'
# Run bundled package specs
requireSpecs(path.join(packagePath, 'spec')) for packagePath in packagePaths.bundled ? []
setSpecType('bundled')
# Run bundled package specs
requireSpecs(path.join(packagePath, 'spec')) for packagePath in packagePaths.bundled ? []
setSpecType('bundled')
# Run user package specs
requireSpecs(path.join(packagePath, 'spec')) for packagePath in packagePaths.user ? []
setSpecType('user')
# Run user package specs
requireSpecs(path.join(packagePath, 'spec')) for packagePath in packagePaths.user ? []
setSpecType('user')
if specDirectory = atom.getLoadSettings().specDirectory
requireSpecs(specDirectory)
setSpecType('user')
else
runAllSpecs()
if specDirectory = atom.getLoadSettings().specDirectory
requireSpecs(specDirectory)
setSpecType('user')
else
runAllSpecs()
+7 -7
Ver Arquivo
@@ -5,23 +5,23 @@ TextMateGrammar = require '../src/text-mate-grammar'
describe "the `syntax` global", ->
beforeEach ->
atom.activatePackage('language-text', sync: true)
atom.activatePackage('language-javascript', sync: true)
atom.activatePackage('language-coffee-script', sync: true)
atom.activatePackage('language-ruby', sync: true)
atom.packages.activatePackage('language-text', sync: true)
atom.packages.activatePackage('language-javascript', sync: true)
atom.packages.activatePackage('language-coffee-script', sync: true)
atom.packages.activatePackage('language-ruby', sync: true)
describe "serialization", ->
it "remembers grammar overrides by path", ->
filePath = '/foo/bar/file.js'
expect(atom.syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
atom.syntax.setGrammarOverrideForPath(filePath, 'source.ruby')
syntax2 = deserialize(atom.syntax.serialize())
syntax2 = atom.deserializers.deserialize(atom.syntax.serialize())
syntax2.addGrammar(grammar) for grammar in atom.syntax.grammars when grammar isnt atom.syntax.nullGrammar
expect(syntax2.selectGrammar(filePath).name).toBe 'Ruby'
describe ".selectGrammar(filePath)", ->
it "can use the filePath to load the correct grammar based on the grammar's filetype", ->
atom.activatePackage('language-git', sync: true)
atom.packages.activatePackage('language-git', sync: true)
expect(atom.syntax.selectGrammar("file.js").name).toBe "JavaScript" # based on extension (.js)
expect(atom.syntax.selectGrammar(path.join(temp.dir, '.git', 'config')).name).toBe "Git Config" # based on end of the path (.git/config)
@@ -34,7 +34,7 @@ describe "the `syntax` global", ->
expect(atom.syntax.selectGrammar(filePath).name).toBe "Ruby"
it "uses the number of newlines in the first line regex to determine the number of lines to test against", ->
atom.activatePackage('language-property-list', sync: true)
atom.packages.activatePackage('language-property-list', sync: true)
fileContent = "first-line\n<html>"
expect(atom.syntax.selectGrammar("dummy.coffee", fileContent).name).toBe "CoffeeScript"
+47 -77
Ver Arquivo
@@ -10,26 +10,26 @@ describe 'TextBuffer', ->
beforeEach ->
filePath = require.resolve('./fixtures/sample.js')
fileContents = fs.readFileSync(filePath, 'utf8')
buffer = project.bufferForPathSync(filePath)
buffer = atom.project.bufferForPathSync(filePath)
afterEach ->
buffer?.release()
buffer?.destroy()
describe 'constructor', ->
beforeEach ->
buffer.release()
buffer.destroy()
buffer = null
describe "when given a path", ->
describe "when a file exists for the path", ->
it "loads the contents of that file", ->
filePath = require.resolve './fixtures/sample.txt'
buffer = project.bufferForPathSync(filePath)
buffer = atom.project.bufferForPathSync(filePath)
expect(buffer.getText()).toBe fs.readFileSync(filePath, 'utf8')
it "does not allow the initial state of the buffer to be undone", ->
filePath = require.resolve './fixtures/sample.txt'
buffer = project.bufferForPathSync(filePath)
buffer = atom.project.bufferForPathSync(filePath)
buffer.undo()
expect(buffer.getText()).toBe fs.readFileSync(filePath, 'utf8')
@@ -37,13 +37,13 @@ describe 'TextBuffer', ->
it "is modified and is initially empty", ->
filePath = "does-not-exist.txt"
expect(fs.existsSync(filePath)).toBeFalsy()
buffer = project.bufferForPathSync(filePath)
buffer = atom.project.bufferForPathSync(filePath)
expect(buffer.isModified()).toBeTruthy()
expect(buffer.getText()).toBe ''
describe "when no path is given", ->
it "creates an empty buffer", ->
buffer = project.bufferForPathSync(null)
buffer = atom.project.bufferForPathSync(null)
expect(buffer .getText()).toBe ""
describe "path-changed event", ->
@@ -53,7 +53,7 @@ describe 'TextBuffer', ->
filePath = path.join(__dirname, "fixtures", "atom-manipulate-me")
newPath = "#{filePath}-i-moved"
fs.writeFileSync(filePath, "")
bufferToChange = project.bufferForPathSync(filePath)
bufferToChange = atom.project.bufferForPathSync(filePath)
eventHandler = jasmine.createSpy('eventHandler')
bufferToChange.on 'path-changed', eventHandler
@@ -85,7 +85,7 @@ describe 'TextBuffer', ->
buffer.release()
filePath = temp.openSync('atom').path
fs.writeFileSync(filePath, "first")
buffer = project.bufferForPathSync(filePath).retain()
buffer = atom.project.bufferForPathSync(filePath).retain()
afterEach ->
buffer.release()
@@ -156,7 +156,7 @@ describe 'TextBuffer', ->
beforeEach ->
filePath = path.join(temp.dir, 'atom-file-to-delete.txt')
fs.writeFileSync(filePath, 'delete me')
bufferToDelete = project.bufferForPathSync(filePath)
bufferToDelete = atom.project.bufferForPathSync(filePath)
filePath = bufferToDelete.getPath() # symlinks may have been converted
expect(bufferToDelete.getPath()).toBe filePath
@@ -214,7 +214,7 @@ describe 'TextBuffer', ->
buffer.release()
filePath = path.join(temp.dir, 'atom-tmp-file')
fs.writeFileSync(filePath, 'delete me')
buffer = project.bufferForPathSync(filePath)
buffer = atom.project.bufferForPathSync(filePath)
modifiedHandler = jasmine.createSpy("modifiedHandler")
buffer.on 'modified-status-changed', modifiedHandler
@@ -227,7 +227,7 @@ describe 'TextBuffer', ->
filePath = path.join(temp.dir, 'atom-tmp-file')
fs.writeFileSync(filePath, '')
buffer.release()
buffer = project.bufferForPathSync(filePath)
buffer = atom.project.bufferForPathSync(filePath)
modifiedHandler = jasmine.createSpy("modifiedHandler")
buffer.on 'modified-status-changed', modifiedHandler
@@ -251,7 +251,7 @@ describe 'TextBuffer', ->
filePath = path.join(temp.dir, 'atom-tmp-file')
fs.writeFileSync(filePath, '')
buffer.release()
buffer = project.bufferForPathSync(filePath)
buffer = atom.project.bufferForPathSync(filePath)
modifiedHandler = jasmine.createSpy("modifiedHandler")
buffer.on 'modified-status-changed', modifiedHandler
@@ -275,7 +275,7 @@ describe 'TextBuffer', ->
fs.removeSync(filePath) if fs.existsSync(filePath)
expect(fs.existsSync(filePath)).toBeFalsy()
buffer.release()
buffer = project.bufferForPathSync(filePath)
buffer = atom.project.bufferForPathSync(filePath)
modifiedHandler = jasmine.createSpy("modifiedHandler")
buffer.on 'modified-status-changed', modifiedHandler
@@ -298,12 +298,12 @@ describe 'TextBuffer', ->
it "returns false for an empty buffer with no path", ->
buffer.release()
buffer = project.bufferForPathSync(null)
buffer = atom.project.bufferForPathSync(null)
expect(buffer.isModified()).toBeFalsy()
it "returns true for a non-empty buffer with no path", ->
buffer.release()
buffer = project.bufferForPathSync(null)
buffer = atom.project.bufferForPathSync(null)
buffer.setText('a')
expect(buffer.isModified()).toBeTruthy()
buffer.setText('\n')
@@ -311,8 +311,8 @@ describe 'TextBuffer', ->
it "returns false until the buffer is fully loaded", ->
buffer.release()
filePath = temp.openSync('atom').path
buffer = new TextBuffer({project, filePath})
buffer = new TextBuffer({filePath: temp.openSync('atom').path})
atom.project.addBuffer(buffer)
expect(buffer.isModified()).toBeFalsy()
@@ -432,7 +432,7 @@ describe 'TextBuffer', ->
expect(event.newText).toBe "foo\nbar"
it "allows a 'changed' event handler to safely undo the change", ->
buffer.one 'changed', -> buffer.undo()
buffer.once 'changed', -> buffer.undo()
buffer.change([0, 0], "hello")
expect(buffer.lineForRow(0)).toBe "var quicksort = function () {"
@@ -466,7 +466,7 @@ describe 'TextBuffer', ->
beforeEach ->
filePath = path.join(temp.dir, 'temp.txt')
fs.writeFileSync(filePath, "")
saveBuffer = project.bufferForPathSync(filePath)
saveBuffer = atom.project.bufferForPathSync(filePath)
saveBuffer.setText("blah")
it "saves the contents of the buffer to the path", ->
@@ -500,7 +500,7 @@ describe 'TextBuffer', ->
describe "when the buffer has no path", ->
it "throws an exception", ->
saveBuffer = project.bufferForPathSync(null)
saveBuffer = atom.project.bufferForPathSync(null)
saveBuffer.setText "hi"
expect(-> saveBuffer.save()).toThrow()
@@ -524,7 +524,7 @@ describe 'TextBuffer', ->
filePath = path.join(temp.dir, 'temp.txt')
fs.removeSync filePath if fs.existsSync(filePath)
saveAsBuffer = project.bufferForPathSync(null).retain()
saveAsBuffer = atom.project.bufferForPathSync(null).retain()
eventHandler = jasmine.createSpy('eventHandler')
saveAsBuffer.on 'path-changed', eventHandler
@@ -539,7 +539,7 @@ describe 'TextBuffer', ->
newPath = path.join(temp.dir, 'new.txt')
fs.writeFileSync(originalPath, "")
saveAsBuffer = project.bufferForPathSync(originalPath).retain()
saveAsBuffer = atom.project.bufferForPathSync(originalPath).retain()
changeHandler = jasmine.createSpy('changeHandler')
saveAsBuffer.on 'changed', changeHandler
saveAsBuffer.saveAs(newPath)
@@ -554,35 +554,6 @@ describe 'TextBuffer', ->
waitsFor ->
changeHandler.callCount > 0
describe ".getRelativePath()", ->
[filePath, newPath, bufferToChange, eventHandler] = []
beforeEach ->
filePath = path.join(__dirname, "fixtures", "atom-manipulate-me")
newPath = "#{filePath}-i-moved"
fs.writeFileSync(filePath, "")
bufferToChange = project.bufferForPathSync(filePath)
eventHandler = jasmine.createSpy('eventHandler')
bufferToChange.on 'path-changed', eventHandler
afterEach ->
bufferToChange.destroy()
fs.removeSync(filePath) if fs.existsSync(filePath)
fs.removeSync(newPath) if fs.existsSync(newPath)
it "updates when the text buffer's file is moved", ->
expect(bufferToChange.getRelativePath()).toBe('atom-manipulate-me')
jasmine.unspy(window, "setTimeout")
eventHandler.reset()
fs.moveSync(filePath, newPath)
waitsFor "buffer path change", ->
eventHandler.callCount > 0
runs ->
expect(bufferToChange.getRelativePath()).toBe('atom-manipulate-me-i-moved')
describe ".getTextInRange(range)", ->
describe "when range is empty", ->
it "returns an empty string", ->
@@ -926,22 +897,28 @@ describe 'TextBuffer', ->
expect(buffer.getText()).toBe "\ninitialtexthello\n1\n2\n"
describe "serialization", ->
buffer2 = null
[buffer2, project2] = []
beforeEach ->
buffer.destroy()
filePath = temp.openSync('atom').path
fs.writeFileSync(filePath, "words")
buffer = atom.project.bufferForPathSync(filePath)
afterEach ->
buffer2?.release()
project2?.destroy()
describe "when the serialized buffer had no unsaved changes", ->
it "loads the current contents of the file at the serialized path", ->
expect(buffer.isModified()).toBeFalsy()
state = buffer.serialize()
state.get('text').insertTextAtPoint([0, 0], 'simulate divergence of on-disk contents from serialized contents')
project2 = atom.replicate().get('project')
buffer2 = project2.getBuffers()[0]
buffer2 = deserialize(state, {project})
waitsFor ->
buffer2.cachedDiskContents
waitsForPromise ->
buffer2.load()
runs ->
expect(buffer2.isModified()).toBeFalsy()
@@ -951,18 +928,11 @@ describe 'TextBuffer', ->
describe "when the serialized buffer had unsaved changes", ->
describe "when the disk contents were changed since serialization", ->
it "loads the disk contents instead of the previous unsaved state", ->
buffer.release()
filePath = temp.openSync('atom').path
fs.writeFileSync(filePath, "words")
{buffer} = project.openSync(filePath)
buffer.setText("BUFFER CHANGE")
state = buffer.serialize()
expect(state.getObject('text')).toBe 'BUFFER CHANGE'
fs.writeFileSync(filePath, "DISK CHANGE")
buffer2 = deserialize(state, {project})
project2 = atom.replicate().get('project')
buffer2 = project2.getBuffers()[0]
waitsFor ->
buffer2.cachedDiskContents
@@ -976,14 +946,14 @@ describe 'TextBuffer', ->
it "restores the previous unsaved state of the buffer", ->
previousText = buffer.getText()
buffer.setText("abc")
buffer.retain()
state = buffer.serialize()
expect(state.getObject('text')).toBe 'abc'
buffer.getState().serializeForPersistence()
project2 = atom.replicate().get('project')
buffer2 = project2.getBuffers()[0]
buffer2 = deserialize(state, {project})
waitsFor ->
buffer2.cachedDiskContents
waitsForPromise ->
buffer2.load()
runs ->
expect(buffer2.getPath()).toBe(buffer.getPath())
@@ -996,13 +966,13 @@ describe 'TextBuffer', ->
it "restores the previous unsaved state of the buffer", ->
buffer.release()
buffer = project.bufferForPathSync()
buffer = atom.project.bufferForPathSync()
buffer.setText("abc")
state = buffer.serialize()
state = buffer.getState().clone()
expect(state.get('path')).toBeUndefined()
expect(state.getObject('text')).toBe 'abc'
buffer2 = deserialize(state)
buffer2 = atom.project.addBuffer(new TextBuffer(state))
expect(buffer2.getPath()).toBeUndefined()
expect(buffer2.getText()).toBe("abc")
+38 -38
Ver Arquivo
@@ -6,13 +6,13 @@ describe "TextMateGrammar", ->
grammar = null
beforeEach ->
atom.activatePackage('language-text', sync: true)
atom.activatePackage('language-javascript', sync: true)
atom.activatePackage('language-coffee-script', sync: true)
atom.activatePackage('language-ruby', sync: true)
atom.activatePackage('language-html', sync: true)
atom.activatePackage('language-php', sync: true)
atom.activatePackage('language-python', sync: true)
atom.packages.activatePackage('language-text', sync: true)
atom.packages.activatePackage('language-javascript', sync: true)
atom.packages.activatePackage('language-coffee-script', sync: true)
atom.packages.activatePackage('language-ruby', sync: true)
atom.packages.activatePackage('language-html', sync: true)
atom.packages.activatePackage('language-php', sync: true)
atom.packages.activatePackage('language-python', sync: true)
grammar = atom.syntax.selectGrammar("hello.coffee")
describe "@loadSync(path)", ->
@@ -211,8 +211,8 @@ describe "TextMateGrammar", ->
describe "when the pattern includes rules from another grammar", ->
describe "when a grammar matching the desired scope is available", ->
it "parses tokens inside the begin/end patterns based on the included grammar's rules", ->
atom.activatePackage('language-html', sync: true)
atom.activatePackage('language-ruby-on-rails', sync: true)
atom.packages.activatePackage('language-html', sync: true)
atom.packages.activatePackage('language-ruby-on-rails', sync: true)
grammar = atom.syntax.grammarForScopeName('text.html.ruby')
{tokens} = grammar.tokenizeLine("<div class='name'><%= User.find(2).full_name %></div>")
@@ -242,8 +242,8 @@ describe "TextMateGrammar", ->
expect(tokens[22]).toEqual value: '>', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.end.html"]
it "updates the grammar if the included grammar is updated later", ->
atom.activatePackage('language-html', sync: true)
atom.activatePackage('language-ruby-on-rails', sync: true)
atom.packages.activatePackage('language-html', sync: true)
atom.packages.activatePackage('language-ruby-on-rails', sync: true)
grammar = atom.syntax.selectGrammar('foo.html.erb')
grammarUpdatedHandler = jasmine.createSpy("grammarUpdatedHandler")
@@ -252,7 +252,7 @@ describe "TextMateGrammar", ->
{tokens} = grammar.tokenizeLine("<div class='name'><% <<-SQL select * from users;")
expect(tokens[12].value).toBe " select * from users;"
atom.activatePackage('language-sql', sync: true)
atom.packages.activatePackage('language-sql', sync: true)
expect(grammarUpdatedHandler).toHaveBeenCalled()
{tokens} = grammar.tokenizeLine("<div class='name'><% <<-SQL select * from users;")
expect(tokens[12].value).toBe " "
@@ -260,8 +260,8 @@ describe "TextMateGrammar", ->
describe "when a grammar matching the desired scope is unavailable", ->
it "updates the grammar if a matching grammar is added later", ->
atom.deactivatePackage('language-html')
atom.activatePackage('language-ruby-on-rails', sync: true)
atom.packages.deactivatePackage('language-html')
atom.packages.activatePackage('language-ruby-on-rails', sync: true)
grammar = atom.syntax.grammarForScopeName('text.html.ruby')
{tokens} = grammar.tokenizeLine("<div class='name'><%= User.find(2).full_name %></div>")
@@ -270,7 +270,7 @@ describe "TextMateGrammar", ->
expect(tokens[2]).toEqual value: ' ', scopes: ["text.html.ruby","source.ruby.rails.embedded.html"]
expect(tokens[3]).toEqual value: 'User', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","support.class.ruby"]
atom.activatePackage('language-html', sync: true)
atom.packages.activatePackage('language-html', sync: true)
{tokens} = grammar.tokenizeLine("<div class='name'><%= User.find(2).full_name %></div>")
expect(tokens[0]).toEqual value: '<', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.begin.html"]
expect(tokens[1]).toEqual value: 'div', scopes: ["text.html.ruby","meta.tag.block.any.html","entity.name.tag.block.any.html"]
@@ -314,7 +314,7 @@ describe "TextMateGrammar", ->
describe "when inside a C block", ->
beforeEach ->
atom.activatePackage('language-c', sync: true)
atom.packages.activatePackage('language-c', sync: true)
it "correctly parses a method. (regression)", ->
grammar = atom.syntax.selectGrammar("hello.c")
@@ -330,7 +330,7 @@ describe "TextMateGrammar", ->
describe "when the grammar can infinitely loop over a line", ->
it "aborts tokenization", ->
spyOn(console, 'error')
atom.activatePackage("package-with-infinite-loop-grammar")
atom.packages.activatePackage("package-with-infinite-loop-grammar")
grammar = atom.syntax.selectGrammar("something.package-with-infinite-loop-grammar")
{tokens} = grammar.tokenizeLine("abc")
expect(tokens[0].value).toBe "a"
@@ -339,7 +339,7 @@ describe "TextMateGrammar", ->
describe "when a grammar has a pattern that has back references in the match value", ->
it "does not special handle the back references and instead allows oniguruma to resolve them", ->
atom.activatePackage('language-sass', sync: true)
atom.packages.activatePackage('language-sass', sync: true)
grammar = atom.syntax.selectGrammar("style.scss")
{tokens} = grammar.tokenizeLine("@mixin x() { -moz-selector: whatever; }")
expect(tokens[9]).toEqual value: "-moz-selector", scopes: ["source.css.scss", "meta.property-list.scss", "meta.property-name.scss"]
@@ -428,14 +428,14 @@ describe "TextMateGrammar", ->
describe "when the grammar's pattern name has a group number in it", ->
it "replaces the group number with the matched captured text", ->
atom.activatePackage('language-hyperlink', sync: true)
atom.packages.activatePackage('language-hyperlink', sync: true)
grammar = atom.syntax.grammarForScopeName("text.hyperlink")
{tokens} = grammar.tokenizeLine("https://github.com")
expect(tokens[0].scopes).toEqual ["text.hyperlink", "markup.underline.link.https.hyperlink"]
describe "when the grammar has an injection selector", ->
it "includes the grammar's patterns when the selector matches the current scope in other grammars", ->
atom.activatePackage('language-hyperlink', sync: true)
atom.packages.activatePackage('language-hyperlink', sync: true)
grammar = atom.syntax.selectGrammar("text.js")
{tokens} = grammar.tokenizeLine("var i; // http://github.com")
@@ -447,25 +447,25 @@ describe "TextMateGrammar", ->
describe "when the grammar is added", ->
it "retokenizes existing buffers that contain tokens that match the injection selector", ->
editSession = project.openSync('sample.js')
editSession.setText("// http://github.com")
editor = atom.project.openSync('sample.js')
editor.setText("// http://github.com")
{tokens} = editSession.lineForScreenRow(0)
{tokens} = editor.lineForScreenRow(0)
expect(tokens[1].value).toBe " http://github.com"
expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"]
atom.activatePackage('language-hyperlink', sync: true)
atom.packages.activatePackage('language-hyperlink', sync: true)
{tokens} = editSession.lineForScreenRow(0)
{tokens} = editor.lineForScreenRow(0)
expect(tokens[2].value).toBe "http://github.com"
expect(tokens[2].scopes).toEqual ["source.js", "comment.line.double-slash.js", "markup.underline.link.http.hyperlink"]
describe "when the grammar is updated", ->
it "retokenizes existing buffers that contain tokens that match the injection selector", ->
editSession = project.openSync('sample.js')
editSession.setText("// SELECT * FROM OCTOCATS")
editor = atom.project.openSync('sample.js')
editor.setText("// SELECT * FROM OCTOCATS")
{tokens} = editSession.lineForScreenRow(0)
{tokens} = editor.lineForScreenRow(0)
expect(tokens[1].value).toBe " SELECT * FROM OCTOCATS"
expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"]
@@ -477,13 +477,13 @@ describe "TextMateGrammar", ->
patterns: [ { include: "source.sql" } ]
))
{tokens} = editSession.lineForScreenRow(0)
{tokens} = editor.lineForScreenRow(0)
expect(tokens[1].value).toBe " SELECT * FROM OCTOCATS"
expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"]
atom.activatePackage('language-sql', sync: true)
atom.packages.activatePackage('language-sql', sync: true)
{tokens} = editSession.lineForScreenRow(0)
{tokens} = editor.lineForScreenRow(0)
expect(tokens[2].value).toBe "SELECT"
expect(tokens[2].scopes).toEqual ["source.js", "comment.line.double-slash.js", "keyword.other.DML.sql"]
@@ -514,7 +514,7 @@ describe "TextMateGrammar", ->
lines = null
beforeEach ->
atom.activatePackage('language-todo', sync: true)
atom.packages.activatePackage('language-todo', sync: true)
grammar = atom.syntax.selectGrammar('main.rb')
lines = grammar.tokenizeLines "# TODO be nicer"
@@ -528,7 +528,7 @@ describe "TextMateGrammar", ->
describe "Git commit messages", ->
beforeEach ->
atom.activatePackage('language-git', sync: true)
atom.packages.activatePackage('language-git', sync: true)
grammar = atom.syntax.selectGrammar('COMMIT_EDITMSG')
lines = grammar.tokenizeLines """
longggggggggggggggggggggggggggggggggggggggggggggggg
@@ -547,7 +547,7 @@ describe "TextMateGrammar", ->
describe "C++", ->
beforeEach ->
atom.activatePackage('language-c', sync: true)
atom.packages.activatePackage('language-c', sync: true)
grammar = atom.syntax.selectGrammar('includes.cc')
lines = grammar.tokenizeLines """
#include "a.h"
@@ -585,8 +585,8 @@ describe "TextMateGrammar", ->
describe "Objective-C", ->
beforeEach ->
atom.activatePackage('language-c', sync: true)
atom.activatePackage('language-objective-c', sync: true)
atom.packages.activatePackage('language-c', sync: true)
atom.packages.activatePackage('language-objective-c', sync: true)
grammar = atom.syntax.selectGrammar('function.mm')
lines = grammar.tokenizeLines """
void test() {
@@ -612,7 +612,7 @@ describe "TextMateGrammar", ->
describe "Java", ->
beforeEach ->
atom.activatePackage('language-java', sync: true)
atom.packages.activatePackage('language-java', sync: true)
grammar = atom.syntax.selectGrammar('Function.java')
it "correctly parses single line comments", ->
@@ -664,7 +664,7 @@ describe "TextMateGrammar", ->
describe "when the line contains unicode characters", ->
it "correctly parses tokens starting after them", ->
atom.activatePackage('language-json', sync: true)
atom.packages.activatePackage('language-json', sync: true)
grammar = atom.syntax.selectGrammar('package.json')
{tokens} = grammar.tokenizeLine '{"\u2026": 1}'
+8 -8
Ver Arquivo
@@ -80,7 +80,7 @@ describe "ThemeManager", ->
describe "requireStylesheet(path)", ->
it "synchronously loads css at the given path and installs a style tag for it in the head", ->
cssPath = project.resolve('css.css')
cssPath = atom.project.resolve('css.css')
lengthBefore = $('head style').length
themeManager.requireStylesheet(cssPath)
@@ -97,7 +97,7 @@ describe "ThemeManager", ->
$('head style[id*="css.css"]').remove()
it "synchronously loads and parses less files at the given path and installs a style tag for it in the head", ->
lessPath = project.resolve('sample.less')
lessPath = atom.project.resolve('sample.less')
lengthBefore = $('head style').length
themeManager.requireStylesheet(lessPath)
expect($('head style').length).toBe lengthBefore + 1
@@ -121,9 +121,9 @@ describe "ThemeManager", ->
it "supports requiring css and less stylesheets without an explicit extension", ->
themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'css')
expect($('head style[id*="css.css"]').attr('id')).toBe themeManager.stringToId(project.resolve('css.css'))
expect($('head style[id*="css.css"]').attr('id')).toBe themeManager.stringToId(atom.project.resolve('css.css'))
themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'sample')
expect($('head style[id*="sample.less"]').attr('id')).toBe themeManager.stringToId(project.resolve('sample.less'))
expect($('head style[id*="sample.less"]').attr('id')).toBe themeManager.stringToId(atom.project.resolve('sample.less'))
$('head style[id*="css.css"]').remove()
$('head style[id*="sample.less"]').remove()
@@ -140,16 +140,16 @@ describe "ThemeManager", ->
describe "base stylesheet loading", ->
beforeEach ->
window.rootView = new RootView
rootView.append $$ -> @div class: 'editor'
rootView.attachToDom()
atom.rootView = new RootView
atom.rootView.append $$ -> @div class: 'editor'
atom.rootView.attachToDom()
themeManager.activateThemes()
it "loads the correct values from the theme's ui-variables file", ->
atom.config.set('core.themes', ['theme-with-ui-variables'])
# an override loaded in the base css
expect(rootView.css("background-color")).toBe "rgb(0, 0, 255)"
expect(atom.rootView.css("background-color")).toBe "rgb(0, 0, 255)"
# from within the theme itself
expect($(".editor").css("padding-top")).toBe "150px"
+15 -15
Ver Arquivo
@@ -5,7 +5,7 @@ describe "TokenizedBuffer", ->
[tokenizedBuffer, buffer, changeHandler] = []
beforeEach ->
atom.activatePackage('language-javascript', sync: true)
atom.packages.activatePackage('language-javascript', sync: true)
# enable async tokenization
TokenizedBuffer.prototype.chunkSize = 5
jasmine.unspy(TokenizedBuffer.prototype, 'tokenizeInBackground')
@@ -20,15 +20,15 @@ describe "TokenizedBuffer", ->
describe "@deserialize(state)", ->
it "constructs a tokenized buffer with the same buffer and tabLength setting", ->
buffer = project.bufferForPathSync('sample.js')
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBuffer1 = new TokenizedBuffer(buffer: buffer, tabLength: 4)
tokenizedBuffer2 = deserialize(tokenizedBuffer1.serialize())
tokenizedBuffer2 = atom.deserializers.deserialize(tokenizedBuffer1.serialize())
expect(tokenizedBuffer2.buffer).toBe tokenizedBuffer1.buffer
expect(tokenizedBuffer2.getTabLength()).toBe tokenizedBuffer1.getTabLength()
describe "when the buffer is destroyed", ->
beforeEach ->
buffer = project.bufferForPathSync('sample.js')
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBuffer = new TokenizedBuffer({buffer})
startTokenizing(tokenizedBuffer)
@@ -40,7 +40,7 @@ describe "TokenizedBuffer", ->
describe "when the buffer contains soft-tabs", ->
beforeEach ->
buffer = project.bufferForPathSync('sample.js')
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBuffer = new TokenizedBuffer({buffer})
startTokenizing(tokenizedBuffer)
tokenizedBuffer.on "changed", changeHandler = jasmine.createSpy('changeHandler')
@@ -319,8 +319,8 @@ describe "TokenizedBuffer", ->
describe "when the buffer contains hard-tabs", ->
beforeEach ->
atom.activatePackage('language-coffee-script', sync: true)
buffer = project.bufferForPathSync('sample-with-tabs.coffee')
atom.packages.activatePackage('language-coffee-script', sync: true)
buffer = atom.project.bufferForPathSync('sample-with-tabs.coffee')
tokenizedBuffer = new TokenizedBuffer({buffer})
startTokenizing(tokenizedBuffer)
@@ -349,8 +349,8 @@ describe "TokenizedBuffer", ->
describe "when the buffer contains surrogate pairs", ->
beforeEach ->
atom.activatePackage('language-javascript', sync: true)
buffer = project.buildBufferSync 'sample-with-pairs.js'
atom.packages.activatePackage('language-javascript', sync: true)
buffer = atom.project.bufferForPathSync 'sample-with-pairs.js'
buffer.setText """
'abc\uD835\uDF97def'
//\uD835\uDF97xyz
@@ -387,10 +387,10 @@ describe "TokenizedBuffer", ->
describe "when the grammar is updated because a grammar it includes is activated", ->
it "retokenizes the buffer", ->
atom.activatePackage('language-ruby-on-rails', sync: true)
atom.activatePackage('language-ruby', sync: true)
atom.packages.activatePackage('language-ruby-on-rails', sync: true)
atom.packages.activatePackage('language-ruby', sync: true)
buffer = project.bufferForPathSync()
buffer = atom.project.bufferForPathSync()
buffer.setText "<div class='name'><%= User.find(2).full_name %></div>"
tokenizedBuffer = new TokenizedBuffer({buffer})
tokenizedBuffer.setGrammar(atom.syntax.selectGrammar('test.erb'))
@@ -399,7 +399,7 @@ describe "TokenizedBuffer", ->
{tokens} = tokenizedBuffer.lineForScreenRow(0)
expect(tokens[0]).toEqual value: "<div class='name'>", scopes: ["text.html.ruby"]
atom.activatePackage('language-html', sync: true)
atom.packages.activatePackage('language-html', sync: true)
fullyTokenize(tokenizedBuffer)
{tokens} = tokenizedBuffer.lineForScreenRow(0)
expect(tokens[0]).toEqual value: '<', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.begin.html"]
@@ -410,7 +410,7 @@ describe "TokenizedBuffer", ->
buffer.release()
it "returns the correct token (regression)", ->
buffer = project.bufferForPathSync('sample.js')
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBuffer = new TokenizedBuffer({buffer})
fullyTokenize(tokenizedBuffer)
expect(tokenizedBuffer.tokenForPosition([1,0]).scopes).toEqual ["source.js"]
@@ -419,7 +419,7 @@ describe "TokenizedBuffer", ->
describe ".bufferRangeForScopeAtPosition(selector, position)", ->
beforeEach ->
buffer = project.bufferForPathSync('sample.js')
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBuffer = new TokenizedBuffer({buffer})
fullyTokenize(tokenizedBuffer)
+26 -26
Ver Arquivo
@@ -8,11 +8,11 @@ describe "Window", ->
beforeEach ->
spyOn(atom, 'hide')
atom.getLoadSettings() # Causes atom.loadSettings to be initialized
atom.loadSettings.initialPath = project.getPath()
project.destroy()
atom.loadSettings.initialPath = atom.project.getPath()
atom.project.destroy()
windowEventHandler = new WindowEventHandler()
window.deserializeEditorWindow()
projectPath = project.getPath()
atom.deserializeEditorWindow()
projectPath = atom.project.getPath()
afterEach ->
windowEventHandler.unsubscribe()
@@ -59,49 +59,49 @@ describe "Window", ->
describe "when pane items are are modified", ->
it "prompts user to save and and calls rootView.confirmClose", ->
spyOn(rootView, 'confirmClose').andCallThrough()
spyOn(atom, "confirmSync").andReturn(2)
editSession = rootView.openSync("sample.js")
editSession.insertText("I look different, I feel different.")
spyOn(atom.rootView, 'confirmClose').andCallThrough()
spyOn(atom, "confirm").andReturn(2)
editor = atom.rootView.openSync("sample.js")
editor.insertText("I look different, I feel different.")
$(window).trigger(beforeUnloadEvent)
expect(rootView.confirmClose).toHaveBeenCalled()
expect(atom.confirmSync).toHaveBeenCalled()
expect(atom.rootView.confirmClose).toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
it "prompts user to save and handler returns true if don't save", ->
spyOn(atom, "confirmSync").andReturn(2)
editSession = rootView.openSync("sample.js")
editSession.insertText("I look different, I feel different.")
spyOn(atom, "confirm").andReturn(2)
editor = atom.rootView.openSync("sample.js")
editor.insertText("I look different, I feel different.")
$(window).trigger(beforeUnloadEvent)
expect(atom.confirmSync).toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
it "prompts user to save and handler returns false if dialog is canceled", ->
spyOn(atom, "confirmSync").andReturn(1)
editSession = rootView.openSync("sample.js")
editSession.insertText("I look different, I feel different.")
spyOn(atom, "confirm").andReturn(1)
editor = atom.rootView.openSync("sample.js")
editor.insertText("I look different, I feel different.")
$(window).trigger(beforeUnloadEvent)
expect(atom.confirmSync).toHaveBeenCalled()
expect(atom.confirm).toHaveBeenCalled()
describe ".unloadEditorWindow()", ->
it "saves the serialized state of the window so it can be deserialized after reload", ->
rootViewState = rootView.serialize()
rootViewState = atom.rootView.serialize()
syntaxState = atom.syntax.serialize()
window.unloadEditorWindow()
atom.unloadEditorWindow()
expect(atom.getWindowState().getObject('rootView')).toEqual rootViewState.toObject()
expect(atom.getWindowState().getObject('syntax')).toEqual syntaxState
expect(atom.saveWindowState).toHaveBeenCalled()
it "unsubscribes from all buffers", ->
rootView.openSync('sample.js')
buffer = rootView.getActivePaneItem().buffer
pane = rootView.getActivePane()
atom.rootView.openSync('sample.js')
buffer = atom.rootView.getActivePaneItem().buffer
pane = atom.rootView.getActivePane()
pane.splitRight(pane.copyActiveItem())
expect(window.rootView.find('.editor').length).toBe 2
expect(atom.rootView.find('.editor').length).toBe 2
window.unloadEditorWindow()
atom.unloadEditorWindow()
expect(buffer.subscriptionCount()).toBe 0
expect(buffer.getSubscriptionCount()).toBe 0
describe "drag and drop", ->
buildDragEvent = (type, files) ->
+7 -7
Ver Arquivo
@@ -212,18 +212,18 @@ class AtomPackage extends Package
registerDeferredDeserializers: ->
for deserializerName in @metadata.deferredDeserializers ? []
registerDeferredDeserializer deserializerName, =>
atom.deserializers.addDeferred deserializerName, =>
@activateStylesheets()
@requireMainModule()
subscribeToActivationEvents: ->
return unless @metadata.activationEvents?
if _.isArray(@metadata.activationEvents)
rootView.command(event, @handleActivationEvent) for event in @metadata.activationEvents
atom.rootView.command(event, @handleActivationEvent) for event in @metadata.activationEvents
else if _.isString(@metadata.activationEvents)
rootView.command(@metadata.activationEvents, @handleActivationEvent)
atom.rootView.command(@metadata.activationEvents, @handleActivationEvent)
else
rootView.command(event, selector, @handleActivationEvent) for event, selector of @metadata.activationEvents
atom.rootView.command(event, selector, @handleActivationEvent) for event, selector of @metadata.activationEvents
handleActivationEvent: (event) =>
bubblePathEventHandlers = @disableEventHandlersOnBubblePath(event)
@@ -234,11 +234,11 @@ class AtomPackage extends Package
unsubscribeFromActivationEvents: ->
if _.isArray(@metadata.activationEvents)
rootView.off(event, @handleActivationEvent) for event in @metadata.activationEvents
atom.rootView.off(event, @handleActivationEvent) for event in @metadata.activationEvents
else if _.isString(@metadata.activationEvents)
rootView.off(@metadata.activationEvents, @handleActivationEvent)
atom.rootView.off(@metadata.activationEvents, @handleActivationEvent)
else
rootView.off(event, selector, @handleActivationEvent) for event, selector of @metadata.activationEvents
atom.rootView.off(event, selector, @handleActivationEvent) for event, selector of @metadata.activationEvents
disableEventHandlersOnBubblePath: (event) ->
bubblePathEventHandlers = []
+203 -79
Ver Arquivo
@@ -1,49 +1,52 @@
#TODO remove once all packages have been updated
{Emitter} = require 'emissary'
Emitter::one = (args...) -> @once(args...)
Emitter::trigger = (args...) -> @emit(args...)
Emitter::subscriptionCount = (args...) -> @getSubscriptionCount(args...)
#TODO remove once all packages have been updated
fs = require 'fs-plus'
fs.exists = fs.existsSync
fs.makeTree = fs.makeTreeSync
fs.move = fs.moveSync
fs.read = (filePath) -> fs.readFileSync(filePath, 'utf8')
fs.remove = fs.removeSync
fs.write = fs.writeFile
fs.writeSync = fs.writeFileSync
fs = require 'fs-plus'
{$} = require './space-pen-extensions'
_ = require 'underscore-plus'
Package = require './package'
crypto = require 'crypto'
ipc = require 'ipc'
os = require 'os'
path = require 'path'
remote = require 'remote'
shell = require 'shell'
crypto = require 'crypto'
path = require 'path'
os = require 'os'
dialog = remote.require 'dialog'
app = remote.require 'app'
_ = require 'underscore-plus'
{Document} = require 'telepath'
DeserializerManager = require './deserializer-manager'
fs = require 'fs-plus'
{Subscriber} = require 'emissary'
{$} = require './space-pen-extensions'
DeserializerManager = require './deserializer-manager'
Package = require './package'
SiteShim = require './site-shim'
WindowEventHandler = require './window-event-handler'
# Public: Atom global for dealing with packages, themes, menus, and the window.
#
# An instance of this class is always available as the `atom` global.
#
# ## Useful properties available:
#
# * `atom.config` - A {Config} instance
# * `atom.contextMenu` - A {ContextMenuManager} instance
# * `atom.keymap` - A {Keymap} instance
# * `atom.menu` - A {MenuManager} instance
# * `atom.rootView` - A {RootView} instance
# * `atom.packages` - A {PackageManager} instance
# * `atom.pasteboard` - A {Pasteboard} instance
# * `atom.project` - A {Project} instance
# * `atom.syntax` - A {Syntax} instance
# * `atom.themes` - A {ThemeManager} instance
module.exports =
class Atom
Subscriber.includeInto(this)
# Private:
constructor: ->
@rootViewParentSelector = 'body'
@deserializers = new DeserializerManager()
# Private: Initialize all the properties in this object.
initialize: ->
@unsubscribe()
@setBodyPlatformClass()
{devMode, resourcePath} = atom.getLoadSettings()
configDirPath = @getConfigDirPath()
@@ -66,8 +69,17 @@ class Atom
@contextMenu = new ContextMenuManager(devMode)
@menu = new MenuManager({resourcePath})
@pasteboard = new Pasteboard()
@syntax = deserialize(@getWindowState('syntax')) ? new Syntax()
@syntax = @deserializers.deserialize(@getWindowState('syntax')) ? new Syntax()
# Private: This method is called in any window needing a general environment, including specs
setUpEnvironment: (@windowMode) ->
@initialize()
# Private:
setBodyPlatformClass: ->
document.body.classList.add("platform-#{process.platform}")
# Public: Get the current window
getCurrentWindow: ->
remote.getCurrentWindow()
@@ -102,6 +114,7 @@ class Atom
else
browserWindow.center()
# Private:
restoreDimensions: ->
dimensions = @getWindowState().getObject('dimensions')
unless dimensions?.width and dimensions?.height
@@ -118,54 +131,95 @@ class Atom
@loadSettings ?= _.deepClone(@getCurrentWindow().loadSettings)
_.deepClone(@loadSettings)
# Private:
deserializeProject: ->
Project = require './project'
state = @getWindowState()
@project = deserialize(state.get('project'))
unless @project?
@project = new Project(@getLoadSettings().initialPath)
state.set('project', @project.getState())
@project = @getWindowState('project')
unless @project instanceof Project
@project = new Project(path: @getLoadSettings().initialPath)
@setWindowState('project', @project)
# Private:
deserializeRootView: ->
RootView = require './root-view'
state = @getWindowState()
@rootView = deserialize(state.get('rootView'))
@rootView = @deserializers.deserialize(state.get('rootView'))
unless @rootView?
@rootView = new RootView()
state.set('rootView', @rootView.getState())
$(@rootViewParentSelector).append(@rootView)
# Private:
deserializePackageStates: ->
state = @getWindowState()
@packages.packageStates = state.getObject('packageStates') ? {}
state.remove('packageStates')
#TODO Remove theses once packages have been migrated
getPackageState: (args...) -> @packages.getPackageState(args...)
setPackageState: (args...) -> @packages.setPackageState(args...)
activatePackages: (args...) -> @packages.activatePackages(args...)
activatePackage: (args...) -> @packages.activatePackage(args...)
deactivatePackages: (args...) -> @packages.deactivatePackages(args...)
deactivatePackage: (args...) -> @packages.deactivatePackage(args...)
getActivePackage: (args...) -> @packages.getActivePackage(args...)
isPackageActive: (args...) -> @packages.isPackageActive(args...)
getActivePackages: (args...) -> @packages.getActivePackages(args...)
loadPackages: (args...) -> @packages.loadPackages(args...)
loadPackage: (args...) -> @packages.loadPackage(args...)
unloadPackage: (args...) -> @packages.unloadPackage(args...)
resolvePackagePath: (args...) -> @packages.resolvePackagePath(args...)
isInternalPackage: (args...) -> @packages.isInternalPackage(args...)
getLoadedPackage: (args...) -> @packages.getLoadedPackage(args...)
isPackageLoaded: (args...) -> @packages.isPackageLoaded(args...)
getLoadedPackages: (args...) -> @packages.getLoadedPackages(args...)
isPackageDisabled: (args...) -> @packages.isPackageDisabled(args...)
getAvailablePackagePaths: (args...) -> @packages.getAvailablePackagePaths(args...)
getAvailablePackageNames: (args...) -> @packages.getAvailablePackageNames(args...)
getAvailablePackageMetadata: (args...)-> @packages.getAvailablePackageMetadata(args...)
# Private:
deserializeEditorWindow: ->
@deserializePackageStates()
@deserializeProject()
@deserializeRootView()
# Private: This method is only called when opening a real application window
startEditorWindow: ->
if process.platform is 'darwin'
CommandInstaller = require './command-installer'
CommandInstaller.installAtomCommand()
CommandInstaller.installApmCommand()
@windowEventHandler = new WindowEventHandler
@restoreDimensions()
@config.load()
@config.setDefaults('core', require('./root-view').configDefaults)
@config.setDefaults('editor', require('./editor-view').configDefaults)
@keymap.loadBundledKeymaps()
@themes.loadBaseStylesheets()
@packages.loadPackages()
@deserializeEditorWindow()
@packages.activate()
@keymap.loadUserKeymap()
@requireUserInitScript()
@menu.update()
$(window).on 'unload', =>
$(document.body).hide()
@unloadEditorWindow()
false
@displayWindow()
# Private:
unloadEditorWindow: ->
return if not @project and not @rootView
windowState = @getWindowState()
windowState.set('project', @project)
windowState.set('syntax', @syntax.serialize())
windowState.set('rootView', @rootView.serialize())
@packages.deactivatePackages()
windowState.set('packageStates', @packages.packageStates)
@saveWindowState()
@rootView.remove()
@project.destroy()
@windowEventHandler?.unsubscribe()
# Set up the default event handlers and menus for a non-editor window.
#
# This can be used by packages to have a minimum level of keybindings and
# menus available when not using the standard editor window.
#
# This should only be called after setUpEnvironment() has been called.
setUpDefaultEvents: ->
@windowEventHandler = new WindowEventHandler
@keymap.loadBundledKeymaps()
@menu.update()
# Private:
loadThemes: ->
@themes.load()
# Private:
watchThemes: ->
@themes.on 'reloaded', =>
# Only reload stylesheets from non-theme packages
@@ -173,91 +227,144 @@ class Atom
pack.reloadStylesheets?()
null
# Public: Open a new Atom window using the given options.
#
# Calling this method without an options parameter will open a prompt to pick
# a file/folder to open in the new window.
#
# * options
# * pathsToOpen: A string array of paths to open
open: (options) ->
ipc.sendChannel('open', options)
confirm: (message, detailedMessage, buttonLabelsAndCallbacks...) ->
buttons = []
callbacks = []
while buttonLabelsAndCallbacks.length
do =>
buttons.push buttonLabelsAndCallbacks.shift()
callbacks.push buttonLabelsAndCallbacks.shift()
# Public: Open a confirm dialog.
#
# ## Example:
# ```coffeescript
# atom.confirm
# message: 'How you feeling?'
# detailedMessage: 'Be honest.'
# buttons:
# Good: -> window.alert('good to hear')
# Bad: -> window.alert('bummer')
# ```
#
# * options:
# + message: The string message to display.
# + detailedMessage: The string detailed message to display.
# + buttons: Either an array of strings or an object where the values
# are callbacks to invoke when clicked.
#
# Returns the chosen index if buttons was an array or the return of the
# callback if buttons was an object.
confirm: ({message, detailedMessage, buttons}={}) ->
buttons ?= {}
if _.isArray(buttons)
buttonLabels = buttons
else
buttonLabels = Object.keys(buttons)
chosen = @confirmSync(message, detailedMessage, buttons)
callbacks[chosen]?()
confirmSync: (message, detailedMessage, buttons, browserWindow=@getCurrentWindow()) ->
dialog.showMessageBox browserWindow,
chosen = dialog.showMessageBox @getCurrentWindow(),
type: 'info'
message: message
detail: detailedMessage
buttons: buttons
buttons: buttonLabels
if _.isArray(buttons)
chosen
else
callback = buttons[buttonLabels[chosen]]
callback?()
# Private:
showSaveDialog: (callback) ->
callback(showSaveDialogSync())
# Private:
showSaveDialogSync: (defaultPath) ->
defaultPath ?= project?.getPath()
defaultPath ?= @project?.getPath()
currentWindow = @getCurrentWindow()
dialog.showSaveDialog currentWindow, {title: 'Save File', defaultPath}
# Public: Open the dev tools for the current window.
openDevTools: ->
@getCurrentWindow().openDevTools()
# Public: Toggle the visibility of the dev tools for the current window.
toggleDevTools: ->
@getCurrentWindow().toggleDevTools()
# Public: Reload the current window.
reload: ->
@getCurrentWindow().restart()
# Public: Focus the current window.
focus: ->
@getCurrentWindow().focus()
$(window).focus()
# Public: Show the current window.
show: ->
@getCurrentWindow().show()
# Public: Hide the current window.
hide: ->
@getCurrentWindow().hide()
# Private: Schedule the window to be shown and focused on the next tick.
#
# This is done in a next tick to prevent a white flicker from occurring
# if called synchronously.
displayWindow: ->
setImmediate =>
@show()
@focus()
@setFullScreen(true) if @rootView.getState().get('fullScreen')
# Public: Close the current window.
close: ->
@getCurrentWindow().close()
# Private:
exit: (status) -> app.exit(status)
# Public: Is the current window in development mode?
inDevMode: ->
@getLoadSettings().devMode
# Public: Is the current window running specs?
inSpecMode: ->
@getLoadSettings().isSpec
# Public: Toggle the full screen state of the current window.
toggleFullScreen: ->
@setFullScreen(!@isFullScreen())
# Public: Set the full screen state of the current window.
setFullScreen: (fullScreen=false) ->
@getCurrentWindow().setFullScreen(fullScreen)
# Public: Is the current window in full screen mode?
isFullScreen: ->
@getCurrentWindow().isFullScreen()
# Public: Get the version of the Atom application.
getVersion: ->
app.getVersion()
getHomeDirPath: ->
process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME']
getTempDirPath: ->
if process.platform is 'win32' then os.tmpdir() else '/tmp'
# Public: Get the directory path to Atom's configuration area.
#
# Returns the absolute path to ~/.atom
getConfigDirPath: ->
@configDirPath ?= fs.absolute('~/.atom')
# Public: Get the directory path to Atom's storage area.
#
# Returns the absoluste path to ~/.atom/storage
getStorageDirPath: ->
@storageDirPath ?= path.join(@getConfigDirPath(), 'storage')
# Private:
getWindowStatePath: ->
switch @windowMode
when 'spec'
@@ -273,11 +380,13 @@ class Atom
else
null
# Public: Set the window state of the given keypath to the value.
setWindowState: (keyPath, value) ->
windowState = @getWindowState()
windowState.set(keyPath, value)
windowState
# Private:
loadWindowState: ->
if windowStatePath = @getWindowStatePath()
if fs.existsSync(windowStatePath)
@@ -295,6 +404,7 @@ class Atom
doc = Document.deserialize(documentState) if documentState?
doc ?= Document.create()
doc.registerModelClasses(require('./text-buffer'), require('./project'))
# TODO: Remove this when everything is using telepath models
if @site?
@site.setRootDocument(doc)
@@ -302,13 +412,15 @@ class Atom
@site = new SiteShim(doc)
doc
# Private:
saveWindowState: ->
windowState = @getWindowState()
if windowStatePath = @getWindowStatePath()
windowState.saveSync(windowStatePath)
else
@getCurrentWindow().loadSettings.windowState = JSON.stringify(windowState.serialize())
@getCurrentWindow().loadSettings.windowState = JSON.stringify(windowState.serializeForPersistence())
# Public: Get the window state for the key path.
getWindowState: (keyPath) ->
@windowState ?= @loadWindowState()
if keyPath
@@ -316,23 +428,35 @@ class Atom
else
@windowState
# Private: Returns a replicated copy of the current state.
replicate: ->
@getWindowState().replicate()
# Private:
crashMainProcess: ->
remote.process.crash()
# Private:
crashRenderProcess: ->
process.crash()
# Public: Visually and audibly trigger a beep.
beep: ->
shell.beep() if @config.get('core.audioBeep')
@rootView.trigger 'beep'
# Private:
requireUserInitScript: ->
userInitScriptPath = path.join(@getConfigDirPath(), "user.coffee")
try
require userInitScriptPath if fs.isFileSync(userInitScriptPath)
catch error
console.error "Failed to load `#{userInitScriptPath}`", error.stack, error
if userInitScriptPath = fs.resolve(@getConfigDirPath(), 'user', ['js', 'coffee'])
try
require userInitScriptPath
catch error
console.error "Failed to load `#{userInitScriptPath}`", error.stack, error
# Public: Require the module with the given globals.
#
# The globals will be set on the `window` object and removed after the
# require completes.
requireWithGlobals: (id, globals={}) ->
existingGlobals = {}
for key, value of globals
-66
Ver Arquivo
@@ -1,66 +0,0 @@
{$} = require './space-pen-extensions'
_ = require 'underscore-plus'
fs = require 'fs-plus'
{specificity} = require 'clear-cut'
PEG = require 'pegjs'
### Internal ###
module.exports =
class BindingSet
@parser: null
selector: null
commandsByKeystrokes: null
parser: null
name: null
constructor: (selector, commandsByKeystrokes, @index, @name) ->
keystrokePattern = fs.readFileSync(require.resolve('./keystroke-pattern.pegjs'), 'utf8')
BindingSet.parser ?= PEG.buildParser(keystrokePattern)
@specificity = specificity(selector)
@selector = selector.replace(/!important/g, '')
@commandsByKeystrokes = @normalizeCommandsByKeystrokes(commandsByKeystrokes)
# Private:
getName: ->
@name
# Private:
getSelector: ->
@selector
# Private:
getCommandsByKeystrokes: ->
@commandsByKeystrokes
commandForEvent: (event) ->
for keystrokes, command of @commandsByKeystrokes
return command if event.keystrokes == keystrokes
null
matchesKeystrokePrefix: (event) ->
eventKeystrokes = event.keystrokes.split(' ')
for keystrokes, command of @commandsByKeystrokes
bindingKeystrokes = keystrokes.split(' ')
continue unless eventKeystrokes.length < bindingKeystrokes.length
return true if _.isEqual(eventKeystrokes, bindingKeystrokes[0...eventKeystrokes.length])
false
normalizeCommandsByKeystrokes: (commandsByKeystrokes) ->
normalizedCommandsByKeystrokes = {}
for keystrokes, command of commandsByKeystrokes
normalizedCommandsByKeystrokes[@normalizeKeystrokes(keystrokes)] = command
normalizedCommandsByKeystrokes
normalizeKeystrokes: (keystrokes) ->
normalizedKeystrokes = keystrokes.split(/\s+/).map (keystroke) =>
@normalizeKeystroke(keystroke)
normalizedKeystrokes.join(' ')
normalizeKeystroke: (keystroke) ->
keys = BindingSet.parser.parse(keystroke)
modifiers = keys[0...-1]
modifiers.sort()
[modifiers..., _.last(keys)].join('-')
+8 -8
Ver Arquivo
@@ -22,7 +22,7 @@ class ApplicationMenu
# The Object which describes the menu to display.
# * keystrokesByCommand:
# An Object where the keys are commands and the values are Arrays containing
# the keystrokes.
# the keystroke.
update: (template, keystrokesByCommand) ->
@translateTemplate(template, keystrokesByCommand)
@substituteVersion(template)
@@ -97,14 +97,14 @@ class ApplicationMenu
]
]
# Private: Combines a menu template with the appropriate keystrokes.
# Private: Combines a menu template with the appropriate keystroke.
#
# * template:
# An Object conforming to atom-shell's menu api but lacking accelerator and
# click properties.
# * keystrokesByCommand:
# An Object where the keys are commands and the values are Arrays containing
# the keystrokes.
# the keystroke.
#
# Returns a complete menu configuration object for atom-shell's menu API.
translateTemplate: (template, keystrokesByCommand) ->
@@ -123,21 +123,21 @@ class ApplicationMenu
# The name of the command.
# * keystrokesByCommand:
# An Object where the keys are commands and the values are Arrays containing
# the keystrokes.
# the keystroke.
#
# Returns a String containing the keystroke in a format that can be interpreted
# by atom shell to provide nice icons where available.
acceleratorForCommand: (command, keystrokesByCommand) ->
keystroke = keystrokesByCommand[command]?[0]
return null unless keystroke
firstKeystroke = keystrokesByCommand[command]?[0]
return null unless firstKeystroke
modifiers = keystroke.split('-')
modifiers = firstKeystroke.split('-')
key = modifiers.pop()
modifiers.push("Shift") if key != key.toLowerCase()
modifiers = modifiers.map (modifier) ->
modifier.replace(/shift/ig, "Shift")
.replace(/meta/ig, "Command")
.replace(/cmd/ig, "Command")
.replace(/ctrl/ig, "Ctrl")
.replace(/alt/ig, "Alt")
+1
Ver Arquivo
@@ -1,5 +1,6 @@
Menu = require 'menu'
# Private:
module.exports =
class ContextMenu
constructor: (template, browserWindow) ->
+1 -1
Ver Arquivo
@@ -62,7 +62,7 @@ delegate.browserMainParts.preMainMessageLoopRun = ->
AtomApplication = require './atom-application'
AtomApplication.open(args)
console.log("App load time: #{Date.now() - startTime}ms")
console.log("App load time: #{Date.now() - startTime}ms") unless args.test
global.devResourcePath = path.join(app.getHomeDir(), 'github', 'atom')
+10
Ver Arquivo
@@ -47,3 +47,13 @@ module.exports =
symlinkCommand(commandPath, destinationPath, installCallback)
else
installCallback(new Error("No destination directory exists to install"))
installAtomCommand: (callback) ->
{resourcePath} = atom.getLoadSettings()
commandPath = path.join(resourcePath, 'atom.sh')
@install(commandPath, callback)
installApmCommand: (callback) ->
{resourcePath} = atom.getLoadSettings()
commandPath = path.join(resourcePath, 'node_modules', '.bin', 'apm')
@install(commandPath, callback)
+1 -1
Ver Arquivo
@@ -5,5 +5,5 @@ module.exports =
unobserveConfig: ->
if @configSubscriptions?
subscription.cancel() for keyPath, subscription of @configSubscriptions
subscription.off() for keyPath, subscription of @configSubscriptions
@configSubscriptions = null
+1 -2
Ver Arquivo
@@ -216,8 +216,7 @@ class Config
callback(value, {previous})
eventName = "updated.#{keyPath.replace(/\./, '-')}"
subscription = { cancel: => @off eventName, updateCallback }
@on eventName, updateCallback
subscription = @on eventName, updateCallback
callback(value) if options.callNow ? true
subscription
+6 -6
Ver Arquivo
@@ -9,14 +9,14 @@ class CursorView extends View
@div class: 'cursor idle', => @raw '&nbsp;'
blinkPeriod: 800
editor: null
editorView: null
visible: true
needsUpdate: true
needsRemoval: false
shouldPauseBlinking: false
initialize: (@cursor, @editor) ->
initialize: (@cursor, @editorView) ->
@cursor.on 'moved.cursor-view', =>
@needsUpdate = true
@shouldPauseBlinking = true
@@ -25,7 +25,7 @@ class CursorView extends View
@needsUpdate = true
@cursor.on 'autoscrolled.cursor-view', =>
@editor.requestDisplayUpdate()
@editorView.requestDisplayUpdate()
@cursor.on 'destroyed.cursor-view', =>
@needsRemoval = true
@@ -34,7 +34,7 @@ class CursorView extends View
@addClass("site-#{@cursor.marker.getOriginSiteId()}")
beforeRemove: ->
@editor.removeCursorView(this)
@editorView.removeCursorView(this)
@cursor.off('.cursor-view')
@stopBlinking()
@@ -52,7 +52,7 @@ class CursorView extends View
else if !@startBlinkingTimeout
@startBlinking()
@setVisible(@cursor.isVisible() and not @editor.isFoldedAtScreenRow(screenPosition.row))
@setVisible(@cursor.isVisible() and not @editorView.isFoldedAtScreenRow(screenPosition.row))
# Override for speed. The base function checks the computedStyle
isHidden: ->
@@ -69,7 +69,7 @@ class CursorView extends View
@cursor.clearAutoscroll()
getPixelPosition: ->
@editor.pixelPositionForScreenPosition(@getScreenPosition())
@editorView.pixelPositionForScreenPosition(@getScreenPosition())
setVisible: (visible) ->
unless @visible == visible
+44 -32
Ver Arquivo
@@ -5,7 +5,7 @@ _ = require 'underscore-plus'
# Public: The `Cursor` class represents the little blinking line identifying
# where text can be inserted.
#
# Cursors belong to {EditSession}s and have some metadata attached in the form
# Cursors belong to {Editor}s and have some metadata attached in the form
# of a {StringMarker}.
module.exports =
class Cursor
@@ -17,8 +17,8 @@ class Cursor
visible: true
needsAutoscroll: null
# Private: Instantiated by an {EditSession}
constructor: ({@editSession, @marker}) ->
# Private: Instantiated by an {Editor}
constructor: ({@editor, @marker}) ->
@updateVisibility()
@marker.on 'changed', (e) =>
@updateVisibility()
@@ -37,10 +37,10 @@ class Cursor
textChanged: textChanged
@emit 'moved', movedEvent
@editSession.emit 'cursor-moved', movedEvent
@editor.emit 'cursor-moved', movedEvent
@marker.on 'destroyed', =>
@destroyed = true
@editSession.removeCursor(this)
@editor.removeCursor(this)
@emit 'destroyed'
@needsAutoscroll = true
@@ -62,7 +62,7 @@ class Cursor
# An {Array} of two numbers: the screen row, and the screen column.
# * options:
# + autoscroll:
# A Boolean which, if `true`, scrolls the {EditSession} to wherever the
# A Boolean which, if `true`, scrolls the {Editor} to wherever the
# cursor moves to.
setScreenPosition: (screenPosition, options={}) ->
@changePosition options, =>
@@ -78,7 +78,7 @@ class Cursor
# An {Array} of two numbers: the buffer row, and the buffer column.
# * options:
# + autoscroll:
# A Boolean which, if `true`, scrolls the {EditSession} to wherever the
# A Boolean which, if `true`, scrolls the {Editor} to wherever the
# cursor moves to.
setBufferPosition: (bufferPosition, options={}) ->
@changePosition options, =>
@@ -118,13 +118,13 @@ class Cursor
segments.push("[#{_.escapeRegExp(nonWordCharacters)}]+")
new RegExp(segments.join("|"), "g")
# Public: Identifies if this cursor is the last in the {EditSession}.
# Public: Identifies if this cursor is the last in the {Editor}.
#
# "Last" is defined as the most recently added cursor.
#
# Returns a Boolean.
isLastCursor: ->
this == @editSession.getCursor()
this == @editor.getCursor()
# Public: Identifies if the cursor is surrounded by whitespace.
#
@@ -135,7 +135,7 @@ class Cursor
isSurroundedByWhitespace: ->
{row, column} = @getBufferPosition()
range = [[row, Math.min(0, column - 1)], [row, Math.max(0, column + 1)]]
/^\s+$/.test @editSession.getTextInBufferRange(range)
/^\s+$/.test @editor.getTextInBufferRange(range)
# Public: Returns whether the cursor is currently between a word and non-word
# character. The non-word characters are defined by the
@@ -150,7 +150,7 @@ class Cursor
{row, column} = @getBufferPosition()
range = [[row, column - 1], [row, column + 1]]
[before, after] = @editSession.getTextInBufferRange(range)
[before, after] = @editor.getTextInBufferRange(range)
return false if /\s/.test(before) or /\s/.test(after)
nonWordCharacters = atom.config.get('editor.nonWordCharacters').split('')
@@ -160,7 +160,7 @@ class Cursor
isInsideWord: ->
{row, column} = @getBufferPosition()
range = [[row, column], [row, Infinity]]
@editSession.getTextInBufferRange(range).search(@wordRegExp()) == 0
@editor.getTextInBufferRange(range).search(@wordRegExp()) == 0
# Public: Prevents this cursor from causing scrolling.
clearAutoscroll: ->
@@ -189,7 +189,7 @@ class Cursor
# Public: Returns the cursor's current buffer row of text excluding its line
# ending.
getCurrentBufferLine: ->
@editSession.lineForBufferRow(@getBufferRow())
@editor.lineForBufferRow(@getBufferRow())
# Public: Moves the cursor up one screen row.
moveUp: (rowCount = 1, {moveToEndOfSelection}={}) ->
@@ -248,7 +248,7 @@ class Cursor
# Public: Moves the cursor to the bottom of the buffer.
moveToBottom: ->
@setBufferPosition(@editSession.getEofBufferPosition())
@setBufferPosition(@editor.getEofBufferPosition())
# Public: Moves the cursor to the beginning of the screen line.
moveToBeginningOfLine: ->
@@ -258,7 +258,7 @@ class Cursor
# line.
moveToFirstCharacterOfLine: ->
{row, column} = @getScreenPosition()
screenline = @editSession.lineForScreenRow(row)
screenline = @editor.lineForScreenRow(row)
goalColumn = screenline.text.search(/\S/)
return if goalColumn == -1
@@ -272,7 +272,7 @@ class Cursor
position = @getBufferPosition()
scanRange = @getCurrentLineBufferRange()
endOfLeadingWhitespace = null
@editSession.scanInBufferRange /^[ \t]*/, scanRange, ({range}) =>
@editor.scanInBufferRange /^[ \t]*/, scanRange, ({range}) =>
endOfLeadingWhitespace = range.end
@setBufferPosition(endOfLeadingWhitespace) if endOfLeadingWhitespace.isGreaterThan(position)
@@ -318,11 +318,11 @@ class Cursor
getBeginningOfCurrentWordBufferPosition: (options = {}) ->
allowPrevious = options.allowPrevious ? true
currentBufferPosition = @getBufferPosition()
previousNonBlankRow = @editSession.buffer.previousNonBlankRow(currentBufferPosition.row)
previousNonBlankRow = @editor.buffer.previousNonBlankRow(currentBufferPosition.row)
scanRange = [[previousNonBlankRow, 0], currentBufferPosition]
beginningOfWordPosition = null
@editSession.backwardsScanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, stop}) =>
@editor.backwardsScanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, stop}) =>
if range.end.isGreaterThanOrEqual(currentBufferPosition) or allowPrevious
beginningOfWordPosition = range.start
if not beginningOfWordPosition?.isEqual(currentBufferPosition)
@@ -334,11 +334,11 @@ class Cursor
# the current word, or the previous word.
getPreviousWordBoundaryBufferPosition: (options = {}) ->
currentBufferPosition = @getBufferPosition()
previousNonBlankRow = @editSession.buffer.previousNonBlankRow(currentBufferPosition.row)
previousNonBlankRow = @editor.buffer.previousNonBlankRow(currentBufferPosition.row)
scanRange = [[previousNonBlankRow, 0], currentBufferPosition]
beginningOfWordPosition = null
@editSession.backwardsScanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) =>
@editor.backwardsScanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) =>
if range.start.row < currentBufferPosition.row and currentBufferPosition.column > 0
# force it to stop at the beginning of each line
beginningOfWordPosition = new Point(currentBufferPosition.row, 0)
@@ -356,10 +356,10 @@ class Cursor
# the current word, or the previous word.
getMoveNextWordBoundaryBufferPosition: (options = {}) ->
currentBufferPosition = @getBufferPosition()
scanRange = [currentBufferPosition, @editSession.getEofBufferPosition()]
scanRange = [currentBufferPosition, @editor.getEofBufferPosition()]
endOfWordPosition = null
@editSession.scanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) =>
@editor.scanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) =>
if range.start.row > currentBufferPosition.row
# force it to stop at the beginning of each line
endOfWordPosition = new Point(range.start.row, 0)
@@ -386,10 +386,10 @@ class Cursor
getEndOfCurrentWordBufferPosition: (options = {}) ->
allowNext = options.allowNext ? true
currentBufferPosition = @getBufferPosition()
scanRange = [currentBufferPosition, @editSession.getEofBufferPosition()]
scanRange = [currentBufferPosition, @editor.getEofBufferPosition()]
endOfWordPosition = null
@editSession.scanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, stop}) =>
@editor.scanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, stop}) =>
if range.start.isLessThanOrEqual(currentBufferPosition) or allowNext
endOfWordPosition = range.end
if not endOfWordPosition?.isEqual(currentBufferPosition)
@@ -407,10 +407,10 @@ class Cursor
getBeginningOfNextWordBufferPosition: (options = {}) ->
currentBufferPosition = @getBufferPosition()
start = if @isInsideWord() then @getEndOfCurrentWordBufferPosition() else currentBufferPosition
scanRange = [start, @editSession.getEofBufferPosition()]
scanRange = [start, @editor.getEofBufferPosition()]
beginningOfNextWordPosition = null
@editSession.scanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) =>
@editor.scanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) =>
beginningOfNextWordPosition = range.start
stop()
@@ -432,7 +432,7 @@ class Cursor
# + includeNewline:
# A boolean which controls whether the Range should include the newline.
getCurrentLineBufferRange: (options) ->
@editSession.bufferRangeForBufferRow(@getBufferRow(), options)
@editor.bufferRangeForBufferRow(@getBufferRow(), options)
# Public: Retrieves the range for the current paragraph.
#
@@ -440,11 +440,11 @@ class Cursor
#
# Returns a {Range}.
getCurrentParagraphBufferRange: ->
@editSession.languageMode.rowRangeForParagraphAtBufferRow(@getBufferRow())
@editor.languageMode.rowRangeForParagraphAtBufferRow(@getBufferRow())
# Public: Returns the characters preceeding the cursor in the current word.
getCurrentWordPrefix: ->
@editSession.getTextInBufferRange([@getBeginningOfCurrentWordBufferPosition(), @getBufferPosition()])
@editor.getTextInBufferRange([@getBeginningOfCurrentWordBufferPosition(), @getBufferPosition()])
# Public: Returns whether the cursor is at the start of a line.
isAtBeginningOfLine: ->
@@ -452,8 +452,8 @@ class Cursor
# Public: Returns the indentation level of the current line.
getIndentLevel: ->
if @editSession.getSoftTabs()
@getBufferColumn() / @editSession.getTabLength()
if @editor.getSoftTabs()
@getBufferColumn() / @editor.getTabLength()
else
@getBufferColumn()
@@ -465,4 +465,16 @@ class Cursor
#
# Returns an {Array} of {String}s.
getScopes: ->
@editSession.scopesForBufferPosition(@getBufferPosition())
@editor.scopesForBufferPosition(@getBufferPosition())
# Public: Returns true if this cursor has no non-whitespace characters before
# its current position.
hasPrecedingCharactersOnLine: ->
bufferPosition = @getBufferPosition()
line = @editor.lineForBufferRow(bufferPosition.row)
firstCharacterColumn = line.search(/\S/)
if firstCharacterColumn is -1
false
else
bufferPosition.column > firstCharacterColumn
+6 -4
Ver Arquivo
@@ -1,21 +1,23 @@
{Document} = require 'telepath'
# Public: Manages the deserializers used for serialized state
#
# Should be accessed via `atom.deserializers`
module.exports =
class DeserializerManager
constructor: ->
@deserializers = {}
@deferredDeserializers = {}
# Public: Add a deserializer.
# Public: Register the given class(es) as deserializers.
add: (klasses...) ->
@deserializers[klass.name] = klass for klass in klasses
# Public: Add a deferred deserializer.
# Public: Add a deferred deserializer for the given class name.
addDeferred: (name, fn) ->
@deferredDeserializers[name] = fn
# Public: Remove a deserializer.
# Public: Remove the given class(es) as deserializers.
remove: (klasses...) ->
delete @deserializers[klass.name] for klass in klasses
@@ -32,7 +34,7 @@ class DeserializerManager
else
console.warn "No deserializer found for", state
# Public: Get the deserializer for the state.
# Private: Get the deserializer for the state.
get: (state) ->
return unless state?
+5 -3
Ver Arquivo
@@ -18,7 +18,7 @@ class DisplayBuffer
_.extend @prototype, ConfigObserver
@acceptsDocuments: true
registerDeserializer(this)
atom.deserializers.add(this)
@version: 2
@deserialize: (state) -> new this(state)
@@ -27,7 +27,7 @@ class DisplayBuffer
if optionsOrState instanceof telepath.Document
@state = optionsOrState
@id = @state.get('id')
@tokenizedBuffer = deserialize(@state.get('tokenizedBuffer'))
@tokenizedBuffer = atom.deserializers.deserialize(@state.get('tokenizedBuffer'))
@buffer = @tokenizedBuffer.buffer
else
{@buffer, softWrap, editorWidthInChars} = optionsOrState
@@ -365,7 +365,9 @@ class DisplayBuffer
setTabLength: (tabLength) ->
@tokenizedBuffer.setTabLength(tabLength)
# Retrieves the grammar for the buffer.
# Get the grammar for this buffer.
#
# Returns the current {TextMateGrammar} or the {NullGrammar}.
getGrammar: ->
@tokenizedBuffer.grammar
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+1316 -1731
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+3 -1
Ver Arquivo
@@ -58,7 +58,7 @@ class File
previouslyExisted = @exists()
@cachedContents = text
fs.writeFileSync(@getPath(), text)
@subscribeToNativeChangeEvents() if not previouslyExisted and @subscriptionCount() > 0
@subscribeToNativeChangeEvents() if not previouslyExisted and @hasSubscriptions()
# Private: Deprecated
readSync: (flushCache) ->
@@ -112,9 +112,11 @@ class File
exists: ->
fs.existsSync(@getPath())
# Private:
setDigest: (contents) ->
@digest = crypto.createHash('sha1').update(contents ? '').digest('hex')
# Public: Get the SHA-1 digest of this file
getDigest: ->
@digest ? @setDigest(@readSync())
+5 -6
Ver Arquivo
@@ -12,7 +12,7 @@ GitUtils = require 'git-utils'
# ## Example
#
# ```coffeescript
# git = global.project.getRepo()
# git = atom.project.getRepo()
# console.log git.getOriginUrl()
# ```
module.exports =
@@ -61,7 +61,7 @@ class Git
@statuses = {}
@upstream = {ahead: 0, behind: 0}
{project, refreshOnWindowFocus} = options
{@project, refreshOnWindowFocus} = options
refreshOnWindowFocus ?= true
if refreshOnWindowFocus
@@ -70,9 +70,8 @@ class Git
@refreshIndex()
@refreshStatus()
if project?
@subscribeToBuffer(buffer) for buffer in project.getBuffers()
@subscribe project, 'buffer-created', (buffer) => @subscribeToBuffer(buffer)
if @project?
@subscribe @project.buffers.onEach (buffer) => @subscribeToBuffer(buffer)
# Private: Subscribes to buffer events.
subscribeToBuffer: (buffer) ->
@@ -146,7 +145,7 @@ class Git
# Public: Returns true if at the root, false if in a subfolder of the
# repository.
isProjectAtRoot: ->
@projectAtRoot ?= project.relativize(@getWorkingDirectory()) is ''
@projectAtRoot ?= @project?.relativize(@getWorkingDirectory()) is ''
# Public: Makes a path relative to the repository's working directory.
relativize: (path) -> @getRepo().relativize(path)
+22 -22
Ver Arquivo
@@ -2,7 +2,7 @@
{Range} = require 'telepath'
_ = require 'underscore-plus'
# Private: Represents the portion of the {Editor} containing row numbers.
# Private: Represents the portion of the {EditorView} containing row numbers.
#
# The gutter also indicates if rows are folded.
module.exports =
@@ -25,37 +25,37 @@ class Gutter extends View
@attached = true
highlightLines = => @highlightLines()
@getEditor().on 'cursor:moved', highlightLines
@getEditor().on 'selection:changed', highlightLines
@getEditorView().on 'cursor:moved', highlightLines
@getEditorView().on 'selection:changed', highlightLines
@on 'mousedown', (e) => @handleMouseEvents(e)
beforeRemove: ->
$(document).off(".gutter-#{@getEditor().id}")
$(document).off(".gutter-#{@getEditorView().id}")
handleMouseEvents: (e) ->
editor = @getEditor()
startRow = editor.screenPositionFromMouseEvent(e).row
editorView = @getEditorView()
startRow = editorView.screenPositionFromMouseEvent(e).row
if e.shiftKey
editor.selectToScreenPosition([startRow + 1, 0])
editorView.selectToScreenPosition([startRow + 1, 0])
return
else
editor.getSelection().setScreenRange([[startRow, 0], [startRow, 0]])
editorView.getSelection().setScreenRange([[startRow, 0], [startRow, 0]])
moveHandler = (e) =>
start = startRow
end = editor.screenPositionFromMouseEvent(e).row
end = editorView.screenPositionFromMouseEvent(e).row
if end > start then end++ else start++
editor.getSelection().setScreenRange([[start, 0], [end, 0]])
editorView.getSelection().setScreenRange([[start, 0], [end, 0]])
$(document).on "mousemove.gutter-#{@getEditor().id}", moveHandler
$(document).one "mouseup.gutter-#{@getEditor().id}", => $(document).off 'mousemove', moveHandler
$(document).on "mousemove.gutter-#{@getEditorView().id}", moveHandler
$(document).one "mouseup.gutter-#{@getEditorView().id}", => $(document).off 'mousemove', moveHandler
### Public ###
# Retrieves the containing {Editor}.
# Retrieves the containing {EditorView}.
#
# Returns an {Editor}.
getEditor: ->
# Returns an {EditorView}.
getEditorView: ->
@parentView
# Defines whether to show the gutter or not.
@@ -192,9 +192,9 @@ class Gutter extends View
@elementBuilder.children
buildLineElementsHtml: (startScreenRow, endScreenRow) =>
editor = @getEditor()
maxDigits = editor.getLineCount().toString().length
rows = editor.bufferRowsForScreenRows(startScreenRow, endScreenRow)
editorView = @getEditorView()
maxDigits = editorView.getLineCount().toString().length
rows = editorView.bufferRowsForScreenRows(startScreenRow, endScreenRow)
html = ''
for row in rows
@@ -204,7 +204,7 @@ class Gutter extends View
rowValue = (row + 1).toString()
classes = "line-number line-number-#{row}"
classes += ' fold' if editor.isFoldedAtBufferRow(row)
classes += ' fold' if editorView.isFoldedAtBufferRow(row)
rowValuePadding = _.multiplyString('&nbsp;', maxDigits - rowValue.length)
@@ -230,8 +230,8 @@ class Gutter extends View
@highlightedLineNumbers.push(highlightedLineNumber)
highlightLines: ->
if @getEditor().getSelection().isEmpty()
row = @getEditor().getCursorScreenPosition().row
if @getEditorView().getSelection().isEmpty()
row = @getEditorView().getCursorScreenPosition().row
rowRange = new Range([row, 0], [row, 0])
return if @selectionEmpty and @highlightedRows?.isEqual(rowRange)
@@ -240,7 +240,7 @@ class Gutter extends View
@highlightedRows = rowRange
@selectionEmpty = true
else
selectedRows = @getEditor().getSelection().getScreenRange()
selectedRows = @getEditorView().getSelection().getScreenRange()
endRow = selectedRows.end.row
endRow-- if selectedRows.end.column is 0
selectedRows = new Range([selectedRows.start.row, 0], [endRow, 0])
+48
Ver Arquivo
@@ -0,0 +1,48 @@
{$} = require './space-pen-extensions'
_ = require 'underscore-plus'
fs = require 'fs-plus'
{specificity} = require 'clear-cut'
PEG = require 'pegjs'
### Internal ###
module.exports =
class KeyBinding
@parser: null
@currentIndex: 1
@normalizeKeystroke: (keystroke) ->
normalizedKeystroke = keystroke.split(/\s+/).map (keystroke) =>
keys = @getParser().parse(keystroke)
modifiers = keys[0...-1]
modifiers.sort()
[modifiers..., _.last(keys)].join('-')
normalizedKeystroke.join(' ')
@getParser: ->
if not KeyBinding.parser
keystrokePattern = fs.readFileSync(require.resolve('./keystroke-pattern.pegjs'), 'utf8')
KeyBinding.parser = PEG.buildParser(keystrokePattern)
KeyBinding.parser
constructor: (source, command, keystroke, selector) ->
@source = source
@command = command
@keystroke = KeyBinding.normalizeKeystroke(keystroke)
@selector = selector.replace(/!important/g, '')
@specificity = specificity(selector)
@index = KeyBinding.currentIndex++
matches: (keystroke) ->
multiKeystroke = /\s/.test keystroke
if multiKeystroke
keystroke == @keystroke
else
keystroke.split(' ')[0] == @keystroke.split(' ')[0]
compare: (keyBinding) ->
if keyBinding.specificity == @specificity
keyBinding.index - @index
else
keyBinding.specificity - @specificity
+124 -169
Ver Arquivo
@@ -3,10 +3,10 @@ _ = require 'underscore-plus'
fs = require 'fs-plus'
path = require 'path'
CSON = require 'season'
BindingSet = require './binding-set'
KeyBinding = require './key-binding'
{Emitter} = require 'emissary'
Modifiers = ['alt', 'control', 'ctrl', 'shift', 'meta']
Modifiers = ['alt', 'control', 'ctrl', 'shift', 'cmd']
# Internal: Associates keymaps with actions.
#
@@ -25,14 +25,94 @@ module.exports =
class Keymap
Emitter.includeInto(this)
bindingSets: null
nextBindingSetIndex: 0
bindingSetsByFirstKeystroke: null
queuedKeystrokes: null
constructor: ({@resourcePath, @configDirPath})->
@bindingSets = []
@bindingSetsByFirstKeystroke = {}
@keyBindings = []
# Public: Returns an array of all {KeyBinding}s.
getKeyBindings: ->
_.clone(@keyBindings)
# Public: Returns a array of {KeyBinding}s (sorted by selector specificity)
# that match a keystroke and element.
#
# * keystroke:
# The string representing the keys pressed (e.g. ctrl-P).
# * element:
# The DOM node that will match a {KeyBinding}'s selector.
keyBindingsForKeystrokeMatchingElement: (keystroke, element) ->
keyBindings = @keyBindingsForKeystroke(keystroke)
@keyBindingsMatchingElement(element, keyBindings)
# Public: Returns a array of {KeyBinding}s (sorted by selector specificity)
# that match a command.
#
# * command:
# The string representing the command (tree-view:toggle)
# * element:
# The DOM node that will match a {KeyBinding}'s selector.
keyBindingsForCommandMatchingElement: (command, element) ->
keyBindings = @keyBindingsForCommand(command)
@keyBindingsMatchingElement(element, keyBindings)
# Public: Returns an array of {KeyBinding}s that match a keystroke
# * keystroke:
# The string representing the keys pressed (e.g. ctrl-P)
keyBindingsForKeystroke: (keystroke) ->
keystroke = KeyBinding.normalizeKeystroke(keystroke)
@keyBindings.filter (keyBinding) -> keyBinding.matches(keystroke)
# Public: Returns an array of {KeyBinding}s that match a command
# * keystroke:
# The string representing the keys pressed (e.g. ctrl-P)
keyBindingsForCommand: (command) ->
@keyBindings.filter (keyBinding) -> keyBinding.command == command
# Public: Returns a array of {KeyBinding}s (sorted by selector specificity)
# whos selector matches the element.
#
# * element:
# The DOM node that will match a {KeyBinding}'s selector.
keyBindingsMatchingElement: (element, keyBindings=@keyBindings) ->
keyBindings = keyBindings.filter ({selector}) -> $(element).closest(selector).length > 0
keyBindings.sort (a, b) -> a.compare(b)
# Public: Returns a keystroke string derived from an event.
# * event:
# A DOM or jQuery event
# * previousKeystroke:
# An optional string used for multiKeystrokes
keystrokeStringForEvent: (event, previousKeystroke) ->
if event.originalEvent.keyIdentifier.indexOf('U+') == 0
hexCharCode = event.originalEvent.keyIdentifier[2..]
charCode = parseInt(hexCharCode, 16)
charCode = event.which if !@isAscii(charCode) and @isAscii(event.which)
key = @keyFromCharCode(charCode)
else
key = event.originalEvent.keyIdentifier.toLowerCase()
modifiers = []
if event.altKey and key not in Modifiers
modifiers.push 'alt'
if event.metaKey and key not in Modifiers
modifiers.push 'cmd'
if event.ctrlKey and key not in Modifiers
modifiers.push 'ctrl'
if event.shiftKey and key not in Modifiers
isNamedKey = key.length > 1
modifiers.push 'shift' if isNamedKey
else
key = key.toLowerCase()
keystroke = [modifiers..., key].join('-')
if previousKeystroke
if keystroke in Modifiers
previousKeystroke
else
"#{previousKeystroke} #{keystroke}"
else
keystroke
loadBundledKeymaps: ->
@loadDirectory(path.join(@resourcePath, 'keymaps'))
@@ -48,175 +128,50 @@ class Keymap
load: (path) ->
@add(path, CSON.readFileSync(path))
add: (args...) ->
name = args.shift() if args.length > 1
keymap = args.shift()
for selector, bindings of keymap
@bindKeys(name, selector, bindings)
add: (source, keyMappingsBySelector) ->
for selector, keyMappings of keyMappingsBySelector
@bindKeys(source, selector, keyMappings)
remove: (name) ->
for bindingSet in @bindingSets.filter((bindingSet) -> bindingSet.name is name)
_.remove(@bindingSets, bindingSet)
for keystrokes of bindingSet.commandsByKeystrokes
keystroke = keystrokes.split(' ')[0]
_.remove(@bindingSetsByFirstKeystroke[keystroke], bindingSet)
remove: (source) ->
@keyBindings = @keyBindings.filter (keyBinding) -> keyBinding.source isnt source
# Public: Returns an array of objects that represent every keystroke to
# command mapping. Each object contains the following keys `source`,
# `selector`, `command`, `keystrokes`.
getAllKeyMappings: ->
mappings = []
for bindingSet in @bindingSets
selector = bindingSet.getSelector()
source = @determineSource(bindingSet.getName())
for keystrokes, command of bindingSet.getCommandsByKeystrokes()
mappings.push {keystrokes, command, selector, source}
bindKeys: (source, selector, keyMappings) ->
for keystroke, command of keyMappings
@keyBindings.push new KeyBinding(source, command, keystroke, selector)
mappings
handleKeyEvent: (event) ->
element = event.target
element = atom.rootView if element == document.body
keystroke = @keystrokeStringForEvent(event, @queuedKeystroke)
keyBindings = @keyBindingsForKeystrokeMatchingElement(keystroke, element)
# Private: Returns a user friendly description of where a keybinding was
# loaded from.
#
# * filePath:
# The absolute path from which the keymap was loaded
#
# Returns one of:
# * `Core` indicates it comes from a bundled package.
# * `User` indicates that it was defined by a user.
# * `<package-name>` the package which defined it.
# * `Unknown` if an invalid path was passed in.
determineSource: (filePath) ->
return 'Unknown' unless filePath
pathParts = filePath.split(path.sep)
if _.contains(pathParts, 'node_modules') or _.contains(pathParts, 'atom') or _.contains(pathParts, 'src')
'Core'
else if _.contains(pathParts, '.atom') and _.contains(pathParts, 'keymaps') and !_.contains(pathParts, 'packages')
'User'
if keyBindings.length == 0 and @queuedKeystroke
@queuedKeystroke = null
return false
else
packageNameIndex = pathParts.length - 3
pathParts[packageNameIndex]
@queuedKeystroke = null
bindKeys: (args...) ->
name = args.shift() if args.length > 2
[selector, bindings] = args
bindingSet = new BindingSet(selector, bindings, @nextBindingSetIndex++, name)
@bindingSets.unshift(bindingSet)
for keystrokes of bindingSet.commandsByKeystrokes
keystroke = keystrokes.split(' ')[0] # only index by first keystroke
@bindingSetsByFirstKeystroke[keystroke] ?= []
@bindingSetsByFirstKeystroke[keystroke].push(bindingSet)
unbindKeys: (selector, bindings) ->
bindingSet = _.detect @bindingSets, (bindingSet) ->
bindingSet.selector is selector and bindingSet.bindings is bindings
if bindingSet
_.remove(@bindingSets, bindingSet)
bindingsForElement: (element) ->
keystrokeMap = {}
currentNode = $(element)
while currentNode.length
bindingSets = @bindingSetsForNode(currentNode)
_.defaults(keystrokeMap, set.commandsByKeystrokes) for set in bindingSets
currentNode = currentNode.parent()
keystrokeMap
handleKeyEvent: (event) =>
event.keystrokes = @multiKeystrokeStringForEvent(event)
isMultiKeystroke = @queuedKeystrokes?
@queuedKeystrokes = null
firstKeystroke = event.keystrokes.split(' ')[0]
bindingSetsForFirstKeystroke = @bindingSetsByFirstKeystroke[firstKeystroke]
if bindingSetsForFirstKeystroke?
currentNode = $(event.target)
currentNode = rootView if currentNode is $('body')[0]
while currentNode.length
candidateBindingSets = @bindingSetsForNode(currentNode, bindingSetsForFirstKeystroke)
for bindingSet in candidateBindingSets
command = bindingSet.commandForEvent(event)
if command is 'native!'
return true
else if command
continue if @triggerCommandEvent(event, command)
return false
else if command == false
return false
if bindingSet.matchesKeystrokePrefix(event)
@queuedKeystrokes = event.keystrokes
return false
currentNode = currentNode.parent()
return false if isMultiKeystroke
return false if firstKeystroke is 'tab'
bindingSetsForNode: (node, candidateBindingSets = @bindingSets) ->
bindingSets = candidateBindingSets.filter (set) -> node.is(set.selector)
bindingSets.sort (a, b) ->
if b.specificity == a.specificity
b.index - a.index
for keyBinding in keyBindings
partialMatch = keyBinding.keystroke isnt keystroke
if partialMatch
@queuedKeystroke = keystroke
shouldBubble = false
else
b.specificity - a.specificity
if keyBinding.command is 'native!'
shouldBubble = true
else if @triggerCommandEvent(element, keyBinding.command, event)
shouldBubble = false
triggerCommandEvent: (keyEvent, commandName) ->
keyEvent.target = rootView[0] if keyEvent.target == document.body and window.rootView
break if shouldBubble?
shouldBubble ? true
triggerCommandEvent: (element, commandName, event) ->
commandEvent = $.Event(commandName)
commandEvent.keyEvent = keyEvent
aborted = false
commandEvent.abortKeyBinding = ->
@stopImmediatePropagation()
aborted = true
$(keyEvent.target).trigger(commandEvent)
aborted
multiKeystrokeStringForEvent: (event) ->
currentKeystroke = @keystrokeStringForEvent(event)
if @queuedKeystrokes
if currentKeystroke in Modifiers
@queuedKeystrokes
else
@queuedKeystrokes + ' ' + currentKeystroke
else
currentKeystroke
keystrokeStringForEvent: (event) ->
if event.originalEvent.keyIdentifier.indexOf('U+') == 0
hexCharCode = event.originalEvent.keyIdentifier[2..]
charCode = parseInt(hexCharCode, 16)
charCode = event.which if !@isAscii(charCode) and @isAscii(event.which)
key = @keyFromCharCode(charCode)
else
key = event.originalEvent.keyIdentifier.toLowerCase()
modifiers = []
if event.altKey and key not in Modifiers
modifiers.push 'alt'
if event.ctrlKey and key not in Modifiers
modifiers.push 'ctrl'
if event.metaKey and key not in Modifiers
modifiers.push 'meta'
if event.shiftKey and key not in Modifiers
isNamedKey = key.length > 1
modifiers.push 'shift' if isNamedKey
else
key = key.toLowerCase()
[modifiers..., key].join('-')
keystrokesByCommandForSelector: (selector)->
keystrokesByCommand = {}
for bindingSet in @bindingSets
for keystroke, command of bindingSet.commandsByKeystrokes
continue if selector? and selector != bindingSet.selector
keystrokesByCommand[command] ?= []
keystrokesByCommand[command].push keystroke
keystrokesByCommand
commandEvent.originalEvent = event
commandEvent.abortKeyBinding = -> commandEvent.stopImmediatePropagation()
$(element).trigger(commandEvent)
not commandEvent.isImmediatePropagationStopped()
isAscii: (charCode) ->
0 <= charCode <= 127
+45 -45
Ver Arquivo
@@ -12,7 +12,7 @@ class LanguageMode
buffer: null
grammar: null
editSession: null
editor: null
currentGrammarScore: null
### Internal ###
@@ -22,11 +22,11 @@ class LanguageMode
### Public ###
# Sets up a `LanguageMode` for the given {EditSession}.
# Sets up a `LanguageMode` for the given {Editor}.
#
# editSession - The {EditSession} to associate with
constructor: (@editSession) ->
@buffer = @editSession.buffer
# editor - The {Editor} to associate with
constructor: (@editor) ->
@buffer = @editor.buffer
# Wraps the lines between two rows in comments.
#
@@ -37,7 +37,7 @@ class LanguageMode
#
# Returns an {Array} of the commented {Ranges}.
toggleLineCommentsForBufferRows: (start, end) ->
scopes = @editSession.scopesForBufferPosition([start, 0])
scopes = @editor.scopesForBufferPosition([start, 0])
properties = atom.syntax.propertiesForScope(scopes, "editor.commentStart")[0]
return unless properties
@@ -46,7 +46,7 @@ class LanguageMode
return unless commentStartString
buffer = @editSession.buffer
buffer = @editor.buffer
commentStartRegexString = _.escapeRegExp(commentStartString).replace(/(\s+)$/, '($1)?')
commentStartRegex = new OnigRegExp("^(\\s*)(#{commentStartRegexString})")
shouldUncomment = commentStartRegex.test(buffer.lineForRow(start))
@@ -83,8 +83,8 @@ class LanguageMode
buffer.change([[row, columnStart], [row, columnEnd]], "")
else
indent = @minIndentLevelForRowRange(start, end)
indentString = @editSession.buildIndentString(indent)
tabLength = @editSession.getTabLength()
indentString = @editor.buildIndentString(indent)
tabLength = @editor.getTabLength()
indentRegex = new RegExp("(\t|[ ]{#{tabLength}}){#{Math.floor(indent)}}")
for row in [start..end]
line = buffer.lineForRow(row)
@@ -98,12 +98,12 @@ class LanguageMode
for currentRow in [0..@buffer.getLastRow()]
[startRow, endRow] = @rowRangeForFoldAtBufferRow(currentRow) ? []
continue unless startRow?
@editSession.createFold(startRow, endRow)
@editor.createFold(startRow, endRow)
# Unfolds all the foldable lines in the buffer.
unfoldAll: ->
for row in [@buffer.getLastRow()..0]
fold.destroy() for fold in @editSession.displayBuffer.foldsStartingAtBufferRow(row)
fold.destroy() for fold in @editor.displayBuffer.foldsStartingAtBufferRow(row)
# Fold all comment and code blocks at a given indentLevel
#
@@ -114,8 +114,8 @@ class LanguageMode
continue unless startRow?
# assumption: startRow will always be the min indent level for the entire range
if @editSession.indentationForBufferRow(startRow) == indentLevel
@editSession.createFold(startRow, endRow)
if @editor.indentationForBufferRow(startRow) == indentLevel
@editor.createFold(startRow, endRow)
# Given a buffer row, creates a fold at it.
#
@@ -126,14 +126,14 @@ class LanguageMode
for currentRow in [bufferRow..0]
[startRow, endRow] = @rowRangeForFoldAtBufferRow(currentRow) ? []
continue unless startRow? and startRow <= bufferRow <= endRow
fold = @editSession.displayBuffer.largestFoldStartingAtBufferRow(startRow)
return @editSession.createFold(startRow, endRow) unless fold
fold = @editor.displayBuffer.largestFoldStartingAtBufferRow(startRow)
return @editor.createFold(startRow, endRow) unless fold
# Given a buffer row, this unfolds it.
#
# bufferRow - A {Number} indicating the buffer row
unfoldBufferRow: (bufferRow) ->
@editSession.displayBuffer.largestFoldContainingBufferRow(bufferRow)?.destroy()
@editor.displayBuffer.largestFoldContainingBufferRow(bufferRow)?.destroy()
# Find the row range for a fold at a given bufferRow. Will handle comments
# and code.
@@ -147,30 +147,30 @@ class LanguageMode
rowRange
rowRangeForCommentAtBufferRow: (bufferRow) ->
return unless @editSession.displayBuffer.tokenizedBuffer.lineForScreenRow(bufferRow).isComment()
return unless @editor.displayBuffer.tokenizedBuffer.lineForScreenRow(bufferRow).isComment()
startRow = bufferRow
for currentRow in [bufferRow-1..0]
break if @buffer.isRowBlank(currentRow)
break unless @editSession.displayBuffer.tokenizedBuffer.lineForScreenRow(currentRow).isComment()
break unless @editor.displayBuffer.tokenizedBuffer.lineForScreenRow(currentRow).isComment()
startRow = currentRow
endRow = bufferRow
for currentRow in [bufferRow+1..@buffer.getLastRow()]
break if @buffer.isRowBlank(currentRow)
break unless @editSession.displayBuffer.tokenizedBuffer.lineForScreenRow(currentRow).isComment()
break unless @editor.displayBuffer.tokenizedBuffer.lineForScreenRow(currentRow).isComment()
endRow = currentRow
return [startRow, endRow] if startRow isnt endRow
rowRangeForCodeFoldAtBufferRow: (bufferRow) ->
return null unless @doesBufferRowStartFold(bufferRow)
startIndentLevel = @editSession.indentationForBufferRow(bufferRow)
scopes = @editSession.scopesForBufferPosition([bufferRow, 0])
for row in [(bufferRow + 1)..@editSession.getLastBufferRow()]
continue if @editSession.isBufferRowBlank(row)
indentation = @editSession.indentationForBufferRow(row)
startIndentLevel = @editor.indentationForBufferRow(bufferRow)
scopes = @editor.scopesForBufferPosition([bufferRow, 0])
for row in [(bufferRow + 1)..@editor.getLastBufferRow()]
continue if @editor.isBufferRowBlank(row)
indentation = @editor.indentationForBufferRow(row)
if indentation <= startIndentLevel
includeRowInFold = indentation == startIndentLevel and @foldEndRegexForScopes(scopes)?.search(@editSession.lineForBufferRow(row))
includeRowInFold = indentation == startIndentLevel and @foldEndRegexForScopes(scopes)?.search(@editor.lineForBufferRow(row))
foldEndRow = row if includeRowInFold
break
@@ -179,19 +179,19 @@ class LanguageMode
[bufferRow, foldEndRow]
doesBufferRowStartFold: (bufferRow) ->
return false if @editSession.isBufferRowBlank(bufferRow)
nextNonEmptyRow = @editSession.nextNonBlankBufferRow(bufferRow)
return false if @editor.isBufferRowBlank(bufferRow)
nextNonEmptyRow = @editor.nextNonBlankBufferRow(bufferRow)
return false unless nextNonEmptyRow?
@editSession.indentationForBufferRow(nextNonEmptyRow) > @editSession.indentationForBufferRow(bufferRow)
@editor.indentationForBufferRow(nextNonEmptyRow) > @editor.indentationForBufferRow(bufferRow)
# Find a row range for a 'paragraph' around specified bufferRow.
# Right now, a paragraph is a block of text bounded by and empty line or a
# block of text that is not the same type (comments next to source code).
rowRangeForParagraphAtBufferRow: (bufferRow) ->
return unless /\w/.test(@editSession.lineForBufferRow(bufferRow))
return unless /\w/.test(@editor.lineForBufferRow(bufferRow))
isRowComment = (row) =>
@editSession.displayBuffer.tokenizedBuffer.lineForScreenRow(row).isComment()
@editor.displayBuffer.tokenizedBuffer.lineForScreenRow(row).isComment()
if isRowComment(bufferRow)
isOriginalRowComment = true
@@ -199,22 +199,22 @@ class LanguageMode
[firstRow, lastRow] = range or [bufferRow, bufferRow]
else
isOriginalRowComment = false
[firstRow, lastRow] = [0, @editSession.getLastBufferRow()-1]
[firstRow, lastRow] = [0, @editor.getLastBufferRow()-1]
startRow = bufferRow
while startRow > firstRow
break if isRowComment(startRow - 1) != isOriginalRowComment
break unless /\w/.test(@editSession.lineForBufferRow(startRow - 1))
break unless /\w/.test(@editor.lineForBufferRow(startRow - 1))
startRow--
endRow = bufferRow
lastRow = @editSession.getLastBufferRow()
lastRow = @editor.getLastBufferRow()
while endRow < lastRow
break if isRowComment(endRow + 1) != isOriginalRowComment
break unless /\w/.test(@editSession.lineForBufferRow(endRow + 1))
break unless /\w/.test(@editor.lineForBufferRow(endRow + 1))
endRow++
new Range([startRow, 0], [endRow, @editSession.lineLengthForBufferRow(endRow)])
new Range([startRow, 0], [endRow, @editor.lineLengthForBufferRow(endRow)])
# Given a buffer row, this returns a suggested indentation level.
#
@@ -224,8 +224,8 @@ class LanguageMode
#
# Returns a {Number}.
suggestedIndentForBufferRow: (bufferRow) ->
currentIndentLevel = @editSession.indentationForBufferRow(bufferRow)
scopes = @editSession.scopesForBufferPosition([bufferRow, 0])
currentIndentLevel = @editor.indentationForBufferRow(bufferRow)
scopes = @editor.scopesForBufferPosition([bufferRow, 0])
return currentIndentLevel unless increaseIndentRegex = @increaseIndentRegexForScopes(scopes)
currentLine = @buffer.lineForRow(bufferRow)
@@ -233,8 +233,8 @@ class LanguageMode
return currentIndentLevel unless precedingRow?
precedingLine = @buffer.lineForRow(precedingRow)
desiredIndentLevel = @editSession.indentationForBufferRow(precedingRow)
desiredIndentLevel += 1 if increaseIndentRegex.test(precedingLine) and not @editSession.isBufferRowCommented(precedingRow)
desiredIndentLevel = @editor.indentationForBufferRow(precedingRow)
desiredIndentLevel += 1 if increaseIndentRegex.test(precedingLine) and not @editor.isBufferRowCommented(precedingRow)
return desiredIndentLevel unless decreaseIndentRegex = @decreaseIndentRegexForScopes(scopes)
desiredIndentLevel -= 1 if decreaseIndentRegex.test(currentLine)
@@ -248,7 +248,7 @@ class LanguageMode
#
# Returns a {Number} of the indent level of the block of lines.
minIndentLevelForRowRange: (startRow, endRow) ->
indents = (@editSession.indentationForBufferRow(row) for row in [startRow..endRow] when not @editSession.isBufferRowBlank(row))
indents = (@editor.indentationForBufferRow(row) for row in [startRow..endRow] when not @editor.isBufferRowBlank(row))
indents = [0] unless indents.length
Math.min(indents...)
@@ -264,13 +264,13 @@ class LanguageMode
# bufferRow - The row {Number}
autoIndentBufferRow: (bufferRow) ->
indentLevel = @suggestedIndentForBufferRow(bufferRow)
@editSession.setIndentationForBufferRow(bufferRow, indentLevel)
@editor.setIndentationForBufferRow(bufferRow, indentLevel)
# Given a buffer row, this decreases the indentation.
#
# bufferRow - The row {Number}
autoDecreaseIndentForBufferRow: (bufferRow) ->
scopes = @editSession.scopesForBufferPosition([bufferRow, 0])
scopes = @editor.scopesForBufferPosition([bufferRow, 0])
increaseIndentRegex = @increaseIndentRegexForScopes(scopes)
decreaseIndentRegex = @decreaseIndentRegexForScopes(scopes)
return unless increaseIndentRegex and decreaseIndentRegex
@@ -278,16 +278,16 @@ class LanguageMode
line = @buffer.lineForRow(bufferRow)
return unless decreaseIndentRegex.test(line)
currentIndentLevel = @editSession.indentationForBufferRow(bufferRow)
currentIndentLevel = @editor.indentationForBufferRow(bufferRow)
return if currentIndentLevel is 0
precedingRow = @buffer.previousNonBlankRow(bufferRow)
return unless precedingRow?
precedingLine = @buffer.lineForRow(precedingRow)
desiredIndentLevel = @editSession.indentationForBufferRow(precedingRow)
desiredIndentLevel = @editor.indentationForBufferRow(precedingRow)
desiredIndentLevel -= 1 unless increaseIndentRegex.test(precedingLine)
if desiredIndentLevel >= 0 and desiredIndentLevel < currentIndentLevel
@editSession.setIndentationForBufferRow(bufferRow, desiredIndentLevel)
@editor.setIndentationForBufferRow(bufferRow, desiredIndentLevel)
tokenizeLine: (line, stack, firstLine) ->
{tokens, stack} = @grammar.tokenizeLine(line, stack, firstLine)
+10 -5
Ver Arquivo
@@ -5,27 +5,32 @@ LessCache = require 'less-cache'
tmpDir = if process.platform is 'win32' then os.tmpdir() else '/tmp'
# Private: {LessCache} wrapper used by {ThemeManager} to read stylesheets.
module.exports =
class LessCompileCache
Subscriber.includeInto(this)
@cacheDir: path.join(tmpDir, 'atom-compile-cache', 'less')
constructor: ({resourcePath}) ->
constructor: ({resourcePath, importPaths}) ->
@lessSearchPaths = [
path.join(resourcePath, 'static', 'variables')
path.join(resourcePath, 'static')
]
if importPaths?
importPaths = importPaths.concat(@lessSearchPaths)
else
importPaths = @lessSearchPaths
@cache = new LessCache
cacheDir: @constructor.cacheDir
importPaths: @getImportPaths()
importPaths: importPaths
resourcePath: resourcePath
fallbackDir: path.join(resourcePath, 'less-compile-cache')
@subscribe atom.themes, 'reloaded', => @cache.setImportPaths(@getImportPaths())
getImportPaths: -> atom.themes.getImportPaths().concat(@lessSearchPaths)
setImportPaths: (importPaths=[]) ->
@cache.setImportPaths(importPaths.concat(@lessSearchPaths))
read: (stylesheetPath) -> @cache.readFileSync(stylesheetPath)
+44 -15
Ver Arquivo
@@ -14,7 +14,7 @@ class MenuManager
# Private:
constructor: ({@resourcePath}) ->
@template = []
atom.keymap.on 'bundled-keymaps-loaded', => @loadCoreItems()
atom.keymap.on 'bundled-keymaps-loaded', => @loadPlatformItems()
# Public: Adds the given item definition to the existing template.
#
@@ -27,35 +27,55 @@ class MenuManager
@merge(@template, item) for item in items
@update()
# Private: Should the binding for the given selector be included in the menu
# commands.
#
# * selector: A String selector to check.
#
# Returns true to include the selector, false otherwise.
includeSelector: (selector) ->
return true if document.body.webkitMatchesSelector(selector)
# Simulate an .editor element attached to a body element that has the same
# classes as the current body element.
unless @testEditor?
@testEditor = document.createElement('div')
@testEditor.classList.add('editor')
testBody = document.createElement('body')
testBody.classList.add(document.body.classList.toString().split(' ')...)
testBody.appendChild(@testEditor)
@testEditor.webkitMatchesSelector(selector)
# Public: Refreshes the currently visible menu.
update: ->
keystrokesByCommand = atom.keymap.keystrokesByCommandForSelector('body')
_.extend(keystrokesByCommand, atom.keymap.keystrokesByCommandForSelector('.editor'))
_.extend(keystrokesByCommand, atom.keymap.keystrokesByCommandForSelector('.editor:not(.mini)'))
keystrokesByCommand = {}
for binding in atom.keymap.getKeyBindings() when @includeSelector(binding.selector)
keystrokesByCommand[binding.command] ?= []
keystrokesByCommand[binding.command].push binding.keystroke
@sendToBrowserProcess(@template, keystrokesByCommand)
# Private
loadCoreItems: ->
# Private:
loadPlatformItems: ->
menusDirPath = path.join(@resourcePath, 'menus')
menuPaths = fs.listSync(menusDirPath, ['cson', 'json'])
for menuPath in menuPaths
data = CSON.readFileSync(menuPath)
@add(data.menu)
platformMenuPath = fs.resolve(menusDirPath, process.platform, ['cson', 'json'])
{menu} = CSON.readFileSync(platformMenuPath)
@add(menu)
# Private: Merges an item in a submenu aware way such that new items are always
# appended to the bottom of existing menus where possible.
merge: (menu, item) ->
item = _.deepClone(item)
if item.submenu? and match = _.find(menu, (i) -> i.submenu? and i.label == item.label)
if item.submenu? and match = _.find(menu, (i) => i.submenu? and @normalizeLabel(i.label) == @normalizeLabel(item.label))
@merge(match.submenu, i) for i in item.submenu
else
menu.push(item) unless _.find(menu, (i) -> i.label == item.label)
menu.push(item) unless _.find(menu, (i) => @normalizeLabel(i.label) == @normalizeLabel(item.label))
# Private: OSX can't handle displaying accelerators for multiple keystrokes.
# If they are sent across, it will stop processing accelerators for the rest
# of the menu items.
filterMultipleKeystrokes: (keystrokesByCommand) ->
filterMultipleKeystroke: (keystrokesByCommand) ->
filtered = {}
for key, bindings of keystrokesByCommand
for binding in bindings
@@ -65,7 +85,16 @@ class MenuManager
filtered[key].push(binding)
filtered
# Private
# Private:
sendToBrowserProcess: (template, keystrokesByCommand) ->
keystrokesByCommand = @filterMultipleKeystrokes(keystrokesByCommand)
keystrokesByCommand = @filterMultipleKeystroke(keystrokesByCommand)
ipc.sendChannel 'update-application-menu', template, keystrokesByCommand
# Private:
normalizeLabel: (label) ->
return undefined unless label?
if process.platform is 'win32'
label.replace(/\&/g, '')
else
label
+52 -27
Ver Arquivo
@@ -4,25 +4,26 @@ _ = require 'underscore-plus'
Package = require './package'
path = require 'path'
###
Packages have a lifecycle
* The paths to all non-disabled packages and themes are found on disk (these are available packages)
* Every package (except those in core.disabledPackages) is 'loaded', meaning
`Package` objects are created, and their metadata loaded. This includes themes,
as themes are packages
* The ThemeManager.activateThemes() is called 'activating' all the themes, meaning
their stylesheets are loaded into the window.
* The PackageManager.activatePackages() function is called 'activating' non-theme
package, meaning its resources -- keymaps, classes, etc. -- are loaded, and
the package's activate() method is called.
* Packages and themes can then be enabled and disabled via the public
.enablePackage(name) and .disablePackage(name) functions.
###
# Public: Package manager for coordinating the lifecycle of Atom packages.
#
# Packages can be loaded, activated, and deactivated, and unloaded:
# * Loading a package reads and parses the package's metadata and resources
# such as keymaps, menus, stylesheets, etc.
# * Activating a package registers the loaded resources and calls `activate()`
# on the package's main module.
# * Deactivating a package unregisters the package's resources and calls
# `deactivate()` on the package's main module.
# * Unloading a package removes it completely from the package manager.
#
# Packages can also be enabled/disabled via the `core.disabledPackages` config
# settings and also by calling `enablePackage()/disablePackage()`.
#
# An instance of this class is globally available via `atom.packages`.
module.exports =
class PackageManager
Emitter.includeInto(this)
# Private:
constructor: ({configDirPath, devMode, @resourcePath}) ->
@packageDirPaths = [path.join(configDirPath, "packages")]
if devMode
@@ -46,42 +47,44 @@ class PackageManager
getPackageDirPaths: ->
_.clone(@packageDirPaths)
# Private:
getPackageState: (name) ->
@packageStates[name]
# Private:
setPackageState: (name, state) ->
@packageStates[name] = state
# Public:
# Public: Enable the package with the given name
enablePackage: (name) ->
pack = @loadPackage(name)
pack?.enable()
pack
# Public:
# Public: Disable the package with the given name
disablePackage: (name) ->
pack = @loadPackage(name)
pack?.disable()
pack
# Internal-only: Activate all the packages that should be activated.
# Private: Activate all the packages that should be activated.
activate: ->
for [activator, types] in @packageActivators
packages = @getLoadedPackagesForTypes(types)
activator.activatePackages(packages)
@emit 'activated'
# Public: another type of package manager can handle other package types.
# Private: another type of package manager can handle other package types.
# See ThemeManager
registerPackageActivator: (activator, types) ->
@packageActivators.push([activator, types])
# Internal-only:
# Private:
activatePackages: (packages) ->
@activatePackage(pack.name) for pack in packages
@observeDisabledPackages()
# Internal-only: Activate a single package by name
# Private: Activate a single package by name
activatePackage: (name, options) ->
return pack if pack = @getActivePackage(name)
if pack = @loadPackage(name, options)
@@ -89,10 +92,12 @@ class PackageManager
pack.activate(options)
pack
# Private: Deactivate all packages
deactivatePackages: ->
@deactivatePackage(pack.name) for pack in @getActivePackages()
@unobserveDisabledPackages()
# Private: Deactivate the package with the given name
deactivatePackage: (name) ->
if pack = @getActivePackage(name)
@setPackageState(pack.name, state) if state = pack.serialize?()
@@ -101,20 +106,25 @@ class PackageManager
else
throw new Error("No active package for name '#{name}'")
# Public: Get an array of all the active packages
getActivePackages: ->
_.values(@activePackages)
# Public: Get the active package with the given name
getActivePackage: (name) ->
@activePackages[name]
# Public: Is the package with the given name active?
isPackageActive: (name) ->
@getActivePackage(name)?
# Private:
unobserveDisabledPackages: ->
return unless @observingDisabledPackages
atom.config.unobserve('core.disabledPackages')
@observingDisabledPackages = false
# Private:
observeDisabledPackages: ->
return if @observingDisabledPackages
@@ -128,6 +138,7 @@ class PackageManager
@observingDisabledPackages = true
# Private:
loadPackages: (options) ->
# Ensure atom exports is already in the require cache so the load time
# of the first package isn't skewed by being the first to require atom
@@ -139,6 +150,7 @@ class PackageManager
@loadPackage(packagePath, options) for packagePath in packagePaths
@emit 'loaded'
# Private:
loadPackage: (nameOrPath, options) ->
if packagePath = @resolvePackagePath(nameOrPath)
name = path.basename(nameOrPath)
@@ -150,10 +162,12 @@ class PackageManager
else
throw new Error("Could not resolve '#{nameOrPath}' to a package path")
# Private:
unloadPackages: ->
@unloadPackage(name) for name in _.keys(@loadedPackages)
null
# Private:
unloadPackage: (name) ->
if @isPackageActive(name)
throw new Error("Tried to unload active package '#{name}'")
@@ -163,12 +177,15 @@ class PackageManager
else
throw new Error("No loaded package for name '#{name}'")
# Public: Get the loaded package with the given name
getLoadedPackage: (name) ->
@loadedPackages[name]
# Public: Is the package with the given name loaded?
isPackageLoaded: (name) ->
@getLoadedPackage(name)?
# Public: Get an array of all the loaded packages
getLoadedPackages: ->
_.values(@loadedPackages)
@@ -178,6 +195,7 @@ class PackageManager
getLoadedPackagesForTypes: (types) ->
pack for pack in @getLoadedPackages() when pack.getType() in types
# Public: Resolve the given package name to a path on disk.
resolvePackagePath: (name) ->
return name if fs.isDirectorySync(name)
@@ -185,18 +203,22 @@ class PackageManager
return packagePath if fs.isDirectorySync(packagePath)
packagePath = path.join(@resourcePath, 'node_modules', name)
return packagePath if @isInternalPackage(packagePath)
return packagePath if @hasAtomEngine(packagePath)
# Public: Is the package with the given name disabled?
isPackageDisabled: (name) ->
_.include(atom.config.get('core.disabledPackages') ? [], name)
isInternalPackage: (packagePath) ->
{engines} = Package.loadMetadata(packagePath, true)
engines?.atom?
# Private:
hasAtomEngine: (packagePath) ->
metadata = Package.loadMetadata(packagePath, true)
metadata?.engines?.atom?
isBundledPackage: (packageName) ->
@getPackageDependencies().hasOwnProperty(packageName)
# Public: Is the package with the given name bundled with Atom?
isBundledPackage: (name) ->
@getPackageDependencies().hasOwnProperty(name)
# Private:
getPackageDependencies: ->
unless @packageDependencies?
try
@@ -206,6 +228,7 @@ class PackageManager
@packageDependencies
# Public: Get an array of all the available package paths.
getAvailablePackagePaths: ->
packagePaths = []
@@ -220,9 +243,11 @@ class PackageManager
_.uniq(packagePaths)
# Public: Get an array of all the available package names.
getAvailablePackageNames: ->
_.uniq _.map @getAvailablePackagePaths(), (packagePath) -> path.basename(packagePath)
# Public: Get an array of all the available package metadata.
getAvailablePackageMetadata: ->
packages = []
for packagePath in @getAvailablePackagePaths()
+1 -1
Ver Arquivo
@@ -45,7 +45,7 @@ class Package
@name = basename(@path)
isActive: ->
atom.isPackageActive(@name)
atom.packages.isPackageActive(@name)
isTheme: ->
!!@metadata?.theme
+3 -2
Ver Arquivo
@@ -12,7 +12,8 @@ class PaneAxis extends View
initialize: (args...) ->
if args[0] instanceof telepath.Document
@state = args[0]
@state.get('children').each (child, index) => @addChild(deserialize(child), index, updateState: false)
@state.get('children').each (child, index) =>
@addChild(atom.deserializers.deserialize(child), index, updateState: false)
else
@state = atom.site.createDocument(deserializer: @className(), children: [])
@addChild(child) for child in args
@@ -22,7 +23,7 @@ class PaneAxis extends View
for childState in removedValues
@removeChild(@children(":eq(#{index})").view(), updateState: false)
for childState, i in insertedValues
@addChild(deserialize(childState), index + i, updateState: false)
@addChild(atom.deserializers.deserialize(childState), index + i, updateState: false)
addChild: (child, index=@children().length, options={}) ->
@insertAt(index, child)
+5 -5
Ver Arquivo
@@ -5,7 +5,7 @@ telepath = require 'telepath'
# Private: Manages the list of panes within a {RootView}
module.exports =
class PaneContainer extends View
registerDeserializer(this)
atom.deserializers.add(this)
### Internal ###
@acceptsDocuments: true
@@ -23,7 +23,7 @@ class PaneContainer extends View
if state instanceof telepath.Document
@state = state
@setRoot(deserialize(@state.get('root')))
@setRoot(atom.deserializers.deserialize(@state.get('root')))
else
@state = atom.site.createDocument(deserializer: 'PaneContainer')
@@ -89,10 +89,10 @@ class PaneContainer extends View
reopenItem: ->
if lastItemState = @destroyedItemStates.pop()
if activePane = @getActivePane()
activePane.showItem(deserialize(lastItemState))
activePane.showItem(atom.deserializers.deserialize(lastItemState))
true
else
newPane = new Pane(deserialize(lastItemState))
newPane = new Pane(atom.deserializers.deserialize(lastItemState))
@setRoot(newPane)
newPane.focus()
@@ -147,7 +147,7 @@ class PaneContainer extends View
callback(pane) for pane in @getPanes()
paneAttached = (e) -> callback($(e.target).view())
@on 'pane:attached', paneAttached
cancel: => @off 'pane:attached', paneAttached
off: => @off 'pane:attached', paneAttached
getFocusedPane: ->
@find('.pane:has(:focus)').view()
+12 -12
Ver Arquivo
@@ -7,7 +7,7 @@ PaneColumn = require './pane-column'
# Public: A container which can contains multiple items to be switched between.
#
# Items can be almost anything however most commonly they're {Editor}s.
# Items can be almost anything however most commonly they're {EditorView}s.
#
# Most packages won't need to use this class, unless you're interested in
# building a package that deals with switching between panes or tiems.
@@ -33,7 +33,8 @@ class Pane extends View
initialize: (args...) ->
if args[0] instanceof telepath.Document
@state = args[0]
@items = _.compact(@state.get('items').map (item) -> deserialize(item))
@items = _.compact @state.get('items').map (item) ->
atom.deserializers.deserialize(item)
else
@items = args
@state = atom.site.createDocument
@@ -45,10 +46,10 @@ class Pane extends View
for itemState in removedValues
@removeItemAtIndex(index, updateState: false)
for itemState, i in insertedValues
@addItem(deserialize(itemState), index + i, updateState: false)
@addItem(atom.deserializers.deserialize(itemState), index + i, updateState: false)
@subscribe @state, 'changed', ({newValues, siteId}) =>
return if site is @state.siteId
return if siteId is @state.siteId
if newValues.activeItemUri
@showItemForUri(newValues.activeItemUri)
@@ -219,12 +220,11 @@ class Pane extends View
return true unless item.shouldPromptToSave?()
uri = item.getUri()
chosen = atom.confirmSync(
"'#{item.getTitle?() ? item.getUri()}' has changes, do you want to save them?"
"Your changes will be lost if you close this item without saving."
["Save", "Cancel", "Don't Save"]
atom.getCurrentWindow()
)
chosen = atom.confirm
message: "'#{item.getTitle?() ? item.getUri()}' has changes, do you want to save them?"
detailedMessage: "Your changes will be lost if you close this item without saving."
buttons: ["Save", "Cancel", "Don't Save"]
switch chosen
when 0 then @saveItem(item, -> true)
when 1 then false
@@ -416,7 +416,7 @@ class Pane extends View
# Private:
copyActiveItem: ->
@activeItem.copy?() ? deserialize(@activeItem.serialize())
@activeItem.copy?() ? atom.deserializers.deserialize(@activeItem.serialize())
# Private:
remove: (selector, keepData) ->
@@ -426,7 +426,7 @@ class Pane extends View
# Private:
beforeRemove: ->
if @is(':has(:focus)')
@getContainer().focusNextPane() or rootView?.focus()
@getContainer().focusNextPane() or atom.rootView?.focus()
else if @isActive()
@getContainer().makeNextPaneActive()
+73 -105
Ver Arquivo
@@ -5,10 +5,9 @@ _ = require 'underscore-plus'
fs = require 'fs-plus'
Q = require 'q'
telepath = require 'telepath'
{Range} = telepath
TextBuffer = require './text-buffer'
EditSession = require './edit-session'
Editor = require './editor'
{Emitter} = require 'emissary'
Directory = require './directory'
Task = require './task'
@@ -19,16 +18,12 @@ Git = require './git'
# Ultimately, a project is a git directory that's been opened. It's a collection
# of directories and files that you can operate on.
module.exports =
class Project
class Project extends telepath.Model
Emitter.includeInto(this)
@acceptsDocuments: true
@version: 1
registerDeserializer(this)
# Private:
@deserialize: (state) -> new Project(state)
@properties
buffers: []
path: null
# Public: Find the local path for the given repository URL.
@pathForRepositoryUrl: (repoUrl) ->
@@ -36,20 +31,39 @@ class Project
repoName = repoName.replace(/\.git$/, '')
path.join(atom.config.get('core.projectHome'), repoName)
rootDirectory: null
editSessions: null
ignoredPathRegexes: null
openers: null
# Private: Called by telepath.
attached: ->
for buffer in @buffers.getValues()
buffer.once 'destroyed', (buffer) => @removeBuffer(buffer)
# Public:
@openers = []
@editors = []
@setPath(@path)
# Private: Called by telepath.
beforePersistence: ->
@destroyUnretainedBuffers()
# Public: Register an opener for project files.
#
# An {Editor} will be used if no openers return a value.
#
# ## Example:
# ```coffeescript
# atom.project.registerOpener (filePath) ->
# if path.extname(filePath) is '.toml'
# return new TomlEditor(filePath)
# ```
#
# * opener: A function to be called when a path is being opened.
registerOpener: (opener) -> @openers.push(opener)
# Public:
# Public: Remove a previously registered opener.
unregisterOpener: (opener) -> _.remove(@openers, opener)
# Private:
destroy: ->
editSession.destroy() for editSession in @getEditSessions()
editor.destroy() for editor in @getEditSessions()
buffer.release() for buffer in @getBuffers()
@destroyRepo()
@@ -59,51 +73,10 @@ class Project
@repo.destroy()
@repo = null
# Public: Establishes a new project at a given path.
#
# path - The {String} name of the path
constructor: (pathOrState) ->
@openers = []
@editSessions = []
@buffers = []
if pathOrState instanceof telepath.Document
@state = pathOrState
if projectPath = @state.remove('path')
@setPath(projectPath)
else
@setPath(@constructor.pathForRepositoryUrl(@state.get('repoUrl')))
@state.get('buffers').each (bufferState) =>
if buffer = deserialize(bufferState, project: this)
@addBuffer(buffer, updateState: false)
else
@state = atom.site.createDocument(deserializer: @constructor.name, version: @constructor.version, buffers: [])
@setPath(pathOrState)
@state.get('buffers').on 'changed', ({index, insertedValues, removedValues, siteId}) =>
return if siteId is @state.siteId
for removedBuffer in removedValues
@removeBufferAtIndex(index, updateState: false)
for insertedBuffer, i in insertedValues
@addBufferAtIndex(deserialize(insertedBuffer, project: this), index + i, updateState: false)
# Private:
serialize: ->
state = @state.clone()
state.set('path', @getPath())
@destroyUnretainedBuffers()
state.set('buffers', buffer.serialize() for buffer in @getBuffers())
state
# Private:
destroyUnretainedBuffers: ->
buffer.destroy() for buffer in @getBuffers() when not buffer.isRetained()
# Public: ?
getState: -> @state
# Public: Returns the {Git} repository if available.
getRepo: -> @repo
@@ -113,6 +86,7 @@ class Project
# Public: Sets the project's fullpath.
setPath: (projectPath) ->
@path = projectPath
@rootDirectory?.off()
@destroyRepo()
@@ -125,12 +99,9 @@ class Project
else
@rootDirectory = null
if originUrl = @repo?.getOriginUrl()
@state.set('repoUrl', originUrl)
@emit "path-changed"
# Public: Returns the name of the root directory.
# Public: Returns the root {Directory} object for this project.
getRootDirectory: ->
@rootDirectory
@@ -173,14 +144,14 @@ class Project
@rootDirectory?.contains(pathToCheck) ? false
# Public: Given a path to a file, this constructs and associates a new
# {EditSession}, showing the file.
# {Editor}, showing the file.
#
# * filePath:
# The {String} path of the file to associate with
# * editSessionOptions:
# Options that you can pass to the {EditSession} constructor
# * options:
# Options that you can pass to the {Editor} constructor
#
# Returns a promise that resolves to an {EditSession}.
# Returns a promise that resolves to an {Editor}.
open: (filePath, options={}) ->
filePath = @resolve(filePath)
resource = null
@@ -200,40 +171,38 @@ class Project
@buildEditSessionForBuffer(@bufferForPathSync(filePath), options)
# Public: Retrieves all {EditSession}s for all open files.
# Public: Retrieves all {Editor}s for all open files.
#
# Returns an {Array} of {EditSession}s.
# Returns an {Array} of {Editor}s.
getEditSessions: ->
new Array(@editSessions...)
new Array(@editors...)
# Public: Add the given {EditSession}.
addEditSession: (editSession) ->
@editSessions.push editSession
@emit 'edit-session-created', editSession
# Public: Add the given {Editor}.
addEditSession: (editor) ->
@editors.push editor
@emit 'editor-created', editor
# Public: Return and removes the given {EditSession}.
removeEditSession: (editSession) ->
_.remove(@editSessions, editSession)
# Public: Return and removes the given {Editor}.
removeEditSession: (editor) ->
_.remove(@editors, editor)
# Private: Retrieves all the {TextBuffer}s in the project; that is, the
# buffers for all open files.
#
# Returns an {Array} of {TextBuffer}s.
getBuffers: ->
new Array(@buffers...)
new Array(@buffers.getValues()...)
isPathModified: (filePath) ->
absoluteFilePath = @resolve(filePath)
existingBuffer = _.find @buffers, (buffer) -> buffer.getPath() == absoluteFilePath
existingBuffer?.isModified()
@findBufferForPath(@resolve(filePath))?.isModified()
findBufferForPath: (filePath) ->
_.find @buffers.getValues(), (buffer) -> buffer.getPath() == filePath
# Private: Only to be used in specs
bufferForPathSync: (filePath) ->
absoluteFilePath = @resolve(filePath)
if filePath
existingBuffer = _.find @buffers, (buffer) -> buffer.getPath() == absoluteFilePath
existingBuffer = @findBufferForPath(absoluteFilePath) if filePath
existingBuffer ? @buildBufferSync(absoluteFilePath)
# Private: Given a file path, this retrieves or creates a new {TextBuffer}.
@@ -246,9 +215,7 @@ class Project
# Returns a promise that resolves to the {TextBuffer}.
bufferForPath: (filePath) ->
absoluteFilePath = @resolve(filePath)
if absoluteFilePath
existingBuffer = _.find @buffers, (buffer) -> buffer.getPath() == absoluteFilePath
existingBuffer = @findBufferForPath(absoluteFilePath) if absoluteFilePath
Q(existingBuffer ? @buildBuffer(absoluteFilePath))
# Private:
@@ -257,9 +224,9 @@ class Project
# Private: DEPRECATED
buildBufferSync: (absoluteFilePath) ->
buffer = new TextBuffer({project: this, filePath: absoluteFilePath})
buffer.loadSync()
buffer = new TextBuffer({filePath: absoluteFilePath})
@addBuffer(buffer)
buffer.loadSync()
buffer
# Private: Given a file path, this sets its {TextBuffer}.
@@ -269,10 +236,11 @@ class Project
#
# Returns a promise that resolves to the {TextBuffer}.
buildBuffer: (absoluteFilePath) ->
buffer = new TextBuffer({project: this, filePath: absoluteFilePath})
buffer.load().then (buffer) =>
@addBuffer(buffer)
buffer
buffer = new TextBuffer({filePath: absoluteFilePath})
@addBuffer(buffer)
buffer.load()
.then((buffer) -> buffer)
.catch(=> @removeBuffer(buffer))
# Private:
addBuffer: (buffer, options={}) ->
@@ -280,9 +248,10 @@ class Project
# Private:
addBufferAtIndex: (buffer, index, options={}) ->
@buffers[index] = buffer
@state.get('buffers').insert(index, buffer.getState()) if options.updateState ? true
buffer = @buffers.insert(index, buffer)
buffer.once 'destroyed', => @removeBuffer(buffer)
@emit 'buffer-created', buffer
buffer
# Private: Removes a {TextBuffer} association from the project.
#
@@ -294,7 +263,6 @@ class Project
# Private:
removeBufferAtIndex: (index, options={}) ->
[buffer] = @buffers.splice(index, 1)
@state.get('buffers')?.remove(index) if options.updateState ? true
buffer?.destroy()
# Public: Performs a search across all the files in the project.
@@ -329,7 +297,7 @@ class Project
task.on 'scan:paths-searched', (numberOfPathsSearched) ->
options.onPathsSearched(numberOfPathsSearched)
for buffer in @buffers when buffer.isModified()
for buffer in @buffers.getValues() when buffer.isModified()
filePath = buffer.getPath()
matches = []
buffer.scan regex, (match) -> matches.push match
@@ -346,7 +314,7 @@ class Project
replace: (regex, replacementText, filePaths, iterator) ->
deferred = Q.defer()
openPaths = (buffer.getPath() for buffer in @buffers)
openPaths = (buffer.getPath() for buffer in @buffers.getValues())
outOfProcessPaths = _.difference(filePaths, openPaths)
inProcessFinished = !openPaths.length
@@ -364,7 +332,7 @@ class Project
task.on 'replace:path-replaced', iterator
for buffer in @buffers
for buffer in @buffers.getValues()
replacements = buffer.replace(regex, replacementText, iterator)
iterator({filePath: buffer.getPath(), replacements}) if replacements
@@ -374,15 +342,15 @@ class Project
deferred.promise
# Private:
buildEditSessionForBuffer: (buffer, editSessionOptions) ->
editSession = new EditSession(_.extend({buffer}, editSessionOptions))
@addEditSession(editSession)
editSession
buildEditSessionForBuffer: (buffer, editorOptions) ->
editor = new Editor(_.extend({buffer}, editorOptions))
@addEditSession(editor)
editor
# Private:
eachEditSession: (callback) ->
callback(editSession) for editSession in @getEditSessions()
@on 'edit-session-created', (editSession) -> callback(editSession)
callback(editor) for editor in @getEditSessions()
@on 'editor-created', (editor) -> callback(editor)
# Private:
eachBuffer: (args...) ->
+33 -36
Ver Arquivo
@@ -5,12 +5,12 @@ Q = require 'q'
_ = require 'underscore-plus'
fs = require 'fs-plus'
telepath = require 'telepath'
Editor = require './editor'
EditorView = require './editor-view'
Pane = require './pane'
PaneColumn = require './pane-column'
PaneRow = require './pane-row'
PaneContainer = require './pane-container'
EditSession = require './edit-session'
Editor = require './editor'
# Public: The container for the entire Atom application.
#
@@ -38,7 +38,7 @@ EditSession = require './edit-session'
#
module.exports =
class RootView extends View
registerDeserializers(this, Pane, PaneRow, PaneColumn, Editor)
atom.deserializers.add(this, Pane, PaneRow, PaneColumn, EditorView)
@version: 1
@@ -47,7 +47,7 @@ class RootView extends View
excludeVcsIgnoredPaths: true
disabledPackages: []
themes: ['atom-dark-ui', 'atom-dark-syntax']
projectHome: path.join(atom.getHomeDirPath(), 'github')
projectHome: path.join(fs.getHomeDirectory(), 'github')
audioBeep: true
@acceptsDocuments: true
@@ -69,7 +69,7 @@ class RootView extends View
if state instanceof telepath.Document
@state = state
panes = deserialize(state.get('panes'))
panes = atom.deserializers.deserialize(state.get('panes'))
else
panes = new PaneContainer
@state = atom.site.createDocument
@@ -85,7 +85,7 @@ class RootView extends View
@subscribe $(window), 'focus', (e) =>
@handleFocus(e) if document.activeElement is document.body
project.on 'path-changed', => @updateTitle()
atom.project.on 'path-changed', => @updateTitle()
@on 'pane-container:active-pane-item-changed', => @updateTitle()
@on 'pane:active-item-title-changed', '.active.pane', => @updateTitle()
@@ -105,12 +105,12 @@ class RootView extends View
@command 'application:zoom', -> ipc.sendChannel('command', 'application:zoom')
@command 'application:bring-all-windows-to-front', -> ipc.sendChannel('command', 'application:bring-all-windows-to-front')
@command 'window:run-package-specs', => ipc.sendChannel('run-package-specs', path.join(project.getPath(), 'spec'))
@command 'window:run-package-specs', => ipc.sendChannel('run-package-specs', path.join(atom.project.getPath(), 'spec'))
@command 'window:increase-font-size', =>
atom.config.set("editor.fontSize", config.get("editor.fontSize") + 1)
atom.config.set("editor.fontSize", atom.config.get("editor.fontSize") + 1)
@command 'window:decrease-font-size', =>
fontSize = config.get "editor.fontSize"
fontSize = atom.config.get "editor.fontSize"
atom.config.set("editor.fontSize", fontSize - 1) if fontSize > 1
@command 'window:focus-next-pane', => @focusNextPane()
@@ -127,9 +127,6 @@ class RootView extends View
@command 'pane:reopen-closed-item', =>
@panes.reopenItem()
if @state.get('fullScreen')
setImmediate => atom.setFullScreen(true)
# Private:
serialize: ->
state = @state.clone()
@@ -169,26 +166,26 @@ class RootView extends View
# * options
# + initialLine: The buffer line number to open to.
#
# Returns a promise that resolves to the {EditSession} for the file URI.
# Returns a promise that resolves to the {Editor} for the file URI.
open: (filePath, options={}) ->
changeFocus = options.changeFocus ? true
filePath = project.resolve(filePath)
filePath = atom.project.resolve(filePath)
initialLine = options.initialLine
activePane = @getActivePane()
editSession = activePane.itemForUri(project.relativize(filePath)) if activePane and filePath
promise = project.open(filePath, {initialLine}) if not editSession
editor = activePane.itemForUri(atom.project.relativize(filePath)) if activePane and filePath
promise = atom.project.open(filePath, {initialLine}) if not editor
Q(editSession ? promise)
.then (editSession) =>
Q(editor ? promise)
.then (editor) =>
if not activePane
activePane = new Pane(editSession)
activePane = new Pane(editor)
@panes.setRoot(activePane)
activePane.showItem(editSession)
activePane.showItem(editor)
activePane.focus() if changeFocus
@trigger "uri-opened"
editSession
editor
.catch (error) ->
console.error(error.stack ? error)
@@ -196,13 +193,13 @@ class RootView extends View
openSync: (uri, {changeFocus, initialLine, pane, split}={}) ->
changeFocus ?= true
pane ?= @getActivePane()
uri = project.relativize(uri)
uri = atom.project.relativize(uri)
if pane
if uri
paneItem = pane.itemForUri(uri) ? project.openSync(uri, {initialLine})
paneItem = pane.itemForUri(uri) ? atom.project.openSync(uri, {initialLine})
else
paneItem = project.openSync()
paneItem = atom.project.openSync()
if split == 'right'
panes = @getPanes()
@@ -215,7 +212,7 @@ class RootView extends View
pane.showItem(paneItem)
else
paneItem = project.openSync(uri, {initialLine})
paneItem = atom.project.openSync(uri, {initialLine})
pane = new Pane(paneItem)
@panes.setRoot(pane)
@@ -224,7 +221,7 @@ class RootView extends View
openSingletonSync: (uri, {changeFocus, initialLine, split}={}) ->
changeFocus ?= true
uri = project.relativize(uri)
uri = atom.project.relativize(uri)
pane = @panes.paneForUri(uri)
if pane
@@ -237,7 +234,7 @@ class RootView extends View
# Public: Updates the application's title, based on whichever file is open.
updateTitle: ->
if projectPath = project.getPath()
if projectPath = atom.project.getPath()
if item = @getActivePaneItem()
@setTitle("#{item.getTitle?() ? 'untitled'} - #{projectPath}")
else
@@ -249,7 +246,7 @@ class RootView extends View
setTitle: (title) ->
document.title = title
# Private: Returns an Array of all of the application's {Editor}s.
# Private: Returns an Array of all of the application's {EditorView}s.
getEditors: ->
@panes.find('.pane > .item-views > .editor').map(-> $(this).view()).toArray()
@@ -259,7 +256,7 @@ class RootView extends View
getModifiedBuffers: ->
modifiedBuffers = []
for pane in @getPanes()
for item in pane.getItems() when item instanceof EditSession
for item in pane.getItems() when item instanceof Editor
modifiedBuffers.push item.buffer if item.buffer.isModified()
modifiedBuffers
@@ -267,7 +264,7 @@ class RootView extends View
#
# Returns an {Array} of {String}s.
getOpenBufferPaths: ->
_.uniq(_.flatten(@getEditors().map (editor) -> editor.getOpenBufferPaths()))
_.uniq(_.flatten(@getEditors().map (editorView) -> editorView.getOpenBufferPaths()))
# Public: Returns the currently focused {Pane}.
getActivePane: ->
@@ -308,23 +305,23 @@ class RootView extends View
indexOfPane: (pane) ->
@panes.indexOfPane(pane)
# Private: Fires a callback on each open {Editor}.
# Private: Fires a callback on each open {EditorView}.
eachEditor: (callback) ->
callback(editor) for editor in @getEditors()
attachedCallback = (e, editor) -> callback(editor)
@on('editor:attached', attachedCallback)
off: => @off('editor:attached', attachedCallback)
# Public: Fires a callback on each open {EditSession}.
# Public: Fires a callback on each open {Editor}.
eachEditSession: (callback) ->
project.eachEditSession(callback)
atom.project.eachEditSession(callback)
# Private: Fires a callback on each open {TextBuffer}.
eachBuffer: (callback) ->
project.eachBuffer(callback)
atom.project.eachBuffer(callback)
# Private: Destroys everything.
remove: ->
editor.remove() for editor in @getEditors()
project?.destroy()
editorView.remove() for editorView in @getEditors()
atom.project?.destroy()
super
+3 -3
Ver Arquivo
@@ -1,5 +1,5 @@
{$, View} = require './space-pen-extensions'
Editor = require './editor'
EditorView = require './editor-view'
fuzzyFilter = require('fuzzaldrin').filter
# Public: Provides a widget for users to make a selection from a list of
@@ -10,7 +10,7 @@ class SelectList extends View
# Private:
@content: ->
@div class: @viewClass(), =>
@subview 'miniEditor', new Editor(mini: true)
@subview 'miniEditor', new EditorView(mini: true)
@div class: 'error-message', outlet: 'error'
@div class: 'loading', outlet: 'loadingArea', =>
@span class: 'loading-message', outlet: 'loading'
@@ -171,7 +171,7 @@ class SelectList extends View
if @previouslyFocusedElement?.isOnDom()
@previouslyFocusedElement.focus()
else
rootView.focus()
atom.rootView.focus()
# Public:
cancelled: ->
+9 -9
Ver Arquivo
@@ -11,12 +11,12 @@ class SelectionView extends View
regions: null
needsRemoval: false
initialize: ({@editor, @selection} = {}) ->
initialize: ({@editorView, @selection} = {}) ->
@regions = []
@selection.on 'screen-range-changed', => @editor.requestDisplayUpdate()
@selection.on 'screen-range-changed', => @editorView.requestDisplayUpdate()
@selection.on 'destroyed', =>
@needsRemoval = true
@editor.requestDisplayUpdate()
@editorView.requestDisplayUpdate()
if @selection.marker.isRemote()
@addClass("site-#{@selection.marker.getOriginSiteId()}")
@@ -26,7 +26,7 @@ class SelectionView extends View
range = @getScreenRange()
@trigger 'selection:changed'
@editor.highlightFoldsContainingBufferRange(@getBufferRange())
@editorView.highlightFoldsContainingBufferRange(@getBufferRange())
return if range.isEmpty()
rowSpan = range.end.row - range.start.row
@@ -40,11 +40,11 @@ class SelectionView extends View
@appendRegion(1, { row: range.end.row, column: 0 }, range.end)
appendRegion: (rows, start, end) ->
{ lineHeight, charWidth } = @editor
css = @editor.pixelPositionForScreenPosition(start)
{ lineHeight, charWidth } = @editorView
css = @editorView.pixelPositionForScreenPosition(start)
css.height = lineHeight * rows
if end
css.width = @editor.pixelPositionForScreenPosition(end).left - css.left
css.width = @editorView.pixelPositionForScreenPosition(end).left - css.left
else
css.right = 0
@@ -57,7 +57,7 @@ class SelectionView extends View
startRow = start.row
endRow = end.row
endRow-- if end.column == 0
@editor.pixelPositionForScreenPosition([((startRow + endRow + 1) / 2), start.column])
@editorView.pixelPositionForScreenPosition([((startRow + endRow + 1) / 2), start.column])
clearRegions: ->
region.remove() for region in @regions
@@ -85,5 +85,5 @@ class SelectionView extends View
@removeClass('highlighted')
remove: ->
@editor.removeSelectionView(this)
@editorView.removeSelectionView(this)
super
+58 -53
Ver Arquivo
@@ -2,27 +2,26 @@
{Emitter} = require 'emissary'
{pick} = require 'underscore-plus'
# Public: Represents a selection in the {EditSession}.
# Public: Represents a selection in the {Editor}.
module.exports =
class Selection
Emitter.includeInto(this)
cursor: null
marker: null
editSession: null
editor: null
initialScreenRange: null
wordwise: false
needsAutoscroll: null
# Private:
constructor: ({@cursor, @marker, @editSession}) ->
constructor: ({@cursor, @marker, @editor}) ->
@cursor.selection = this
@marker.on 'changed', => @screenRangeChanged()
@marker.on 'destroyed', =>
@destroyed = true
@editSession.removeSelection(this)
@emit 'destroyed' unless @editSession.destroyed
@editor.removeSelection(this)
@emit 'destroyed' unless @editor.destroyed
# Private:
destroy: ->
@@ -65,7 +64,7 @@ class Selection
# * options:
# + A hash of options matching those found in {.setBufferRange}
setScreenRange: (screenRange, options) ->
@setBufferRange(@editSession.bufferRangeForScreenRange(screenRange), options)
@setBufferRange(@editor.bufferRangeForScreenRange(screenRange), options)
# Public: Returns the buffer {Range} for the selection.
getBufferRange: ->
@@ -79,12 +78,12 @@ class Selection
# + preserveFolds:
# if `true`, the fold settings are preserved after the selection moves
# + autoscroll:
# if `true`, the {EditSession} scrolls to the new selection
# if `true`, the {Editor} scrolls to the new selection
setBufferRange: (bufferRange, options={}) ->
bufferRange = Range.fromObject(bufferRange)
@needsAutoscroll = options.autoscroll
options.isReversed ?= @isReversed()
@editSession.destroyFoldsIntersectingBufferRange(bufferRange) unless options.preserveFolds
@editor.destroyFoldsIntersectingBufferRange(bufferRange) unless options.preserveFolds
@modifySelection =>
@cursor.needsAutoscroll = false if options.autoscroll?
@marker.setBufferRange(bufferRange, options)
@@ -102,7 +101,7 @@ class Selection
# Public: Returns the text in the selection.
getText: ->
@editSession.buffer.getTextInRange(@getBufferRange())
@editor.buffer.getTextInRange(@getBufferRange())
# Public: Clears the selection, moving the marker to the head.
clear: ->
@@ -132,7 +131,7 @@ class Selection
# * row:
# The line Number to select (default: the row of the cursor)
selectLine: (row=@cursor.getBufferPosition().row) ->
range = @editSession.bufferRangeForBufferRow(row, includeNewline: true)
range = @editor.bufferRangeForBufferRow(row, includeNewline: true)
@setBufferRange(range)
@linewise = true
@wordwise = false
@@ -202,7 +201,7 @@ class Selection
# Public: Selects all the text in the buffer.
selectAll: ->
@setBufferRange(@editSession.buffer.getRange(), autoscroll: false)
@setBufferRange(@editor.buffer.getRange(), autoscroll: false)
# Public: Selects all the text from the current cursor position to the
# beginning of the line.
@@ -247,17 +246,17 @@ class Selection
range = (@getGoalBufferRange() ? @getBufferRange()).copy()
nextRow = range.end.row + 1
for row in [nextRow..@editSession.getLastBufferRow()]
for row in [nextRow..@editor.getLastBufferRow()]
range.start.row = row
range.end.row = row
clippedRange = @editSession.clipBufferRange(range)
clippedRange = @editor.clipBufferRange(range)
if range.isEmpty()
continue if range.end.column > 0 and clippedRange.end.column is 0
else
continue if clippedRange.isEmpty()
@editSession.addSelectionForBufferRange(range, goalBufferRange: range)
@editor.addSelectionForBufferRange(range, goalBufferRange: range)
break
# Public:
@@ -274,14 +273,14 @@ class Selection
for row in [previousRow..0]
range.start.row = row
range.end.row = row
clippedRange = @editSession.clipBufferRange(range)
clippedRange = @editor.clipBufferRange(range)
if range.isEmpty()
continue if range.end.column > 0 and clippedRange.end.column is 0
else
continue if clippedRange.isEmpty()
@editSession.addSelectionForBufferRange(range, goalBufferRange: range)
@editor.addSelectionForBufferRange(range, goalBufferRange: range)
break
# Public: Replaces text at the current selection.
@@ -302,7 +301,7 @@ class Selection
# if `skip`, skips the undo stack for this operation.
insertText: (text, options={}) ->
oldBufferRange = @getBufferRange()
@editSession.destroyFoldsContainingBufferRow(oldBufferRange.end.row)
@editor.destroyFoldsContainingBufferRow(oldBufferRange.end.row)
wasReversed = @isReversed()
@clear()
@cursor.needsAutoscroll = @cursor.isLastCursor()
@@ -310,18 +309,18 @@ class Selection
if options.indentBasis? and not options.autoIndent
text = @normalizeIndents(text, options.indentBasis)
newBufferRange = @editSession.buffer.change(oldBufferRange, text, pick(options, 'undo'))
newBufferRange = @editor.buffer.change(oldBufferRange, text, pick(options, 'undo'))
if options.select
@setBufferRange(newBufferRange, isReversed: wasReversed)
else
@cursor.setBufferPosition(newBufferRange.end, skipAtomicTokens: true) if wasReversed
if options.autoIndent
@editSession.autoIndentBufferRow(row) for row in newBufferRange.getRows()
@editor.autoIndentBufferRow(row) for row in newBufferRange.getRows()
else if options.autoIndentNewline and text == '\n'
@editSession.autoIndentBufferRow(newBufferRange.end.row)
@editor.autoIndentBufferRow(newBufferRange.end.row)
else if options.autoDecreaseIndent and /\S/.test text
@editSession.autoDecreaseIndentForBufferRow(newBufferRange.start.row)
@editor.autoDecreaseIndentForBufferRow(newBufferRange.start.row)
newBufferRange
@@ -336,9 +335,9 @@ class Selection
isCursorInsideExistingLine = /\S/.test(textPrecedingCursor)
lines = text.split('\n')
firstLineIndentLevel = @editSession.indentLevelForLine(lines[0])
firstLineIndentLevel = @editor.indentLevelForLine(lines[0])
if isCursorInsideExistingLine
minimumIndentLevel = @editSession.indentationForBufferRow(@cursor.getBufferRow())
minimumIndentLevel = @editor.indentationForBufferRow(@cursor.getBufferRow())
else
minimumIndentLevel = @cursor.getIndentLevel()
@@ -349,7 +348,7 @@ class Selection
else if line == '' # remove all indentation from empty lines
indentLevel = 0
else
lineIndentLevel = @editSession.indentLevelForLine(lines[i])
lineIndentLevel = @editor.indentLevelForLine(lines[i])
indentLevel = minimumIndentLevel + (lineIndentLevel - indentBasis)
normalizedLines.push(@setIndentationForLine(line, indentLevel))
@@ -361,19 +360,19 @@ class Selection
# * options - A hash with one key,
# + autoIndent:
# If `true`, the indentation is performed appropriately. Otherwise,
# {EditSession.getTabText} is used
# {Editor.getTabText} is used
indent: ({ autoIndent }={})->
{ row, column } = @cursor.getBufferPosition()
if @isEmpty()
@cursor.skipLeadingWhitespace()
desiredIndent = @editSession.suggestedIndentForBufferRow(row)
desiredIndent = @editor.suggestedIndentForBufferRow(row)
delta = desiredIndent - @cursor.getIndentLevel()
if autoIndent and delta > 0
@insertText(@editSession.buildIndentString(delta))
@insertText(@editor.buildIndentString(delta))
else
@insertText(@editSession.getTabText())
@insertText(@editor.getTabText())
else
@indentSelectedRows()
@@ -381,18 +380,18 @@ class Selection
indentSelectedRows: ->
[start, end] = @getBufferRowRange()
for row in [start..end]
@editSession.buffer.insert([row, 0], @editSession.getTabText()) unless @editSession.buffer.lineLengthForRow(row) == 0
@editor.buffer.insert([row, 0], @editor.getTabText()) unless @editor.buffer.lineLengthForRow(row) == 0
# Public: ?
setIndentationForLine: (line, indentLevel) ->
desiredIndentLevel = Math.max(0, indentLevel)
desiredIndentString = @editSession.buildIndentString(desiredIndentLevel)
desiredIndentString = @editor.buildIndentString(desiredIndentLevel)
line.replace(/^[\t ]*/, desiredIndentString)
# Public: Removes the first character before the selection if the selection
# is empty otherwise it deletes the selection.
backspace: ->
@selectLeft() if @isEmpty() and not @editSession.isFoldedAtScreenRow(@cursor.getScreenRow())
@selectLeft() if @isEmpty() and not @editor.isFoldedAtScreenRow(@cursor.getScreenRow())
@deleteSelectedText()
# Public: Removes from the start of the selection to the beginning of the
@@ -414,7 +413,7 @@ class Selection
# selection if the selection is empty.
delete: ->
if @isEmpty()
if @cursor.isAtEndOfLine() and fold = @editSession.largestFoldStartingAtScreenRow(@cursor.getScreenRow() + 1)
if @cursor.isAtEndOfLine() and fold = @editor.largestFoldStartingAtScreenRow(@cursor.getScreenRow() + 1)
@selectToBufferPosition(fold.getBufferRange().end)
else
@selectRight()
@@ -429,9 +428,9 @@ class Selection
# Public: Removes only the selected text.
deleteSelectedText: ->
bufferRange = @getBufferRange()
if bufferRange.isEmpty() and fold = @editSession.largestFoldContainingBufferRow(bufferRange.start.row)
if bufferRange.isEmpty() and fold = @editor.largestFoldContainingBufferRow(bufferRange.start.row)
bufferRange = bufferRange.union(fold.getBufferRange(includeNewline: true))
@editSession.buffer.delete(bufferRange) unless bufferRange.isEmpty()
@editor.buffer.delete(bufferRange) unless bufferRange.isEmpty()
@cursor?.setBufferPosition(bufferRange.start)
# Public: Removes the line at the beginning of the selection if the selection
@@ -440,18 +439,18 @@ class Selection
deleteLine: ->
if @isEmpty()
start = @cursor.getScreenRow()
range = @editSession.bufferRowsForScreenRows(start, start + 1)
range = @editor.bufferRowsForScreenRows(start, start + 1)
if range[1] > range[0]
@editSession.buffer.deleteRows(range[0], range[1] - 1)
@editor.buffer.deleteRows(range[0], range[1] - 1)
else
@editSession.buffer.deleteRow(range[0])
@editor.buffer.deleteRow(range[0])
else
range = @getBufferRange()
start = range.start.row
end = range.end.row
if end isnt @editSession.buffer.getLastRow() and range.end.column is 0
if end isnt @editor.buffer.getLastRow() and range.end.column is 0
end--
@editSession.buffer.deleteRows(start, end)
@editor.buffer.deleteRows(start, end)
# Public: Joins the current line with the one below it.
#
@@ -459,16 +458,16 @@ class Selection
joinLine: ->
selectedRange = @getBufferRange()
if selectedRange.isEmpty()
return if selectedRange.start.row is @editSession.buffer.getLastRow()
return if selectedRange.start.row is @editor.buffer.getLastRow()
else
joinMarker = @editSession.markBufferRange(selectedRange, invalidationStrategy: 'never')
joinMarker = @editor.markBufferRange(selectedRange, invalidationStrategy: 'never')
rowCount = Math.max(1, selectedRange.getRowCount() - 1)
for row in [0...rowCount]
@cursor.setBufferPosition([selectedRange.start.row])
@cursor.moveToEndOfLine()
nextRow = selectedRange.start.row + 1
if nextRow <= @editSession.buffer.getLastRow() and @editSession.buffer.lineLengthForRow(nextRow) > 0
if nextRow <= @editor.buffer.getLastRow() and @editor.buffer.lineLengthForRow(nextRow) > 0
@insertText(' ')
@cursor.moveToEndOfLine()
@modifySelection =>
@@ -484,8 +483,8 @@ class Selection
# Public: Removes one level of indent from the currently selected rows.
outdentSelectedRows: ->
[start, end] = @getBufferRowRange()
buffer = @editSession.buffer
leadingTabRegex = new RegExp("^ {1,#{@editSession.getTabLength()}}|\t")
buffer = @editor.buffer
leadingTabRegex = new RegExp("^ {1,#{@editor.getTabLength()}}|\t")
for row in [start..end]
if matchLength = buffer.lineForRow(row).match(leadingTabRegex)?[0].length
buffer.delete [[row, 0], [row, matchLength]]
@@ -494,7 +493,7 @@ class Selection
# by the relevant grammars.
autoIndentSelectedRows: ->
[start, end] = @getBufferRowRange()
@editSession.autoIndentBufferRows(start, end)
@editor.autoIndentBufferRows(start, end)
# Public: Wraps the selected lines in comments if they aren't currently part
# of a comment.
@@ -503,7 +502,7 @@ class Selection
#
# Returns an Array of the commented {Range}s.
toggleLineComments: ->
@editSession.toggleLineCommentsForBufferRows(@getBufferRowRange()...)
@editor.toggleLineCommentsForBufferRows(@getBufferRowRange()...)
# Public: Cuts the selection until the end of the line.
#
@@ -527,19 +526,19 @@ class Selection
# ?
copy: (maintainPasteboard=false) ->
return if @isEmpty()
text = @editSession.buffer.getTextInRange(@getBufferRange())
text = @editor.buffer.getTextInRange(@getBufferRange())
if maintainPasteboard
[currentText, metadata] = atom.pasteboard.read()
text = currentText + '\n' + text
else
metadata = { indentBasis: @editSession.indentationForBufferRow(@getBufferRange().start.row) }
metadata = { indentBasis: @editor.indentationForBufferRow(@getBufferRange().start.row) }
atom.pasteboard.write(text, metadata)
# Public: Creates a fold containing the current selection.
fold: ->
range = @getBufferRange()
@editSession.createFold(range.start.row, range.end.row)
@editor.createFold(range.start.row, range.end.row)
@cursor.setBufferPosition([range.end.row + 1, 0])
# Public: ?
@@ -592,9 +591,15 @@ class Selection
@setBufferRange(@getBufferRange().union(otherSelection.getBufferRange()), options)
otherSelection.destroy()
# Public: ?
compare: (other) ->
@getBufferRange().compare(other.getBufferRange())
# Public: Compare this selection's buffer range to another selection's buffer
# range.
#
# See {Range.compare} for more details.
#
# * otherSelection:
# A {Selection} to compare with.
compare: (otherSelection) ->
@getBufferRange().compare(otherSelection.getBufferRange())
# Public: Returns true if it was locally created.
isLocal: ->
+1
Ver Arquivo
@@ -1,3 +1,4 @@
# Private: TODO remove once telepath upgrades are complete.
module.exports =
class SiteShim
constructor: (document) ->
+64
Ver Arquivo
@@ -15,4 +15,68 @@ jQuery.cleanData = (elements) ->
view.unsubscribe()
originalCleanData(elements)
tooltipDefaults =
delay:
show: 500
hide: 100
container: 'body'
html: true
placement: 'auto top'
viewportPadding: 2
modifiers =
cmd: ''
ctrl: ''
alt: ''
option: ''
shift: ''
enter: ''
left: ''
right: ''
up: ''
down: ''
replaceKey = (key) ->
if modifiers[key]
modifiers[key]
else if key.length == 1 and key == key.toUpperCase() and key.toUpperCase() != key.toLowerCase()
[modifiers.shift, key.toUpperCase()]
else if key.length == 1
key.toUpperCase()
else
key
replaceModifiersInSingleKeystroke = (keystroke) ->
keys = keystroke.split('-')
keys = _.flatten(replaceKey(key) for key in keys)
keys.join('')
replaceModifiers = (keystroke) ->
keystrokes = keystroke.split(' ')
keystrokes = (replaceModifiersInSingleKeystroke(stroke) for stroke in keystrokes)
keystrokes.join(' ')
getKeystroke = (bindings) ->
if bindings?.length
"<span class=\"keystroke\">#{replaceModifiers(bindings[0].keystroke)}</span>"
else
''
# options from http://getbootstrap.com/javascript/#tooltips
jQuery.fn.setTooltip = (tooltipOptions, {command, commandElement}={}) ->
atom.requireWithGlobals('bootstrap/js/tooltip', {jQuery})
tooltipOptions = {title: tooltipOptions} if _.isString(tooltipOptions)
bindings = if commandElement
atom.keymap.keyBindingsForCommandMatchingElement(command, commandElement)
else
atom.keymap.keyBindingsForCommand(command)
tooltipOptions.title = "#{tooltipOptions.title} #{getKeystroke(bindings)}"
this.tooltip(jQuery.extend({}, tooltipDefaults, tooltipOptions))
jQuery.fn.setTooltip.getKeystroke = getKeystroke
jQuery.fn.setTooltip.replaceModifiers = replaceModifiers
module.exports = spacePen
+1 -1
Ver Arquivo
@@ -11,7 +11,7 @@ module.exports =
class Syntax
Emitter.includeInto(this)
registerDeserializer(this)
atom.deserializers.add(this)
@deserialize: ({grammarOverridesByPath}) ->
syntax = new Syntax()
+1 -1
Ver Arquivo
@@ -86,7 +86,7 @@ class Task
@callback = args.pop() if _.isFunction(args[args.length - 1])
@send({event: 'start', args})
# Public: Send message to the task
# Public: Send message to the task.
#
# * message:
# The message to send
+39 -67
Ver Arquivo
@@ -1,32 +1,28 @@
crypto = require 'crypto'
_ = require 'underscore-plus'
{Emitter, Subscriber} = require 'emissary'
guid = require 'guid'
Q = require 'q'
{P} = require 'scandal'
telepath = require 'telepath'
_ = require 'underscore-plus'
File = require './file'
{Point, Range} = telepath
# Private: Represents the contents of a file.
#
# The `Buffer` is often associated with a {File}. However, this is not always
# the case, as a `Buffer` could be an unsaved chunk of text.
# The `TextBuffer` is often associated with a {File}. However, this is not always
# the case, as a `TextBuffer` could be an unsaved chunk of text.
module.exports =
class TextBuffer
class TextBuffer extends telepath.Model
Emitter.includeInto(this)
Subscriber.includeInto(this)
@acceptsDocuments: true
@version: 2
registerDeserializer(this)
@deserialize: (state, params) ->
buffer = new this(state, params)
buffer.load()
buffer
@properties
text: -> new telepath.String('', replicated: false)
filePath: null
relativePath: null
modifiedWhenLastPersisted: false
digestWhenLastPersisted: null
stoppedChangingDelay: 300
stoppedChangingTimeout: null
@@ -36,34 +32,28 @@ class TextBuffer
file: null
refcount: 0
# Creates a new buffer.
#
# * optionsOrState - An {Object} or a telepath.Document
# + filePath - A {String} representing the file path
constructor: (optionsOrState={}, params={}) ->
if optionsOrState instanceof telepath.Document
{@project} = params
@state = optionsOrState
@id = @state.get('id')
filePath = @state.get('relativePath')
@text = @state.get('text')
@useSerializedText = @state.get('isModified') != false
else
{@project, filePath} = optionsOrState
@text = new telepath.String(initialText ? '', replicated: false)
@id = guid.create().toString()
@state = atom.site.createDocument
id: @id
deserializer: @constructor.name
version: @constructor.version
text: @text
constructor: ->
super
@loadWhenAttached = @getState()?
# Private: Called by telepath.
attached: ->
@loaded = false
@useSerializedText = @modifiedWhenLastPersisted != false
@subscribe @text, 'changed', @handleTextChange
@subscribe @text, 'marker-created', (marker) => @emit 'marker-created', marker
@subscribe @text, 'markers-updated', => @emit 'markers-updated'
@setPath(@project.resolve(filePath)) if @project
@setPath(@filePath)
@load() if @loadWhenAttached
# Private: Called by telepath.
beforePersistence: ->
@modifiedWhenLastPersisted = @isModified()
@digestWhenLastPersisted = @file?.getDigest()
loadSync: ->
@updateCachedDiskContentsSync()
@@ -74,7 +64,7 @@ class TextBuffer
finishLoading: ->
@loaded = true
if @useSerializedText and @state.get('diskContentsDigest') == @file?.getDigest()
if @useSerializedText and @digestWhenLastPersisted is @file?.getDigest()
@emitModifiedStatusChanged(true)
else
@reload()
@@ -92,11 +82,11 @@ class TextBuffer
destroy: ->
unless @destroyed
@cancelStoppedChangingTimeout()
@file?.off()
@unsubscribe()
@destroyed = true
@project?.removeBuffer(this)
@emit 'destroyed'
@emit 'destroyed', this
isRetained: -> @refcount > 0
@@ -109,16 +99,6 @@ class TextBuffer
@destroy() unless @isRetained()
this
serialize: ->
state = @state.clone()
state.set('isModified', @isModified())
state.set('diskContentsDigest', @file.getDigest()) if @file
for marker in state.get('text').getMarkers() when marker.isRemote()
marker.destroy()
state
getState: -> @state
subscribeToFile: ->
@file.on "contents-changed", =>
@conflict = true if @isModified()
@@ -140,19 +120,18 @@ class TextBuffer
@emitModifiedStatusChanged(@isModified())
@file.on "moved", =>
@state.set('relativePath', @project.relativize(@getPath()))
@emit "path-changed", this
### Public ###
# Identifies if the buffer belongs to multiple editors.
#
# For example, if the {Editor} was split.
# For example, if the {EditorView} was split.
#
# Returns a {Boolean}.
hasMultipleEditors: -> @refcount > 1
# Reloads a file in the {EditSession}.
# Reloads a file in the {Editor}.
#
# Sets the buffer's content to the cached disk contents
reload: ->
@@ -183,10 +162,7 @@ class TextBuffer
@file?.getPath()
getUri: ->
@getRelativePath()
getRelativePath: ->
@state.get('relativePath')
atom.project.relativize(@getPath())
# Sets the path for the file.
#
@@ -202,7 +178,6 @@ class TextBuffer
else
@file = null
@state.set('relativePath', @project.relativize(path))
@emit "path-changed", this
# Retrieves the current buffer's file extension.
@@ -411,12 +386,12 @@ class TextBuffer
saveAs: (path) ->
unless path then throw new Error("Can't save buffer with no file path")
@emit 'will-be-saved'
@emit 'will-be-saved', this
@setPath(path)
@cachedDiskContents = @getText()
@file.write(@getText())
@emitModifiedStatusChanged(false)
@emit 'saved'
@emit 'saved', this
# Identifies if the buffer was modified.
#
@@ -653,12 +628,6 @@ class TextBuffer
return match[0][0] != '\t'
undefined
# Checks out the current `HEAD` revision of the file.
checkoutHead: ->
path = @getPath()
return unless path
@project.getRepo()?.checkoutHead(path)
### Internal ###
transact: (fn) -> @text.transact fn
@@ -680,8 +649,11 @@ class TextBuffer
else
text
scheduleModifiedEvents: ->
cancelStoppedChangingTimeout: ->
clearTimeout(@stoppedChangingTimeout) if @stoppedChangingTimeout
scheduleModifiedEvents: ->
@cancelStoppedChangingTimeout()
stoppedChangingCallback = =>
@stoppedChangingTimeout = null
modifiedStatus = @isModified()
@@ -700,7 +672,7 @@ class TextBuffer
console.log row, line, line.length
getDebugSnapshot: ->
lines = ['Buffer:']
lines = ['TextBuffer:']
for row in [0..@getLastRow()]
lines.push "#{row}: #{@lineForRow(row)}"
lines.join('\n')
+18 -15
Ver Arquivo
@@ -8,11 +8,9 @@ Package = require './package'
AtomPackage = require './atom-package'
{$} = require './space-pen-extensions'
# Private: Handles discovering and loading available themes.
###
Themes are a subset of packages
###
#
# Themes are a subset of packages
module.exports =
class ThemeManager
Emitter.includeInto(this)
@@ -56,6 +54,7 @@ class ThemeManager
themeNames = _.clone(themeNames).reverse()
@packageManager.activatePackage(themeName) for themeName in themeNames
@refreshLessCache()
@loadUserStylesheet()
@reloadBaseStylesheets()
@emit('reloaded')
@@ -66,6 +65,10 @@ class ThemeManager
@packageManager.deactivatePackage(pack.name) for pack in @getActiveThemes()
null
# Internal-only:
refreshLessCache: ->
@lessCache?.setImportPaths(@getImportPaths())
# Public: Set the list of enabled themes.
#
# * enabledThemeNames: An {Array} of {String} theme names.
@@ -112,8 +115,8 @@ class ThemeManager
@requireStylesheet(nativeStylesheetPath)
# Internal-only:
stylesheetElementForId: (id) ->
$("""head style[id="#{id}"]""")
stylesheetElementForId: (id, htmlElement=$('html')) ->
htmlElement.find("""head style[id="#{id}"]""")
# Internal-only:
resolveStylesheet: (stylesheetPath) ->
@@ -128,10 +131,10 @@ class ThemeManager
# LESS file in the stylesheets path.
#
# Returns the absolute path to the stylesheet
requireStylesheet: (stylesheetPath) ->
requireStylesheet: (stylesheetPath, ttype = 'bundled', htmlElement) ->
if fullPath = @resolveStylesheet(stylesheetPath)
content = @loadStylesheet(fullPath)
@applyStylesheet(fullPath, content)
@applyStylesheet(fullPath, content, ttype = 'bundled', htmlElement)
else
throw new Error("Could not find a file at path '#{stylesheetPath}'")
@@ -146,9 +149,9 @@ class ThemeManager
# Internal-only:
loadLessStylesheet: (lessStylesheetPath) ->
unless lessCache?
unless @lessCache?
LessCompileCache = require './less-compile-cache'
@lessCache = new LessCompileCache({@resourcePath})
@lessCache = new LessCompileCache({@resourcePath, importPaths: @getImportPaths()})
try
@lessCache.read(lessStylesheetPath)
@@ -170,12 +173,12 @@ class ThemeManager
@stylesheetElementForId(@stringToId(fullPath)).remove()
# Internal-only:
applyStylesheet: (path, text, ttype = 'bundled') ->
styleElement = @stylesheetElementForId(@stringToId(path))
applyStylesheet: (path, text, ttype = 'bundled', htmlElement=$('html')) ->
styleElement = @stylesheetElementForId(@stringToId(path), htmlElement)
if styleElement.length
styleElement.text(text)
else
if $("head style.#{ttype}").length
$("head style.#{ttype}:last").after "<style class='#{ttype}' id='#{@stringToId(path)}'>#{text}</style>"
if htmlElement.find("head style.#{ttype}").length
htmlElement.find("head style.#{ttype}:last").after "<style class='#{ttype}' id='#{@stringToId(path)}'>#{text}</style>"
else
$("head").append "<style class='#{ttype}' id='#{@stringToId(path)}'>#{text}</style>"
htmlElement.find("head").append "<style class='#{ttype}' id='#{@stringToId(path)}'>#{text}</style>"
+5 -5
Ver Arquivo
@@ -21,7 +21,7 @@ class TokenizedBuffer
visible: false
@acceptsDocuments: true
registerDeserializer(this)
atom.deserializers.add(this)
@deserialize: (state) ->
new this(state)
@@ -31,15 +31,15 @@ class TokenizedBuffer
@state = optionsOrState
# TODO: This needs to be made async, but should wait until the new Telepath changes land
@buffer = project.bufferForPathSync(optionsOrState.get('bufferPath'))
@buffer = atom.project.bufferForPathSync(optionsOrState.get('bufferPath'))
else
{ @buffer, tabLength } = optionsOrState
@state = atom.site.createDocument
deserializer: @constructor.name
bufferPath: @buffer.getRelativePath()
bufferPath: @buffer.getPath()
tabLength: tabLength ? atom.config.get('editor.tabLength') ? 2
@subscribe syntax, 'grammar-added grammar-updated', (grammar) =>
@subscribe atom.syntax, 'grammar-added grammar-updated', (grammar) =>
if grammar.injectionSelector?
@resetTokenizedLines() if @hasTokenForSelector(grammar.injectionSelector)
else
@@ -48,7 +48,7 @@ class TokenizedBuffer
@on 'grammar-changed grammar-updated', => @resetTokenizedLines()
@subscribe @buffer, "changed", (e) => @handleBufferChange(e)
@subscribe @buffer, "path-changed", => @state.set('bufferPath', @buffer.getRelativePath())
@subscribe @buffer, "path-changed", => @state.set('bufferPath', @buffer.getPath())
@reloadGrammar()
+2 -2
Ver Arquivo
@@ -5,6 +5,6 @@ require './window'
Atom = require './atom'
window.atom = new Atom()
window.setUpEnvironment('editor')
window.startEditorWindow()
atom.setUpEnvironment('editor')
atom.startEditorWindow()
console.log "Window load time: #{Date.now() - startTime}ms"
+2 -1
Ver Arquivo
@@ -54,7 +54,8 @@ class WindowEventHandler
@subscribeToCommand $(document), 'core:focus-previous', @focusPrevious
@subscribe $(document), 'keydown', atom.keymap.handleKeyEvent
@subscribe $(document), 'keydown', (event) ->
atom.keymap.handleKeyEvent(event)
@subscribe $(document), 'drop', (e) ->
e.preventDefault()
+2 -116
Ver Arquivo
@@ -1,120 +1,6 @@
path = require 'path'
{$} = require './space-pen-extensions'
_ = require 'underscore-plus'
ipc = require 'ipc'
WindowEventHandler = require './window-event-handler'
### Internal ###
windowEventHandler = null
# Schedule the window to be shown and focused on the next tick
#
# This is done in a next tick to prevent a white flicker from occurring
# if called synchronously.
displayWindow = ->
setImmediate ->
atom.show()
atom.focus()
# This method is called in any window needing a general environment, including specs
window.setUpEnvironment = (windowMode) ->
atom.windowMode = windowMode
window.resourcePath = atom.getLoadSettings().resourcePath
atom.initialize()
#TODO remove once all packages use the atom global
window.config = atom.config
window.syntax = atom.syntax
window.pasteboard = atom.pasteboard
window.keymap = atom.keymap
window.site = atom.site
# Set up the default event handlers and menus for a non-editor windows.
#
# This can be used by packages to have a minimum level of keybindings and
# menus available when not using the standard editor window.
#
# This should only be called after setUpEnvironment() has been called.
window.setUpDefaultEvents = ->
windowEventHandler = new WindowEventHandler
atom.keymap.loadBundledKeymaps()
atom.menu.update()
# This method is only called when opening a real application window
window.startEditorWindow = ->
if process.platform is 'darwin'
installAtomCommand()
installApmCommand()
windowEventHandler = new WindowEventHandler
atom.restoreDimensions()
atom.config.load()
atom.config.setDefaults('core', require('./root-view').configDefaults)
atom.config.setDefaults('editor', require('./editor').configDefaults)
atom.keymap.loadBundledKeymaps()
atom.themes.loadBaseStylesheets()
atom.packages.loadPackages()
deserializeEditorWindow()
atom.packages.activate()
atom.keymap.loadUserKeymap()
atom.requireUserInitScript()
atom.menu.update()
$(window).on 'unload', ->
$(document.body).hide()
unloadEditorWindow()
false
displayWindow()
window.unloadEditorWindow = ->
return if not atom.project and not atom.rootView
windowState = atom.getWindowState()
windowState.set('project', atom.project.serialize())
windowState.set('syntax', atom.syntax.serialize())
windowState.set('rootView', atom.rootView.serialize())
atom.packages.deactivatePackages()
windowState.set('packageStates', atom.packages.packageStates)
atom.saveWindowState()
atom.rootView.remove()
atom.project.destroy()
windowEventHandler?.unsubscribe()
window.rootView = null
window.project = null
installAtomCommand = (callback) ->
commandPath = path.join(window.resourcePath, 'atom.sh')
require('./command-installer').install(commandPath, callback)
installApmCommand = (callback) ->
commandPath = path.join(window.resourcePath, 'node_modules', '.bin', 'apm')
require('./command-installer').install(commandPath, callback)
window.deserializeEditorWindow = ->
atom.deserializePackageStates()
atom.deserializeProject()
window.project = atom.project
atom.deserializeRootView()
window.rootView = atom.rootView
window.onerror = ->
atom.openDevTools()
#TODO remove once all packages use the atom global
window.registerDeserializers = (args...) ->
atom.deserializers.add(args...)
window.registerDeserializer = (args...) ->
atom.deserializers.add(args...)
window.registerDeferredDeserializer = (args...) ->
atom.deserializers.addDeferred(args...)
window.unregisterDeserializer = (args...) ->
atom.deserializers.remove(args...)
window.deserialize = (args...) ->
atom.deserializers.deserialize(args...)
window.getDeserializer = (args...) ->
atom.deserializers.get(args...)
window.requireWithGlobals = (args...) ->
atom.requireWithGlobals(args...)
# Public: Measure how long a function takes to run.
#
# * description:
@@ -124,9 +10,9 @@ window.requireWithGlobals = (args...) ->
#
# Returns the value returned by the given function.
window.measure = (description, fn) ->
start = new Date().getTime()
start = Date.now()
value = fn()
result = new Date().getTime() - start
result = Date.now() - start
console.log description, result
value
+1 -1
Ver Arquivo
@@ -8,7 +8,7 @@
-webkit-user-select: none;
position: relative;
z-index: 0;
font-family: Inconsolata, Monaco, Courier;
font-family: Inconsolata, Monaco, Consolas, 'Courier New', Courier;
line-height: 1.3;
}
+1 -1
Ver Arquivo
@@ -22,6 +22,6 @@
}
</script>
</head>
<body tabindex="-1">
<body class="workspace" tabindex="-1">
</body>
</html>
+1 -1
Ver Arquivo
@@ -20,7 +20,7 @@ body {
list-style: none;
}
#HTMLReporter { font-size: 11px; font-family: Monaco, monospace; line-height: 1.6em; color: #333333; }
#HTMLReporter { font-size: 11px; font-family: Monaco, Consolas, monospace; line-height: 1.6em; color: #333333; }
#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
#HTMLReporter .symbolHeader {
+1
Ver Arquivo
@@ -9,6 +9,7 @@ body {
height: 100%;
overflow: hidden;
font-family: @font-family;
font-size: @font-size;
}
h1,
+2 -2
Ver Arquivo
@@ -66,7 +66,7 @@
// Sizes
@font-size: 12px;
@font-size: 13px;
@disclosure-arrow-size: 12px;
@@ -81,4 +81,4 @@
// Other
@font-family: 'Lucida Grande', Arial, sans-serif;
@font-family: 'Lucida Grande', 'Segoe UI', sans-serif;
+3 -3
Ver Arquivo
@@ -30,16 +30,16 @@ module.exports = (grunt) ->
themeMains.push(mainPath) if grunt.file.isFile(mainPath)
importPaths.unshift(stylesheetsDir) if grunt.file.isDir(stylesheetsDir)
grunt.log.writeln("Building LESS cache for #{configuration.join(', ').yellow}")
grunt.verbose.writeln("Building LESS cache for #{configuration.join(', ').yellow}")
lessCache = new LessCache
cacheDir: directory
resourcePath: path.resolve('.')
importPaths: importPaths
for file in @filesSrc
grunt.log.writeln("File #{file.cyan} created in cache.")
grunt.verbose.writeln("File #{file.cyan} created in cache.")
lessCache.readFileSync(file)
for file in themeMains
grunt.log.writeln("File #{file.cyan} created in cache.")
grunt.verbose.writeln("File #{file.cyan} created in cache.")
lessCache.readFileSync(file)
+1 -1
Ver Arquivo
@@ -84,7 +84,7 @@ module.exports = (grunt) ->
for name, version of packageDependencies
do (name, version) ->
tasks.push (callback) ->
grunt.log.writeln("Publishing #{name}@#{version}")
grunt.verbose.writeln("Publishing #{name}@#{version}")
tag = "v#{version}"
packageExists name, token, (error, exists) ->
if error?
+16 -10
Ver Arquivo
@@ -2,6 +2,7 @@ fs = require 'fs'
path = require 'path'
_ = require 'underscore-plus'
async = require 'async'
module.exports = (grunt) ->
@@ -10,7 +11,7 @@ module.exports = (grunt) ->
packageSpecQueue = null
runPackageSpecs = (callback) ->
passed = true
failedPackages = []
rootDir = grunt.config.get('atom.shellAppDir')
appDir = grunt.config.get('atom.appDir')
atomPath = path.join(appDir, 'atom.sh')
@@ -23,10 +24,10 @@ module.exports = (grunt) ->
opts:
cwd: packagePath
env: _.extend({}, process.env, ATOM_PATH: rootDir)
grunt.log.writeln("Launching #{path.basename(packagePath)} specs.")
grunt.verbose.writeln "Launching #{path.basename(packagePath)} specs."
spawn options, (error, results, code) ->
grunt.log.writeln()
passed = passed and not error and code is 0
failedPackages.push path.basename(packagePath) if error
callback()
modulesDirectory = path.resolve('node_modules')
@@ -37,7 +38,7 @@ module.exports = (grunt) ->
packageSpecQueue.push(packagePath)
packageSpecQueue.concurrency = 1
packageSpecQueue.drain = -> callback(null, passed)
packageSpecQueue.drain = -> callback(null, failedPackages)
runCoreSpecs = (callback) ->
contentsDir = grunt.config.get('atom.contentsDir')
@@ -49,15 +50,20 @@ module.exports = (grunt) ->
cmd: appPath
args: ['--test', "--resource-path=#{resourcePath}", "--spec-directory=#{coreSpecsPath}"]
spawn options, (error, results, code) ->
grunt.log.writeln()
packageSpecQueue.concurrency = 2
callback(null, not error and code is 0)
callback(null, error)
grunt.registerTask 'run-specs', 'Run the specs', ->
done = @async()
startTime = Date.now()
async.parallel [runCoreSpecs, runPackageSpecs], (error, results) ->
[coreSpecPassed, packageSpecsPassed] = results
[coreSpecFailed, failedPackages] = results
elapsedTime = Math.round((Date.now() - startTime) / 100) / 10
grunt.log.writeln("Total spec time: #{elapsedTime}s")
done(coreSpecPassed and packageSpecsPassed)
grunt.verbose.writeln("Total spec time: #{elapsedTime}s")
failures = failedPackages
failures.push "atom core" if coreSpecFailed
grunt.log.error("[Error]".red + " #{failures.join(', ')} spec(s) failed") if failures.length > 0
done(!coreSpecFailed and failedPackages.length == 0)
+13 -4
Ver Arquivo
@@ -23,7 +23,7 @@ module.exports = (grunt) ->
catch error
grunt.fatal(error)
grunt.log.writeln("Copied #{source.cyan} to #{destination.cyan}.")
grunt.verbose.writeln("Copied #{source.cyan} to #{destination.cyan}.")
mkdir: (args...) ->
grunt.file.mkdir(args...)
@@ -32,9 +32,18 @@ module.exports = (grunt) ->
grunt.file.delete(args..., force: true) if grunt.file.exists(args...)
spawn: (options, callback) ->
grunt.util.spawn options, (error, results, code) ->
grunt.log.errorlns results.stderr if results.stderr
callback(error, results, code)
childProcess = require 'child_process'
stdout = []
stderr = []
error = null
proc = childProcess.spawn(options.cmd, options.args, options.opts)
proc.stdout.on 'data', (data) -> stdout.push(data.toString())
proc.stderr.on 'data', (data) -> stderr.push(data.toString())
proc.on 'exit', (exitCode, signal) ->
error = new Error(signal) if exitCode != 0
results = {stderr: stderr.join(''), stdout: stdout.join(''), code: exitCode}
grunt.log.error results.stderr if exitCode != 0
callback(error, results, exitCode)
isAtomPackage: (packagePath) ->
try
+6 -6
Ver Arquivo
@@ -17,7 +17,7 @@ module.exports = (grunt) ->
return
spawn {cmd: 'security', args: ['-q', 'find-generic-password', '-ws', 'GitHub API Token']}, (error, result, code) ->
accessToken = result unless error?
accessToken = result.stdout unless error?
callback(error, accessToken)
callAtomShellReposApi = (path, callback) ->
@@ -112,7 +112,7 @@ module.exports = (grunt) ->
# Manually handle redirection so headers would not be sent for S3.
downloadAtomShell(version, response.headers.location, callback)
else if response.statusCode is 200
grunt.log.writeln("Downloading atom-shell version #{version.cyan}")
grunt.verbose.writeln("Downloading atom-shell version #{version.cyan}")
cacheDirectory = getCachePath(version)
rm(cacheDirectory)
mkdir(cacheDirectory)
@@ -146,7 +146,7 @@ module.exports = (grunt) ->
downloadAtomShell version, url, callback
unzipAtomShell = (zipPath, callback) ->
grunt.log.writeln('Unzipping atom-shell')
grunt.verbose.writeln('Unzipping atom-shell')
directoryPath = path.dirname(zipPath)
if process.platform is 'darwin'
@@ -167,7 +167,7 @@ module.exports = (grunt) ->
rebuildNativeModules = (previousVersion, callback) ->
newVersion = getAtomShellVersion()
if newVersion and newVersion isnt previousVersion
grunt.log.writeln("Rebuilding native modules for new atom-shell version #{newVersion.cyan}.")
grunt.verbose.writeln("Rebuilding native modules for new atom-shell version #{newVersion.cyan}.")
cmd = path.join('node_modules', '.bin', 'apm')
cmd += ".cmd" if process.platform is 'win32'
spawn {cmd, args: ['rebuild']}, (error) -> callback(error)
@@ -186,7 +186,7 @@ module.exports = (grunt) ->
currentAtomShellVersion = getAtomShellVersion()
if atomShellVersion isnt currentAtomShellVersion
if isAtomShellVersionCached(atomShellVersion)
grunt.log.writeln("Installing cached atom-shell #{atomShellVersion.cyan}")
grunt.verbose.writeln("Installing cached atom-shell #{atomShellVersion.cyan}")
installAtomShell(atomShellVersion)
rebuildNativeModules(currentAtomShellVersion, done)
else
@@ -198,7 +198,7 @@ module.exports = (grunt) ->
if error?
done(error)
else
grunt.log.writeln("Installing atom-shell #{atomShellVersion.cyan}")
grunt.verbose.writeln("Installing atom-shell #{atomShellVersion.cyan}")
installAtomShell(atomShellVersion)
rebuildNativeModules(currentAtomShellVersion, done)
else
externo
+1 -1
Submodule vendor/apm updated: 687d81f5a1...809d8d42f7