Comparar commits

...

220 Commits

Autor SHA1 Mensagem Data
Max Brunsfeld cffe733641 Fix config event subscription methods
Signed-off-by: Nathan Sobo <nathan@github.com>
2014-12-19 17:28:33 -08:00
Nathan Sobo 3127171b2b Fix Config::isDefault 2014-12-19 16:47:24 -08:00
Nathan Sobo 1d48cb641c Fix Config::save 2014-12-19 16:47:24 -08:00
Nathan Sobo b7b5852863 Store all settings in the scoped property store
There are a few failing specs, but I think they can all be addressed by
having a `source` for all properties and using it to target only the
user settings in various cases.
2014-12-19 16:47:18 -08:00
Max Brunsfeld d104e68342 Revert "Revert "Merge pull request #4631""
This reverts commit dc2a453986.

Conflicts:
	spec/config-spec.coffee
	src/config.coffee
2014-12-19 14:20:27 -08:00
Max Brunsfeld 9640678c29 ⬆️ snippets@0.60.0 2014-12-19 14:19:16 -08:00
Kevin Sawicki 2ce1677aa5 Prepare 0.164 2014-12-19 13:46:19 -08:00
Kevin Sawicki d5c8956d38 ⬆️ release-notes@0.43 2014-12-19 13:27:45 -08:00
Kevin Sawicki d532f506fe ⬆️ package-generator@0.34 2014-12-19 11:53:55 -08:00
Kevin Sawicki 32b414328a ⬆️ release-notes@0.42 2014-12-19 11:49:18 -08:00
Ben Ogle b1697399dc Merge pull request #4698 from atom/bo-fix-load-settings
Pass safeMode and devMode load settings to new windows
2014-12-19 11:36:31 -08:00
Ben Ogle 27eccfaf81 Upgrade notification@0.20.0 2014-12-19 11:35:46 -08:00
Ben Ogle ebbd8101ba Upgrade notifications to provide more user info 2014-12-19 10:45:19 -08:00
Ben Ogle 20504fc7a8 Pull load settings out of the focused window 2014-12-19 10:38:03 -08:00
Ben Ogle 0db1971825 Default devMode and safeMode to false 2014-12-19 10:38:03 -08:00
Ben Ogle 80c828d001 Pass the load settings through so all windows share devMode and safeMode 2014-12-19 10:38:03 -08:00
Ben Ogle e688df57f2 Add atom.inSafeMode() 2014-12-19 10:38:03 -08:00
Max Brunsfeld 0790d33e9d ⬆️ language-html@0.27.0
For handlebars template scope fix
2014-12-19 10:34:14 -08:00
Kevin Sawicki 05820a3044 ⬆️ release-notes@0.41 2014-12-19 09:08:36 -08:00
Kevin Sawicki c4ac602644 ⬆️ language-sass@0.29 2014-12-18 18:23:37 -08:00
Kevin Sawicki 12d4fae91c Fall back to system root for cmd.exe path 2014-12-18 17:58:18 -08:00
Kevin Sawicki 2f334979d5 Add explorer check using SystemRoot path
Closes #4551
2014-12-18 17:20:40 -08:00
Max Brunsfeld d9e414af27 ⬆️ scoped-property-store@0.15.4
For performance improvements
2014-12-18 16:24:20 -08:00
Kevin Sawicki 335c1e215a Prepare 0.163 2014-12-18 11:46:03 -08:00
Max Brunsfeld b9b7646d4b ⬆️ tree-view@0.139.0
For bug fixes
2014-12-18 11:27:23 -08:00
Kevin Sawicki d885fb2d13 Merge pull request #4691 from atom/ks-improve-middle-mouse-paste
Improve middle mouse paste on Linux
2014-12-18 11:23:47 -08:00
Kevin Sawicki f5ae96820a Update spec for new middle mouse paste behavior 2014-12-18 11:04:52 -08:00
Kevin Sawicki 435fee1433 Use skinny arrow 2014-12-18 10:40:44 -08:00
Kevin Sawicki c96f976162 Write to selection clipboard from setTimeout
This is so that in progress transactions aren't written to the
selection clipboard.
2014-12-18 10:40:04 -08:00
Kevin Sawicki 5115540f8e Track middle button mouse down events on Linux 2014-12-18 09:51:32 -08:00
Kevin Sawicki d642553351 Paste selection clipboard after finalizing selections 2014-12-18 09:26:14 -08:00
Kevin Sawicki fa090345a8 ⬆️ release-notes@0.40 2014-12-18 08:58:19 -08:00
Max Brunsfeld 55d291ffde ⬆️ underscore-plus@1.6.6 2014-12-18 08:50:16 -08:00
Max Brunsfeld 48f63926ab ⬆️ underscore-plus@1.6.5 2014-12-17 18:13:48 -08:00
Max Brunsfeld b0501c9cb2 Merge pull request #4672 from atom/mb-optimize-config-events
Avoid firing repeated config events while packages are loaded
2014-12-17 18:11:33 -08:00
Max Brunsfeld 355ab1eb2f ⬆️ underscore-plus@1.6.4 2014-12-17 17:35:07 -08:00
Max Brunsfeld 28ac51d140 Add Config::transact
Use this method to avoid emitting unecessary config events
when activating or deactivating multiple packages
2014-12-17 16:54:47 -08:00
Kevin Sawicki d6210b24d9 ⬆️ status-bar@0.54 2014-12-17 13:01:54 -08:00
Max Brunsfeld b0731afd4c Don't pass keyPath to Config::onDidChange callback
The keyPath field was never used by core or any package, and
for scoped settings, its value was always equal to the keyPath
specified by the caller.
2014-12-17 12:03:46 -08:00
Kevin Sawicki 1c81aa90c0 Add initial SquirrelUpdate specs 2014-12-17 10:47:43 -08:00
Kevin Sawicki bbf6930061 💄 2014-12-17 10:02:34 -08:00
Kevin Sawicki 3d149eb9d1 Only update desktop shortcut if it already exists
Delete the created shortcut if it was previously deleted
after it was first installed.

Closes #4665
2014-12-17 09:55:46 -08:00
Kevin Sawicki 5a8b96b180 Add git as debian dependency
Used by npm to install module dependencies that use git URLs

Closes #4668
2014-12-17 09:11:25 -08:00
Kevin Sawicki 5add777291 Prepare 0.162 2014-12-16 18:35:01 -08:00
Max Brunsfeld f866e69704 ⬆️ scoped-property-store@0.15.3 2014-12-16 18:06:28 -08:00
Ben Ogle b27b4387fc Upgrade solarized-dark-syntax@0.29.0 2014-12-16 16:39:40 -08:00
Ben Ogle 1f850f0af1 Upgrade solarized dark to fix some ruby highlighting 2014-12-16 16:35:14 -08:00
Kevin Sawicki 9f1bbc54de Delete docker image after running 2014-12-16 16:20:46 -08:00
Ben Ogle e7d34d4b83 Upgrade wrap guide to use scoped config 2014-12-16 16:17:36 -08:00
simurai c5a15fb50e Add a note about font-family in syntax themes
#4646
2014-12-17 09:14:21 +09:00
Kevin Sawicki 7a251f5432 Prepare 0.161 2014-12-16 15:44:41 -08:00
Max Brunsfeld dc2a453986 Revert "Merge pull request #4631 from atom/mb-new-config-api"
This reverts commit 5147fb6a8b, reversing
changes made to 9bbbb58084.
2014-12-16 15:27:39 -08:00
Kevin Sawicki fdd55dfd27 Restart Atom with project path from focused window
Closes #4653
2014-12-16 15:26:42 -08:00
Max Brunsfeld 5147fb6a8b Merge pull request #4631 from atom/mb-new-config-api
New config API
2014-12-16 15:22:15 -08:00
Ben Ogle 9bbbb58084 Fix context menu when shadow DOM is enabled
Closes #4623
2014-12-16 15:16:12 -08:00
Kevin Sawicki 9ad080cd31 ⬆️ grammar-selector@0.40 2014-12-16 15:10:33 -08:00
Ben Ogle 509976fa18 Merge pull request #4655 from atom/bo-fix-dragging
Handle the case when the editor is destroyed while dragging
2014-12-16 15:05:58 -08:00
Ben Ogle aad5700418 Merge pull request #4652 from atom/bo-fix-unmount
Properly unmount the component when the shadow DOM is enabled
2014-12-16 14:52:37 -08:00
Ben Ogle 09a0773043 Handle editor destruction when dragging.
Closes #4622
2014-12-16 14:52:07 -08:00
Ben Ogle 0829da53b0 Properly unmount the component when the shadow DOM is enabled. 2014-12-16 14:36:51 -08:00
Kevin Sawicki 2ea92cf0e5 💄 2014-12-16 14:31:52 -08:00
Max Brunsfeld 9a2cc36c6b 💄 2014-12-16 14:27:57 -08:00
Max Brunsfeld 965a6243e1 Remove toBe parens 2014-12-16 14:27:57 -08:00
Max Brunsfeld 503fa30c28 Flesh out deprecation messages for Config::{is,set}Default
Also, simplify the shim in ::isDefault
2014-12-16 14:27:46 -08:00
Max Brunsfeld b8f239cd39 Deprecate Config::isDefault and ::getDefault 2014-12-16 14:00:57 -08:00
Max Brunsfeld 231da60e13 📝 new config APIs 2014-12-16 14:00:57 -08:00
Max Brunsfeld a47719eb53 Fix config priorities 2014-12-16 14:00:57 -08:00
Max Brunsfeld 9f851e55d1 Add Config::unset
Deprecate Config::restoreDefault
2014-12-16 14:00:57 -08:00
Max Brunsfeld ab89776f01 Throw when Config::set is called w/ source and no scope 2014-12-16 14:00:57 -08:00
Max Brunsfeld 2cea51b50e Take 'scope' option in Config::onDidChange
Deprecate passing the scope as an optional first argument
2014-12-16 14:00:57 -08:00
Max Brunsfeld 4e4794f3fd Take 'scope' option in Config::observe
Deprecate using the scope as an optional first argument
2014-12-16 14:00:57 -08:00
Max Brunsfeld ac6fbf100d Fix deprecation in package-manager-spec 2014-12-16 14:00:57 -08:00
Max Brunsfeld 8c8e866a97 Use a schema in all specs for Config::observeUserConfig
Before, values loaded from the config file were set in a
way that allowed any key to be set in the root object.
Now, these values are set in a way that's similar to how
::set works.
2014-12-16 14:00:56 -08:00
Max Brunsfeld f859ad5fc5 Allow null keyPath with options argument in ::get 2014-12-16 14:00:56 -08:00
Nathan Sobo d30cf35a16 Use ‘source’ option rather than internal state in Config spec 2014-12-16 14:00:56 -08:00
Nathan Sobo c35fb90653 Don’t return schema defaults when sources are specified in Config::get 2014-12-16 14:00:56 -08:00
Nathan Sobo 73df017d83 Add a ‘sources’ and ‘excludeSources’ options to Config::get
If the option is supplied, we will only retrieve values from the
specified sources.
2014-12-16 14:00:56 -08:00
Nathan Sobo 0e1ef201c1 Pass source to ::scopedSettingsStore on calls to ::set
Default it to the user’s config if no source is specified.
2014-12-16 14:00:56 -08:00
Nathan Sobo be4d23aa13 Use the user’s config.cson path as the default config source 2014-12-16 14:00:56 -08:00
Nathan Sobo c58606907a Make scope a trailing option to Config::get 2014-12-16 14:00:56 -08:00
Nathan Sobo c489a4662b Make scopeSelector a trailing option to Config::set 2014-12-16 14:00:56 -08:00
Kevin Sawicki 44fceaae20 Prepare 0.160 2014-12-16 13:15:19 -08:00
Kevin Sawicki 1b393e4f48 ⬆️ release-notes@0.39 2014-12-16 12:57:00 -08:00
Kevin Sawicki e84bd28c64 Add --rm flag 2014-12-16 12:38:34 -08:00
Kevin Sawicki bbf199fb60 ⬆️ release-notes@0.38 2014-12-16 11:38:28 -08:00
Ben Ogle 367a4c4bd3 Merge pull request #4630 from atom/bo-better-save-notification
Better save notifications
2014-12-16 11:07:34 -08:00
Kevin Sawicki 7d74f8179b ⬆️ apm@0.116 2014-12-16 10:56:05 -08:00
Kevin Sawicki bcafef385f Merge pull request #4632 from atom/ks-windows-atom-sh
Add atom.sh and apm.sh Windows scripts
2014-12-16 10:00:25 -08:00
Kevin Sawicki 83d5890962 Add missing .. segment 2014-12-16 09:40:16 -08:00
Kevin Sawicki 7ee3ccb43d Move up one more directory 2014-12-16 09:33:16 -08:00
Kevin Sawicki 9126f2e45c Include apm.sh 2014-12-16 09:19:40 -08:00
Kevin Sawicki 89ed95e2ae Add apm sh shim 2014-12-16 09:08:31 -08:00
Ben Ogle 27174b2880 Betta spec description 2014-12-16 09:07:44 -08:00
Kevin Sawicki ed1fbcc8e7 Use forward slashes in sh path 2014-12-16 09:02:09 -08:00
Kevin Sawicki 307ce4dc54 Write atom.sh to atom in bin folder 2014-12-15 17:52:56 -08:00
Kevin Sawicki 0833be4c27 Use correct variable name for sh text 2014-12-15 17:52:21 -08:00
Kevin Sawicki af116b2b8a Install atom.sh shim 2014-12-15 17:50:59 -08:00
Kevin Sawicki 59d582722b Add .sh extension 2014-12-15 17:48:04 -08:00
Kevin Sawicki 9239b95241 Use $0 instead of %~dp0 2014-12-15 17:47:01 -08:00
Kevin Sawicki ab8b5959d3 Add initial Windows atom wrapper script 2014-12-15 17:46:34 -08:00
Ben Ogle 5ff7a286fc 💄 2014-12-15 17:42:38 -08:00
Ben Ogle f199c71fa8 Specs for the eacces error 2014-12-15 17:42:27 -08:00
Ben Ogle 265601cbdb Nof 2014-12-15 17:20:13 -08:00
Ben Ogle 67b39845c8 Add a better error message when a directory cannot be written to.
Closes #4607
2014-12-15 17:19:54 -08:00
Ben Ogle a42505b6ae Handle is a directory error
Closes #4616
2014-12-15 17:08:46 -08:00
Nathan Sobo f026d30426 💄 Call deprecate on Grim local in Config 2014-12-15 17:06:02 -08:00
Max Brunsfeld b4db61a7e7 Fix Config::getSettings 2014-12-15 16:25:19 -08:00
Ben Ogle fad93b8d7e Remove fake catch of Q errors on open
Closes #4628
2014-12-15 15:47:10 -08:00
Max Brunsfeld feb72b38f8 ⬆️ snippets@0.59.0 2014-12-15 14:20:12 -08:00
Max Brunsfeld 23ce2cd1ac ⬆️ scoped-property-store and underscore-plus 2014-12-15 13:06:44 -08:00
Kevin Sawicki ee2509e90f ⬆️ notifications@0.18 2014-12-15 12:14:50 -08:00
Kevin Sawicki ca5e66bbd1 ⬆️ grammar-selector@0.38 2014-12-15 11:21:51 -08:00
Kevin Sawicki 3389555d71 ⬆️ encoding-selector@0.12 2014-12-15 11:19:09 -08:00
Kevin Sawicki 202426a85b Remove unneeded dotAtomPath assignment 2014-12-15 10:42:24 -08:00
Kevin Sawicki a6d68f8683 ⬆️ deprecation-cop@0.20 2014-12-15 10:18:33 -08:00
Kevin Sawicki 6674bfbf97 ⬆️ release-notes@0.37 2014-12-15 10:10:59 -08:00
Kevin Sawicki cd5309e494 ⬆️ incompatible-packages@0.16 2014-12-15 10:07:27 -08:00
Kevin Sawicki 11b2f4a18d ⬆️ image-view@0.44 2014-12-15 10:03:08 -08:00
Kevin Sawicki 88442ccb78 ⬆️ encoding-selector@0.11 2014-12-15 09:59:41 -08:00
Kevin Sawicki c4768cb266 ⬆️ spell-check@0.45 2014-12-15 09:41:17 -08:00
Kevin Sawicki cf772295fb ⬆️ autoflow@0.20 2014-12-15 09:39:36 -08:00
Kevin Sawicki dabedeb065 ⬆️ language-css@0.24 2014-12-15 09:35:35 -08:00
Kevin Sawicki 224e6cb5d4 ⬆️ styleguide@0.36 2014-12-15 09:31:01 -08:00
Kevin Sawicki 3f745e3d67 ⬆️ language-todo@0.15 2014-12-15 09:19:30 -08:00
Ben Ogle d9a5e3c7e1 Upgrade notifications to fix fatal notifications in windows 2014-12-12 16:33:04 -08:00
Ben Ogle d272606408 Upgrade tabs to fix exception 2014-12-12 16:32:37 -08:00
Kevin Sawicki 263567649d Only call log when deprecations exist 2014-12-12 15:37:49 -08:00
Kevin Sawicki c345532864 stdout -> stderr 2014-12-12 14:57:31 -08:00
Kevin Sawicki c0c4e65b5d Warnings to do stderr 2014-12-12 14:54:48 -08:00
Kevin Sawicki b441b3cd6f Remove prefix and suffix from deprecation lines 2014-12-12 14:01:33 -08:00
Kevin Sawicki 3a51228899 Label output 2014-12-12 13:53:52 -08:00
Kevin Sawicki 42d5d0ba87 Log deprecations from apm test output 2014-12-12 13:52:46 -08:00
Kevin Sawicki a1d0635d98 Start logging deprecations on CI 2014-12-12 13:24:10 -08:00
Kevin Sawicki b66e931a99 Only run package specs when project path exists
Closes #4579
2014-12-12 13:18:14 -08:00
Kevin Sawicki 0a7ea419a0 ⬆️ git-utils@2.2 2014-12-12 12:59:42 -08:00
Kevin Sawicki 91770f2885 Add buffer subscriptions to repo's subscriptions
Closes #4570
2014-12-12 12:26:09 -08:00
Kevin Sawicki d4c7fe4b47 ⬆️ keybinding-resolver@0.24 2014-12-12 12:22:29 -08:00
Kevin Sawicki 8b848c1853 Merge pull request #4560 from atom/ks-atom-windows-wrapper
Add better atom.cmd exe wrapper
2014-12-12 12:20:42 -08:00
Kevin Sawicki eef6532b8c atom.exe is now up one more directory 2014-12-12 12:11:38 -08:00
Kevin Sawicki 43de383b14 Use \r\n line endings for cmd shims 2014-12-12 12:11:38 -08:00
Kevin Sawicki 9d3aaad394 atom.exe is now up on more directory 2014-12-12 12:11:38 -08:00
Kevin Sawicki 3cf104444c Add missing resources segment 2014-12-12 12:11:38 -08:00
Kevin Sawicki f91741eec1 Install cli folder to resources directory 2014-12-12 12:11:37 -08:00
Kevin Sawicki 8f77d65aab Add --executed-from as first argument 2014-12-12 12:11:37 -08:00
Kevin Sawicki 3dced04aab Add -t and --test to expected output args 2014-12-12 12:11:37 -08:00
Kevin Sawicki bac9eac1fc Resolve atom path and executed-from in atom.js 2014-12-12 12:11:37 -08:00
Kevin Sawicki d3e53c5ada Use correct path variable 2014-12-12 12:11:37 -08:00
Kevin Sawicki cad8afe78b Use correct resources path 2014-12-12 12:11:37 -08:00
Kevin Sawicki a7f30c63cb Don't bundle atom.sh on Windows 2014-12-12 12:11:37 -08:00
Kevin Sawicki 1d0dd86041 Use new atom.cmd wrapper from installer 2014-12-12 12:11:37 -08:00
Kevin Sawicki 690ece3a9e Remove escaped slashes 2014-12-12 12:11:37 -08:00
Kevin Sawicki 100a1f5764 Parse output flags in atom.cmd 2014-12-12 12:11:37 -08:00
Kevin Sawicki 35f49be82a Pass through arguments 2014-12-12 12:11:36 -08:00
Kevin Sawicki 4225c25ad7 Add initial atom.cmd 2014-12-12 12:11:36 -08:00
Kevin Sawicki 330592e2bd Add atom.cmd 2014-12-12 12:11:36 -08:00
Kevin Sawicki d306876229 Remove disconnect call 2014-12-12 12:11:36 -08:00
Kevin Sawicki 47aa269de5 Exit main process 2014-12-12 12:11:36 -08:00
Kevin Sawicki 2a80762d5b Disconnect spawned process 2014-12-12 12:11:36 -08:00
Kevin Sawicki 42ab14c2cb Add initial atom.exe wrapper 2014-12-12 12:11:36 -08:00
Ben Ogle e83784e141 Merge pull request #4535 from mark-hahn/activateNowAPI
Fixed activateNow when no activation promise
2014-12-12 11:58:26 -08:00
Ben Ogle cedb41f4b0 Merge pull request #4581 from mnquintana/patch-2
Add OS default fonts for Ubuntu (Unity) and Fedora (GNOME 3)
2014-12-12 11:20:16 -08:00
Machiste N. Quintana d873f3d255 Add OS default fonts for Ubuntu (Unity) and Fedora (GNOME 3) 2014-12-12 14:01:57 -05:00
Ben Ogle 2781c24fce Upgrade solarized-dark-syntax to fix some punctuation 2014-12-12 10:52:38 -08:00
Ben Ogle 2a45bd7f69 Upgrade dev live reload to remove deprecations 2014-12-12 10:52:38 -08:00
Ben Ogle f4fab84869 Upgrade metrics to remove deprecations 2014-12-12 10:52:38 -08:00
Kevin Sawicki 204e5a6b46 Prepare 0.159 2014-12-12 09:40:23 -08:00
Kevin Sawicki 9459bd15a2 ⬆️ language-javascript@0.51 2014-12-12 09:23:43 -08:00
Ben Ogle 6cd96c8284 Upgrade deprecation-cop to remove deprecations 2014-12-11 17:27:06 -08:00
Ben Ogle 2ceced2b84 Upgrade notifications@0.16.0 2014-12-11 17:22:07 -08:00
Ben Ogle be78572d78 Upgrade notifications to fix errors with semicolons 2014-12-11 17:07:46 -08:00
Kevin Sawicki 61abda5166 ⬆️ tree-view@0.138 2014-12-11 16:54:24 -08:00
Kevin Sawicki 93f98ec14e ⬆️ styleguide@0.35 2014-12-11 16:39:34 -08:00
Kevin Sawicki d581c41c0e Update spec since { lines now outdent in JS 2014-12-11 16:35:21 -08:00
Nathan Sobo 252bef63bf Merge pull request #4566 from atom/mb-config-cleanup
Clean up config
2014-12-11 17:15:19 -07:00
Kevin Sawicki 9c63a4f517 ⬆️ language-javascript@0.50 2014-12-11 16:07:50 -08:00
Max Brunsfeld e7b0c3e519 Deprecate Config::getSettings
Also, remove support for getting all settings for a scope selector

Signed-off-by: Nathan Sobo <nathan@github.com>
2014-12-11 15:04:55 -08:00
Kevin Sawicki 697ccedbd3 Prepare 0.158 2014-12-11 14:18:09 -08:00
Nathan Sobo 87efc7e1df Only respond to stylesheet changes for mounted components
Refs #4493
2014-12-11 14:55:00 -07:00
Ben Ogle 6a0a694a7b Upgrade notifications to lessen noise 2014-12-11 13:53:05 -08:00
Kevin Sawicki be1f28b3d8 ⬆️ apm@0.114 2014-12-11 13:45:26 -08:00
Kevin Sawicki 32f7c72d28 ⬆️ language-javascript@0.49 2014-12-11 13:07:21 -08:00
Nathan Sobo d51a86e804 ⬆️ markdown-preview for deprecation fixes 2014-12-11 09:03:31 -07:00
Mark Hahn 93e3a5af2a Fixed activateNow when no activation promise 2014-12-10 23:00:14 -08:00
Ben Ogle 278a507653 Merge pull request #4531 from atom/bo-buffered-process-error
Better BufferedProcess error handling
2014-12-10 18:17:09 -08:00
Nathan Sobo 7422f4378e Add property filters to TextEditor::getDecorations methods
This makes it much easier to write tests that inspect the state of
decorations.
2014-12-10 19:11:50 -07:00
Ben Ogle f2ab14656b BufferedProcess::onDidThrowError -> ::onDidThrowError 2014-12-10 18:08:43 -08:00
Ben Ogle 453abf8b90 Update solarized-dark-syntax to fix ruby 2014-12-10 17:54:01 -08:00
Ben Ogle 7866f0819d Upgrade keybinding-resolver to fix the inability to unhide 2014-12-10 17:53:40 -08:00
Kevin Sawicki 921e3c581d ⬆️ keybinding-resolver@0.22 2014-12-10 17:29:17 -08:00
Max Brunsfeld 58aa87438d ⬆️ snippets@0.58.0
For deprecation fixes
2014-12-10 16:45:14 -08:00
Ben Ogle ad73902382 📝 Add docs 2014-12-10 16:27:05 -08:00
Ben Ogle bf63a9715c Add BufferedProcess::onDidThrowError() 2014-12-10 16:26:57 -08:00
Kevin Sawicki 06c52c6873 ⬆️ language-javascript@0.48 2014-12-10 16:21:33 -08:00
Kevin Sawicki 9ac27bc2f8 Grim.logDeprecationWarnings -> Grim.logDeprecations
Closes #4486
2014-12-10 16:05:36 -08:00
Ben Ogle 98caaf0d70 :up_arrow: fuzzy-finder@0.62.0 2014-12-10 15:30:29 -08:00
Ben Ogle a102d1e134 Upgrade styleguide to fix build 2014-12-10 15:14:36 -08:00
Ben Ogle 6caa86fb04 Upgrade styleguide to include colors 2014-12-10 14:54:12 -08:00
Max Brunsfeld b1e0c8132d ⬆️ tree-view@0.137.0 2014-12-10 14:39:05 -08:00
Kevin Sawicki f3947dd6e0 ⬆️ find-and-replace@0.152 2014-12-10 14:06:18 -08:00
Kevin Sawicki 27dbbabe09 Prepare 0.157 2014-12-10 13:34:06 -08:00
Max Brunsfeld 5950110860 ⬆️ status-bar@0.53.0
For new panel-like API
2014-12-10 12:31:46 -08:00
Kevin Sawicki ab5d71e6b5 ⬆️ encoding-selector@0.10 2014-12-10 12:25:43 -08:00
Kevin Sawicki 1ee2839245 📝 Mention config files 2014-12-10 09:22:51 -08:00
Max Brunsfeld a6f31ed791 Pass event to Cursor::onDidChangePosition callbacks 2014-12-09 17:21:03 -08:00
Max Brunsfeld e04b5a74d7 Fix position in Cursor::moveToBeginningOfPreviousParagraph
Also, remove unused parameters to private Cursor methods
2014-12-09 16:59:50 -08:00
Kevin Sawicki 4acf143f45 📝 Mention cuninst is not destructive 2014-12-09 16:50:28 -08:00
Kevin Sawicki 5ad5ce0841 📝 add or above 2014-12-09 16:40:53 -08:00
Kevin Sawicki 31d1ca12c1 📝 Add chocolatey uninstall doc 2014-12-09 16:37:54 -08:00
Kevin Sawicki ace3325db8 Remove chocolatey doc 2014-12-09 16:34:35 -08:00
Kevin Sawicki b718114fc4 📝 Tweak installer wording 2014-12-09 16:34:16 -08:00
Kevin Sawicki 1df8c77f41 Merge pull request #4322 from tsunamistate/upgrade-readme-windows
Upgrade Windows README
2014-12-09 16:31:56 -08:00
Kevin Sawicki 26e867d65e Remove squirrel logging 2014-12-09 16:02:36 -08:00
Nathan Sobo 2688761c29 ⬆️ keybinding-resolver for deprecation fixes 2014-12-09 16:38:51 -07:00
Nathan Sobo b64d9db198 ⬆️ image-view for deprecation fixes 2014-12-09 16:38:51 -07:00
Max Brunsfeld bc5b786bb2 ⬆️ styleguide@0.32.0
To fix build; avoid using devDependencies
2014-12-09 15:15:43 -08:00
Max Brunsfeld 13025c17f1 ⬆️ styleguide@0.31.0
For deprecation fixes
2014-12-09 14:59:40 -08:00
Max Brunsfeld 8b4b5230ab ⬆️ wrap-guide@0.26.0
For deprecation fixes
2014-12-09 14:57:15 -08:00
Kevin Sawicki 7d6d634ceb Prepare 0.156 2014-12-09 14:07:45 -08:00
Aleksandr Kalko 67f4d51774 Fixed link error 2014-11-26 09:44:50 +02:00
Aleksandr Kalko 1bf4db15b2 Updated README WIndows installing section, added Choclatey installation file 2014-11-26 09:42:32 +02:00
48 arquivos alterados com 1309 adições e 579 exclusões
+17 -8
Ver Arquivo
@@ -17,16 +17,25 @@ Atom will automatically update when a new release is available.
### Windows
Install the [Atom chocolatey package](https://chocolatey.org/packages/Atom).
Download the latest [AtomSetup.exe installer](https://github.com/atom/atom/releases/latest).
1. Install [chocolatey](https://chocolatey.org).
2. Close and reopen your command prompt or PowerShell window.
3. Run `cinst Atom`
4. In the future run `cup Atom` to upgrade to the latest release.
Atom will automatically update when a new release is available.
You can also download a `.zip` file from the [releases page](https://github.com/atom/atom/releases/latest).
The Windows version does not currently automatically update so you will need to
manually upgrade to future releases by re-downloading the `.zip` file.
You can also download an `atom-windows.zip` file from the [releases page](https://github.com/atom/atom/releases/latest).
The `.zip` version will not automatically update.
#### Uninstalling Chocolatey Version
The recommended installation of Atom on Windows used to be using [Chocolatey](https://chocolatey.org/packages/Atom/).
This is no longer recommended now that the Atom Windows installer & auto-updater
exists.
To switch from Chocolatey to the new installer:
* Upgrade to Atom 0.155 or above by running `cup Atom`
* Run `cuninst Atom` to uninstall the Chocolatey version of Atom
* This will not delete any of your installed packages or Atom config files.
* Download the latest [AtomSetup.exe installer](https://github.com/atom/atom/releases/latest).
* Double-click the downloaded file to install Atom
### Debian Linux (Ubuntu)
+1 -1
Ver Arquivo
@@ -6,6 +6,6 @@
"url": "https://github.com/atom/atom.git"
},
"dependencies": {
"atom-package-manager": "0.113.0"
"atom-package-manager": "0.116.0"
}
}
+7 -5
Ver Arquivo
@@ -21,7 +21,9 @@ module.exports = (grunt) ->
mkdir appDir
cp 'atom.sh', path.join(appDir, 'atom.sh')
if process.platform isnt 'win32'
cp 'atom.sh', path.join(appDir, 'atom.sh')
cp 'package.json', path.join(appDir, 'package.json')
packageDirectories = []
@@ -149,10 +151,10 @@ module.exports = (grunt) ->
grunt.file.copy(sourcePath, path.resolve(appDir, '..', subDirectory, filename))
if process.platform is 'win32'
# Set up chocolatey ignore and gui files
fs.writeFileSync path.join(appDir, 'apm', 'node_modules', 'atom-package-manager', 'bin', 'node.exe.ignore'), ''
fs.writeFileSync path.join(appDir, 'node_modules', 'symbols-view', 'vendor', 'ctags-win32.exe.ignore'), ''
fs.writeFileSync path.join(shellAppDir, 'atom.exe.gui'), ''
cp path.join('resources', 'win', 'atom.cmd'), path.join(shellAppDir, 'resources', 'cli', 'atom.cmd')
cp path.join('resources', 'win', 'atom.sh'), path.join(shellAppDir, 'resources', 'cli', 'atom.sh')
cp path.join('resources', 'win', 'atom.js'), path.join(shellAppDir, 'resources', 'cli', 'atom.js')
cp path.join('resources', 'win', 'apm.sh'), path.join(shellAppDir, 'resources', 'cli', 'apm.sh')
dependencies = ['compile', 'generate-license:save', 'generate-module-cache', 'compile-packages-slug']
dependencies.push('copy-info-plist') if process.platform is 'darwin'
+9
Ver Arquivo
@@ -11,6 +11,13 @@ module.exports = (grunt) ->
packageSpecQueue = null
logDeprecations = (label, {stderr}={}) ->
if process.env.JANKY_SHA1 and stderr?.indexOf('Calls to deprecated functions') isnt -1
grunt.log.error(label)
stderr = stderr.replace(/^\[.*\] "/g, '')
stderr = stderr.replace(/source: .*$/g, '')
grunt.log.error(stderr)
getAppPath = ->
contentsDir = grunt.config.get('atom.contentsDir')
switch process.platform
@@ -54,6 +61,7 @@ module.exports = (grunt) ->
fs.unlinkSync(path.join(packagePath, 'ci.log'))
failedPackages.push path.basename(packagePath) if error
logDeprecations("#{path.basename(packagePath)} Specs", results)
callback()
modulesDirectory = path.resolve('node_modules')
@@ -87,6 +95,7 @@ module.exports = (grunt) ->
else
# TODO: Restore concurrency on Windows
packageSpecQueue.concurrency = concurrency
logDeprecations('Core Specs', results)
callback(null, error)
+2
Ver Arquivo
@@ -59,6 +59,8 @@ window in dev mode. To open a Dev Mode Atom window run `atom --dev .` in the
terminal, use `cmd-shift-o` or use the _View > Developer > Open in Dev Mode_
menu. When you edit your theme, changes will instantly be reflected!
> Note: It's advised to _not_ specify a `font-family` in your syntax theme because it will override the Font Family field in Atom's settings. If you still like to recommend a font that goes well with your theme, we recommend you do so in your README.
## Creating an Interface Theme
Interface themes **must** provide a `ui-variables.less` file which contains all
+1 -1
Ver Arquivo
@@ -202,7 +202,7 @@
]
'context-menu':
'.overlayer': [
'atom-text-editor, .overlayer': [
{label: 'Undo', command: 'core:undo'}
{label: 'Redo', command: 'core:redo'}
{type: 'separator'}
+1 -1
Ver Arquivo
@@ -160,7 +160,7 @@
]
'context-menu':
'.overlayer': [
'atom-text-editor, .overlayer': [
{label: 'Undo', command: 'core:undo'}
{label: 'Redo', command: 'core:redo'}
{type: 'separator'}
+1 -1
Ver Arquivo
@@ -181,7 +181,7 @@
]
'context-menu':
'.overlayer': [
'atom-text-editor, .overlayer': [
{label: 'Undo', command: 'core:undo'}
{label: 'Redo', command: 'core:redo'}
{type: 'separator'}
+32 -32
Ver Arquivo
@@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "0.155.0",
"version": "0.164.0",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/browser/main.js",
"repository": {
@@ -32,7 +32,7 @@
"fs-plus": "^2.3.2",
"fstream": "0.1.24",
"fuzzaldrin": "^2.1",
"git-utils": "^2.1.5",
"git-utils": "^2.2",
"grim": "0.12.0",
"guid": "0.0.10",
"jasmine-json": "~0.0",
@@ -53,7 +53,7 @@
"reactionary-atom-fork": "^1.0.0",
"runas": "1.0.1",
"scandal": "1.0.3",
"scoped-property-store": "^0.15.0",
"scoped-property-store": "^0.15.4",
"scrollbar-style": "^1.0.2",
"season": "^1.0.2",
"semver": "2.2.1",
@@ -63,7 +63,7 @@
"temp": "0.7.0",
"text-buffer": "^3.8.2",
"theorist": "^1.0.2",
"underscore-plus": "^1.6.1",
"underscore-plus": "^1.6.6",
"vm-compatibility-layer": "0.1.0"
},
"packageDependencies": {
@@ -73,59 +73,59 @@
"atom-light-ui": "0.36.0",
"base16-tomorrow-dark-theme": "0.22.0",
"base16-tomorrow-light-theme": "0.5.0",
"solarized-dark-syntax": "0.25.0",
"solarized-dark-syntax": "0.29.0",
"solarized-light-syntax": "0.13.0",
"archive-view": "0.40.0",
"autocomplete": "0.34.0",
"autoflow": "0.19.0",
"autoflow": "0.20.0",
"autosave": "0.19.0",
"background-tips": "0.18.0",
"bookmarks": "0.31.0",
"bracket-matcher": "0.64.0",
"command-palette": "0.30.0",
"deprecation-cop": "0.18.0",
"dev-live-reload": "0.35.0",
"encoding-selector": "0.9.0",
"deprecation-cop": "0.20.0",
"dev-live-reload": "0.36.0",
"encoding-selector": "0.12.0",
"exception-reporting": "0.21.0",
"find-and-replace": "0.151.0",
"fuzzy-finder": "0.61.0",
"find-and-replace": "0.152.0",
"fuzzy-finder": "0.62.0",
"git-diff": "0.45.0",
"go-to-line": "0.27.0",
"grammar-selector": "0.37.0",
"image-view": "0.42.0",
"incompatible-packages": "0.15.0",
"keybinding-resolver": "0.20.0",
"grammar-selector": "0.40.0",
"image-view": "0.44.0",
"incompatible-packages": "0.16.0",
"keybinding-resolver": "0.24.0",
"link": "0.28.0",
"markdown-preview": "0.111.0",
"metrics": "0.39.0",
"notifications": "0.13.0",
"markdown-preview": "0.112.0",
"metrics": "0.40.0",
"notifications": "0.20.0",
"open-on-github": "0.31.0",
"package-generator": "0.33.0",
"release-notes": "0.36.0",
"package-generator": "0.34.0",
"release-notes": "0.43.0",
"settings-view": "0.161.0",
"snippets": "0.57.0",
"spell-check": "0.44.0",
"status-bar": "0.52.0",
"styleguide": "0.30.0",
"snippets": "0.60.0",
"spell-check": "0.45.0",
"status-bar": "0.54.0",
"styleguide": "0.36.0",
"symbols-view": "0.70.0",
"tabs": "0.57.0",
"tabs": "0.58.0",
"timecop": "0.24.0",
"tree-view": "0.136.0",
"tree-view": "0.139.0",
"update-package-dependencies": "0.7.0",
"welcome": "0.21.0",
"whitespace": "0.27.0",
"wrap-guide": "0.24.0",
"wrap-guide": "0.27.0",
"language-c": "0.33.0",
"language-clojure": "0.9.0",
"language-coffee-script": "0.38.1",
"language-css": "0.23.1",
"language-css": "0.24.0",
"language-gfm": "0.55.0",
"language-git": "0.9.0",
"language-go": "0.19.1",
"language-html": "0.26.1",
"language-html": "0.27.0",
"language-hyperlink": "0.12.2",
"language-java": "0.13.0",
"language-javascript": "0.47.0",
"language-javascript": "0.51.0",
"language-json": "0.10.0",
"language-less": "0.21.0",
"language-make": "0.12.0",
@@ -137,12 +137,12 @@
"language-python": "0.26.0",
"language-ruby": "0.44.0",
"language-ruby-on-rails": "0.18.0",
"language-sass": "0.28.0",
"language-sass": "0.29.0",
"language-shellscript": "0.10.1",
"language-source": "0.8.0",
"language-sql": "0.11.0",
"language-text": "0.6.0",
"language-todo": "0.14.0",
"language-todo": "0.15.0",
"language-toml": "0.14.1",
"language-xml": "0.25.0",
"language-yaml": "0.21.0"
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
Package: <%= name %>
Version: <%= version %>
Depends: gconf2, gconf-service, libgtk2.0-0, libudev0 | libudev1, libgcrypt11, libnotify4, libxtst6, libnss3, python, gvfs-bin, xdg-utils
Depends: git, gconf2, gconf-service, libgtk2.0-0, libudev0 | libudev1, libgcrypt11, libnotify4, libxtst6, libnss3, python, gvfs-bin, xdg-utils
Suggests: libgnome-keyring0, gir1.2-gnomekeyring-1.0
Section: <%= section %>
Priority: optional
+3
Ver Arquivo
@@ -0,0 +1,3 @@
#!/bin/sh
"$0/../../app/apm/node_modules/atom-package-manager/bin/node.exe" "$0/../../app/apm/node_modules/atom-package-manager/lib/cli.js" "$@"
+22
Ver Arquivo
@@ -0,0 +1,22 @@
@echo off
SET EXPECT_OUTPUT=
FOR %%a IN (%*) DO (
IF /I "%%a"=="-f" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="--foreground" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="-h" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="--help" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="-t" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="--test" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="-v" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="--version" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="-w" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="--wait" SET EXPECT_OUTPUT=YES
)
IF "%EXPECT_OUTPUT%"=="YES" (
"%~dp0\..\..\atom.exe" %*
) ELSE (
"%~dp0\..\app\apm\node_modules\atom-package-manager\bin\node.exe" "%~dp0\atom.js" %*
)
+9
Ver Arquivo
@@ -0,0 +1,9 @@
var path = require('path');
var spawn = require('child_process').spawn;
var atomCommandPath = path.resolve(__dirname, '..', '..', 'atom.exe');
var arguments = process.argv.slice(2);
arguments.unshift('--executed-from', process.cwd());
var options = {detached: true, stdio: 'ignore'};
spawn(atomCommandPath, arguments, options);
process.exit(0);
+22
Ver Arquivo
@@ -0,0 +1,22 @@
#!/bin/sh
while getopts ":fhtvw-:" opt; do
case "$opt" in
-)
case "${OPTARG}" in
foreground|help|test|version|wait)
EXPECT_OUTPUT=1
;;
esac
;;
f|h|t|v|w)
EXPECT_OUTPUT=1
;;
esac
done
if [ $EXPECT_OUTPUT ]; then
"$0/../../../atom.exe" "$@"
else
"$0/../../app/apm/node_modules/atom-package-manager/bin/node.exe" "$0/../atom.js" "$@"
fi
+2
Ver Arquivo
@@ -4,7 +4,9 @@ set -e
docker build -t atom-rpm .
docker run \
--rm \
--env JANKY_SHA1="$JANKY_SHA1" \
--env JANKY_BRANCH="$JANKY_BRANCH" \
--env ATOM_ACCESS_TOKEN="$BUILD_ATOM_RPM_ACCESS_TOKEN" \
atom-rpm /atom/script/rpmbuild
docker rmi atom-rpm
+75
Ver Arquivo
@@ -0,0 +1,75 @@
ChildProcess = require 'child_process'
path = require 'path'
BufferedProcess = require '../src/buffered-process'
describe "BufferedProcess", ->
describe "when a bad command is specified", ->
[oldOnError] = []
beforeEach ->
oldOnError = window.onerror
window.onerror = jasmine.createSpy()
afterEach ->
window.onerror = oldOnError
describe "when there is an error handler specified", ->
it "calls the error handler and does not throw an exception", ->
process = new BufferedProcess
command: 'bad-command-nope'
args: ['nothing']
options: {}
errorSpy = jasmine.createSpy().andCallFake (error) -> error.handle()
process.onWillThrowError(errorSpy)
waitsFor -> errorSpy.callCount > 0
runs ->
expect(window.onerror).not.toHaveBeenCalled()
expect(errorSpy).toHaveBeenCalled()
expect(errorSpy.mostRecentCall.args[0].error.message).toContain 'spawn bad-command-nope ENOENT'
describe "when there is not an error handler specified", ->
it "calls the error handler and does not throw an exception", ->
process = new BufferedProcess
command: 'bad-command-nope'
args: ['nothing']
options: {}
waitsFor -> window.onerror.callCount > 0
runs ->
expect(window.onerror).toHaveBeenCalled()
expect(window.onerror.mostRecentCall.args[0]).toContain 'Failed to spawn command `bad-command-nope`'
expect(window.onerror.mostRecentCall.args[4].name).toBe 'BufferedProcessError'
describe "on Windows", ->
originalPlatform = null
beforeEach ->
# Prevent any commands from actually running and affecting the host
originalSpawn = ChildProcess.spawn
spyOn(ChildProcess, 'spawn').andCallFake ->
# Just spawn something that won't actually modify the host
if originalPlatform is 'win32'
originalSpawn('dir')
else
originalSpawn('ls')
originalPlatform = process.platform
Object.defineProperty process, 'platform', value: 'win32'
afterEach ->
Object.defineProperty process, 'platform', value: originalPlatform
describe "when the explorer command is spawned on Windows", ->
it "doesn't quote arguments of the form /root,C...", ->
new BufferedProcess({command: 'explorer.exe', args: ['/root,C:\\foo']})
expect(ChildProcess.spawn.argsForCall[0][1][2]).toBe '"explorer.exe /root,C:\\foo"'
it "spawns the command using a cmd.exe wrapper", ->
new BufferedProcess({command: 'dir'})
expect(path.basename(ChildProcess.spawn.argsForCall[0][0])).toBe 'cmd.exe'
expect(ChildProcess.spawn.argsForCall[0][1][0]).toBe '/s'
expect(ChildProcess.spawn.argsForCall[0][1][1]).toBe '/c'
expect(ChildProcess.spawn.argsForCall[0][1][2]).toBe '"dir"'
+350 -171
Ver Arquivo
@@ -2,9 +2,9 @@ path = require 'path'
temp = require 'temp'
CSON = require 'season'
fs = require 'fs-plus'
Grim = require 'grim'
describe "Config", ->
dotAtomPath = path.join(temp.dir, 'dot-atom-dir')
dotAtomPath = null
beforeEach ->
@@ -35,6 +35,36 @@ describe "Config", ->
atom.config.setDefaults("bar", baz: 7)
expect(atom.config.get("bar.baz")).toEqual {a: 3}
describe "when a 'sources' option is specified", ->
it "only retrieves values from the specified sources", ->
atom.config.set("x.y", 1, scopeSelector: ".foo", source: "a")
atom.config.set("x.y", 2, scopeSelector: ".foo", source: "b")
atom.config.set("x.y", 3, scopeSelector: ".foo", source: "c")
atom.config.setSchema("x.y", type: "integer", default: 4)
expect(atom.config.get("x.y", sources: ["a"], scope: [".foo"])).toBe 1
expect(atom.config.get("x.y", sources: ["b"], scope: [".foo"])).toBe 2
expect(atom.config.get("x.y", sources: ["c"], scope: [".foo"])).toBe 3
# Schema defaults never match a specific source. We could potentially add a special "schema" source.
expect(atom.config.get("x.y", sources: ["x"], scope: [".foo"])).toBeUndefined()
expect(atom.config.get(null, sources: ['a'], scope: [".foo"]).x.y).toBe 1
describe "when an 'excludeSources' option is specified", ->
it "only retrieves values from the specified sources", ->
atom.config.set("x.y", 0)
atom.config.set("x.y", 1, scopeSelector: ".foo", source: "a")
atom.config.set("x.y", 2, scopeSelector: ".foo", source: "b")
atom.config.set("x.y", 3, scopeSelector: ".foo", source: "c")
atom.config.setSchema("x.y", type: "integer", default: 4)
expect(atom.config.get("x.y", excludeSources: ["a"], scope: [".foo"])).toBe 3
expect(atom.config.get("x.y", excludeSources: ["c"], scope: [".foo"])).toBe 2
expect(atom.config.get("x.y", excludeSources: ["b", "c"], scope: [".foo"])).toBe 1
expect(atom.config.get("x.y", excludeSources: ["b", "c", "a"], scope: [".foo"])).toBe 0
expect(atom.config.get("x.y", excludeSources: ["b", "c", "a", atom.config.getUserConfigPath()], scope: [".foo"])).toBe 4
expect(atom.config.get("x.y", excludeSources: [atom.config.getUserConfigPath()])).toBe 4
describe ".set(keyPath, value)", ->
it "allows a key path's value to be written", ->
expect(atom.config.set("foo.bar.baz", 42)).toBe true
@@ -51,7 +81,7 @@ describe "Config", ->
expect(observeHandler).toHaveBeenCalledWith 42
describe "when the value equals the default value", ->
it "does not store the value", ->
it "does not store the value in the user's config", ->
atom.config.setDefaults "foo",
same: 1
changes: 1
@@ -67,60 +97,84 @@ describe "Config", ->
atom.config.set('foo.null', undefined)
atom.config.set('foo.undefined', null)
atom.config.set('foo.sameObject', {b: 2, a: 1})
expect(atom.config.settings.foo).toEqual {changes: 2}
expect(atom.config.get("foo.same", sources: [atom.config.getUserConfigPath()])).toBeUndefined()
expect(atom.config.get("foo.changes", sources: [atom.config.getUserConfigPath()])).toBe 2
atom.config.set('foo.changes', 1)
expect(atom.config.settings.foo).toEqual {}
expect(atom.config.get("foo.changes", sources: [atom.config.getUserConfigPath()])).toBeUndefined()
describe ".getDefault(keyPath)", ->
it "returns a clone of the default value", ->
atom.config.setDefaults("foo", same: 1, changes: 1)
spyOn(Grim, 'deprecate')
expect(atom.config.getDefault('foo.same')).toBe 1
expect(atom.config.getDefault('foo.changes')).toBe 1
expect(Grim.deprecate.callCount).toBe 2
atom.config.set('foo.same', 2)
atom.config.set('foo.changes', 3)
expect(atom.config.getDefault('foo.same')).toBe 1
expect(atom.config.getDefault('foo.changes')).toBe 1
expect(Grim.deprecate.callCount).toBe 4
initialDefaultValue = [1, 2, 3]
atom.config.setDefaults("foo", bar: initialDefaultValue)
expect(atom.config.getDefault('foo.bar')).toEqual initialDefaultValue
expect(atom.config.getDefault('foo.bar')).not.toBe initialDefaultValue
expect(Grim.deprecate.callCount).toBe 6
describe "when scoped settings are used", ->
it "returns the global default when no scoped default set", ->
atom.config.setDefaults("foo", bar: baz: 10)
expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 10
it "returns the scoped default when a scoped default is set", ->
spyOn(Grim, 'deprecate')
expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 10
expect(Grim.deprecate).toHaveBeenCalled()
it "returns the scoped settings not including the user's config file", ->
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: baz: 42)
expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 42
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
spyOn(Grim, 'deprecate')
expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 42
expect(Grim.deprecate.callCount).toBe 1
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 42
expect(Grim.deprecate.callCount).toBe 2
describe ".isDefault(keyPath)", ->
it "returns true when the value of the key path is its default value", ->
atom.config.setDefaults("foo", same: 1, changes: 1)
spyOn(Grim, 'deprecate')
expect(atom.config.isDefault('foo.same')).toBe true
expect(atom.config.isDefault('foo.changes')).toBe true
expect(Grim.deprecate.callCount).toBe 2
atom.config.set('foo.same', 2)
atom.config.set('foo.same', 1)
atom.config.set('foo.changes', 3)
expect(atom.config.isDefault('foo.same')).toBe false
expect(atom.config.isDefault('foo.same')).toBe true
expect(atom.config.isDefault('foo.changes')).toBe false
expect(Grim.deprecate.callCount).toBe 4
describe "when scoped settings are used", ->
it "returns false when a scoped setting was set by the user", ->
spyOn(Grim, 'deprecate')
expect(atom.config.isDefault('.source.coffee', 'foo.bar.baz')).toBe true
expect(Grim.deprecate.callCount).toBe 1
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: baz: 42)
expect(atom.config.isDefault('.source.coffee', 'foo.bar.baz')).toBe true
expect(Grim.deprecate.callCount).toBe 2
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
expect(atom.config.isDefault('.source.coffee', 'foo.bar.baz')).toBe false
expect(Grim.deprecate.callCount).toBe 3
describe ".setDefaults(keyPath)", ->
it "sets a default when the setting's key contains an escaped dot", ->
@@ -151,17 +205,17 @@ describe "Config", ->
atom.config.toggle('foo.a')
expect(atom.config.get('foo.a')).toBe false
describe ".restoreDefault(keyPath)", ->
describe ".unset(keyPath, {scope})", ->
it "sets the value of the key path to its default", ->
atom.config.setDefaults('a', b: 3)
atom.config.set('a.b', 4)
expect(atom.config.get('a.b')).toBe 4
atom.config.restoreDefault('a.b')
atom.config.unset('a.b')
expect(atom.config.get('a.b')).toBe 3
atom.config.set('a.c', 5)
expect(atom.config.get('a.c')).toBe 5
atom.config.restoreDefault('a.c')
atom.config.unset('a.c')
expect(atom.config.get('a.c')).toBeUndefined()
it "calls ::save()", ->
@@ -169,43 +223,61 @@ describe "Config", ->
atom.config.set('a.b', 4)
atom.config.save.reset()
atom.config.restoreDefault('a.c')
atom.config.unset('a.c')
expect(atom.config.save.callCount).toBe 1
describe "when scoped settings are used", ->
it "restores the global default when no scoped default set", ->
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 55
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 55
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 10
atom.config.unset('foo.bar.baz', scopeSelector: '.source.coffee')
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 10
it "restores the scoped default when a scoped default is set", ->
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: baz: 42)
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
atom.config.set('.source.coffee', 'foo.bar.ok', 100)
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 55
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
atom.config.set('foo.bar.ok', 100, scopeSelector: '.source.coffee')
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 55
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 42
expect(atom.config.get(['.source.coffee'], 'foo.bar.ok')).toBe 100
atom.config.unset('foo.bar.baz', scopeSelector: '.source.coffee')
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 42
expect(atom.config.get('foo.bar.ok', scope: ['.source.coffee'])).toBe 100
it "calls ::save()", ->
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: baz: 42)
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
atom.config.save.reset()
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
atom.config.unset('foo.bar.baz', scopeSelector: '.source.coffee')
expect(atom.config.save.callCount).toBe 1
it "allows removing settings for a specific source and scope selector", ->
atom.config.set('foo.bar', 55, scopeSelector: '.source.coffee', source: "source-a")
atom.config.set('foo.bar', 65, scopeSelector: '.source.coffee', source: "source-b")
expect(atom.config.get('foo.bar', scope: ['.source.coffee'])).toBe 65
atom.config.unset('foo.bar', source: "source-b", scopeSelector: ".source.coffee")
expect(atom.config.get('foo.bar', scope: ['.source.coffee', '.string'])).toBe 55
it "allows removing all settings for a specific source", ->
atom.config.set('foo.bar', 55, scopeSelector: '.source.coffee', source: "source-a")
atom.config.set('foo.bar', 65, scopeSelector: '.source.coffee', source: "source-b")
atom.config.set('foo.baz', 65, scopeSelector: '.source.coffee', source: "source-b")
expect(atom.config.get('foo.bar', scope: ['.source.coffee'])).toBe 65
atom.config.unset(null, source: "source-b", scopeSelector: ".source.coffee")
expect(atom.config.get('foo.bar', scope: ['.source.coffee', '.string'])).toBe 55
expect(atom.config.get('foo.baz', scope: ['.source.coffee', '.string'])).toBe undefined
it "does not call ::save or add a scoped property when no value has been set", ->
# see https://github.com/atom/atom/issues/4175
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 10
atom.config.unset('foo.bar.baz', scopeSelector: '.source.coffee')
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 10
expect(atom.config.save).not.toHaveBeenCalled()
@@ -217,14 +289,14 @@ describe "Config", ->
jasmine.unspy atom.config, 'save'
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
atom.config.set('.source.coffee', 'foo.bar.zfoo', 20)
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
atom.config.set('foo.bar.zfoo', 20, scopeSelector: '.source.coffee')
CSON.writeFileSync.reset()
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 55
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 55
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 10
expect(atom.config.get(['.source.coffee'], 'foo.bar.zfoo')).toBe 20
atom.config.unset('foo.bar.baz', scopeSelector: '.source.coffee')
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 10
expect(atom.config.get('foo.bar.zfoo', scope: ['.source.coffee'])).toBe 20
expect(CSON.writeFileSync).toHaveBeenCalled()
properties = CSON.writeFileSync.mostRecentCall.args[1]
expect(properties['.coffee.source']).toEqual
@@ -233,42 +305,41 @@ describe "Config", ->
zfoo: 20
CSON.writeFileSync.reset()
atom.config.restoreDefault('.source.coffee', 'foo.bar.zfoo')
atom.config.unset('foo.bar.zfoo', scopeSelector: '.source.coffee')
expect(CSON.writeFileSync).toHaveBeenCalled()
properties = CSON.writeFileSync.mostRecentCall.args[1]
expect(properties['.coffee.source']).toBeUndefined()
it "does not call ::save when the value is already at the default", ->
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
atom.config.set('foo.bar.baz', 55)
atom.config.save.reset()
atom.config.restoreDefault('.source.coffee', 'foo.bar.ok')
atom.config.unset('foo.bar.ok', scopeSelector: '.source.coffee')
expect(atom.config.save).not.toHaveBeenCalled()
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 55
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 55
it "deprecates passing a scope selector as the first argument", ->
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee')
spyOn(Grim, 'deprecate')
atom.config.unset('.source.coffee', 'foo.bar.baz')
expect(Grim.deprecate).toHaveBeenCalled()
expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 10
describe ".getSettings()", ->
it "returns all settings including defaults", ->
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.set("foo.ok", 12)
jasmine.snapshotDeprecations()
expect(atom.config.getSettings().foo).toEqual
ok: 12
bar:
baz: 10
describe "when scoped settings are used", ->
it "returns all the scoped settings including all the defaults", ->
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.set("foo.ok", 12)
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: baz: 42)
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: omg: 'omg')
expect(atom.config.getSettings(".source.coffee").foo).toEqual
ok: 12
bar:
baz: 42
omg: 'omg'
jasmine.restoreDeprecationsSnapshot()
describe ".pushAtKeyPath(keyPath, value)", ->
it "pushes the given value to the array at the key path and updates observers", ->
@@ -333,56 +404,37 @@ describe "Config", ->
spyOn(CSON, 'writeFileSync')
jasmine.unspy atom.config, 'save'
describe "when ~/.atom/config.json exists", ->
it "writes any non-default properties to ~/.atom/config.json", ->
atom.config.configFilePath = path.join(atom.config.configDirPath, "atom.config.json")
atom.config.set("a.b.c", 1)
atom.config.set("a.b.d", 2)
atom.config.set("x.y.z", 3)
atom.config.setDefaults("a.b", e: 4, f: 5)
it "writes properties from the user config path source to the user config path", ->
atom.config.configFilePath = "/fake/config/path"
atom.config.set("a.b.c", 1)
atom.config.set("a.b.d", 2)
atom.config.set("x.y.z", 3)
atom.config.set("x.y.q", 3, source: "/not/user/config")
atom.config.set('foo.bar', 'ruby', scopeSelector: '.source.ruby')
atom.config.set('foo.omg', 'wow', scopeSelector: '.source.ruby')
atom.config.set('foo.bar', 'coffee', scopeSelector: '.source.coffee')
CSON.writeFileSync.reset()
atom.config.save()
atom.config.setDefaults("a.b", e: 4, f: 5)
expect(CSON.writeFileSync.argsForCall[0][0]).toBe(path.join(atom.config.configDirPath, "atom.config.json"))
writtenConfig = CSON.writeFileSync.argsForCall[0][1]
expect(writtenConfig).toEqual global: atom.config.settings
CSON.writeFileSync.reset()
atom.config.save()
describe "when ~/.atom/config.json doesn't exist", ->
it "writes any non-default properties to ~/.atom/config.cson", ->
atom.config.configFilePath = path.join(atom.config.configDirPath, "atom.config.cson")
atom.config.set("a.b.c", 1)
atom.config.set("a.b.d", 2)
atom.config.set("x.y.z", 3)
atom.config.setDefaults("a.b", e: 4, f: 5)
CSON.writeFileSync.reset()
atom.config.save()
expect(CSON.writeFileSync.argsForCall[0][0]).toBe(path.join(atom.config.configDirPath, "atom.config.cson"))
writtenConfig = CSON.writeFileSync.argsForCall[0][1]
expect(writtenConfig).toEqual global: atom.config.settings
describe "when scoped settings are defined", ->
it 'writes out explicitly set config settings', ->
atom.config.set('.source.ruby', 'foo.bar', 'ruby')
atom.config.set('.source.ruby', 'foo.omg', 'wow')
atom.config.set('.source.coffee', 'foo.bar', 'coffee')
CSON.writeFileSync.reset()
atom.config.save()
writtenConfig = CSON.writeFileSync.argsForCall[0][1]
expect(writtenConfig).toEqualJson
global:
atom.config.settings
'.ruby.source':
foo:
bar: 'ruby'
omg: 'wow'
'.coffee.source':
foo:
bar: 'coffee'
expect(CSON.writeFileSync.argsForCall[0][0]).toBe atom.config.getUserConfigPath()
writtenConfig = CSON.writeFileSync.argsForCall[0][1]
global.debug = true
expect(writtenConfig).toEqual
'global':
a: b:
c: 1
d: 2
x: y: z: 3
'.ruby.source':
foo:
bar: 'ruby'
omg: 'wow'
'.coffee.source':
foo:
bar: 'coffee'
describe ".setDefaults(keyPath, defaults)", ->
it "assigns any previously-unassigned keys to the object at the key path", ->
@@ -418,17 +470,26 @@ describe "Config", ->
it "fires the callback every time the observed value changes", ->
observeHandler.reset() # clear the initial call
atom.config.set('foo.bar.baz', "value 2")
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1', keyPath: 'foo.bar.baz'})
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1'})
observeHandler.reset()
atom.config.set('foo.bar.baz', "value 1")
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2', keyPath: 'foo.bar.baz'})
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2'})
observeHandler.reset()
atom.config.set('foo.bar', {baz: "value 3"})
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 3', oldValue: 'value 1'})
observeHandler.reset()
atom.config.set('foo.bar', null)
expect(observeHandler).toHaveBeenCalledWith({newValue: undefined, oldValue: 'value 3'})
observeHandler.reset()
describe 'when a keyPath is not specified', ->
beforeEach ->
observeHandler = jasmine.createSpy("observeHandler")
atom.config.set("foo.bar.baz", "value 1")
observeSubscription = atom.config.onDidChange observeHandler
atom.config.set("foo", bar: baz: "value 1")
observeSubscription = atom.config.onDidChange(observeHandler)
it "does not fire the given callback initially", ->
expect(observeHandler).not.toHaveBeenCalled()
@@ -436,15 +497,22 @@ describe "Config", ->
it "fires the callback every time any value changes", ->
observeHandler.reset() # clear the initial call
atom.config.set('foo.bar.baz', "value 2")
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1', keyPath: 'foo.bar.baz'})
expect(observeHandler).toHaveBeenCalled()
expect(observeHandler.mostRecentCall.args[0].newValue.foo.bar.baz).toBe("value 2")
expect(observeHandler.mostRecentCall.args[0].oldValue.foo.bar.baz).toBe("value 1")
observeHandler.reset()
atom.config.set('foo.bar.baz', "value 1")
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2', keyPath: 'foo.bar.baz'})
expect(observeHandler).toHaveBeenCalled()
expect(observeHandler.mostRecentCall.args[0].newValue.foo.bar.baz).toBe("value 1")
expect(observeHandler.mostRecentCall.args[0].oldValue.foo.bar.baz).toBe("value 2")
observeHandler.reset()
atom.config.set('foo.bar.int', 1)
expect(observeHandler).toHaveBeenCalledWith({newValue: 1, oldValue: undefined, keyPath: 'foo.bar.int'})
expect(observeHandler).toHaveBeenCalled()
expect(observeHandler.mostRecentCall.args[0].newValue.foo.bar.int).toBe(1)
expect(observeHandler.mostRecentCall.args[0].oldValue.foo.bar.int).toBe(undefined)
describe ".observe(keyPath)", ->
[observeHandler, observeSubscription] = []
@@ -452,7 +520,7 @@ describe "Config", ->
beforeEach ->
observeHandler = jasmine.createSpy("observeHandler")
atom.config.set("foo.bar.baz", "value 1")
observeSubscription = 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")
@@ -465,6 +533,25 @@ describe "Config", ->
atom.config.set('foo.bar.baz', "value 1")
expect(observeHandler).toHaveBeenCalledWith("value 1")
observeHandler.reset()
atom.config.set('foo.bar', {baz: "value 3"})
expect(observeHandler).toHaveBeenCalledWith("value 3")
observeHandler.reset()
atom.config.set('foo.bar', null)
expect(observeHandler).toHaveBeenCalledWith(undefined)
observeHandler.reset()
atom.config.set('foo.bar.baz.quux', "value 4")
expect(observeHandler).toHaveBeenCalledWith({quux: "value 4"})
atom.config.set('foo.bar.baz.buzz', "value 5")
expect(observeHandler).toHaveBeenCalledWith({quux: "value 4", buzz: "value 5"})
observeHandler.reset()
atom.config.loadUserConfig()
expect(observeHandler).toHaveBeenCalledWith(undefined)
it "fires the callback when the observed value is deleted", ->
observeHandler.reset() # clear the initial call
@@ -494,6 +581,51 @@ describe "Config", ->
atom.config.set('foo.bar.baz', "value 10")
expect(bazCatHandler).not.toHaveBeenCalled()
describe "observing scoped settings", ->
otherHandler = null
beforeEach ->
observeSubscription.dispose()
otherHandler = jasmine.createSpy('otherHandler')
it "allows settings to be observed in a specific scope", ->
atom.config.observe("foo.bar.baz", scope: [".some.scope"], observeHandler)
atom.config.observe("foo.bar.baz", scope: [".another.scope"], otherHandler)
atom.config.set('foo.bar.baz', "value 2", scopeSelector: ".some")
expect(observeHandler).toHaveBeenCalledWith("value 2")
expect(otherHandler).not.toHaveBeenCalledWith("value 2")
it "deprecates using a scope descriptor as the first argument", ->
spyOn(Grim, 'deprecate')
atom.config.observe([".some.scope"], "foo.bar.baz", observeHandler)
atom.config.observe([".another.scope"], "foo.bar.baz", otherHandler)
expect(Grim.deprecate).toHaveBeenCalled()
atom.config.set('foo.bar.baz', "value 2", scopeSelector: ".some")
expect(observeHandler).toHaveBeenCalledWith("value 2")
expect(otherHandler).not.toHaveBeenCalledWith("value 2")
describe ".transact(callback)", ->
changeSpy = null
beforeEach ->
changeSpy = jasmine.createSpy('onDidChange callback')
atom.config.onDidChange("foo.bar.baz", changeSpy)
it "allows only one change event for the duration of the given callback", ->
atom.config.transact ->
atom.config.set("foo.bar.baz", 1)
atom.config.set("foo.bar.baz", 2)
atom.config.set("foo.bar.baz", 3)
expect(changeSpy.callCount).toBe(1)
expect(changeSpy.argsForCall[0][0]).toEqual(newValue: 3, oldValue: undefined)
it "does not emit an event if no changes occur while paused", ->
atom.config.transact ->
expect(changeSpy).not.toHaveBeenCalled()
describe ".initializeConfigDirectory()", ->
beforeEach ->
if fs.existsSync(dotAtomPath)
@@ -526,6 +658,15 @@ describe "Config", ->
atom.config.configDirPath = dotAtomPath
atom.config.configFilePath = path.join(atom.config.configDirPath, "atom.config.cson")
expect(fs.existsSync(atom.config.configDirPath)).toBeFalsy()
atom.config.setSchema 'foo',
type: 'object'
properties:
bar:
type: 'string'
default: 'def'
int:
type: 'integer'
default: 12
afterEach ->
fs.removeSync(dotAtomPath)
@@ -545,7 +686,7 @@ describe "Config", ->
it "updates the config data based on the file contents", ->
expect(atom.config.get("foo.bar")).toBe 'baz'
expect(atom.config.get(['.source.ruby'], "foo.bar")).toBe 'more-specific'
expect(atom.config.get("foo.bar", scope: ['.source.ruby'])).toBe 'more-specific'
describe "when the config file contains valid cson", ->
beforeEach ->
@@ -583,43 +724,42 @@ describe "Config", ->
expect(fs.existsSync(atom.config.configFilePath)).toBe true
expect(CSON.readFileSync(atom.config.configFilePath)).toEqual {}
describe "when a schema is specified", ->
describe "when the config file contains values that do not adhere to the schema", ->
warnSpy = null
beforeEach ->
schema =
type: 'object'
properties:
bar:
type: 'string'
default: 'def'
int:
type: 'integer'
default: 12
warnSpy = spyOn console, 'warn'
fs.writeFileSync atom.config.configFilePath, """
foo:
bar: 'baz'
int: 'bad value'
"""
atom.config.loadUserConfig()
atom.config.setSchema('foo', schema)
it "updates the only the settings that have values matching the schema", ->
expect(atom.config.get("foo.bar")).toBe 'baz'
expect(atom.config.get("foo.int")).toBe 12
describe "when the config file contains values that do not adhere to the schema", ->
warnSpy = null
beforeEach ->
warnSpy = spyOn console, 'warn'
fs.writeFileSync atom.config.configFilePath, """
foo:
bar: 'baz'
int: 'bad value'
"""
atom.config.loadUserConfig()
it "updates the only the settings that have values matching the schema", ->
expect(atom.config.get("foo.bar")).toBe 'baz'
expect(atom.config.get("foo.int")).toBe 12
expect(warnSpy).toHaveBeenCalled()
expect(warnSpy.mostRecentCall.args[0]).toContain "'foo.int' could not be set"
expect(warnSpy).toHaveBeenCalled()
expect(warnSpy.mostRecentCall.args[0]).toContain "foo.int"
describe ".observeUserConfig()", ->
updatedHandler = null
beforeEach ->
atom.config.setDefaults('foo', bar: 'def')
atom.config.setSchema 'foo',
type: 'object'
properties:
bar:
type: 'string'
default: 'def'
baz:
type: 'string'
scoped:
type: 'boolean'
int:
type: 'integer'
default: 12
atom.config.configDirPath = dotAtomPath
atom.config.configFilePath = path.join(atom.config.configDirPath, "atom.config.cson")
expect(fs.existsSync(atom.config.configDirPath)).toBeFalsy()
@@ -652,32 +792,38 @@ describe "Config", ->
it "does not fire a change event for paths that did not change", ->
atom.config.onDidChange 'foo.bar', noChangeSpy = jasmine.createSpy()
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: 'baz', omg: 'ok'}")
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: 'baz', baz: 'ok'}")
waitsFor 'update event', -> updatedHandler.callCount > 0
runs ->
expect(noChangeSpy).not.toHaveBeenCalled()
expect(atom.config.get('foo.bar')).toBe 'baz'
expect(atom.config.get('foo.omg')).toBe 'ok'
expect(atom.config.get('foo.baz')).toBe 'ok'
describe 'when the default value is a complex value', ->
beforeEach ->
atom.config.setSchema 'foo.bar',
type: 'array'
items:
type: 'string'
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: ['baz', 'ok']}")
waitsFor 'update event', -> updatedHandler.callCount > 0
runs -> updatedHandler.reset()
it "does not fire a change event for paths that did not change", ->
atom.config.onDidChange 'foo.bar', noChangeSpy = jasmine.createSpy()
noChangeSpy = jasmine.createSpy()
atom.config.onDidChange('foo.bar', noChangeSpy)
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: ['baz', 'ok'], omg: 'another'}")
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: ['baz', 'ok'], baz: 'another'}")
waitsFor 'update event', -> updatedHandler.callCount > 0
runs ->
expect(noChangeSpy).not.toHaveBeenCalled()
expect(atom.config.get('foo.bar')).toEqual ['baz', 'ok']
expect(atom.config.get('foo.omg')).toBe 'another'
expect(atom.config.get('foo.baz')).toBe 'another'
describe 'when scoped settings are used', ->
it "fires a change event for scoped settings that are removed", ->
atom.config.onDidChange ['.source.ruby'], 'foo.scoped', scopedSpy = jasmine.createSpy()
scopedSpy = jasmine.createSpy()
atom.config.onDidChange('foo.scoped', scope: ['.source.ruby'], scopedSpy)
fs.writeFileSync atom.config.configFilePath, """
global:
@@ -687,10 +833,11 @@ describe "Config", ->
waitsFor 'update event', -> updatedHandler.callCount > 0
runs ->
expect(scopedSpy).toHaveBeenCalled()
expect(atom.config.get(['.source.ruby'], 'foo.scoped')).toBe false
expect(atom.config.get('foo.scoped', scope: ['.source.ruby'])).toBe false
it "does not fire a change event for paths that did not change", ->
atom.config.onDidChange ['.source.ruby'], 'foo.scoped', noChangeSpy = jasmine.createSpy()
noChangeSpy = jasmine.createSpy()
atom.config.onDidChange('foo.scoped', scope: ['.source.ruby'], noChangeSpy)
fs.writeFileSync atom.config.configFilePath, """
global:
@@ -703,8 +850,8 @@ describe "Config", ->
waitsFor 'update event', -> updatedHandler.callCount > 0
runs ->
expect(noChangeSpy).not.toHaveBeenCalled()
expect(atom.config.get(['.source.ruby'], 'foo.bar')).toBe 'baz'
expect(atom.config.get(['.source.ruby'], 'foo.scoped')).toBe true
expect(atom.config.get('foo.bar', scope: ['.source.ruby'])).toBe 'baz'
expect(atom.config.get('foo.scoped', scope: ['.source.ruby'])).toBe true
describe "when the config file changes to omit a setting with a default", ->
it "resets the setting back to the default", ->
@@ -1107,8 +1254,8 @@ describe "Config", ->
it 'it respects the scoped defaults', ->
expect(atom.config.get('foo.bar.str')).toBe 'ok'
expect(atom.config.get(['.source.js'], 'foo.bar.str')).toBe 'omg'
expect(atom.config.get(['.source.coffee'], 'foo.bar.str')).toBe 'ok'
expect(atom.config.get('foo.bar.str', scope: ['.source.js'])).toBe 'omg'
expect(atom.config.get('foo.bar.str', scope: ['.source.coffee'])).toBe 'ok'
describe "scoped settings", ->
describe ".get(scopeDescriptor, keyPath)", ->
@@ -1117,29 +1264,29 @@ describe "Config", ->
atom.config.addScopedSettings("config", ".source .string.quoted.double", foo: bar: baz: 22)
atom.config.addScopedSettings("config", ".source", foo: bar: baz: 11)
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
expect(atom.config.get([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBe 22
expect(atom.config.get([".source.js", ".variable.assignment.js"], "foo.bar.baz")).toBe 11
expect(atom.config.get([".text"], "foo.bar.baz")).toBeUndefined()
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee", ".string.quoted.double.coffee"])).toBe 42
expect(atom.config.get("foo.bar.baz", scope: [".source.js", ".string.quoted.double.js"])).toBe 22
expect(atom.config.get("foo.bar.baz", scope: [".source.js", ".variable.assignment.js"])).toBe 11
expect(atom.config.get("foo.bar.baz", scope: [".text"])).toBeUndefined()
it "favors the most recently added properties in the event of a specificity tie", ->
atom.config.addScopedSettings("config", ".source.coffee .string.quoted.single", foo: bar: baz: 42)
atom.config.addScopedSettings("config", ".source.coffee .string.quoted.double", foo: bar: baz: 22)
expect(atom.config.get([".source.coffee", ".string.quoted.single"], "foo.bar.baz")).toBe 42
expect(atom.config.get([".source.coffee", ".string.quoted.single.double"], "foo.bar.baz")).toBe 22
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee", ".string.quoted.single"])).toBe 42
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee", ".string.quoted.single.double"])).toBe 22
describe 'when there are global defaults', ->
it 'falls back to the global when there is no scoped property specified', ->
atom.config.setDefaults("foo", hasDefault: 'ok')
expect(atom.config.get([".source.coffee", ".string.quoted.single"], "foo.hasDefault")).toBe 'ok'
expect(atom.config.get("foo.hasDefault", scope: [".source.coffee", ".string.quoted.single"])).toBe 'ok'
describe 'setting priority', ->
describe 'when package settings are added after user settings', ->
it "returns the user's setting because the user's setting has higher priority", ->
atom.config.set(".source.coffee", "foo.bar.baz", 100)
atom.config.set("foo.bar.baz", 100, scopeSelector: ".source.coffee")
atom.config.addScopedSettings("some-package", ".source.coffee", foo: bar: baz: 1)
expect(atom.config.get([".source.coffee"], "foo.bar.baz")).toBe 100
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee"])).toBe 100
describe ".set(scope, keyPath, value)", ->
it "sets the value and overrides the others", ->
@@ -1147,10 +1294,10 @@ describe "Config", ->
atom.config.addScopedSettings("config", ".source .string.quoted.double", foo: bar: baz: 22)
atom.config.addScopedSettings("config", ".source", foo: bar: baz: 11)
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee", ".string.quoted.double.coffee"])).toBe 42
expect(atom.config.set(".source.coffee .string.quoted.double.coffee", "foo.bar.baz", 100)).toBe true
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 100
expect(atom.config.set("foo.bar.baz", 100, scopeSelector: ".source.coffee .string.quoted.double.coffee")).toBe true
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee", ".string.quoted.double.coffee"])).toBe 100
describe ".removeScopedSettingsForName(name)", ->
it "allows properties to be removed by name", ->
@@ -1158,12 +1305,13 @@ describe "Config", ->
disposable2 = atom.config.addScopedSettings("b", ".source .string.quoted.double", foo: bar: baz: 22)
disposable2.dispose()
expect(atom.config.get([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBeUndefined()
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
expect(atom.config.get("foo.bar.baz", scope: [".source.js", ".string.quoted.double.js"])).toBeUndefined()
expect(atom.config.get("foo.bar.baz", scope: [".source.coffee", ".string.quoted.double.coffee"])).toBe 42
describe ".observe(scopeDescriptor, keyPath)", ->
it 'calls the supplied callback when the value at the descriptor/keypath changes', ->
atom.config.observe [".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz", changeSpy = jasmine.createSpy()
changeSpy = jasmine.createSpy()
atom.config.observe("foo.bar.baz", scope: [".source.coffee", ".string.quoted.double.coffee"], changeSpy)
expect(changeSpy).toHaveBeenCalledWith(undefined)
changeSpy.reset()
@@ -1194,28 +1342,59 @@ describe "Config", ->
describe ".onDidChange(scopeDescriptor, keyPath)", ->
it 'calls the supplied callback when the value at the descriptor/keypath changes', ->
keyPath = "foo.bar.baz"
atom.config.onDidChange [".source.coffee", ".string.quoted.double.coffee"], keyPath, changeSpy = jasmine.createSpy()
changeSpy = jasmine.createSpy('onDidChange callback')
atom.config.onDidChange keyPath, scope: [".source.coffee", ".string.quoted.double.coffee"], changeSpy
atom.config.set("foo.bar.baz", 12)
expect(changeSpy).toHaveBeenCalledWith({oldValue: undefined, newValue: 12, keyPath})
expect(changeSpy).toHaveBeenCalledWith({oldValue: undefined, newValue: 12})
changeSpy.reset()
disposable1 = atom.config.addScopedSettings("a", ".source .string.quoted.double", foo: bar: baz: 22)
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: 22, keyPath})
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: 22})
changeSpy.reset()
disposable2 = atom.config.addScopedSettings("b", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 42, keyPath})
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 42})
changeSpy.reset()
disposable2.dispose()
expect(changeSpy).toHaveBeenCalledWith({oldValue: 42, newValue: 22, keyPath})
expect(changeSpy).toHaveBeenCalledWith({oldValue: 42, newValue: 22})
changeSpy.reset()
disposable1.dispose()
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 12, keyPath})
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 12})
changeSpy.reset()
atom.config.set("foo.bar.baz", undefined)
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: undefined, keyPath})
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: undefined})
changeSpy.reset()
it 'deprecates using a scope descriptor as an optional first argument', ->
keyPath = "foo.bar.baz"
spyOn(Grim, 'deprecate')
atom.config.onDidChange [".source.coffee", ".string.quoted.double.coffee"], keyPath, changeSpy = jasmine.createSpy()
expect(Grim.deprecate).toHaveBeenCalled()
atom.config.set("foo.bar.baz", 12)
expect(changeSpy).toHaveBeenCalledWith({oldValue: undefined, newValue: 12})
changeSpy.reset()
disposable1 = atom.config.addScopedSettings("a", ".source .string.quoted.double", foo: bar: baz: 22)
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: 22})
changeSpy.reset()
disposable2 = atom.config.addScopedSettings("b", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 42})
changeSpy.reset()
disposable2.dispose()
expect(changeSpy).toHaveBeenCalledWith({oldValue: 42, newValue: 22})
changeSpy.reset()
disposable1.dispose()
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 12})
changeSpy.reset()
atom.config.set("foo.bar.baz", undefined)
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: undefined})
changeSpy.reset()
+6
Ver Arquivo
@@ -1085,6 +1085,12 @@ describe "DisplayBuffer", ->
expect(oldProperties).toEqual decorationProperties
expect(newProperties).toEqual type: 'gutter', class: 'two', id: decoration.id
describe "::getDecorations(properties)", ->
it "returns decorations matching the given optional properties", ->
expect(displayBuffer.getDecorations()).toEqual [decoration]
expect(displayBuffer.getDecorations(class: 'two').length).toEqual 0
expect(displayBuffer.getDecorations(class: 'one').length).toEqual 1
describe "::setScrollTop", ->
beforeEach ->
displayBuffer.manageScrollPosition = true
+4
Ver Arquivo
@@ -259,6 +259,10 @@ describe "GitRepository", ->
editor.getBuffer().emitter.emit 'did-change-path'
expect(statusHandler.callCount).toBe 1
it "stops listening to the buffer when the repository is destroyed (regression)", ->
atom.project.getRepositories()[0].destroy()
expect(-> editor.save()).not.toThrow()
describe "when a project is deserialized", ->
[buffer, project2] = []
+3
Ver Arquivo
@@ -25,6 +25,9 @@ module.exports.runSpecSuite = (specSuite, logFile, logErrors=true) ->
log(str)
onComplete: (runner) ->
fs.closeSync(logStream) if logStream?
if process.env.JANKY_SHA1
grim = require 'grim'
grim.logDeprecations() if grim.getDeprecationsLength() > 0
atom.exit(runner.results().failedCount > 0 ? 1 : 0)
else
AtomReporter = require './atom-reporter'
+6 -6
Ver Arquivo
@@ -367,7 +367,7 @@ describe "PackageManager", ->
atom.packages.activatePackage("package-with-scoped-properties")
runs ->
expect(atom.config.get ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
expect(atom.config.get 'editor.increaseIndentPattern', scope: ['.source.omg']).toBe '^a'
describe "converted textmate packages", ->
it "loads the package's grammars", ->
@@ -380,13 +380,13 @@ describe "PackageManager", ->
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Ruby"
it "loads the translated scoped properties", ->
expect(atom.config.get(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
expect(atom.config.get('editor.commentStart', scope: ['.source.ruby'])).toBeUndefined()
waitsForPromise ->
atom.packages.activatePackage('language-ruby')
runs ->
expect(atom.config.get(['.source.ruby'], 'editor.commentStart')).toBe '# '
expect(atom.config.get('editor.commentStart', scope: ['.source.ruby'])).toBe '# '
describe "::deactivatePackage(id)", ->
afterEach ->
@@ -493,9 +493,9 @@ describe "PackageManager", ->
atom.packages.activatePackage("package-with-scoped-properties")
runs ->
expect(atom.config.get ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
expect(atom.config.get 'editor.increaseIndentPattern', scope: ['.source.omg']).toBe '^a'
atom.packages.deactivatePackage("package-with-scoped-properties")
expect(atom.config.get ['.source.omg'], 'editor.increaseIndentPattern').toBeUndefined()
expect(atom.config.get 'editor.increaseIndentPattern', scope: ['.source.omg']).toBeUndefined()
describe "textmate packages", ->
it "removes the package's grammars", ->
@@ -515,7 +515,7 @@ describe "PackageManager", ->
runs ->
atom.packages.deactivatePackage('language-ruby')
expect(atom.config.get(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
expect(atom.config.get('editor.commentStart', scope: ['.source.ruby'])).toBeUndefined()
describe "::activate()", ->
packageActivator = null
+94
Ver Arquivo
@@ -0,0 +1,94 @@
ChildProcess = require 'child_process'
{EventEmitter} = require 'events'
fs = require 'fs-plus'
path = require 'path'
temp = require 'temp'
SquirrelUpdate = require '../src/browser/squirrel-update'
describe "Windows squirrel updates", ->
tempHomeDirectory = null
beforeEach ->
# Prevent the actually home directory from being manipulated
tempHomeDirectory = temp.mkdirSync('atom-temp-home-')
spyOn(fs, 'getHomeDirectory').andReturn(tempHomeDirectory)
# Prevent any commands from actually running and affecting the host
originalSpawn = ChildProcess.spawn
spyOn(ChildProcess, 'spawn').andCallFake (command, args) ->
if path.basename(command) is 'Update.exe' and args?[0] is '--createShortcut'
fs.writeFileSync(path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk'), '')
# Just spawn something that won't actually modify the host
if process.platform is 'win32'
originalSpawn('dir')
else
originalSpawn('ls')
it "quits the app on all squirrel events", ->
app = quit: jasmine.createSpy('quit')
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-install')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
app.quit.reset()
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-updated')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
app.quit.reset()
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-uninstall')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
app.quit.reset()
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-obsolete')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
expect(SquirrelUpdate.handleStartupEvent(app, '--not-squirrel')).toBe false
it "keeps the desktop shortcut deleted on updates if it was previously deleted after install", ->
desktopShortcutPath = path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk')
expect(fs.existsSync(desktopShortcutPath)).toBe false
app = quit: jasmine.createSpy('quit')
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-install')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
app.quit.reset()
expect(fs.existsSync(desktopShortcutPath)).toBe true
fs.removeSync(desktopShortcutPath)
expect(fs.existsSync(desktopShortcutPath)).toBe false
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-updated')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
expect(fs.existsSync(desktopShortcutPath)).toBe false
describe ".restartAtom", ->
it "quits the app and spawns a new one", ->
app = new EventEmitter()
app.quit = jasmine.createSpy('quit')
SquirrelUpdate.restartAtom(app)
expect(app.quit.callCount).toBe 1
expect(ChildProcess.spawn.callCount).toBe 0
app.emit('will-quit')
expect(ChildProcess.spawn.callCount).toBe 1
expect(path.basename(ChildProcess.spawn.argsForCall[0][0])).toBe 'atom.cmd'
+54 -29
Ver Arquivo
@@ -1612,6 +1612,22 @@ describe "TextEditorComponent", ->
expect(nextAnimationFrame).toBe noAnimationFrame
expect(editor.getSelectedScreenRange()).toEqual [[2, 4], [6, 8]]
describe "when the editor is destroyed while dragging", ->
it "cleans up the handlers for window.mouseup and window.mousemove", ->
linesNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([2, 4]), which: 1))
linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([6, 8]), which: 1))
nextAnimationFrame()
spyOn(window, 'removeEventListener').andCallThrough()
linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([6, 10]), which: 1))
editor.destroy()
nextAnimationFrame()
call.args.pop() for call in window.removeEventListener.calls
expect(window.removeEventListener).toHaveBeenCalledWith('mouseup')
expect(window.removeEventListener).toHaveBeenCalledWith('mousemove')
describe "when a line is folded", ->
beforeEach ->
editor.foldBufferRow 4
@@ -2577,9 +2593,9 @@ describe "TextEditorComponent", ->
describe 'soft wrap settings', ->
beforeEach ->
atom.config.set '.source.coffee', 'editor.softWrap', true
atom.config.set '.source.coffee', 'editor.preferredLineLength', 17
atom.config.set '.source.coffee', 'editor.softWrapAtPreferredLineLength', true
atom.config.set 'editor.softWrap', true, scopeSelector: '.source.coffee'
atom.config.set 'editor.preferredLineLength', 17, scopeSelector: '.source.coffee'
atom.config.set 'editor.softWrapAtPreferredLineLength', true, scopeSelector: '.source.coffee'
editor.setEditorWidthInChars(20)
coffeeEditor.setEditorWidthInChars(20)
@@ -2589,18 +2605,18 @@ describe "TextEditorComponent", ->
expect(coffeeEditor.lineTextForScreenRow(3)).toEqual ' return items '
it 'updates the wrapped lines when editor.preferredLineLength changes', ->
atom.config.set '.source.coffee', 'editor.preferredLineLength', 20
atom.config.set 'editor.preferredLineLength', 20, scopeSelector: '.source.coffee'
expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if '
it 'updates the wrapped lines when editor.softWrapAtPreferredLineLength changes', ->
atom.config.set '.source.coffee', 'editor.softWrapAtPreferredLineLength', false
atom.config.set 'editor.softWrapAtPreferredLineLength', false, scopeSelector: '.source.coffee'
expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if '
it 'updates the wrapped lines when editor.softWrap changes', ->
atom.config.set '.source.coffee', 'editor.softWrap', false
atom.config.set 'editor.softWrap', false, scopeSelector: '.source.coffee'
expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if items.length <= 1'
atom.config.set '.source.coffee', 'editor.softWrap', true
atom.config.set 'editor.softWrap', true, scopeSelector: '.source.coffee'
expect(coffeeEditor.lineTextForScreenRow(3)).toEqual ' return items '
it 'updates the wrapped lines when the grammar changes', ->
@@ -2628,11 +2644,11 @@ describe "TextEditorComponent", ->
tab: 'F'
cr: 'E'
atom.config.set '.source.js', 'editor.showInvisibles', true
atom.config.set '.source.js', 'editor.invisibles', jsInvisibles
atom.config.set 'editor.showInvisibles', true, scopeSelector: '.source.js'
atom.config.set 'editor.invisibles', jsInvisibles, scopeSelector: '.source.js'
atom.config.set '.source.coffee', 'editor.showInvisibles', false
atom.config.set '.source.coffee', 'editor.invisibles', coffeeInvisibles
atom.config.set 'editor.showInvisibles', false, scopeSelector: '.source.coffee'
atom.config.set 'editor.invisibles', coffeeInvisibles, scopeSelector: '.source.coffee'
editor.setText " a line with tabs\tand spaces \n"
nextAnimationFrame()
@@ -2648,7 +2664,7 @@ describe "TextEditorComponent", ->
it "re-renders the invisibles when the invisible settings change", ->
jsGrammar = editor.getGrammar()
editor.setGrammar(coffeeEditor.getGrammar())
atom.config.set '.source.coffee', 'editor.showInvisibles', true
atom.config.set 'editor.showInvisibles', true, scopeSelector: '.source.coffee'
nextAnimationFrame()
expect(component.lineNodeForScreenRow(0).textContent).toBe "#{coffeeInvisibles.space}a line with tabs#{coffeeInvisibles.tab}and spaces#{coffeeInvisibles.space}#{coffeeInvisibles.eol}"
@@ -2657,7 +2673,7 @@ describe "TextEditorComponent", ->
space: 'E'
tab: 'W'
cr: 'I'
atom.config.set '.source.coffee', 'editor.invisibles', newInvisibles
atom.config.set 'editor.invisibles', newInvisibles, scopeSelector: '.source.coffee'
nextAnimationFrame()
expect(component.lineNodeForScreenRow(0).textContent).toBe "#{newInvisibles.space}a line with tabs#{newInvisibles.tab}and spaces#{newInvisibles.space}#{newInvisibles.eol}"
@@ -2667,8 +2683,8 @@ describe "TextEditorComponent", ->
describe 'editor.showIndentGuide', ->
beforeEach ->
atom.config.set '.source.js', 'editor.showIndentGuide', true
atom.config.set '.source.coffee', 'editor.showIndentGuide', false
atom.config.set 'editor.showIndentGuide', true, scopeSelector: '.source.js'
atom.config.set 'editor.showIndentGuide', false, scopeSelector: '.source.coffee'
it "has an 'indent-guide' class when scoped editor.showIndentGuide is true, but not when scoped editor.showIndentGuide is false", ->
line1LeafNodes = getLeafNodes(component.lineNodeForScreenRow(1))
@@ -2689,7 +2705,7 @@ describe "TextEditorComponent", ->
expect(line1LeafNodes[0].classList.contains('indent-guide')).toBe true
expect(line1LeafNodes[1].classList.contains('indent-guide')).toBe false
atom.config.set '.source.js', 'editor.showIndentGuide', false
atom.config.set 'editor.showIndentGuide', false, scopeSelector: '.source.js'
line1LeafNodes = getLeafNodes(component.lineNodeForScreenRow(1))
expect(line1LeafNodes[0].textContent).toBe ' '
@@ -2697,26 +2713,35 @@ describe "TextEditorComponent", ->
expect(line1LeafNodes[1].classList.contains('indent-guide')).toBe false
describe "middle mouse paste on Linux", ->
it "pastes the previously selected text", ->
originalPlatform = null
beforeEach ->
originalPlatform = process.platform
Object.defineProperty process, 'platform', value: 'linux'
afterEach ->
Object.defineProperty process, 'platform', value: originalPlatform
it "pastes the previously selected text at the clicked location", ->
jasmine.unspy(window, 'setTimeout')
clipboardWrittenTo = false
spyOn(require('ipc'), 'send').andCallFake (eventName, selectedText) ->
if eventName is 'write-text-to-selection-clipboard'
require('clipboard').writeText(selectedText, 'selection')
clipboardWrittenTo = true
atom.clipboard.write('')
component.listenForMiddleMousePaste()
editor.setCursorBufferPosition([10, 0])
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', which: 2))
expect(atom.clipboard.read()).toBe ''
expect(editor.lineTextForBufferRow(10)).toBe ''
component.trackSelectionClipboard()
editor.setSelectedBufferRange([[1, 6], [1, 10]])
editor.setCursorBufferPosition([10, 0])
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', which: 2))
expect(atom.clipboard.read()).toBe 'sort'
expect(editor.lineTextForBufferRow(10)).toBe 'sort'
waitsFor ->
clipboardWrittenTo
runs ->
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([10, 0]), button: 1))
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenPosition([10, 0]), which: 2))
expect(atom.clipboard.read()).toBe 'sort'
expect(editor.lineTextForBufferRow(10)).toBe 'sort'
buildMouseEvent = (type, properties...) ->
properties = extend({bubbles: true, cancelable: true}, properties...)
+25
Ver Arquivo
@@ -32,6 +32,31 @@ describe "TextEditorElement", ->
element.setModel(model)
expect(element.hasAttribute('mini')).toBe true
describe "when the editor is attached to the DOM", ->
describe "when the editor.useShadowDOM config option is true", ->
it "mounts the react component and unmounts when removed from the dom", ->
atom.config.set('editor.useShadowDOM', true)
element = new TextEditorElement
jasmine.attachToDOM(element)
component = element.component
expect(component.isMounted()).toBe true
element.getModel().destroy()
expect(component.isMounted()).toBe false
describe "when the editor.useShadowDOM config option is false", ->
it "mounts the react component and unmounts when removed from the dom", ->
atom.config.set('editor.useShadowDOM', false)
element = new TextEditorElement
jasmine.attachToDOM(element)
component = element.component
expect(component.isMounted()).toBe true
element.getModel().destroy()
expect(component.isMounted()).toBe false
describe "focus and blur handling", ->
describe "when the editor.useShadowDOM config option is true", ->
it "proxies focus/blur events to/from the hidden input inside the shadow root", ->
+18 -12
Ver Arquivo
@@ -192,12 +192,18 @@ describe "TextEditor", ->
expect(editor.getCursorBufferPosition()).toEqual [1, 1]
it "emits an event with the old position, new position, and the cursor that moved", ->
editor.onDidChangeCursorPosition positionChangedHandler = jasmine.createSpy()
cursorCallback = jasmine.createSpy('cursor-changed-position')
editorCallback = jasmine.createSpy('editor-changed-cursor-position')
editor.getLastCursor().onDidChangePosition(cursorCallback)
editor.onDidChangeCursorPosition(editorCallback)
editor.setCursorBufferPosition([2, 4])
expect(positionChangedHandler).toHaveBeenCalled()
eventObject = positionChangedHandler.mostRecentCall.args[0]
expect(editorCallback).toHaveBeenCalled()
expect(cursorCallback).toHaveBeenCalled()
eventObject = editorCallback.mostRecentCall.args[0]
expect(cursorCallback.mostRecentCall.args[0]).toEqual(eventObject)
expect(eventObject.oldBufferPosition).toEqual [0, 0]
expect(eventObject.oldScreenPosition).toEqual [0, 0]
@@ -1321,7 +1327,7 @@ describe "TextEditor", ->
coffeeEditor.selectWordsContainingCursors()
expect(coffeeEditor.getSelectedBufferRange()).toEqual [[0, 6], [0, 15]]
atom.config.set '.source.coffee', 'editor.nonWordCharacters', 'qusort'
atom.config.set 'editor.nonWordCharacters', 'qusort', scopeSelector: '.source.coffee'
coffeeEditor.setCursorBufferPosition [0, 9]
coffeeEditor.selectWordsContainingCursors()
@@ -3270,7 +3276,7 @@ describe "TextEditor", ->
atom.packages.unloadPackages()
it 'returns correct values based on the scope of the set grammars', ->
atom.config.set '.source.coffee', 'editor.tabLength', 6
atom.config.set 'editor.tabLength', 6, scopeSelector: '.source.coffee'
expect(editor.getTabLength()).toBe 2
expect(coffeeEditor.getTabLength()).toBe 6
@@ -3292,12 +3298,12 @@ describe "TextEditor", ->
expect(editor.getTabLength()).toBe 2
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 2
atom.config.set '.source.js', 'editor.tabLength', 6
atom.config.set 'editor.tabLength', 6, scopeSelector: '.source.js'
expect(editor.getTabLength()).toBe 6
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 6
it 'updates the tab length when the grammar changes', ->
atom.config.set '.source.coffee', 'editor.tabLength', 6
atom.config.set 'editor.tabLength', 6, scopeSelector: '.source.coffee'
expect(editor.getTabLength()).toBe 2
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 2
@@ -3414,11 +3420,11 @@ describe "TextEditor", ->
describe "when the cursor is before whitespace", ->
it "retains the whitespace following the cursor on the new line", ->
editor.setText(" var sort = function() {}")
editor.setCursorScreenPosition([0, 23])
editor.setCursorScreenPosition([0, 12])
editor.insertNewline()
expect(buffer.lineForRow(0)).toBe ' var sort = function()'
expect(buffer.lineForRow(1)).toBe ' {}'
expect(buffer.lineForRow(0)).toBe ' var sort ='
expect(buffer.lineForRow(1)).toBe ' function() {}'
expect(editor.getCursorScreenPosition()).toEqual [1, 2]
describe "when inserted text matches a decrease indent pattern", ->
@@ -3467,8 +3473,8 @@ describe "TextEditor", ->
atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o
runs ->
atom.config.set('.source.js', 'editor.autoIndent', true)
atom.config.set('.source.coffee', 'editor.autoIndent', false)
atom.config.set('editor.autoIndent', true, scopeSelector: '.source.js')
atom.config.set('editor.autoIndent', false, scopeSelector: '.source.coffee')
afterEach: ->
atom.packages.deactivatePackages()
+37
Ver Arquivo
@@ -3,6 +3,7 @@ Q = require 'q'
path = require 'path'
temp = require 'temp'
TextEditorView = require '../src/text-editor-view'
Pane = require '../src/pane'
PaneView = require '../src/pane-view'
Workspace = require '../src/workspace'
@@ -294,3 +295,39 @@ describe "WorkspaceView", ->
modalContainer = workspaceElement.querySelector('atom-panel-container.modal')
expect(modalContainer.parentNode).toBe workspaceElement
describe "::saveActivePaneItem()", ->
describe "when there is an error", ->
it "emits a warning notification when the file cannot be saved", ->
spyOn(Pane::, 'saveActiveItem').andCallFake ->
throw new Error("'/some/file' is a directory")
atom.notifications.onDidAddNotification addedSpy = jasmine.createSpy()
atom.workspace.saveActivePaneItem()
expect(addedSpy).toHaveBeenCalled()
expect(addedSpy.mostRecentCall.args[0].getType()).toBe 'warning'
it "emits a warning notification when the directory cannot be written to", ->
spyOn(Pane::, 'saveActiveItem').andCallFake ->
throw new Error("ENOTDIR, not a directory '/Some/dir/and-a-file.js'")
atom.notifications.onDidAddNotification addedSpy = jasmine.createSpy()
atom.workspace.saveActivePaneItem()
expect(addedSpy).toHaveBeenCalled()
expect(addedSpy.mostRecentCall.args[0].getType()).toBe 'warning'
it "emits a warning notification when the user does not have permission", ->
spyOn(Pane::, 'saveActiveItem').andCallFake ->
throw new Error("EACCES, permission denied '/Some/dir/and-a-file.js'")
atom.notifications.onDidAddNotification addedSpy = jasmine.createSpy()
atom.workspace.saveActivePaneItem()
expect(addedSpy).toHaveBeenCalled()
expect(addedSpy.mostRecentCall.args[0].getType()).toBe 'warning'
it "emits a warning notification when the file cannot be saved", ->
spyOn(Pane::, 'saveActiveItem').andCallFake ->
throw new Error("no one knows")
save = -> atom.workspace.saveActivePaneItem()
expect(save).toThrow()
+4
Ver Arquivo
@@ -341,6 +341,10 @@ class Atom extends Model
inDevMode: ->
@getLoadSettings().devMode
# Public: Is the current window in safe mode?
inSafeMode: ->
@getLoadSettings().safeMode
# Public: Is the current window running specs?
inSpecMode: ->
@getLoadSettings().isSpec
+8 -4
Ver Arquivo
@@ -140,14 +140,18 @@ class AtomApplication
# Registers basic application commands, non-idempotent.
handleEvents: ->
getLoadSettings = =>
devMode: @focusedWindow()?.devMode
safeMode: @focusedWindow()?.safeMode
@on 'application:run-all-specs', -> @runSpecs(exitWhenDone: false, resourcePath: global.devResourcePath, safeMode: @focusedWindow()?.safeMode)
@on 'application:run-benchmarks', -> @runBenchmarks()
@on 'application:quit', -> app.quit()
@on 'application:new-window', -> @openPath(windowDimensions: @focusedWindow()?.getDimensions())
@on 'application:new-window', -> @openPath(_.extend(windowDimensions: @focusedWindow()?.getDimensions(), getLoadSettings()))
@on 'application:new-file', -> (@focusedWindow() ? this).openPath()
@on 'application:open', -> @promptForPath(type: 'all')
@on 'application:open-file', -> @promptForPath(type: 'file')
@on 'application:open-folder', -> @promptForPath(type: 'folder')
@on 'application:open', -> @promptForPath(_.extend(type: 'all', getLoadSettings()))
@on 'application:open-file', -> @promptForPath(_.extend(type: 'file', getLoadSettings()))
@on 'application:open-folder', -> @promptForPath(_.extend(type: 'folder', getLoadSettings()))
@on 'application:open-dev', -> @promptForPath(devMode: true)
@on 'application:open-safe', -> @promptForPath(safeMode: true)
@on 'application:inspect', ({x,y, atomWindow}) ->
+3 -1
Ver Arquivo
@@ -18,7 +18,7 @@ class AtomWindow
isSpec: null
constructor: (settings={}) ->
{@resourcePath, pathToOpen, initialLine, initialColumn, @isSpec, @exitWhenDone, @safeMode} = settings
{@resourcePath, pathToOpen, initialLine, initialColumn, @isSpec, @exitWhenDone, @safeMode, @devMode} = settings
# Normalize to make sure drive letter case is consistent on Windows
@resourcePath = path.normalize(@resourcePath) if @resourcePath
@@ -38,6 +38,8 @@ class AtomWindow
loadSettings.windowState ?= '{}'
loadSettings.appVersion = app.getVersion()
loadSettings.resourcePath = @resourcePath
loadSettings.devMode ?= false
loadSettings.safeMode ?= false
# Only send to the first non-spec window created
if @constructor.includeShellLoadTime and not @isSpec
+1 -7
Ver Arquivo
@@ -8,10 +8,8 @@ class AutoUpdater
setFeedUrl: (@updateUrl) ->
quitAndInstall: ->
console.log 'restarting new atom.exe'
if SquirrelUpdate.existsSync()
SquirrelUpdate.restartAtom()
SquirrelUpdate.restartAtom(require('app'))
else
require('auto-updater').quitAndInstall()
@@ -46,7 +44,6 @@ class AutoUpdater
@downloadUpdate (error, update) =>
if error?
console.log "Failed to download: #{error.message} - #{error.code} - #{error.stdout}"
@emit 'update-not-available'
return
@@ -56,12 +53,9 @@ class AutoUpdater
@installUpdate (error) =>
if error?
console.log "Failed to update: #{error.message} - #{error.code} - #{error.stdout}"
@emit 'update-not-available'
return
console.log "Updated to #{update.version}"
@emit 'update-available'
@emit 'update-downloaded', {}, update.releaseNotes, update.version, new Date(), 'https://atom.io', => @quitAndInstall()
+2 -1
Ver Arquivo
@@ -26,7 +26,8 @@ fs.lstatSyncNoException = (pathToStat) ->
start = ->
if process.platform is 'win32'
SquirrelUpdate = require './squirrel-update'
return if SquirrelUpdate.handleStartupEvent()
squirrelCommand = process.argv[1]
return if SquirrelUpdate.handleStartupEvent(app, squirrelCommand)
args = parseCommandLine()
+51 -22
Ver Arquivo
@@ -1,9 +1,9 @@
app = require 'app'
ChildProcess = require 'child_process'
fs = require 'fs-plus'
path = require 'path'
rootAtomFolder = path.resolve(process.execPath, '..', '..')
appFolder = path.resolve(process.execPath, '..')
rootAtomFolder = path.resolve(appFolder, '..')
binFolder = path.join(rootAtomFolder, 'bin')
updateDotExe = path.join(rootAtomFolder, 'Update.exe')
exeName = path.basename(process.execPath)
@@ -111,22 +111,26 @@ uninstallContextMenu = (callback) ->
addCommandsToPath = (callback) ->
installCommands = (callback) ->
atomCommandPath = path.join(binFolder, 'atom.cmd')
relativeExePath = path.relative(binFolder, process.execPath)
atomCommand = """
@echo off
"%~dp0\\#{relativeExePath}" %*
"""
relativeAtomPath = path.relative(binFolder, path.join(appFolder, 'resources', 'cli', 'atom.cmd'))
atomCommand = "@echo off\r\n\"%~dp0\\#{relativeAtomPath}\" %*"
atomShCommandPath = path.join(binFolder, 'atom')
relativeAtomShPath = path.relative(binFolder, path.join(appFolder, 'resources', 'cli', 'atom.sh'))
atomShCommand = "#!/bin/sh\r\n\"$0/../#{relativeAtomShPath.replace(/\\/g, '/')}\" \"$@\""
apmCommandPath = path.join(binFolder, 'apm.cmd')
relativeApmPath = path.relative(binFolder, path.join(process.resourcesPath, 'app', 'apm', 'node_modules', 'atom-package-manager', 'bin', 'apm.cmd'))
apmCommand = """
@echo off
"%~dp0\\#{relativeApmPath}" %*
"""
apmCommand = "@echo off\r\n\"%~dp0\\#{relativeApmPath}\" %*"
apmShCommandPath = path.join(binFolder, 'apm')
relativeApmShPath = path.relative(binFolder, path.join(appFolder, 'resources', 'cli', 'apm.sh'))
apmShCommand = "#!/bin/sh\r\n\"$0/../#{relativeApmShPath.replace(/\\/g, '/')}\" \"$@\""
fs.writeFile atomCommandPath, atomCommand, ->
fs.writeFile apmCommandPath, apmCommand, ->
callback()
fs.writeFile atomShCommandPath, atomShCommand, ->
fs.writeFile apmCommandPath, apmCommand, ->
fs.writeFile apmShCommandPath, apmShCommand, ->
callback()
addBinToPath = (pathSegments, callback) ->
pathSegments.push(binFolder)
@@ -161,12 +165,29 @@ removeCommandsFromPath = (callback) ->
# Create a desktop and start menu shortcut by using the command line API
# provided by Squirrel's Update.exe
createShortcut = (callback) ->
createShortcuts = (callback) ->
spawnUpdate(['--createShortcut', exeName], callback)
# Update the desktop and start menu shortcuts by using the command line API
# provided by Squirrel's Update.exe
updateShortcuts = (callback) ->
if homeDirectory = fs.getHomeDirectory()
desktopShortcutPath = path.join(homeDirectory, 'Desktop', 'Atom.lnk')
# Check if the desktop shortcut has been previously deleted and
# and keep it deleted if it was
fs.exists desktopShortcutPath, (desktopShortcutExists) ->
createShortcuts ->
if desktopShortcutExists
callback()
else
# Remove the unwanted desktop shortcut that was recreated
fs.unlink(desktopShortcutPath, callback)
else
createShortcuts(callback)
# Remove the desktop and start menu shortcuts by using the command line API
# provided by Squirrel's Update.exe
removeShortcut = (callback) ->
removeShortcuts = (callback) ->
spawnUpdate(['--removeShortcut', exeName], callback)
exports.spawn = spawnUpdate
@@ -176,21 +197,29 @@ exports.existsSync = ->
fs.existsSync(updateDotExe)
# Restart Atom using the version pointed to by the atom.cmd shim
exports.restartAtom = ->
app.once 'will-quit', -> spawn(path.join(binFolder, 'atom.cmd'))
exports.restartAtom = (app) ->
if projectPath = global.atomApplication?.lastFocusedWindow?.projectPath
args = [projectPath]
app.once 'will-quit', -> spawn(path.join(binFolder, 'atom.cmd'), args)
app.quit()
# Handle squirrel events denoted by --squirrel-* command line arguments.
exports.handleStartupEvent = ->
switch process.argv[1]
when '--squirrel-install', '--squirrel-updated'
createShortcut ->
exports.handleStartupEvent = (app, squirrelCommand) ->
switch squirrelCommand
when '--squirrel-install'
createShortcuts ->
installContextMenu ->
addCommandsToPath ->
app.quit()
true
when '--squirrel-updated'
updateShortcuts ->
installContextMenu ->
addCommandsToPath ->
app.quit()
true
when '--squirrel-uninstall'
removeShortcut ->
removeShortcuts ->
uninstallContextMenu ->
removeCommandsFromPath ->
app.quit()
+61 -4
Ver Arquivo
@@ -1,5 +1,6 @@
_ = require 'underscore-plus'
ChildProcess = require 'child_process'
{Emitter} = require 'event-kit'
# Extended: A wrapper which provides standard error/output line buffering for
# Node's ChildProcess.
@@ -17,6 +18,10 @@ ChildProcess = require 'child_process'
# ```
module.exports =
class BufferedProcess
###
Section: Construction
###
# Public: Runs the given command by spawning a new child process.
#
# * `options` An {Object} with the following keys:
@@ -39,14 +44,15 @@ class BufferedProcess
# * `exit` The callback {Function} which receives a single argument
# containing the exit status (optional).
constructor: ({command, args, options, stdout, stderr, exit}={}) ->
@emitter = new Emitter
options ?= {}
# Related to joyent/node#2318
if process.platform is "win32"
if process.platform is 'win32'
# Quote all arguments and escapes inner quotes
if args?
cmdArgs = args.filter (arg) -> arg?
cmdArgs = cmdArgs.map (arg) ->
if command in ['explorer.exe', 'explorer'] and /^\/[a-zA-Z]+,.*$/.test(arg)
cmdArgs = cmdArgs.map (arg) =>
if @isExplorerCommand(command) and /^\/[a-zA-Z]+,.*$/.test(arg)
# Don't wrap /root,C:\folder style arguments to explorer calls in
# quotes since they will not be interpreted correctly if they are
arg
@@ -61,7 +67,7 @@ class BufferedProcess
cmdArgs = ['/s', '/c', "\"#{cmdArgs.join(' ')}\""]
cmdOptions = _.clone(options)
cmdOptions.windowsVerbatimArguments = true
@process = ChildProcess.spawn(process.env.comspec or 'cmd.exe', cmdArgs, cmdOptions)
@process = ChildProcess.spawn(@getCmdPath(), cmdArgs, cmdOptions)
else
@process = ChildProcess.spawn(command, args, options)
@killed = false
@@ -94,6 +100,41 @@ class BufferedProcess
processExited = true
triggerExitCallback()
@process.on 'error', (error) =>
handled = false
handle = -> handled = true
@emitter.emit 'will-throw-error', {error, handle}
if error.code is 'ENOENT' and error.syscall.indexOf('spawn') is 0
error = new Error("Failed to spawn command `#{command}`. Make sure `#{command}` is installed and on your PATH", error.path)
error.name = 'BufferedProcessError'
throw error unless handled
###
Section: Event Subscription
###
# Public: Will call your callback when an error will be raised by the process.
# Usually this is due to the command not being available or not on the PATH.
# You can call `handle()` on the object passed to your callback to indicate
# that you have handled this error.
#
# * `callback` {Function} callback
# * `errorObject` {Object}
# * `error` {Object} the error object
# * `handle` {Function} call this to indicate you have handled the error.
# The error will not be thrown if this function is called.
#
# Returns a {Disposable}
onWillThrowError: (callback) ->
@emitter.on 'will-throw-error', callback
###
Section: Helper Methods
###
# Helper method to pass data line by line.
#
# * `stream` The Stream to read from.
@@ -150,6 +191,22 @@ class BufferedProcess
@process?.kill()
@process = null
isExplorerCommand: (command) ->
if command is 'explorer.exe' or command is 'explorer'
true
else if process.env.SystemRoot
command is path.join(process.env.SystemRoot, 'explorer.exe') or command is path.join(process.env.SystemRoot, 'explorer')
else
false
getCmdPath: ->
if process.env.comspec
process.env.compec
else if process.env.SystemRoot
path.join(process.env.SystemRoot, 'System32', 'cmd.exe')
else
'cmd.exe'
# Public: Terminate the process.
kill: ->
return if @killed
+243 -194
Ver Arquivo
@@ -6,7 +6,7 @@ CSON = require 'season'
path = require 'path'
async = require 'async'
pathWatcher = require 'pathwatcher'
{deprecate} = require 'grim'
Grim = require 'grim'
ScopedPropertyStore = require 'scoped-property-store'
ScopeDescriptor = require './scope-descriptor'
@@ -314,10 +314,12 @@ class Config
@settings = {}
@scopedSettingsStore = new ScopedPropertyStore
@usersScopedSettings = new CompositeDisposable
@usersScopedSettingPriority = {priority: 1000}
@configFileHasErrors = false
@configFilePath = fs.resolve(@configDirPath, 'config', ['json', 'cson'])
@configFilePath ?= path.join(@configDirPath, 'config.cson')
@transactDepth = 0
@prioritiesBySource = {}
@prioritiesBySource[@getUserConfigPath()] = 1000
###
Section: Config Subscription
@@ -337,32 +339,36 @@ class Config
# # do stuff with value
# ```
#
# * `scopeDescriptor` (optional) {ScopeDescriptor} describing a path from
# the root of the syntax tree to a token. Get one by calling
# {editor.getLastCursor().getScopeDescriptor()}. See {::get} for examples.
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
# for more information.
# * `keyPath` {String} name of the key to observe
# * `options` {Object}
# * `scopeDescriptor` (optional) {ScopeDescriptor} describing a path from
# the root of the syntax tree to a token. Get one by calling
# {editor.getLastCursor().getScopeDescriptor()}. See {::get} for examples.
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
# for more information.
# * `callback` {Function} to call when the value of the key changes.
# * `value` the new value of the key
#
# Returns a {Disposable} with the following keys on which you can call
# `.dispose()` to unsubscribe.
observe: (scopeDescriptor, keyPath, options, callback) ->
args = Array::slice.call(arguments)
if args.length is 2
# observe(keyPath, callback)
[keyPath, callback, scopeDescriptor, options] = args
else if args.length is 3 and (Array.isArray(scopeDescriptor) or scopeDescriptor instanceof ScopeDescriptor)
# observe(scopeDescriptor, keyPath, callback)
[scopeDescriptor, keyPath, callback, options] = args
else if args.length is 3 and _.isString(scopeDescriptor) and _.isObject(keyPath)
# observe(keyPath, options, callback) # Deprecated!
[keyPath, options, callback, scopeDescriptor] = args
message = ""
message = "`callNow` was set to false. Use ::onDidChange instead. Note that ::onDidChange calls back with different arguments." if options.callNow == false
deprecate "Config::observe no longer supports options; see https://atom.io/docs/api/latest/Config. #{message}"
observe: ->
if arguments.length is 2
[keyPath, callback] = arguments
else if arguments.length is 3 and (_.isArray(arguments[0]) or arguments[0] instanceof ScopeDescriptor)
Grim.deprecate """
Passing a scope descriptor as the first argument to Config::observe is deprecated.
Pass a `scope` in an options hash as the third argument instead.
"""
[scopeDescriptor, keyPath, callback] = arguments
else if arguments.length is 3 and (_.isString(arguments[0]) and _.isObject(arguments[1]))
[keyPath, options, callback] = arguments
scopeDescriptor = options.scope
if options.callNow?
Grim.deprecate """
Config::observe no longer takes a `callNow` option. Use ::onDidChange instead.
Note that ::onDidChange passes its callback different arguments.
See https://atom.io/docs/api/latest/Config
"""
else
console.error 'An unsupported form of Config::observe is being used. See https://atom.io/docs/api/latest/Config for details'
return
@@ -375,13 +381,14 @@ class Config
# Essential: Add a listener for changes to a given key path. If `keyPath` is
# not specified, your callback will be called on changes to any key.
#
# * `scopeDescriptor` (optional) {ScopeDescriptor} describing a path from
# the root of the syntax tree to a token. Get one by calling
# {editor.getLastCursor().getScopeDescriptor()}. See {::get} for examples.
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
# for more information.
# * `keyPath` (optional) {String} name of the key to observe. Must be
# specified if `scopeDescriptor` is specified.
# * `optional` (optional) {Object}
# * `scopeDescriptor` (optional) {ScopeDescriptor} describing a path from
# the root of the syntax tree to a token. Get one by calling
# {editor.getLastCursor().getScopeDescriptor()}. See {::get} for examples.
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
# for more information.
# * `callback` {Function} to call when the value of the key changes.
# * `event` {Object}
# * `newValue` the new value of the key
@@ -390,12 +397,20 @@ class Config
#
# Returns a {Disposable} with the following keys on which you can call
# `.dispose()` to unsubscribe.
onDidChange: (scopeDescriptor, keyPath, callback) ->
args = Array::slice.call(arguments)
onDidChange: ->
if arguments.length is 1
[callback, scopeDescriptor, keyPath] = args
[callback] = arguments
else if arguments.length is 2
[keyPath, callback, scopeDescriptor] = args
[keyPath, callback] = arguments
else if _.isArray(arguments[0]) or arguments[0] instanceof ScopeDescriptor
Grim.deprecate """
Passing a scope descriptor as the first argument to Config::onDidChange is deprecated.
Pass a `scope` in an options hash as the third argument instead.
"""
[scopeDescriptor, keyPath, callback] = arguments
else
[keyPath, options, callback] = arguments
scopeDescriptor = options.scope
if scopeDescriptor?
@onDidChangeScopedKeyPath(scopeDescriptor, keyPath, callback)
@@ -446,24 +461,40 @@ class Config
# atom.config.get(scopeDescriptor, 'editor.tabLength') # => 2
# ```
#
# * `scopeDescriptor` (optional) {ScopeDescriptor} describing a path from
# the root of the syntax tree to a token. Get one by calling
# {editor.getLastCursor().getScopeDescriptor()}
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
# for more information.
# * `keyPath` The {String} name of the key to retrieve.
# * `options` (optional) {Object}
# * `sources` (optional) {Array} of {String} source names. If provided, only
# values that were associated with these sources during {::set} will be used.
# * `excludeSources` (optional) {Array} of {String} source names. If provided,
# values that were associated with these sources during {::set} will not
# be used.
# * `scopeDescriptor` (optional) {ScopeDescriptor} describing a path from
# the root of the syntax tree to a token. Get one by calling
# {editor.getLastCursor().getScopeDescriptor()}
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
# for more information.
#
# Returns the value from Atom's default settings, the user's configuration
# file in the type specified by the configuration schema.
get: (scopeDescriptor, keyPath) ->
if arguments.length == 1
# cannot assign to keyPath for the sake of v8 optimization
globalKeyPath = scopeDescriptor
@getRawValue(globalKeyPath)
get: ->
if arguments.length > 1
if typeof arguments[0] is 'string' or not arguments[0]?
[keyPath, options] = arguments
{scope} = options
else
Grim.deprecate """
Passing a scope descriptor as the first argument to Config::get is deprecated.
Pass a `scope` in an options hash as the final argument instead.
"""
[scope, keyPath] = arguments
else
value = @getRawScopedValue(scopeDescriptor, keyPath)
value ?= @getRawValue(keyPath)
value
[keyPath] = arguments
if scope?
value = @getRawScopedValue(scope, keyPath, options)
value ? @getRawValue(keyPath, options)
else
@getRawValue(keyPath, options)
# Essential: Sets the value for a configuration setting.
#
@@ -494,63 +525,90 @@ class Config
# atom.config.get(['source.js'], 'editor.tabLength') # => 4
# ```
#
# * `scopeSelector` (optional) {String}. eg. '.source.ruby'
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
# for more information.
# * `keyPath` The {String} name of the key.
# * `value` The value of the setting. Passing `undefined` will revert the
# setting to the default value.
# * `options` (optional) {Object}
# * `scopeSelector` (optional) {String}. eg. '.source.ruby'
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
# for more information.
# * `source` (optional) {String} The name of a file with which the setting
# is associated. Defaults to the user's config file.
#
# Returns a {Boolean}
# * `true` if the value was set.
# * `false` if the value was not able to be coerced to the type specified in the setting's schema.
set: (scopeSelector, keyPath, value) ->
if arguments.length < 3
value = keyPath
keyPath = scopeSelector
scopeSelector = undefined
set: ->
if arguments[0]?[0] is '.'
Grim.deprecate """
Passing a scope selector as the first argument to Config::set is deprecated.
Pass a `scopeSelector` in an options hash as the final argument instead.
"""
[scopeSelector, keyPath, value] = arguments
else
[keyPath, value, options] = arguments
scopeSelector = options?.scopeSelector
source = options?.source
unless value == undefined
source ?= @getUserConfigPath()
unless value is undefined
try
value = @makeValueConformToSchema(keyPath, value)
catch e
return false
if scopeSelector?
@setRawScopedValue(scopeSelector, keyPath, value)
@setRawScopedValue(source, scopeSelector, keyPath, value)
else
@setRawValue(keyPath, value)
@setRawValue(source, keyPath, value)
@emitChangeEvent()
@save() unless @configFileHasErrors
true
# Extended: Restore the global setting at `keyPath` to its default value.
# Essential: Restore the setting at `keyPath` to its default value.
#
# * `scopeSelector` (optional) {String}. eg. '.source.ruby'
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
# for more information.
# * `keyPath` The {String} name of the key.
# * `options` (optional) {Object}
# * `scopeSelector` (optional) {String}. See {::set}
# * `source` (optional) {String}. See {::set}
unset: (keyPath, options) ->
if typeof options is 'string'
Grim.deprecate """
Passing a scope selector as the first argument to Config::unset is deprecated.
Pass a `scopeSelector` in an options hash as the second argument instead.
"""
scopeSelector = keyPath
keyPath = options
else
{scopeSelector, source} = options ? {}
source ?= @getUserConfigPath()
if scopeSelector?
if keyPath?
settings = @scopedSettingsStore.propertiesForSourceAndSelector(source, scopeSelector)
if _.valueForKeyPath(settings, keyPath)?
@scopedSettingsStore.removePropertiesForSourceAndSelector(source, scopeSelector)
_.setValueForKeyPath(settings, keyPath, undefined)
settings = withoutEmptyObjects(settings)
@addScopedSettings(source, scopeSelector, settings, priority: @usersScopedSettingPriority) if settings?
@save() unless @configFileHasErrors
else
@scopedSettingsStore.removePropertiesForSource(source)
else
@set(keyPath, _.valueForKeyPath(@defaultSettings, keyPath))
# Deprecated: Restore the global setting at `keyPath` to its default value.
#
# Returns the new value.
restoreDefault: (scopeSelector, keyPath) ->
if arguments.length == 1
keyPath = scopeSelector
scopeSelector = null
Grim.deprecate("Use ::unset instead.")
@unset(scopeSelector, keyPath)
@get(keyPath)
if scopeSelector?
settings = @scopedSettingsStore.propertiesForSourceAndSelector('user-config', scopeSelector)
if _.valueForKeyPath(settings, keyPath)?
@scopedSettingsStore.removePropertiesForSourceAndSelector('user-config', scopeSelector)
_.setValueForKeyPath(settings, keyPath, undefined)
settings = withoutEmptyObjects(settings)
@addScopedSettings('user-config', scopeSelector, settings, @usersScopedSettingPriority) if settings?
@save() unless @configFileHasErrors
@getDefault(scopeSelector, keyPath)
else
@set(keyPath, _.valueForKeyPath(@defaultSettings, keyPath))
@get(keyPath)
# Extended: Get the global default value of the key path. _Please note_ that in most
# Deprecated: Get the global default value of the key path. _Please note_ that in most
# cases calling this is not necessary! {::get} returns the default value when
# a custom value is not specified.
#
@@ -558,35 +616,31 @@ class Config
# * `keyPath` The {String} name of the key.
#
# Returns the default value.
getDefault: (scopeSelector, keyPath) ->
if arguments.length == 1
keyPath = scopeSelector
scopeSelector = null
if scopeSelector?
defaultValue = @scopedSettingsStore.getPropertyValue(scopeSelector, keyPath, excludeSources: ['user-config'])
defaultValue ?= _.valueForKeyPath(@defaultSettings, keyPath)
getDefault: ->
Grim.deprecate("Use `::get(keyPath, {scope, excludeSources: [atom.config.getUserConfigPath()]})` instead")
if arguments.length is 1
[keyPath] = arguments
else
defaultValue = _.valueForKeyPath(@defaultSettings, keyPath)
_.deepClone(defaultValue)
[scopeSelector, keyPath] = arguments
scope = [scopeSelector]
@get(keyPath, {scope, excludeSources: [@getUserConfigPath()]})
# Extended: Is the value at `keyPath` its default value?
# Deprecated: Is the value at `keyPath` its default value?
#
# * `scopeSelector` (optional) {String}. eg. '.source.ruby'
# * `keyPath` The {String} name of the key.
#
# Returns a {Boolean}, `true` if the current value is the default, `false`
# otherwise.
isDefault: (scopeSelector, keyPath) ->
if arguments.length == 1
keyPath = scopeSelector
scopeSelector = null
if scopeSelector?
settings = @scopedSettingsStore.propertiesForSourceAndSelector('user-config', scopeSelector)
not _.valueForKeyPath(settings, keyPath)?
isDefault: ->
Grim.deprecate("Use `not ::get(keyPath, {scope, sources: [atom.config.getUserConfigPath()]})?` instead")
if arguments.length is 1
[keyPath] = arguments
scopeSelector = '*'
else
not _.valueForKeyPath(@settings, keyPath)?
[scopeSelector, keyPath] = arguments
not @get(keyPath, {scope: [scopeSelector], sources: [@getUserConfigPath()]})?
# Extended: Retrieve the schema for a specific key path. The schema will tell
# you what type the keyPath expects, and other metadata about the config
@@ -604,47 +658,53 @@ class Config
schema = schema.properties[key]
schema
# Extended: Returns a new {Object} containing all of the global settings and
# Deprecated: Returns a new {Object} containing all of the global settings and
# defaults. Returns the scoped settings when a `scopeSelector` is specified.
#
# * `scopeSelector` (optional) {String}. eg. '.source.ruby'
getSettings: (scopeSelector) ->
settings = _.deepExtend(@settings, @defaultSettings)
if scopeSelector?
scopedSettings = @scopedSettingsStore.propertiesForSelector(scopeSelector)
settings = _.deepExtend(scopedSettings, settings)
settings
getSettings: ->
Grim.deprecate "Use ::get(keyPath) instead"
_.deepExtend({}, @defaultSettings, @scopedSettingsStore.getProperties('.xxx')...)
# Extended: Get the {String} path to the config file being used.
getUserConfigPath: ->
@configFilePath
# Extended: Suppress calls to handler functions registered with {::onDidChange}
# and {::observe} for the duration of `callback`. After `callback` executes,
# handlers will be called once if the value for their key-path has changed.
#
# * `callback` {Function} to execute while suppressing calls to handlers.
transact: (callback) ->
@transactDepth++
try
callback()
finally
@transactDepth--
@emitChangeEvent()
###
Section: Deprecated
###
getInt: (keyPath) ->
deprecate '''Config::getInt is no longer necessary. Use ::get instead.
Grim.deprecate '''Config::getInt is no longer necessary. Use ::get instead.
Make sure the config option you are accessing has specified an `integer`
schema. See the schema section of
https://atom.io/docs/api/latest/Config for more info.'''
parseInt(@get(keyPath))
getPositiveInt: (keyPath, defaultValue=0) ->
deprecate '''Config::getPositiveInt is no longer necessary. Use ::get instead.
Grim.deprecate '''Config::getPositiveInt is no longer necessary. Use ::get instead.
Make sure the config option you are accessing has specified an `integer`
schema with `minimum: 1`. See the schema section of
https://atom.io/docs/api/latest/Config for more info.'''
Math.max(@getInt(keyPath), 0) or defaultValue
toggle: (keyPath) ->
deprecate 'Config::toggle is no longer supported. Please remove from your code.'
Grim.deprecate 'Config::toggle is no longer supported. Please remove from your code.'
@set(keyPath, !@get(keyPath))
unobserve: (keyPath) ->
deprecate 'Config::unobserve no longer does anything. Call `.dispose()` on the object returned by Config::observe instead.'
Grim.deprecate 'Config::unobserve no longer does anything. Call `.dispose()` on the object returned by Config::observe instead.'
###
Section: Internal methods used by core
@@ -745,55 +805,43 @@ class Config
console.error detail
save: ->
allSettings = global: @settings
allSettings = _.extend allSettings, @scopedSettingsStore.propertiesForSource('user-config')
CSON.writeFileSync(@configFilePath, allSettings)
settings = @scopedSettingsStore.propertiesForSource(@getUserConfigPath())
settings.global = settings['*']
delete settings['*']
CSON.writeFileSync(@configFilePath, settings)
###
Section: Private methods managing global settings
###
resetUserSettings: (newSettings) ->
@scopedSettingsStore.removePropertiesForSource(@getUserConfigPath())
unless isPlainObject(newSettings)
@settings = {}
@emitter.emit 'did-change'
@emitChangeEvent()
return
if newSettings.global?
scopedSettings = newSettings
newSettings = newSettings.global
delete scopedSettings.global
@resetUserScopedSettings(scopedSettings)
unless newSettings.global?
newSettings = {global: newSettings}
unsetUnspecifiedValues = (keyPath, value) =>
if isPlainObject(value)
keys = splitKeyPath(keyPath)
for key, childValue of value
continue unless value.hasOwnProperty(key)
unsetUnspecifiedValues(keys.concat([key]).join('.'), childValue)
for selector, settings of newSettings
unless settings is undefined
try
settings = @makeValueConformToSchema(null, settings)
catch e
continue
if selector is 'global'
@setRawValue(@getUserConfigPath(), null, settings)
else
@setRawValue(keyPath, undefined) unless _.valueForKeyPath(newSettings, keyPath)?
return
@setRawScopedValue(@getUserConfigPath(), selector, null, settings)
@setRecursive(null, newSettings)
unsetUnspecifiedValues(null, @settings)
@emitChangeEvent()
setRecursive: (keyPath, value) ->
if isPlainObject(value)
keys = splitKeyPath(keyPath)
for key, childValue of value
continue unless value.hasOwnProperty(key)
@setRecursive(keys.concat([key]).join('.'), childValue)
else
try
value = @makeValueConformToSchema(keyPath, value)
@setRawValue(keyPath, value)
catch e
console.warn("'#{keyPath}' could not be set. Attempted value: #{JSON.stringify(value)}; Schema: #{JSON.stringify(@getSchema(keyPath))}")
getRawValue: (keyPath) ->
value = _.valueForKeyPath(@settings, keyPath)
defaultValue = _.valueForKeyPath(@defaultSettings, keyPath)
getRawValue: (keyPath, options) ->
value = @getRawScopedValue(['xxx'], keyPath, options)
unless options?.sources?.length > 0
defaultValue = _.valueForKeyPath(@defaultSettings, keyPath)
if value?
value = _.deepClone(value)
@@ -803,23 +851,17 @@ class Config
value
setRawValue: (keyPath, value) ->
setRawValue: (source, keyPath, value) ->
defaultValue = _.valueForKeyPath(@defaultSettings, keyPath)
value = undefined if _.isEqual(defaultValue, value)
oldValue = _.clone(@get(keyPath))
_.setValueForKeyPath(@settings, keyPath, value)
newValue = @get(keyPath)
@emitter.emit 'did-change', {oldValue, newValue, keyPath} unless _.isEqual(newValue, oldValue)
@setRawScopedValue(source, '*', keyPath, value)
@emitChangeEvent()
observeKeyPath: (keyPath, options, callback) ->
callback(_.clone(@get(keyPath))) unless options.callNow == false
@emitter.on 'did-change', (event) =>
callback(event.newValue) if keyPath? and @isSubKeyPath(keyPath, event?.keyPath)
@observeScopedKeyPath(["xxx"], keyPath, callback)
onDidChangeKeyPath: (keyPath, callback) ->
@emitter.on 'did-change', (event) =>
callback(event) if not keyPath? or (keyPath? and @isSubKeyPath(keyPath, event?.keyPath))
@onDidChangeScopedKeyPath(["xxx"], keyPath, callback)
isSubKeyPath: (keyPath, subKeyPath) ->
return false unless keyPath? and subKeyPath?
@@ -828,10 +870,8 @@ class Config
_.isEqual(pathTokens, pathSubTokens)
setRawDefault: (keyPath, value) ->
oldValue = _.clone(@get(keyPath))
_.setValueForKeyPath(@defaultSettings, keyPath, value)
newValue = @get(keyPath)
@emitter.emit 'did-change', {oldValue, newValue, keyPath} unless _.isEqual(newValue, oldValue)
@emitChangeEvent()
setDefaults: (keyPath, defaults) ->
if defaults? and isPlainObject(defaults)
@@ -843,6 +883,7 @@ class Config
try
defaults = @makeValueConformToSchema(keyPath, defaults)
@setRawDefault(keyPath, defaults)
@emitChangeEvent()
catch e
console.warn("'#{keyPath}' could not set the default. Attempted default: #{JSON.stringify(defaults)}; Schema: #{JSON.stringify(@getSchema(keyPath))}")
@@ -889,56 +930,45 @@ class Config
Section: Private Scoped Settings
###
resetUserScopedSettings: (newScopedSettings) ->
@usersScopedSettings?.dispose()
@usersScopedSettings = new CompositeDisposable
@usersScopedSettings.add @scopedSettingsStore.addProperties('user-config', newScopedSettings, @usersScopedSettingPriority)
@emitter.emit 'did-change'
emitChangeEvent: ->
@emitter.emit 'did-change' unless @transactDepth > 0
addScopedSettings: (source, selector, value, options) ->
settingsBySelector = {}
settingsBySelector[selector] = value
disposable = @scopedSettingsStore.addProperties(source, settingsBySelector, options)
@emitter.emit 'did-change'
@emitChangeEvent()
new Disposable =>
disposable.dispose()
@emitter.emit 'did-change'
@emitChangeEvent()
setRawScopedValue: (selector, keyPath, value) ->
setRawScopedValue: (source, selector, keyPath, value) ->
if keyPath?
newValue = {}
_.setValueForKeyPath(newValue, keyPath, value)
setValueAtKeyPath(newValue, keyPath, value)
value = newValue
settingsBySelector = {}
settingsBySelector[selector] = value
@usersScopedSettings.add @scopedSettingsStore.addProperties('user-config', settingsBySelector, @usersScopedSettingPriority)
@emitter.emit 'did-change'
@usersScopedSettings.add @scopedSettingsStore.addProperties(source, settingsBySelector, priority: @prioritiesBySource[source])
getRawScopedValue: (scopeDescriptor, keyPath) ->
getRawScopedValue: (scopeDescriptor, keyPath, options) ->
scopeDescriptor = ScopeDescriptor.fromObject(scopeDescriptor)
@scopedSettingsStore.getPropertyValue(scopeDescriptor.getScopeChain(), keyPath)
value = @scopedSettingsStore.getPropertyValue(scopeDescriptor.getScopeChain(), keyPath, options)
value
observeScopedKeyPath: (scopeDescriptor, keyPath, callback) ->
oldValue = @get(scopeDescriptor, keyPath)
observeScopedKeyPath: (scope, keyPath, callback) ->
callback(@get(keyPath, {scope}))
@onDidChangeScopedKeyPath scope, keyPath, ({newValue}) ->
callback(newValue)
callback(oldValue)
didChange = =>
newValue = @get(scopeDescriptor, keyPath)
callback(newValue) unless _.isEqual(oldValue, newValue)
oldValue = newValue
@emitter.on 'did-change', didChange
onDidChangeScopedKeyPath: (scopeDescriptor, keyPath, callback) ->
oldValue = @get(scopeDescriptor, keyPath)
didChange = =>
newValue = @get(scopeDescriptor, keyPath)
callback({oldValue, newValue, keyPath}) unless _.isEqual(oldValue, newValue)
oldValue = newValue
@emitter.on 'did-change', didChange
onDidChangeScopedKeyPath: (scope, keyPath, callback) ->
oldValue = _.deepClone(@get(keyPath, {scope}))
@emitter.on 'did-change', (event) =>
newValue = @get(keyPath, {scope})
unless _.isEqual(newValue, oldValue)
callback({newValue, oldValue})
oldValue = _.deepClone(newValue)
# TODO: figure out how to change / remove this. The return value is awkward.
# * language mode uses it for one thing.
@@ -1004,7 +1034,11 @@ Config.addSchemaEnforcers
for prop, childSchema of schema.properties
continue unless value.hasOwnProperty(prop)
try
newValue[prop] = @executeSchemaEnforcers("#{keyPath}.#{prop}", value[prop], childSchema)
newKeyPath = if keyPath?
"#{keyPath}.#{prop}"
else
prop
newValue[prop] = @executeSchemaEnforcers(newKeyPath, value[prop], childSchema)
catch error
console.warn "Error setting item in object: #{error.message}"
newValue
@@ -1057,6 +1091,21 @@ splitKeyPath = (keyPath) ->
keyPathArray.push keyPath.substr(startIndex, keyPath.length)
keyPathArray
getValueAtKeyPath = (object, keyPath) ->
keys = splitKeyPath(keyPath)
for key in keys
object = object[key]
return unless object?
object
setValueAtKeyPath = (object, keyPath, value) ->
keys = splitKeyPath(keyPath)
while keys.length > 1
key = keys.shift()
object[key] ?= {}
object = object[key]
object[keys.shift()] = value
withoutEmptyObjects = (object) ->
resultObject = undefined
if isPlainObject(object)
+6 -6
Ver Arquivo
@@ -45,7 +45,7 @@ class Cursor extends Model
cursor: this
@emit 'moved', movedEvent
@emitter.emit 'did-change-position'
@emitter.emit 'did-change-position', movedEvent
@editor.cursorMoved(movedEvent)
@marker.onDidDestroy =>
@destroyed = true
@@ -202,7 +202,7 @@ class Cursor extends Model
[before, after] = @editor.getTextInBufferRange(range)
return false if /\s/.test(before) or /\s/.test(after)
nonWordCharacters = atom.config.get(@getScopeDescriptor(), 'editor.nonWordCharacters').split('')
nonWordCharacters = atom.config.get('editor.nonWordCharacters', scope: @getScopeDescriptor()).split('')
_.contains(nonWordCharacters, before) isnt _.contains(nonWordCharacters, after)
# Public: Returns whether this cursor is between a word's start and end.
@@ -636,7 +636,7 @@ class Cursor extends Model
# Returns a {RegExp}.
wordRegExp: ({includeNonWordCharacters}={}) ->
includeNonWordCharacters ?= true
nonWordCharacters = atom.config.get(@getScopeDescriptor(), 'editor.nonWordCharacters')
nonWordCharacters = atom.config.get('editor.nonWordCharacters', scope: @getScopeDescriptor())
segments = ["^[\t ]*$"]
segments.push("[^\\s#{_.escapeRegExp(nonWordCharacters)}]+")
if includeNonWordCharacters
@@ -665,7 +665,7 @@ class Cursor extends Model
autoscroll: (options) ->
@editor.scrollToScreenRange(@getScreenRange(), options)
getBeginningOfNextParagraphBufferPosition: (editor) ->
getBeginningOfNextParagraphBufferPosition: ->
start = @getBufferPosition()
eof = @editor.getEofBufferPosition()
scanRange = [start, eof]
@@ -679,8 +679,8 @@ class Cursor extends Model
stop()
@editor.screenPositionForBufferPosition(position)
getBeginningOfPreviousParagraphBufferPosition: (editor) ->
start = @editor.getCursorBufferPosition()
getBeginningOfPreviousParagraphBufferPosition: ->
start = @getBufferPosition()
{row, column} = start
scanRange = [[row-1, column], [0,0]]
+23 -18
Ver Arquivo
@@ -67,24 +67,24 @@ class DisplayBuffer extends Model
oldConfigSettings = @configSettings
@configSettings =
scrollPastEnd: atom.config.get(scopeDescriptor, 'editor.scrollPastEnd')
softWrap: atom.config.get(scopeDescriptor, 'editor.softWrap')
softWrapAtPreferredLineLength: atom.config.get(scopeDescriptor, 'editor.softWrapAtPreferredLineLength')
preferredLineLength: atom.config.get(scopeDescriptor, 'editor.preferredLineLength')
scrollPastEnd: atom.config.get('editor.scrollPastEnd', scope: scopeDescriptor)
softWrap: atom.config.get('editor.softWrap', scope: scopeDescriptor)
softWrapAtPreferredLineLength: atom.config.get('editor.softWrapAtPreferredLineLength', scope: scopeDescriptor)
preferredLineLength: atom.config.get('editor.preferredLineLength', scope: scopeDescriptor)
subscriptions.add atom.config.onDidChange scopeDescriptor, 'editor.softWrap', ({newValue}) =>
subscriptions.add atom.config.onDidChange 'editor.softWrap', scope: scopeDescriptor, ({newValue}) =>
@configSettings.softWrap = newValue
@updateWrappedScreenLines()
subscriptions.add atom.config.onDidChange scopeDescriptor, 'editor.softWrapAtPreferredLineLength', ({newValue}) =>
subscriptions.add atom.config.onDidChange 'editor.softWrapAtPreferredLineLength', scope: scopeDescriptor, ({newValue}) =>
@configSettings.softWrapAtPreferredLineLength = newValue
@updateWrappedScreenLines() if @isSoftWrapped()
subscriptions.add atom.config.onDidChange scopeDescriptor, 'editor.preferredLineLength', ({newValue}) =>
subscriptions.add atom.config.onDidChange 'editor.preferredLineLength', scope: scopeDescriptor, ({newValue}) =>
@configSettings.preferredLineLength = newValue
@updateWrappedScreenLines() if @isSoftWrapped() and atom.config.get(scopeDescriptor, 'editor.softWrapAtPreferredLineLength')
@updateWrappedScreenLines() if @isSoftWrapped() and atom.config.get('editor.softWrapAtPreferredLineLength', scope: scopeDescriptor)
subscriptions.add atom.config.observe scopeDescriptor, 'editor.scrollPastEnd', (value) =>
subscriptions.add atom.config.observe 'editor.scrollPastEnd', scope: scopeDescriptor, (value) =>
@configSettings.scrollPastEnd = value
@updateWrappedScreenLines() if oldConfigSettings? and not _.isEqual(oldConfigSettings, @configSettings)
@@ -883,23 +883,28 @@ class DisplayBuffer extends Model
decorationForId: (id) ->
@decorationsById[id]
getDecorations: ->
getDecorations: (propertyFilter) ->
allDecorations = []
for markerId, decorations of @decorationsByMarkerId
allDecorations = allDecorations.concat(decorations) if decorations?
if propertyFilter?
allDecorations = allDecorations.filter (decoration) ->
for key, value of propertyFilter
return false unless decoration.properties[key] is value
true
allDecorations
getLineDecorations: ->
@getDecorations().filter (decoration) -> decoration.isType('line')
getLineDecorations: (propertyFilter) ->
@getDecorations(propertyFilter).filter (decoration) -> decoration.isType('line')
getGutterDecorations: ->
@getDecorations().filter (decoration) -> decoration.isType('gutter')
getGutterDecorations: (propertyFilter) ->
@getDecorations(propertyFilter).filter (decoration) -> decoration.isType('gutter')
getHighlightDecorations: ->
@getDecorations().filter (decoration) -> decoration.isType('highlight')
getHighlightDecorations: (propertyFilter) ->
@getDecorations(propertyFilter).filter (decoration) -> decoration.isType('highlight')
getOverlayDecorations: ->
@getDecorations().filter (decoration) -> decoration.isType('overlay')
getOverlayDecorations: (propertyFilter) ->
@getDecorations(propertyFilter).filter (decoration) -> decoration.isType('overlay')
decorationsForScreenRowRange: (startScreenRow, endScreenRow) ->
decorationsByMarkerId = {}
+2
Ver Arquivo
@@ -412,6 +412,8 @@ class GitRepository
bufferSubscriptions.add buffer.onDidDestroy =>
bufferSubscriptions.dispose()
@subscriptions.remove(bufferSubscriptions)
@subscriptions.add(bufferSubscriptions)
return
# Subscribes to editor view event.
checkoutHeadForEditor: (editor) ->
+1 -1
Ver Arquivo
@@ -316,7 +316,7 @@ class LanguageMode
@editor.setIndentationForBufferRow(bufferRow, desiredIndentLevel)
getRegexForProperty: (scopeDescriptor, property) ->
if pattern = atom.config.get(scopeDescriptor, property)
if pattern = atom.config.get(property, scope: scopeDescriptor)
new OnigRegExp(pattern)
increaseIndentRegexForScopeDescriptor: (scopeDescriptor) ->
+4 -2
Ver Arquivo
@@ -329,7 +329,8 @@ class PackageManager
@packageActivators.push([activator, types])
activatePackages: (packages) ->
@activatePackage(pack.name) for pack in packages
atom.config.transact =>
@activatePackage(pack.name) for pack in packages
@observeDisabledPackages()
# Activate a single package by name
@@ -344,7 +345,8 @@ class PackageManager
# Deactivate all packages
deactivatePackages: ->
@deactivatePackage(pack.name) for pack in @getLoadedPackages()
atom.config.transact =>
@deactivatePackage(pack.name) for pack in @getLoadedPackages()
@unobserveDisabledPackages()
# Deactivate the package with the given name
+1 -1
Ver Arquivo
@@ -156,7 +156,7 @@ class Package
catch e
console.warn "Failed to activate package named '#{@name}'", e.stack
@activationDeferred.resolve()
@activationDeferred?.resolve()
activateConfig: ->
return if @configActivated
+2 -2
Ver Arquivo
@@ -1,5 +1,5 @@
_ = require 'underscore-plus'
child_process = require 'child_process'
{fork} = require 'child_process'
{Emitter} = require 'emissary'
# Extended: Run a node script in a separate process.
@@ -98,7 +98,7 @@ class Task
taskPath = taskPath.replace(/\\/g, "\\\\")
env = _.extend({}, process.env, {taskPath, userAgent: navigator.userAgent})
@childProcess = child_process.fork '--eval', [bootstrap], {env, cwd: __dirname}
@childProcess = fork '--eval', [bootstrap], {env, cwd: __dirname}
@on "task:log", -> console.log(arguments...)
@on "task:warn", -> console.warn(arguments...)
+37 -21
Ver Arquivo
@@ -404,7 +404,7 @@ TextEditorComponent = React.createClass
window.addEventListener 'resize', @requestHeightAndWidthMeasurement
@listenForIMEEvents()
@listenForMiddleMousePaste() if process.platform is 'linux'
@trackSelectionClipboard() if process.platform is 'linux'
listenForIMEEvents: ->
node = @getDOMNode()
@@ -432,21 +432,21 @@ TextEditorComponent = React.createClass
editor.insertText(selectedText, select: true, undo: 'skip')
event.target.value = ''
listenForMiddleMousePaste: ->
clipboard = require 'clipboard'
@refs.scrollView.getDOMNode().addEventListener 'mouseup', ({which}) =>
return unless which is 2
if selection = clipboard.readText('selection')
@props.editor.insertText(selection)
@subscribe @props.editor.onDidChangeSelectionRange =>
if selectedText = @props.editor.getSelectedText()
# Listen for selection changes and store the currently selected text
# in the selection clipboard. This is only applicable on Linux.
trackSelectionClipboard: ->
timeoutId = null
{editor} = @props
writeSelectedTextToSelectionClipboard = =>
return if editor.isDestroyed()
if selectedText = editor.getSelectedText()
# This uses ipc.send instead of clipboard.writeText because
# clipboard.writeText is a sync ipc call on Linux and that
# will slow down selections.
ipc.send('write-text-to-selection-clipboard', selectedText)
@subscribe editor.onDidChangeSelectionRange ->
clearTimeout(timeoutId)
timeoutId = setTimeout(writeSelectedTextToSelectionClipboard)
observeConfig: ->
@subscribe atom.config.observe 'editor.useHardwareAcceleration', @setUseHardwareAcceleration
@@ -462,9 +462,9 @@ TextEditorComponent = React.createClass
scopeDescriptor = editor.getRootScopeDescriptor()
subscriptions.add atom.config.observe scopeDescriptor, 'editor.showIndentGuide', @setShowIndentGuide
subscriptions.add atom.config.observe scopeDescriptor, 'editor.showLineNumbers', @setShowLineNumbers
subscriptions.add atom.config.observe scopeDescriptor, 'editor.scrollSensitivity', @setScrollSensitivity
subscriptions.add atom.config.observe 'editor.showIndentGuide', scope: scopeDescriptor, @setShowIndentGuide
subscriptions.add atom.config.observe 'editor.showLineNumbers', scope: scopeDescriptor, @setShowLineNumbers
subscriptions.add atom.config.observe 'editor.scrollSensitivity', scope: scopeDescriptor, @setScrollSensitivity
focused: ->
if @isMounted()
@@ -560,7 +560,11 @@ TextEditorComponent = React.createClass
scrollViewNode.scrollLeft = 0
onMouseDown: (event) ->
return unless event.button is 0 # only handle the left mouse button
unless event.button is 0 or (event.button is 1 and process.platform is 'linux')
# Only handle mouse down events for left mouse button on all platforms
# and middle mouse button on Linux since it pastes the selection clipboard
return
return if event.target?.classList.contains('horizontal-scrollbar')
{editor} = @props
@@ -669,8 +673,9 @@ TextEditorComponent = React.createClass
# reloaded in dev mode. It seems like a workaround for a browser bug, but
# not totally sure.
requestAnimationFrame =>
@refreshScrollbars() if not styleElement.sheet? or @containsScrollbarSelector(styleElement.sheet)
@handleStylingChange()
if @isMounted()
@refreshScrollbars() if not styleElement.sheet? or @containsScrollbarSelector(styleElement.sheet)
@handleStylingChange()
onAllThemesLoaded: ->
@refreshScrollbars()
@@ -749,10 +754,12 @@ TextEditorComponent = React.createClass
lastMousePosition = {}
animationLoop = =>
@requestAnimationFrame =>
if dragging
if dragging and @isMounted()
screenPosition = @screenPositionForMouseEvent(lastMousePosition)
dragHandler(screenPosition)
animationLoop()
else if not @isMounted()
stopDragging()
onMouseMove = (event) ->
lastMousePosition.clientX = event.clientX
@@ -766,11 +773,20 @@ TextEditorComponent = React.createClass
# Stop dragging when cursor enters dev tools because we can't detect mouseup
onMouseUp() if event.which is 0
onMouseUp = ->
onMouseUp = (event) ->
stopDragging()
editor.finalizeSelections()
pasteSelectionClipboard(event)
stopDragging = ->
dragging = false
window.removeEventListener('mousemove', onMouseMove)
window.removeEventListener('mouseup', onMouseUp)
editor.finalizeSelections()
pasteSelectionClipboard = (event) ->
if event?.which is 2 and process.platform is 'linux'
if selection = require('clipboard').readText('selection')
editor.insertText(selection)
window.addEventListener('mousemove', onMouseMove)
window.addEventListener('mouseup', onMouseUp)
+1 -1
Ver Arquivo
@@ -123,7 +123,7 @@ class TextEditorElement extends HTMLElement
unmountComponent: ->
return unless @component?.isMounted()
callRemoveHooks(this)
React.unmountComponentAtNode(this)
React.unmountComponentAtNode(@rootElement)
@component = null
focused: ->
+31 -16
Ver Arquivo
@@ -168,8 +168,8 @@ class TextEditor extends Model
scopeDescriptor = @getRootScopeDescriptor()
subscriptions.add atom.config.onDidChange scopeDescriptor, 'editor.showInvisibles', => @updateInvisibles()
subscriptions.add atom.config.onDidChange scopeDescriptor, 'editor.invisibles', => @updateInvisibles()
subscriptions.add atom.config.onDidChange 'editor.showInvisibles', scope: scopeDescriptor, => @updateInvisibles()
subscriptions.add atom.config.onDidChange 'editor.invisibles', scope: scopeDescriptor, => @updateInvisibles()
getViewClass: ->
require './text-editor-view'
@@ -1310,33 +1310,48 @@ class TextEditor extends Model
# Extended: Get all decorations.
#
# * `propertyFilter` (optional) An {Object} containing key value pairs that
# the returned decorations' properties must match.
#
# Returns an {Array} of {Decoration}s.
getDecorations: ->
@displayBuffer.getDecorations()
getDecorations: (propertyFilter) ->
@displayBuffer.getDecorations(propertyFilter)
# Extended: Get all decorations of type 'line'.
#
# * `propertyFilter` (optional) An {Object} containing key value pairs that
# the returned decorations' properties must match.
#
# Returns an {Array} of {Decoration}s.
getLineDecorations: ->
@displayBuffer.getLineDecorations()
getLineDecorations: (propertyFilter) ->
@displayBuffer.getLineDecorations(propertyFilter)
# Extended: Get all decorations of type 'gutter'.
#
# * `propertyFilter` (optional) An {Object} containing key value pairs that
# the returned decorations' properties must match.
#
# Returns an {Array} of {Decoration}s.
getGutterDecorations: ->
@displayBuffer.getGutterDecorations()
getGutterDecorations: (propertyFilter) ->
@displayBuffer.getGutterDecorations(propertyFilter)
# Extended: Get all decorations of type 'highlight'.
#
# * `propertyFilter` (optional) An {Object} containing key value pairs that
# the returned decorations' properties must match.
#
# Returns an {Array} of {Decoration}s.
getHighlightDecorations: ->
@displayBuffer.getHighlightDecorations()
getHighlightDecorations: (propertyFilter) ->
@displayBuffer.getHighlightDecorations(propertyFilter)
# Extended: Get all decorations of type 'overlay'.
#
# * `propertyFilter` (optional) An {Object} containing key value pairs that
# the returned decorations' properties must match.
#
# Returns an {Array} of {Decoration}s.
getOverlayDecorations: ->
@displayBuffer.getOverlayDecorations()
getOverlayDecorations: (propertyFilter) ->
@displayBuffer.getOverlayDecorations(propertyFilter)
decorationForId: (id) ->
@displayBuffer.decorationForId(id)
@@ -2797,17 +2812,17 @@ class TextEditor extends Model
###
shouldAutoIndent: ->
atom.config.get(@getRootScopeDescriptor(), "editor.autoIndent")
atom.config.get("editor.autoIndent", scope: @getRootScopeDescriptor())
shouldAutoIndentOnPaste: ->
atom.config.get(@getRootScopeDescriptor(), "editor.autoIndentOnPaste")
atom.config.get("editor.autoIndentOnPaste", scope: @getRootScopeDescriptor())
shouldShowInvisibles: ->
not @mini and atom.config.get(@getRootScopeDescriptor(), 'editor.showInvisibles')
not @mini and atom.config.get('editor.showInvisibles', scope: @getRootScopeDescriptor())
updateInvisibles: ->
if @shouldShowInvisibles()
@displayBuffer.setInvisibles(atom.config.get(@getRootScopeDescriptor(), 'editor.invisibles'))
@displayBuffer.setInvisibles(atom.config.get('editor.invisibles', scope: @getRootScopeDescriptor()))
else
@displayBuffer.setInvisibles(null)
+2 -2
Ver Arquivo
@@ -84,10 +84,10 @@ class TokenizedBuffer extends Model
@currentGrammarScore = score ? grammar.getScore(@buffer.getPath(), @buffer.getText())
@subscribe @grammar.onDidUpdate => @retokenizeLines()
@configSettings = tabLength: atom.config.get(@rootScopeDescriptor, 'editor.tabLength')
@configSettings = tabLength: atom.config.get('editor.tabLength', scope: @rootScopeDescriptor)
@grammarTabLengthSubscription?.dispose()
@grammarTabLengthSubscription = atom.config.onDidChange @rootScopeDescriptor, 'editor.tabLength', ({newValue}) =>
@grammarTabLengthSubscription = atom.config.onDidChange 'editor.tabLength', scope: @rootScopeDescriptor, ({newValue}) =>
@configSettings.tabLength = newValue
@retokenizeLines()
@subscribe @grammarTabLengthSubscription
+6 -2
Ver Arquivo
@@ -112,6 +112,10 @@ class WorkspaceElement extends HTMLElement
focusPaneViewOnRight: -> @paneContainer.focusPaneViewOnRight()
runPackageSpecs: ->
[projectPath] = atom.project.getPaths()
ipc.send('run-package-specs', path.join(projectPath, 'spec')) if projectPath
atom.commands.add 'atom-workspace',
'window:increase-font-size': -> @getModel().increaseFontSize()
'window:decrease-font-size': -> @getModel().decreaseFontSize()
@@ -141,7 +145,7 @@ atom.commands.add 'atom-workspace',
'application:open-your-snippets': -> ipc.send('command', 'application:open-your-snippets')
'application:open-your-stylesheet': -> ipc.send('command', 'application:open-your-stylesheet')
'application:open-license': -> @getModel().openLicense()
'window:run-package-specs': -> ipc.send('run-package-specs', path.join(atom.project.getPath(), 'spec'))
'window:run-package-specs': -> @runPackageSpecs()
'window:focus-next-pane': -> @getModel().activateNextPane()
'window:focus-previous-pane': -> @getModel().activatePreviousPane()
'window:focus-pane-above': -> @focusPaneViewAbove()
@@ -150,7 +154,7 @@ atom.commands.add 'atom-workspace',
'window:focus-pane-on-right': -> @focusPaneViewOnRight()
'window:save-all': -> @getModel().saveAll()
'window:toggle-invisibles': -> atom.config.toggle("editor.showInvisibles")
'window:log-deprecation-warnings': -> Grim.logDeprecationWarnings()
'window:log-deprecation-warnings': -> Grim.logDeprecations()
'window:toggle-auto-indent': -> atom.config.toggle("editor.autoIndent")
'pane:reopen-closed-item': -> @getModel().reopenItem()
'core:close': -> @getModel().destroyActivePaneItemOrEmptyPane()
+17 -5
Ver Arquivo
@@ -459,8 +459,6 @@ class Workspace extends Model
@emit "uri-opened"
@emitter.emit 'did-open', {uri, pane, item, index}
item
.catch (error) ->
console.error(error.stack ? error)
# Public: Asynchronously reopens the last-closed item's URI if it hasn't already been
# reopened.
@@ -557,7 +555,7 @@ class Workspace extends Model
# {::saveActivePaneItemAs} # will be called instead. This method does nothing
# if the active item does not implement a `.save` method.
saveActivePaneItem: ->
@getActivePane().saveActiveItem()
@saveActivePaneItemAndReportErrors('saveActiveItem')
# Prompt the user for a path and save the active pane item to it.
#
@@ -565,7 +563,21 @@ class Workspace extends Model
# `.saveAs` on the item with the selected path. This method does nothing if
# the active item does not implement a `.saveAs` method.
saveActivePaneItemAs: ->
@getActivePane().saveActiveItemAs()
@saveActivePaneItemAndReportErrors('saveActiveItemAs')
saveActivePaneItemAndReportErrors: (method) ->
try
@getActivePane()[method]()
catch error
if error.message.endsWith('is a directory')
atom.notifications.addWarning("Unable to save file: #{error.message}")
else if error.message.startsWith('EACCES,')
atom.notifications.addWarning("Unable to save file: #{error.message.replace('EACCES, ', '')}")
else if errorMatch = /ENOTDIR, not a directory '([^']+)'/.exec(error.message)
fileName = errorMatch[1]
atom.notifications.addWarning("Unable to save file: A directory in the path '#{fileName}' could not be written to")
else
throw error
# Destroy (close) the active pane item.
#
@@ -633,7 +645,7 @@ class Workspace extends Model
# Restore to a default editor font size.
resetFontSize: ->
atom.config.restoreDefault("editor.fontSize")
atom.config.unset("editor.fontSize")
# Removes the item's uri from the list of potential items to reopen.
itemOpened: (item) ->
+1 -1
Ver Arquivo
@@ -82,4 +82,4 @@
// Other
@font-family: 'Lucida Grande', 'Segoe UI', sans-serif;
@font-family: 'Lucida Grande', 'Segoe UI', Ubuntu, Cantarell, sans-serif;