Comparar commits
253 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 7d3553659a | |||
| 28dad3a01a | |||
| be872c2fdd | |||
| 526d87c355 | |||
| cbeb0187da | |||
| 7c614c6c79 | |||
| f4f0b4be72 | |||
| 3e27beeafa | |||
| 4a6b70d261 | |||
| 5917f71685 | |||
| fb42c499b1 | |||
| 1583271e2f | |||
| 020e22a13d | |||
| a37a7e0a76 | |||
| d1b4d0f9f2 | |||
| fb111dd0f4 | |||
| 1392deb29c | |||
| 2dafc5eaa1 | |||
| a407b0107a | |||
| 36c3c38047 | |||
| e56317bd64 | |||
| da49751f24 | |||
| 762559d2b7 | |||
| 2a0070ef10 | |||
| 7c7de4436e | |||
| 87afa50477 | |||
| 2e71e2fa4b | |||
| b537ba8864 | |||
| c156119882 | |||
| fea958c8e4 | |||
| 8e0a695f7c | |||
| 47f99cd74e | |||
| 0eb5fd4c3b | |||
| 0c01de350d | |||
| 77641f138b | |||
| f24843a928 | |||
| 03ab77c60b | |||
| ec0ec3bb16 | |||
| 690fc7180a | |||
| 02553bf8e2 | |||
| 81646532b4 | |||
| 1e7c80aebf | |||
| 27fe5b784c | |||
| 9b2901583e | |||
| 408665d7d2 | |||
| 6ec58e1163 | |||
| 541ffa5057 | |||
| 0ea683e0b5 | |||
| f12004d27b | |||
| 35d268fcf8 | |||
| 20c3ca21e3 | |||
| 37d2e00f4e | |||
| 5bf9bbe764 | |||
| e37fc316fb | |||
| 9128041c20 | |||
| 020c5e795a | |||
| be3a6bc6d0 | |||
| 142bb4b615 | |||
| ddf7bb5303 | |||
| 442342937f | |||
| a967e52f68 | |||
| c475e89a3e | |||
| 58da88b71a | |||
| 71328f21bd | |||
| a1b0f6c25d | |||
| fdccc2dae4 | |||
| 1246f8ed20 | |||
| fb56817895 | |||
| b6d8d5d100 | |||
| 8eb23dbe5c | |||
| 34f624c895 | |||
| d554b7fd03 | |||
| a61dff6e21 | |||
| 47b820ce7d | |||
| 33557b87eb | |||
| aed0c16acc | |||
| b4c8cb4bf9 | |||
| 8988d55d25 | |||
| 5824b127ed | |||
| d6ec73886f | |||
| 411cf579f4 | |||
| ad0ed7e634 | |||
| 7c00e02b1a | |||
| e6040972d8 | |||
| ac2f723aba | |||
| ecfb505144 | |||
| 326d1dce14 | |||
| c2f87fb73b | |||
| 1245835e96 | |||
| e174bdfa40 | |||
| 3d8bc89c42 | |||
| 5fc6524493 | |||
| 6e6c93e6bb | |||
| fd48ad1c67 | |||
| 5163166990 | |||
| 54b60a5253 | |||
| ff1d07bec9 | |||
| 6d56283448 | |||
| 6dfbd5733d | |||
| e56fa3ec4f | |||
| fe0d714710 | |||
| 7c1a7f52a5 | |||
| 590c6be33d | |||
| f1ca7fdbfd | |||
| a8b135b4bc | |||
| 1afdd62a5d | |||
| d47e8fc583 | |||
| 3644a36d67 | |||
| bb98b3ef38 | |||
| 356a7b014a | |||
| 1ea0ef4ea2 | |||
| f37ca3e19c | |||
| 8afd90b9f8 | |||
| 613e05f4ac | |||
| 068eeca862 | |||
| 0502afb0c3 | |||
| e1491ca154 | |||
| e9a975fd92 | |||
| 1459123b15 | |||
| 9996eb825f | |||
| 10392942d5 | |||
| c452d05f44 | |||
| 1043f75c72 | |||
| ec69bb5ffe | |||
| 41cc0ecab4 | |||
| 67f8ddc314 | |||
| 10d626d63a | |||
| 2ec526508b | |||
| 6017ff585f | |||
| e6d656830f | |||
| 1a15c3394e | |||
| b328a69f50 | |||
| e9ee6dca25 | |||
| a2f73fd6b0 | |||
| 9f09173d0f | |||
| 1e052c1113 | |||
| b72bb4ab65 | |||
| 24f751ec83 | |||
| d72e3d9c81 | |||
| 0aeb32ad70 | |||
| 3393583b72 | |||
| 6fcd905d4f | |||
| 993534337c | |||
| 03814246ef | |||
| 053965602c | |||
| b45c1c7548 | |||
| e96d821653 | |||
| e3448b0a46 | |||
| 63a80a4d4d | |||
| d07eea405f | |||
| 87d008c337 | |||
| 4a55c90c63 | |||
| 7bce6cb10a | |||
| 32499351dc | |||
| 2d7dda066c | |||
| 837f3c553f | |||
| 96e3c63291 | |||
| d5da396c0f | |||
| 4b089b62a6 | |||
| be8514b864 | |||
| e826b66dd2 | |||
| 83d6fc2374 | |||
| ecdaf48308 | |||
| a79885eafb | |||
| a3c9a65838 | |||
| 8ca5d6db35 | |||
| 980c17e50c | |||
| c9bf8f04b8 | |||
| 6613b9fd4d | |||
| 3168751c97 | |||
| 6bc471cef1 | |||
| 4b3240eeee | |||
| 1f9de98eb2 | |||
| 7eea30fa7f | |||
| 63e51af87d | |||
| bbc6433a75 | |||
| d4ae836225 | |||
| 789f29e0b5 | |||
| c584c158d7 | |||
| d63c4f88fd | |||
| db327b92f3 | |||
| cd01e6f2ad | |||
| b1be4e9183 | |||
| 009a142273 | |||
| f0f00fd317 | |||
| f5ea098417 | |||
| 82081aa5e9 | |||
| 33adaab8b1 | |||
| e21a1339a2 | |||
| b90849fa66 | |||
| 23d3405ae7 | |||
| d39c422da9 | |||
| 053c0f703a | |||
| 1c91bd3100 | |||
| 0ffb5da515 | |||
| b7db7f6c99 | |||
| cae9782e24 | |||
| 5dbab7bb89 | |||
| ceab8e8166 | |||
| 97cb440a7c | |||
| fcdb42dbe4 | |||
| 11a91fb974 | |||
| 1d426e8fd2 | |||
| 6f0094e6ce | |||
| 915cad39e8 | |||
| d8f0743888 | |||
| 7685b27218 | |||
| 3aab0b7f51 | |||
| 2f5735e264 | |||
| 56bea31b5e | |||
| 52d5e205c7 | |||
| 0f5f6c8657 | |||
| 7457be2805 | |||
| 86842658c0 | |||
| d0276e60b5 | |||
| 18d6a56e82 | |||
| 59108322e7 | |||
| 665088ce27 | |||
| 79399a3c5a | |||
| 4659b95d36 | |||
| bdf73cd198 | |||
| 6e422d5428 | |||
| e464c4f047 | |||
| 4610c4446a | |||
| 156ca14ea6 | |||
| cebb27154d | |||
| afe6685ce8 | |||
| 148e143255 | |||
| 96d1c84f62 | |||
| f40ecccdcc | |||
| 03b9713547 | |||
| 9fb364026e | |||
| 1aa64a9d80 | |||
| 2ea09aa6b6 | |||
| 76ce150448 | |||
| 1d01ff0797 | |||
| a1d78a1062 | |||
| 3ac41a544a | |||
| 3e24d045e5 | |||
| 143738033b | |||
| f153cbb41f | |||
| f1ed5dedd7 | |||
| e58c2d8368 | |||
| bcf1781040 | |||
| 0b0dbbe4ee | |||
| c9e297a511 | |||
| 18082f7cdc | |||
| ca016ce116 | |||
| bb59e46267 | |||
| 9324b538f7 | |||
| 8c6ed69176 | |||
| 56222a072a | |||
| afbf011103 |
@@ -68,8 +68,6 @@ module.exports = (grunt) ->
|
||||
installDir = process.env.INSTALL_PREFIX ? '/usr/local'
|
||||
|
||||
coffeeConfig =
|
||||
options:
|
||||
sourceMap: true
|
||||
glob_to_multiple:
|
||||
expand: true
|
||||
src: [
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
'enter': 'editor:newline'
|
||||
'shift-tab': 'editor:outdent-selected-rows'
|
||||
'ctrl-K': 'editor:delete-line'
|
||||
'ctrl-shift-up': 'editor:add-selection-above'
|
||||
'ctrl-shift-down': 'editor:add-selection-below'
|
||||
|
||||
'.tool-panel.panel-left, .tool-panel.panel-right':
|
||||
'escape': 'tool-panel:unfocus'
|
||||
|
||||
@@ -138,6 +138,8 @@
|
||||
'cmd-j': 'editor:join-lines'
|
||||
'cmd-D': 'editor:duplicate-lines'
|
||||
'cmd-L': 'editor:split-selections-into-lines'
|
||||
'ctrl-shift-up': 'editor:add-selection-above'
|
||||
'ctrl-shift-down': 'editor:add-selection-below'
|
||||
|
||||
'cmd-alt-[': 'editor:fold-current-row'
|
||||
'cmd-alt-]': 'editor:unfold-current-row'
|
||||
|
||||
@@ -11,11 +11,12 @@
|
||||
'ctrl-alt-p': 'window:run-package-specs'
|
||||
'ctrl-alt-s': 'application:run-all-specs'
|
||||
'ctrl-shift-o': 'application:open-dev'
|
||||
'F11': 'window:toggle-full-screen'
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-N': 'application:new-window'
|
||||
'ctrl-W': 'window:close'
|
||||
'ctrl-o': 'application:open'
|
||||
'ctrl-o': 'application:open-file'
|
||||
'ctrl-q': 'application:quit'
|
||||
'ctrl-T': 'pane:reopen-closed-item'
|
||||
'ctrl-n': 'application:new-file'
|
||||
@@ -84,6 +85,8 @@
|
||||
'ctrl-/': 'editor:toggle-line-comments'
|
||||
'ctrl-j': 'editor:join-lines'
|
||||
'ctrl-D': 'editor:duplicate-lines'
|
||||
'alt-shift-up': 'editor:add-selection-above'
|
||||
'alt-shift-down': 'editor:add-selection-below'
|
||||
|
||||
'ctrl-alt-[': 'editor:fold-current-row'
|
||||
'ctrl-alt-]': 'editor:unfold-current-row'
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# Sublime Parity
|
||||
'ctrl-N': 'application:new-window'
|
||||
'ctrl-W': 'window:close'
|
||||
'ctrl-o': 'application:open'
|
||||
'ctrl-o': 'application:open-file'
|
||||
'ctrl-T': 'pane:reopen-closed-item'
|
||||
'ctrl-n': 'application:new-file'
|
||||
'ctrl-s': 'core:save'
|
||||
|
||||
+4
-4
@@ -4,10 +4,10 @@
|
||||
submenu: [
|
||||
{ label: 'About Atom', command: 'application:about' }
|
||||
{ label: 'View License', command: 'application:open-license' }
|
||||
{ label: "VERSION", enabled: false }
|
||||
{ label: "Restart and Install Update", command: 'application:install-update', visible: false}
|
||||
{ label: "Check for Update", command: 'application:check-for-update', visible: false}
|
||||
{ label: "Downloading Update", command: 'application:check-for-update', enabled: false, visible: false}
|
||||
{ label: 'VERSION', enabled: false }
|
||||
{ label: 'Restart and Install Update', command: 'application:install-update', visible: false}
|
||||
{ label: 'Check for Update', command: 'application:check-for-update', visible: false}
|
||||
{ label: 'Downloading Update', enabled: false, visible: false}
|
||||
{ type: 'separator' }
|
||||
{ label: 'Preferences...', command: 'application:show-settings' }
|
||||
{ label: 'Open Your Config', command: 'application:open-your-config' }
|
||||
|
||||
+2
-1
@@ -4,7 +4,8 @@
|
||||
submenu: [
|
||||
{ label: 'New &Window', command: 'application:new-window' }
|
||||
{ label: '&New File', command: 'application:new-file' }
|
||||
{ label: '&Open...', command: 'application:open' }
|
||||
{ label: '&Open File...', command: 'application:open-file' }
|
||||
{ label: 'Open Folder...', command: 'application:open-folder' }
|
||||
{ label: 'Reopen Last &Item', command: 'pane:reopen-closed-item' }
|
||||
{ type: 'separator' }
|
||||
{ label: '&Preferences...', command: 'application:show-settings' }
|
||||
|
||||
+2
-1
@@ -4,7 +4,8 @@
|
||||
submenu: [
|
||||
{ label: 'New &Window', command: 'application:new-window' }
|
||||
{ label: '&New File', command: 'application:new-file' }
|
||||
{ label: '&Open...', command: 'application:open' }
|
||||
{ label: '&Open File...', command: 'application:open-file' }
|
||||
{ label: 'Open Folder...', command: 'application:open-folder' }
|
||||
{ label: 'Reopen Last &Item', command: 'pane:reopen-closed-item' }
|
||||
{ type: 'separator' }
|
||||
{ label: '&Preferences...', command: 'application:show-settings' }
|
||||
|
||||
+49
-48
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.82.0",
|
||||
"version": "0.90.0",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
@@ -12,24 +12,24 @@
|
||||
"url": "https://github.com/atom/atom/issues"
|
||||
},
|
||||
"license": "All Rights Reserved",
|
||||
"atomShellVersion": "0.11.5",
|
||||
"atomShellVersion": "0.11.10",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^0.16.0",
|
||||
"atom-keymap": "^0.18.0",
|
||||
"bootstrap": "git://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
|
||||
"clear-cut": "0.4.0",
|
||||
"coffee-script": "1.7.0",
|
||||
"coffeestack": "0.7.0",
|
||||
"delegato": "1.x",
|
||||
"emissary": "^1.2.1",
|
||||
"first-mate": "^1.4.2",
|
||||
"fs-plus": "^2.2",
|
||||
"first-mate": "^1.5.1",
|
||||
"fs-plus": "^2.2.2",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "~1.1",
|
||||
"git-utils": "^1.2.2",
|
||||
"grim": "0.9.0",
|
||||
"guid": "0.0.10",
|
||||
"jasmine-tagged": "^1.1.1",
|
||||
"keytar": "1.x",
|
||||
"less-cache": "0.12.0",
|
||||
"mixto": "1.x",
|
||||
"mkdirp": "0.3.5",
|
||||
@@ -42,14 +42,14 @@
|
||||
"random-words": "0.0.1",
|
||||
"runas": "0.5.x",
|
||||
"scandal": "0.15.2",
|
||||
"scoped-property-store": "^0.7.0",
|
||||
"scoped-property-store": "^0.8.0",
|
||||
"scrollbar-style": "^0.1.0",
|
||||
"season": "^1.0.2",
|
||||
"semver": "1.1.4",
|
||||
"serializable": "1.x",
|
||||
"space-pen": "3.1.1",
|
||||
"temp": "0.5.0",
|
||||
"text-buffer": "^1.4.6",
|
||||
"text-buffer": "^2.1.0",
|
||||
"theorist": "1.x",
|
||||
"underscore-plus": "^1.1.2",
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
@@ -58,75 +58,76 @@
|
||||
"atom-dark-syntax": "0.15.0",
|
||||
"atom-dark-ui": "0.26.0",
|
||||
"atom-light-syntax": "0.16.0",
|
||||
"atom-light-ui": "0.23.0",
|
||||
"base16-tomorrow-dark-theme": "0.13.0",
|
||||
"atom-light-ui": "0.24.0",
|
||||
"base16-tomorrow-dark-theme": "0.14.0",
|
||||
"solarized-dark-syntax": "0.14.0",
|
||||
"solarized-light-syntax": "0.7.0",
|
||||
"archive-view": "0.30.0",
|
||||
"autocomplete": "0.27.0",
|
||||
"autoflow": "0.15.0",
|
||||
"autoflow": "0.16.0",
|
||||
"autosave": "0.13.0",
|
||||
"background-tips": "0.10.0",
|
||||
"background-tips": "0.13.0",
|
||||
"bookmarks": "0.22.0",
|
||||
"bracket-matcher": "0.29.0",
|
||||
"command-palette": "0.20.0",
|
||||
"bracket-matcher": "0.33.0",
|
||||
"command-palette": "0.21.0",
|
||||
"deprecation-cop": "0.5.0",
|
||||
"dev-live-reload": "0.30.0",
|
||||
"exception-reporting": "0.17.0",
|
||||
"feedback": "0.28.0",
|
||||
"find-and-replace": "0.94.0",
|
||||
"fuzzy-finder": "0.45.0",
|
||||
"git-diff": "0.27.0",
|
||||
"go-to-line": "0.18.0",
|
||||
"grammar-selector": "0.23.0",
|
||||
"image-view": "0.32.0",
|
||||
"keybinding-resolver": "0.15.0",
|
||||
"link": "0.20.0",
|
||||
"markdown-preview": "0.56.0",
|
||||
"feedback": "0.30.0",
|
||||
"find-and-replace": "0.99.0",
|
||||
"fuzzy-finder": "0.50.0",
|
||||
"git-diff": "0.28.0",
|
||||
"go-to-line": "0.19.0",
|
||||
"grammar-selector": "0.24.0",
|
||||
"image-view": "0.33.0",
|
||||
"keybinding-resolver": "0.17.0",
|
||||
"link": "0.22.0",
|
||||
"markdown-preview": "0.64.0",
|
||||
"metrics": "0.32.0",
|
||||
"open-on-github": "0.25.0",
|
||||
"open-on-github": "0.28.0",
|
||||
"package-generator": "0.30.0",
|
||||
"release-notes": "0.26.0",
|
||||
"settings-view": "0.106.0",
|
||||
"snippets": "0.40.0",
|
||||
"spell-check": "0.32.0",
|
||||
"status-bar": "0.38.0",
|
||||
"styleguide": "0.28.0",
|
||||
"release-notes": "0.27.0",
|
||||
"settings-view": "0.110.0",
|
||||
"snippets": "0.41.0",
|
||||
"spell-check": "0.34.0",
|
||||
"status-bar": "0.40.0",
|
||||
"styleguide": "0.29.0",
|
||||
"symbols-view": "0.49.0",
|
||||
"tabs": "0.33.0",
|
||||
"timecop": "0.17.0",
|
||||
"tree-view": "0.86.0",
|
||||
"tabs": "0.36.0",
|
||||
"timecop": "0.18.0",
|
||||
"tree-view": "0.90.0",
|
||||
"update-package-dependencies": "0.6.0",
|
||||
"welcome": "0.12.0",
|
||||
"whitespace": "0.22.0",
|
||||
"wrap-guide": "0.18.0",
|
||||
"language-c": "0.13.0",
|
||||
"language-coffee-script": "0.17.0",
|
||||
"language-css": "0.13.0",
|
||||
"language-gfm": "0.28.0",
|
||||
"language-c": "0.14.0",
|
||||
"language-coffee-script": "0.22.0",
|
||||
"language-css": "0.16.0",
|
||||
"language-gfm": "0.31.0",
|
||||
"language-git": "0.9.0",
|
||||
"language-go": "0.8.0",
|
||||
"language-html": "0.17.0",
|
||||
"language-go": "0.9.0",
|
||||
"language-html": "0.19.0",
|
||||
"language-hyperlink": "0.9.0",
|
||||
"language-java": "0.9.0",
|
||||
"language-javascript": "0.21.0",
|
||||
"language-javascript": "0.24.0",
|
||||
"language-json": "0.8.0",
|
||||
"language-less": "0.6.0",
|
||||
"language-make": "0.9.0",
|
||||
"language-less": "0.8.0",
|
||||
"language-make": "0.10.0",
|
||||
"language-objective-c": "0.11.0",
|
||||
"language-perl": "0.8.0",
|
||||
"language-php": "0.14.0",
|
||||
"language-property-list": "0.7.0",
|
||||
"language-python": "0.14.0",
|
||||
"language-ruby": "0.21.0",
|
||||
"language-python": "0.15.0",
|
||||
"language-ruby": "0.22.0",
|
||||
"language-ruby-on-rails": "0.12.0",
|
||||
"language-sass": "0.8.0",
|
||||
"language-shellscript": "0.8.0",
|
||||
"language-source": "0.7.0",
|
||||
"language-sql": "0.7.0",
|
||||
"language-sql": "0.8.0",
|
||||
"language-text": "0.6.0",
|
||||
"language-todo": "0.9.0",
|
||||
"language-todo": "0.10.0",
|
||||
"language-toml": "0.12.0",
|
||||
"language-xml": "0.9.0",
|
||||
"language-xml": "0.11.0",
|
||||
"language-yaml": "0.6.0"
|
||||
},
|
||||
"private": true,
|
||||
|
||||
+1
-1
@@ -23,9 +23,9 @@ var commands = [
|
||||
[home, '.atom', '.node-gyp'],
|
||||
[home, '.atom', 'storage'],
|
||||
[home, '.atom', '.npm'],
|
||||
[home, '.atom', 'compile-cache'],
|
||||
[tmpdir, 'atom-build'],
|
||||
[tmpdir, 'atom-cached-atom-shells'],
|
||||
[tmpdir, 'atom-compile-cache'],
|
||||
];
|
||||
var run = function() {
|
||||
var next = commands.shift();
|
||||
|
||||
@@ -36,15 +36,53 @@ describe "Config", ->
|
||||
|
||||
describe "when the value equals the default value", ->
|
||||
it "does not store the value", ->
|
||||
atom.config.setDefaults("foo", same: 1, changes: 1)
|
||||
atom.config.setDefaults "foo",
|
||||
same: 1
|
||||
changes: 1
|
||||
sameArray: [1, 2, 3]
|
||||
sameObject: {a: 1, b: 2}
|
||||
null: null
|
||||
undefined: undefined
|
||||
expect(atom.config.settings.foo).toBeUndefined()
|
||||
|
||||
atom.config.set('foo.same', 1)
|
||||
atom.config.set('foo.changes', 2)
|
||||
atom.config.set('foo.sameArray', [1, 2, 3])
|
||||
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}
|
||||
|
||||
atom.config.set('foo.changes', 1)
|
||||
expect(atom.config.settings.foo).toEqual {}
|
||||
|
||||
describe ".getDefault(keyPath)", ->
|
||||
it "returns a clone of the default value", ->
|
||||
atom.config.setDefaults("foo", same: 1, changes: 1)
|
||||
expect(atom.config.getDefault('foo.same')).toBe 1
|
||||
expect(atom.config.getDefault('foo.changes')).toBe 1
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
expect(atom.config.isDefault('foo.same')).toBe true
|
||||
expect(atom.config.isDefault('foo.changes')).toBe true
|
||||
|
||||
atom.config.set('foo.same', 2)
|
||||
atom.config.set('foo.changes', 3)
|
||||
expect(atom.config.isDefault('foo.same')).toBe false
|
||||
expect(atom.config.isDefault('foo.changes')).toBe false
|
||||
|
||||
describe ".toggle(keyPath)", ->
|
||||
it "negates the boolean value of the current key path value", ->
|
||||
atom.config.set('foo.a', 1)
|
||||
@@ -170,6 +208,13 @@ describe "Config", ->
|
||||
expect(atom.config.get("foo.quux.x")).toBe 0
|
||||
expect(atom.config.get("foo.quux.y")).toBe 1
|
||||
|
||||
it "emits an updated event", ->
|
||||
updatedCallback = jasmine.createSpy('updated')
|
||||
atom.config.observe('foo.bar.baz.a', callNow: false, updatedCallback)
|
||||
expect(updatedCallback.callCount).toBe 0
|
||||
atom.config.setDefaults("foo.bar.baz", a: 2)
|
||||
expect(updatedCallback.callCount).toBe 1
|
||||
|
||||
describe ".observe(keyPath)", ->
|
||||
[observeHandler, observeSubscription] = []
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "when there is no whitespace before the boundary", ->
|
||||
it "wraps the line exactly at the boundary since there's no more graceful place to wrap it", ->
|
||||
buffer.change([[0, 0], [1, 0]], 'abcdefghijklmnopqrstuvwxyz\n')
|
||||
buffer.setTextInRange([[0, 0], [1, 0]], 'abcdefghijklmnopqrstuvwxyz\n')
|
||||
displayBuffer.setEditorWidthInChars(10)
|
||||
expect(displayBuffer.lineForRow(0).text).toBe 'abcdefghij'
|
||||
expect(displayBuffer.lineForRow(1).text).toBe 'klmnopqrst'
|
||||
@@ -142,7 +142,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "when buffer lines are removed", ->
|
||||
it "removes lines and emits a change event", ->
|
||||
buffer.change([[3, 21], [7, 5]], ';')
|
||||
buffer.setTextInRange([[3, 21], [7, 5]], ';')
|
||||
expect(displayBuffer.lineForRow(3).text).toBe ' var pivot = items;'
|
||||
expect(displayBuffer.lineForRow(4).text).toBe ' return '
|
||||
expect(displayBuffer.lineForRow(5).text).toBe 'sort(left).concat(pivot).concat(sort(right));'
|
||||
@@ -330,7 +330,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "when the old range surrounds a fold", ->
|
||||
beforeEach ->
|
||||
buffer.change([[1, 0], [5, 1]], 'party!')
|
||||
buffer.setTextInRange([[1, 0], [5, 1]], 'party!')
|
||||
|
||||
it "removes the fold and replaces the selection with the new text", ->
|
||||
expect(displayBuffer.lineForRow(0).text).toBe "0"
|
||||
@@ -352,7 +352,7 @@ describe "DisplayBuffer", ->
|
||||
displayBuffer.createFold(2, 9)
|
||||
changeHandler.reset()
|
||||
|
||||
buffer.change([[1, 0], [10, 0]], 'goodbye')
|
||||
buffer.setTextInRange([[1, 0], [10, 0]], 'goodbye')
|
||||
|
||||
expect(displayBuffer.lineForRow(0).text).toBe "0"
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "goodbye10"
|
||||
@@ -371,7 +371,7 @@ describe "DisplayBuffer", ->
|
||||
describe "when the old range precedes lines with a fold", ->
|
||||
describe "when the new range precedes lines with a fold", ->
|
||||
it "updates the buffer and re-positions subsequent folds", ->
|
||||
buffer.change([[0, 0], [1, 1]], 'abc')
|
||||
buffer.setTextInRange([[0, 0], [1, 1]], 'abc')
|
||||
|
||||
expect(displayBuffer.lineForRow(0).text).toBe "abc"
|
||||
expect(displayBuffer.lineForRow(1).fold).toBe fold1
|
||||
@@ -394,7 +394,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "when the old range straddles the beginning of a fold", ->
|
||||
it "destroys the fold", ->
|
||||
buffer.change([[1, 1], [3, 0]], "a\nb\nc\nd\n")
|
||||
buffer.setTextInRange([[1, 1], [3, 0]], "a\nb\nc\nd\n")
|
||||
expect(displayBuffer.lineForRow(1).text).toBe '1a'
|
||||
expect(displayBuffer.lineForRow(2).text).toBe 'b'
|
||||
expect(displayBuffer.lineForRow(2).fold).toBeUndefined()
|
||||
@@ -402,7 +402,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "when the old range follows a fold", ->
|
||||
it "re-positions the screen ranges for the change event based on the preceding fold", ->
|
||||
buffer.change([[10, 0], [11, 0]], 'abc')
|
||||
buffer.setTextInRange([[10, 0], [11, 0]], 'abc')
|
||||
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "1"
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold1
|
||||
@@ -430,7 +430,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "when the end of the new range exceeds the end of the fold", ->
|
||||
it "expands the fold to contain all the inserted lines", ->
|
||||
buffer.change([[3, 0], [4, 0]], 'a\nb\nc\nd\n')
|
||||
buffer.setTextInRange([[3, 0], [4, 0]], 'a\nb\nc\nd\n')
|
||||
expect(fold1.getStartRow()).toBe 2
|
||||
expect(fold1.getEndRow()).toBe 7
|
||||
|
||||
@@ -447,7 +447,7 @@ describe "DisplayBuffer", ->
|
||||
describe "when the end of the new range precedes the end of the fold", ->
|
||||
it "destroys the fold", ->
|
||||
fold2.destroy()
|
||||
buffer.change([[3, 0], [6, 0]], 'a\n')
|
||||
buffer.setTextInRange([[3, 0], [6, 0]], 'a\n')
|
||||
expect(displayBuffer.lineForRow(2).text).toBe '2'
|
||||
expect(displayBuffer.lineForRow(2).fold).toBeUndefined()
|
||||
expect(displayBuffer.lineForRow(3).text).toBe 'a'
|
||||
@@ -831,7 +831,7 @@ describe "DisplayBuffer", ->
|
||||
expect(marker.getTailScreenPosition()).toEqual [5, 7]
|
||||
expect(marker2.isValid()).toBeFalsy()
|
||||
|
||||
buffer.change([[8, 0], [8, 2]], ".....")
|
||||
buffer.setTextInRange([[8, 0], [8, 2]], ".....")
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
expect(markerChangedHandler).toHaveBeenCalled()
|
||||
expect(marker2ChangedHandler).toHaveBeenCalled()
|
||||
|
||||
@@ -1424,6 +1424,35 @@ describe "Editor", ->
|
||||
editor.undo()
|
||||
expect(editor.getCursorBufferPosition()).toEqual [3,4]
|
||||
|
||||
it "indents the new line to the correct level when editor.autoIndent is true", ->
|
||||
atom.config.set('editor.autoIndent', true)
|
||||
|
||||
editor.setText(' var test')
|
||||
editor.setCursorBufferPosition([0,2])
|
||||
editor.insertNewlineAbove()
|
||||
|
||||
expect(editor.getCursorBufferPosition()).toEqual [0,2]
|
||||
expect(editor.lineForBufferRow(0)).toBe ' '
|
||||
expect(editor.lineForBufferRow(1)).toBe ' var test'
|
||||
|
||||
editor.setText('\n var test')
|
||||
editor.setCursorBufferPosition([1,2])
|
||||
editor.insertNewlineAbove()
|
||||
|
||||
expect(editor.getCursorBufferPosition()).toEqual [1,2]
|
||||
expect(editor.lineForBufferRow(0)).toBe ''
|
||||
expect(editor.lineForBufferRow(1)).toBe ' '
|
||||
expect(editor.lineForBufferRow(2)).toBe ' var test'
|
||||
|
||||
editor.setText('function() {\n}')
|
||||
editor.setCursorBufferPosition([1,1])
|
||||
editor.insertNewlineAbove()
|
||||
|
||||
expect(editor.getCursorBufferPosition()).toEqual [1,2]
|
||||
expect(editor.lineForBufferRow(0)).toBe 'function() {'
|
||||
expect(editor.lineForBufferRow(1)).toBe ' '
|
||||
expect(editor.lineForBufferRow(2)).toBe '}'
|
||||
|
||||
describe ".backspace()", ->
|
||||
describe "when there is a single cursor", ->
|
||||
changeScreenRangeHandler = null
|
||||
@@ -1596,6 +1625,11 @@ describe "Editor", ->
|
||||
expect(cursor1.getBufferPosition()).toEqual [1, 13]
|
||||
expect(cursor2.getBufferPosition()).toEqual [2, 34]
|
||||
|
||||
editor.setText(' var sort')
|
||||
editor.setCursorBufferPosition([0, 2])
|
||||
editor.backspaceToBeginningOfWord()
|
||||
expect(buffer.lineForRow(0)).toBe 'var sort'
|
||||
|
||||
describe "when text is selected", ->
|
||||
it "deletes only selected text", ->
|
||||
editor.setSelectedBufferRanges([[[1, 24], [1, 27]], [[2, 0], [2, 4]]])
|
||||
|
||||
@@ -432,9 +432,9 @@ describe "EditorView", ->
|
||||
editorView.setFontFamily('sans-serif')
|
||||
|
||||
it "positions the cursor to the clicked row and column", ->
|
||||
{top, left} = editorView.pixelOffsetForScreenPosition([3, 30])
|
||||
editorView.renderedLines.trigger mousedownEvent(pageX: left, pageY: top)
|
||||
expect(editor.getCursorScreenPosition()).toEqual [3, 30]
|
||||
{top, left} = editorView.pixelOffsetForScreenPosition([3, 30])
|
||||
editorView.renderedLines.trigger mousedownEvent(pageX: left, pageY: top)
|
||||
expect(editor.getCursorScreenPosition()).toEqual [3, 30]
|
||||
|
||||
describe "double-click", ->
|
||||
it "selects the word under the cursor, and expands the selection wordwise in either direction on a subsequent shift-click", ->
|
||||
@@ -464,6 +464,20 @@ describe "EditorView", ->
|
||||
editorView.renderedLines.trigger mousedownEvent(editorView: editorView, point: [3, 12], originalEvent: {detail: 1}, shiftKey: true)
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[3, 10], [3, 12]]
|
||||
|
||||
it "stops selecting by word when another selection is made", ->
|
||||
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
||||
editorView.renderedLines.trigger mousedownEvent(editorView: editorView, point: [0, 8], originalEvent: {detail: 1})
|
||||
editorView.renderedLines.trigger 'mouseup'
|
||||
editorView.renderedLines.trigger mousedownEvent(editorView: editorView, point: [0, 8], originalEvent: {detail: 2})
|
||||
editorView.renderedLines.trigger 'mouseup'
|
||||
expect(editor.getSelectedText()).toBe "quicksort"
|
||||
|
||||
editorView.renderedLines.trigger mousedownEvent(editorView: editorView, point: [3, 10])
|
||||
editorView.renderedLines.trigger mousemoveEvent(editorView: editorView, point: [3, 12], which: 1)
|
||||
editorView.renderedLines.trigger 'mouseup'
|
||||
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[3, 10], [3, 12]]
|
||||
|
||||
describe "when clicking between a word and a non-word", ->
|
||||
it "selects the word", ->
|
||||
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
||||
@@ -1371,7 +1385,7 @@ describe "EditorView", ->
|
||||
expect(editorView.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
||||
expect(editorView.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(12)
|
||||
|
||||
buffer.change([[1,0], [3,0]], "1\n2\n3\n")
|
||||
buffer.setTextInRange([[1,0], [3,0]], "1\n2\n3\n")
|
||||
expect(editorView.renderedLines.find(".line").length).toBe 7
|
||||
expect(editorView.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
||||
expect(editorView.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(12)
|
||||
@@ -1384,21 +1398,21 @@ describe "EditorView", ->
|
||||
expect(editorView.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
||||
expect(editorView.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(12)
|
||||
|
||||
buffer.change([[2,0], [7,0]], "2\n3\n4\n5\n6\n7\n8\n9\n")
|
||||
buffer.setTextInRange([[2,0], [7,0]], "2\n3\n4\n5\n6\n7\n8\n9\n")
|
||||
expect(editorView.renderedLines.find(".line").length).toBe 7
|
||||
expect(editorView.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
||||
expect(editorView.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(12)
|
||||
|
||||
describe "when the change straddles the last rendered row", ->
|
||||
it "doesn't render rows that were not previously rendered", ->
|
||||
buffer.change([[2,0], [7,0]], "2\n3\n4\n5\n6\n7\n8\n")
|
||||
buffer.setTextInRange([[2,0], [7,0]], "2\n3\n4\n5\n6\n7\n8\n")
|
||||
expect(editorView.renderedLines.find(".line").length).toBe 7
|
||||
expect(editorView.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(0)
|
||||
expect(editorView.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(6)
|
||||
|
||||
describe "when the change the follows the last rendered row", ->
|
||||
it "does not change the rendered lines", ->
|
||||
buffer.change([[12,0], [12,0]], "12\n13\n14\n")
|
||||
buffer.setTextInRange([[12,0], [12,0]], "12\n13\n14\n")
|
||||
expect(editorView.renderedLines.find(".line").length).toBe 7
|
||||
expect(editorView.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(0)
|
||||
expect(editorView.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(6)
|
||||
@@ -1408,7 +1422,7 @@ describe "EditorView", ->
|
||||
setEditorWidthInChars(editorView, maxLineLength)
|
||||
widthBefore = editorView.renderedLines.width()
|
||||
expect(widthBefore).toBe editorView.scrollView.width() + 20
|
||||
buffer.change([[12,0], [12,0]], [1..maxLineLength*2].join(''))
|
||||
buffer.setTextInRange([[12,0], [12,0]], [1..maxLineLength*2].join(''))
|
||||
expect(editorView.renderedLines.width()).toBeGreaterThan widthBefore
|
||||
|
||||
describe "when lines are removed", ->
|
||||
@@ -1418,7 +1432,7 @@ describe "EditorView", ->
|
||||
it "sets the rendered screen line's width to either the max line length or the scollView's width (whichever is greater)", ->
|
||||
maxLineLength = editor.getMaxScreenLineLength()
|
||||
setEditorWidthInChars(editorView, maxLineLength)
|
||||
buffer.change([[12,0], [12,0]], [1..maxLineLength*2].join(''))
|
||||
buffer.setTextInRange([[12,0], [12,0]], [1..maxLineLength*2].join(''))
|
||||
expect(editorView.renderedLines.width()).toBeGreaterThan editorView.scrollView.width()
|
||||
widthBefore = editorView.renderedLines.width()
|
||||
buffer.delete([[12, 0], [12, Infinity]])
|
||||
@@ -1431,7 +1445,7 @@ describe "EditorView", ->
|
||||
expect(editorView.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
||||
expect(editorView.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(12)
|
||||
|
||||
buffer.change([[1,0], [2,0]], "")
|
||||
buffer.setTextInRange([[1,0], [2,0]], "")
|
||||
expect(editorView.renderedLines.find(".line").length).toBe 6
|
||||
expect(editorView.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
||||
expect(editorView.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(11)
|
||||
@@ -1443,21 +1457,21 @@ describe "EditorView", ->
|
||||
expect(editorView.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
||||
expect(editorView.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(12)
|
||||
|
||||
buffer.change([[7,0], [11,0]], "1\n2\n")
|
||||
buffer.setTextInRange([[7,0], [11,0]], "1\n2\n")
|
||||
expect(editorView.renderedLines.find(".line").length).toBe 5
|
||||
expect(editorView.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
||||
expect(editorView.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(10)
|
||||
|
||||
describe "when the change straddles the last rendered row", ->
|
||||
it "renders the correct rows", ->
|
||||
buffer.change([[2,0], [7,0]], "")
|
||||
buffer.setTextInRange([[2,0], [7,0]], "")
|
||||
expect(editorView.renderedLines.find(".line").length).toBe 7
|
||||
expect(editorView.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(0)
|
||||
expect(editorView.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(6)
|
||||
|
||||
describe "when the change the follows the last rendered row", ->
|
||||
it "does not change the rendered lines", ->
|
||||
buffer.change([[10,0], [12,0]], "")
|
||||
buffer.setTextInRange([[10,0], [12,0]], "")
|
||||
expect(editorView.renderedLines.find(".line").length).toBe 7
|
||||
expect(editorView.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(0)
|
||||
expect(editorView.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(6)
|
||||
|
||||
@@ -46,6 +46,16 @@ describe "LanguageMode", ->
|
||||
languageMode.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(buffer.lineForRow(0)).toBe " // var i;"
|
||||
|
||||
buffer.setText(' ')
|
||||
languageMode.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(buffer.lineForRow(0)).toBe " // "
|
||||
|
||||
buffer.setText (' a\n \n b')
|
||||
languageMode.toggleLineCommentsForBufferRows(0, 2)
|
||||
expect(buffer.lineForRow(0)).toBe " // a"
|
||||
expect(buffer.lineForRow(1)).toBe " // "
|
||||
expect(buffer.lineForRow(2)).toBe " // b"
|
||||
|
||||
describe ".rowRangeForCodeFoldAtBufferRow(bufferRow)", ->
|
||||
it "returns the start/end rows of the foldable region starting at the given row", ->
|
||||
expect(languageMode.rowRangeForCodeFoldAtBufferRow(0)).toEqual [0, 12]
|
||||
@@ -178,17 +188,17 @@ describe "LanguageMode", ->
|
||||
expect(buffer.lineForRow(3)).toBe " font-weight: bold !important;"
|
||||
|
||||
it "uncomments lines with leading whitespace", ->
|
||||
buffer.change([[2, 0], [2, Infinity]], " /*width: 110%;*/")
|
||||
buffer.setTextInRange([[2, 0], [2, Infinity]], " /*width: 110%;*/")
|
||||
languageMode.toggleLineCommentsForBufferRows(2, 2)
|
||||
expect(buffer.lineForRow(2)).toBe " width: 110%;"
|
||||
|
||||
it "uncomments lines with trailing whitespace", ->
|
||||
buffer.change([[2, 0], [2, Infinity]], "/*width: 110%;*/ ")
|
||||
buffer.setTextInRange([[2, 0], [2, Infinity]], "/*width: 110%;*/ ")
|
||||
languageMode.toggleLineCommentsForBufferRows(2, 2)
|
||||
expect(buffer.lineForRow(2)).toBe "width: 110%; "
|
||||
|
||||
it "uncomments lines with leading and trailing whitespace", ->
|
||||
buffer.change([[2, 0], [2, Infinity]], " /*width: 110%;*/ ")
|
||||
buffer.setTextInRange([[2, 0], [2, Infinity]], " /*width: 110%;*/ ")
|
||||
languageMode.toggleLineCommentsForBufferRows(2, 2)
|
||||
expect(buffer.lineForRow(2)).toBe " width: 110%; "
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ describe "PaneContainerView", ->
|
||||
afterEach ->
|
||||
atom.deserializers.remove(TestView)
|
||||
|
||||
describe ".getActivePane()", ->
|
||||
describe ".getActivePaneView()", ->
|
||||
it "returns the most-recently focused pane", ->
|
||||
focusStealer = $$ -> @div tabindex: -1, "focus stealer"
|
||||
focusStealer.attachToDom()
|
||||
@@ -35,15 +35,15 @@ describe "PaneContainerView", ->
|
||||
|
||||
pane2.focus()
|
||||
expect(container.getFocusedPane()).toBe pane2
|
||||
expect(container.getActivePane()).toBe pane2
|
||||
expect(container.getActivePaneView()).toBe pane2
|
||||
|
||||
focusStealer.focus()
|
||||
expect(container.getFocusedPane()).toBeUndefined()
|
||||
expect(container.getActivePane()).toBe pane2
|
||||
expect(container.getActivePaneView()).toBe pane2
|
||||
|
||||
pane3.focus()
|
||||
expect(container.getFocusedPane()).toBe pane3
|
||||
expect(container.getActivePane()).toBe pane3
|
||||
expect(container.getActivePaneView()).toBe pane3
|
||||
|
||||
describe ".eachPaneView(callback)", ->
|
||||
it "runs the callback with all current and future panes until the subscription is cancelled", ->
|
||||
|
||||
+12
-54
@@ -33,21 +33,7 @@ describe "Project", ->
|
||||
deserializedProject.getBuffers()[0].destroy()
|
||||
expect(deserializedProject.getBuffers().length).toBe 0
|
||||
|
||||
describe "when an edit session is destroyed", ->
|
||||
it "removes edit session and calls destroy on buffer (if buffer is not referenced by other edit sessions)", ->
|
||||
editor = atom.project.openSync("a")
|
||||
anotherEditor = atom.project.openSync("a")
|
||||
|
||||
expect(atom.project.editors.length).toBe 2
|
||||
expect(editor.buffer).toBe anotherEditor.buffer
|
||||
|
||||
editor.destroy()
|
||||
expect(atom.project.editors.length).toBe 1
|
||||
|
||||
anotherEditor.destroy()
|
||||
expect(atom.project.editors.length).toBe 0
|
||||
|
||||
describe "when an edit session is saved and the project has no path", ->
|
||||
describe "when an editor is saved and the project has no path", ->
|
||||
it "sets the project's path to the saved file's parent directory", ->
|
||||
tempFile = temp.openSync().path
|
||||
atom.project.setPath(undefined)
|
||||
@@ -56,73 +42,49 @@ describe "Project", ->
|
||||
editor.saveAs(tempFile)
|
||||
expect(atom.project.getPath()).toBe path.dirname(tempFile)
|
||||
|
||||
describe "when an edit session is copied", ->
|
||||
it "emits an 'editor-created' event and stores the edit session", ->
|
||||
handler = jasmine.createSpy('editorCreatedHandler')
|
||||
atom.project.on 'editor-created', handler
|
||||
|
||||
editor1 = atom.project.openSync("a")
|
||||
expect(handler.callCount).toBe 1
|
||||
expect(atom.project.getEditors().length).toBe 1
|
||||
expect(atom.project.getEditors()[0]).toBe editor1
|
||||
|
||||
editor2 = editor1.copy()
|
||||
expect(handler.callCount).toBe 2
|
||||
expect(atom.project.getEditors().length).toBe 2
|
||||
expect(atom.project.getEditors()[0]).toBe editor1
|
||||
expect(atom.project.getEditors()[1]).toBe editor2
|
||||
|
||||
describe ".openSync(path)", ->
|
||||
[absolutePath, newBufferHandler, newEditorHandler] = []
|
||||
[absolutePath, newBufferHandler] = []
|
||||
beforeEach ->
|
||||
absolutePath = require.resolve('./fixtures/dir/a')
|
||||
newBufferHandler = jasmine.createSpy('newBufferHandler')
|
||||
atom.project.on 'buffer-created', newBufferHandler
|
||||
newEditorHandler = jasmine.createSpy('newEditorHandler')
|
||||
atom.project.on 'editor-created', newEditorHandler
|
||||
|
||||
describe "when given an absolute path that hasn't been opened previously", ->
|
||||
it "returns a new edit session for the given path and emits 'buffer-created' and 'editor-created' events", ->
|
||||
it "returns a new edit session for the given path and emits 'buffer-created'", ->
|
||||
editor = atom.project.openSync(absolutePath)
|
||||
expect(editor.buffer.getPath()).toBe absolutePath
|
||||
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
|
||||
expect(newEditorHandler).toHaveBeenCalledWith editor
|
||||
|
||||
describe "when given a relative path that hasn't been opened previously", ->
|
||||
it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created' and 'editor-created' events", ->
|
||||
it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created'", ->
|
||||
editor = atom.project.openSync('a')
|
||||
expect(editor.buffer.getPath()).toBe absolutePath
|
||||
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
|
||||
expect(newEditorHandler).toHaveBeenCalledWith editor
|
||||
|
||||
describe "when passed the path to a buffer that has already been opened", ->
|
||||
it "returns a new edit session containing previously opened buffer and emits a 'editor-created' event", ->
|
||||
it "returns a new edit session containing previously opened buffer", ->
|
||||
editor = atom.project.openSync(absolutePath)
|
||||
newBufferHandler.reset()
|
||||
expect(atom.project.openSync(absolutePath).buffer).toBe editor.buffer
|
||||
expect(atom.project.openSync('a').buffer).toBe editor.buffer
|
||||
expect(newBufferHandler).not.toHaveBeenCalled()
|
||||
expect(newEditorHandler).toHaveBeenCalledWith editor
|
||||
|
||||
describe "when not passed a path", ->
|
||||
it "returns a new edit session and emits 'buffer-created' and 'editor-created' events", ->
|
||||
it "returns a new edit session and emits 'buffer-created'", ->
|
||||
editor = atom.project.openSync()
|
||||
expect(editor.buffer.getPath()).toBeUndefined()
|
||||
expect(newBufferHandler).toHaveBeenCalledWith(editor.buffer)
|
||||
expect(newEditorHandler).toHaveBeenCalledWith editor
|
||||
|
||||
describe ".open(path)", ->
|
||||
[absolutePath, newBufferHandler, newEditorHandler] = []
|
||||
[absolutePath, newBufferHandler] = []
|
||||
|
||||
beforeEach ->
|
||||
absolutePath = require.resolve('./fixtures/dir/a')
|
||||
newBufferHandler = jasmine.createSpy('newBufferHandler')
|
||||
atom.project.on 'buffer-created', newBufferHandler
|
||||
newEditorHandler = jasmine.createSpy('newEditorHandler')
|
||||
atom.project.on 'editor-created', newEditorHandler
|
||||
|
||||
describe "when given an absolute path that isn't currently open", ->
|
||||
it "returns a new edit session for the given path and emits 'buffer-created' and 'editor-created' events", ->
|
||||
it "returns a new edit session for the given path and emits 'buffer-created'", ->
|
||||
editor = null
|
||||
waitsForPromise ->
|
||||
atom.project.open(absolutePath).then (o) -> editor = o
|
||||
@@ -130,10 +92,9 @@ describe "Project", ->
|
||||
runs ->
|
||||
expect(editor.buffer.getPath()).toBe absolutePath
|
||||
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
|
||||
expect(newEditorHandler).toHaveBeenCalledWith editor
|
||||
|
||||
describe "when given a relative path that isn't currently opened", ->
|
||||
it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created' and 'editor-created' events", ->
|
||||
it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created'", ->
|
||||
editor = null
|
||||
waitsForPromise ->
|
||||
atom.project.open(absolutePath).then (o) -> editor = o
|
||||
@@ -141,10 +102,9 @@ describe "Project", ->
|
||||
runs ->
|
||||
expect(editor.buffer.getPath()).toBe absolutePath
|
||||
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
|
||||
expect(newEditorHandler).toHaveBeenCalledWith editor
|
||||
|
||||
describe "when passed the path to a buffer that is currently opened", ->
|
||||
it "returns a new edit session containing currently opened buffer and emits a 'editor-created' event", ->
|
||||
it "returns a new edit session containing currently opened buffer", ->
|
||||
editor = null
|
||||
waitsForPromise ->
|
||||
atom.project.open(absolutePath).then (o) -> editor = o
|
||||
@@ -154,10 +114,9 @@ describe "Project", ->
|
||||
expect(atom.project.openSync(absolutePath).buffer).toBe editor.buffer
|
||||
expect(atom.project.openSync('a').buffer).toBe editor.buffer
|
||||
expect(newBufferHandler).not.toHaveBeenCalled()
|
||||
expect(newEditorHandler).toHaveBeenCalledWith editor
|
||||
|
||||
describe "when not passed a path", ->
|
||||
it "returns a new edit session and emits 'buffer-created' and 'editor-created' events", ->
|
||||
it "returns a new edit session and emits 'buffer-created'", ->
|
||||
editor = null
|
||||
waitsForPromise ->
|
||||
atom.project.open().then (o) -> editor = o
|
||||
@@ -165,7 +124,6 @@ describe "Project", ->
|
||||
runs ->
|
||||
expect(editor.buffer.getPath()).toBeUndefined()
|
||||
expect(newBufferHandler).toHaveBeenCalledWith(editor.buffer)
|
||||
expect(newEditorHandler).toHaveBeenCalledWith editor
|
||||
|
||||
it "returns number of read bytes as progress indicator", ->
|
||||
filePath = atom.project.resolve 'a'
|
||||
@@ -312,7 +270,7 @@ describe "Project", ->
|
||||
|
||||
it "does NOT save when modified", ->
|
||||
editor = atom.project.openSync('sample.js')
|
||||
editor.buffer.change([[0,0],[0,0]], 'omg')
|
||||
editor.buffer.setTextInRange([[0,0],[0,0]], 'omg')
|
||||
expect(editor.isModified()).toBeTruthy()
|
||||
|
||||
results = []
|
||||
|
||||
@@ -36,6 +36,22 @@ describe "ThemeManager", ->
|
||||
themes = themeManager.getActiveThemes()
|
||||
expect(themes).toHaveLength(names.length)
|
||||
|
||||
describe "when the core.themes config value contains invalid entry", ->
|
||||
fit "ignores theme", ->
|
||||
atom.config.set 'core.themes', [
|
||||
'atom-light-ui'
|
||||
null
|
||||
undefined
|
||||
''
|
||||
false
|
||||
4
|
||||
{}
|
||||
[]
|
||||
'atom-dark-ui'
|
||||
]
|
||||
|
||||
expect(themeManager.getEnabledThemeNames()).toEqual ['atom-dark-ui', 'atom-light-ui']
|
||||
|
||||
describe "getImportPaths()", ->
|
||||
it "returns the theme directories before the themes are loaded", ->
|
||||
atom.config.set('core.themes', ['theme-with-index-less', 'atom-dark-ui', 'atom-light-ui'])
|
||||
|
||||
@@ -119,7 +119,7 @@ describe "TokenizedBuffer", ->
|
||||
|
||||
describe "when there is a buffer change surrounding an invalid row", ->
|
||||
it "pushes the invalid row to the end of the change", ->
|
||||
buffer.change([[4, 0], [6, 0]], "\n\n\n")
|
||||
buffer.setTextInRange([[4, 0], [6, 0]], "\n\n\n")
|
||||
changeHandler.reset()
|
||||
|
||||
expect(tokenizedBuffer.firstInvalidRow()).toBe 8
|
||||
@@ -128,7 +128,7 @@ describe "TokenizedBuffer", ->
|
||||
describe "when there is a buffer change inside an invalid region", ->
|
||||
it "does not attempt to tokenize the lines in the change, and preserves the existing invalid row", ->
|
||||
expect(tokenizedBuffer.firstInvalidRow()).toBe 5
|
||||
buffer.change([[6, 0], [7, 0]], "\n\n\n")
|
||||
buffer.setTextInRange([[6, 0], [7, 0]], "\n\n\n")
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(6).ruleStack?).toBeFalsy()
|
||||
expect(tokenizedBuffer.lineForScreenRow(7).ruleStack?).toBeFalsy()
|
||||
@@ -143,7 +143,7 @@ describe "TokenizedBuffer", ->
|
||||
describe "when there is a buffer change that is smaller than the chunk size", ->
|
||||
describe "when lines are updated, but none are added or removed", ->
|
||||
it "updates tokens to reflect the change", ->
|
||||
buffer.change([[0, 0], [2, 0]], "foo()\n7\n")
|
||||
buffer.setTextInRange([[0, 0], [2, 0]], "foo()\n7\n")
|
||||
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[1]).toEqual(value: '(', scopes: ['source.js', 'meta.brace.round.js'])
|
||||
expect(tokenizedBuffer.lineForScreenRow(1).tokens[0]).toEqual(value: '7', scopes: ['source.js', 'constant.numeric.js'])
|
||||
@@ -185,7 +185,7 @@ describe "TokenizedBuffer", ->
|
||||
|
||||
describe "when lines are both updated and removed", ->
|
||||
it "updates tokens to reflect the change", ->
|
||||
buffer.change([[1, 0], [3, 0]], "foo()")
|
||||
buffer.setTextInRange([[1, 0], [3, 0]], "foo()")
|
||||
|
||||
# previous line 0 remains
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[0]).toEqual(value: 'var', scopes: ['source.js', 'storage.modifier.js'])
|
||||
@@ -209,7 +209,7 @@ describe "TokenizedBuffer", ->
|
||||
buffer.insert([5, 30], '/* */')
|
||||
changeHandler.reset()
|
||||
|
||||
buffer.change([[2, 0], [3, 0]], '/*')
|
||||
buffer.setTextInRange([[2, 0], [3, 0]], '/*')
|
||||
expect(tokenizedBuffer.lineForScreenRow(2).tokens[0].scopes).toEqual ['source.js', 'comment.block.js', 'punctuation.definition.comment.js']
|
||||
expect(tokenizedBuffer.lineForScreenRow(3).tokens[0].scopes).toEqual ['source.js']
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
@@ -228,7 +228,7 @@ describe "TokenizedBuffer", ->
|
||||
|
||||
describe "when lines are both updated and inserted", ->
|
||||
it "updates tokens to reflect the change", ->
|
||||
buffer.change([[1, 0], [2, 0]], "foo()\nbar()\nbaz()\nquux()")
|
||||
buffer.setTextInRange([[1, 0], [2, 0]], "foo()\nbar()\nbaz()\nquux()")
|
||||
|
||||
# previous line 0 remains
|
||||
expect(tokenizedBuffer.lineForScreenRow(0).tokens[0]).toEqual( value: 'var', scopes: ['source.js', 'storage.modifier.js'])
|
||||
|
||||
@@ -102,7 +102,7 @@ describe "Window", ->
|
||||
it "unsubscribes from all buffers", ->
|
||||
atom.workspaceView.openSync('sample.js')
|
||||
buffer = atom.workspaceView.getActivePaneItem().buffer
|
||||
pane = atom.workspaceView.getActivePane()
|
||||
pane = atom.workspaceView.getActivePaneView()
|
||||
pane.splitRight(pane.copyActiveItem())
|
||||
expect(atom.workspaceView.find('.editor').length).toBe 2
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ describe "Workspace", ->
|
||||
|
||||
beforeEach ->
|
||||
atom.project.setPath(atom.project.resolve('dir'))
|
||||
workspace = new Workspace
|
||||
atom.workspace = workspace = new Workspace
|
||||
|
||||
describe "::open(uri, options)", ->
|
||||
beforeEach ->
|
||||
@@ -152,6 +152,18 @@ describe "Workspace", ->
|
||||
workspace.open("bar://baz").then (item) ->
|
||||
expect(item).toEqual { bar: "bar://baz" }
|
||||
|
||||
it "emits an 'editor-created' event", ->
|
||||
absolutePath = require.resolve('./fixtures/dir/a')
|
||||
newEditorHandler = jasmine.createSpy('newEditorHandler')
|
||||
workspace.on 'editor-created', newEditorHandler
|
||||
|
||||
editor = null
|
||||
waitsForPromise ->
|
||||
workspace.open(absolutePath).then (e) -> editor = e
|
||||
|
||||
runs ->
|
||||
expect(newEditorHandler).toHaveBeenCalledWith editor
|
||||
|
||||
describe "::openSync(uri, options)", ->
|
||||
[activePane, initialItemCount] = []
|
||||
|
||||
@@ -245,3 +257,26 @@ describe "Workspace", ->
|
||||
it "opens the license as plain-text in a buffer", ->
|
||||
waitsForPromise -> workspace.openLicense()
|
||||
runs -> expect(workspace.activePaneItem.getText()).toMatch /Copyright/
|
||||
|
||||
describe "when an editor is destroyed", ->
|
||||
it "removes the editor", ->
|
||||
editor = null
|
||||
|
||||
waitsForPromise ->
|
||||
workspace.open("a").then (e) -> editor = e
|
||||
|
||||
runs ->
|
||||
expect(workspace.getEditors()).toHaveLength 1
|
||||
editor.destroy()
|
||||
expect(workspace.getEditors()).toHaveLength 0
|
||||
|
||||
describe "when an editor is copied", ->
|
||||
it "emits an 'editor-created' event", ->
|
||||
handler = jasmine.createSpy('editorCreatedHandler')
|
||||
workspace.on 'editor-created', handler
|
||||
|
||||
editor1 = workspace.openSync("a")
|
||||
expect(handler.callCount).toBe 1
|
||||
|
||||
editor2 = editor1.copy()
|
||||
expect(handler.callCount).toBe 2
|
||||
|
||||
@@ -36,18 +36,18 @@ describe "WorkspaceView", ->
|
||||
editorView1 = atom.workspaceView.getActiveView()
|
||||
buffer = editorView1.getEditor().getBuffer()
|
||||
editorView1.splitRight()
|
||||
expect(atom.workspaceView.getActivePane()).toBe atom.workspaceView.getPaneViews()[1]
|
||||
expect(atom.workspaceView.getActivePaneView()).toBe atom.workspaceView.getPaneViews()[1]
|
||||
|
||||
simulateReload()
|
||||
|
||||
expect(atom.workspaceView.getEditorViews().length).toBe 2
|
||||
expect(atom.workspaceView.getActivePane()).toBe atom.workspaceView.getPaneViews()[1]
|
||||
expect(atom.workspaceView.getActivePaneView()).toBe atom.workspaceView.getPaneViews()[1]
|
||||
expect(atom.workspaceView.title).toBe "untitled - #{atom.project.getPath()}"
|
||||
|
||||
describe "when there are open editors", ->
|
||||
it "constructs the view with the same panes", ->
|
||||
atom.workspaceView.attachToDom()
|
||||
pane1 = atom.workspaceView.getActivePane()
|
||||
pane1 = atom.workspaceView.getActivePaneView()
|
||||
pane2 = pane1.splitRight()
|
||||
pane3 = pane2.splitRight()
|
||||
pane4 = pane2.splitDown()
|
||||
@@ -89,7 +89,7 @@ describe "WorkspaceView", ->
|
||||
|
||||
describe "where there are no open editors", ->
|
||||
it "constructs the view with no open editors", ->
|
||||
atom.workspaceView.getActivePane().remove()
|
||||
atom.workspaceView.getActivePaneView().remove()
|
||||
expect(atom.workspaceView.getEditorViews().length).toBe 0
|
||||
simulateReload()
|
||||
expect(atom.workspaceView.getEditorViews().length).toBe 0
|
||||
@@ -99,7 +99,7 @@ describe "WorkspaceView", ->
|
||||
atom.workspaceView.attachToDom()
|
||||
|
||||
it "hands off focus to the active pane", ->
|
||||
activePane = atom.workspaceView.getActivePane()
|
||||
activePane = atom.workspaceView.getActivePaneView()
|
||||
$('body').focus()
|
||||
expect(activePane.hasFocus()).toBe false
|
||||
atom.workspaceView.focus()
|
||||
@@ -132,30 +132,30 @@ describe "WorkspaceView", ->
|
||||
|
||||
describe "when there is an active pane item", ->
|
||||
it "sets the title to the pane item's title plus the project path", ->
|
||||
item = atom.workspaceView.getActivePaneItem()
|
||||
item = atom.workspaceView.getActivePaneViewItem()
|
||||
expect(atom.workspaceView.title).toBe "#{item.getTitle()} - #{atom.project.getPath()}"
|
||||
|
||||
describe "when the title of the active pane item changes", ->
|
||||
it "updates the window title based on the item's new title", ->
|
||||
editor = atom.workspaceView.getActivePaneItem()
|
||||
editor = atom.workspaceView.getActivePaneViewItem()
|
||||
editor.buffer.setPath(path.join(temp.dir, 'hi'))
|
||||
expect(atom.workspaceView.title).toBe "#{editor.getTitle()} - #{atom.project.getPath()}"
|
||||
|
||||
describe "when the active pane's item changes", ->
|
||||
it "updates the title to the new item's title plus the project path", ->
|
||||
atom.workspaceView.getActivePane().showNextItem()
|
||||
item = atom.workspaceView.getActivePaneItem()
|
||||
atom.workspaceView.getActivePaneView().showNextItem()
|
||||
item = atom.workspaceView.getActivePaneViewItem()
|
||||
expect(atom.workspaceView.title).toBe "#{item.getTitle()} - #{atom.project.getPath()}"
|
||||
|
||||
describe "when the last pane item is removed", ->
|
||||
it "updates the title to contain the project's path", ->
|
||||
atom.workspaceView.getActivePane().remove()
|
||||
expect(atom.workspaceView.getActivePaneItem()).toBeUndefined()
|
||||
atom.workspaceView.getActivePaneView().remove()
|
||||
expect(atom.workspaceView.getActivePaneViewItem()).toBeUndefined()
|
||||
expect(atom.workspaceView.title).toBe atom.project.getPath()
|
||||
|
||||
describe "when an inactive pane's item changes", ->
|
||||
it "does not update the title", ->
|
||||
pane = atom.workspaceView.getActivePane()
|
||||
pane = atom.workspaceView.getActivePaneView()
|
||||
pane.splitRight()
|
||||
initialTitle = atom.workspaceView.title
|
||||
pane.showNextItem()
|
||||
@@ -164,7 +164,7 @@ describe "WorkspaceView", ->
|
||||
describe "when the root view is deserialized", ->
|
||||
it "updates the title to contain the project's path", ->
|
||||
workspaceView2 = new WorkspaceView(atom.workspace.testSerialization())
|
||||
item = atom.workspaceView.getActivePaneItem()
|
||||
item = atom.workspaceView.getActivePaneViewItem()
|
||||
expect(workspaceView2.title).toBe "#{item.getTitle()} - #{atom.project.getPath()}"
|
||||
workspaceView2.remove()
|
||||
|
||||
@@ -238,9 +238,9 @@ describe "WorkspaceView", ->
|
||||
it "closes the active pane item until all that remains is a single empty pane", ->
|
||||
atom.config.set('core.destroyEmptyPanes', true)
|
||||
atom.project.openSync('../sample.txt')
|
||||
expect(atom.workspaceView.getActivePane().getItems()).toHaveLength 1
|
||||
expect(atom.workspaceView.getActivePaneView().getItems()).toHaveLength 1
|
||||
atom.workspaceView.trigger('core:close')
|
||||
expect(atom.workspaceView.getActivePane().getItems()).toHaveLength 0
|
||||
expect(atom.workspaceView.getActivePaneView().getItems()).toHaveLength 0
|
||||
|
||||
describe "the scrollbar visibility class", ->
|
||||
it "has a class based on the style of the scrollbar", ->
|
||||
|
||||
+28
-18
@@ -1,6 +1,5 @@
|
||||
crypto = require 'crypto'
|
||||
ipc = require 'ipc'
|
||||
keytar = require 'keytar'
|
||||
os = require 'os'
|
||||
path = require 'path'
|
||||
remote = require 'remote'
|
||||
@@ -8,6 +7,7 @@ screen = require 'screen'
|
||||
shell = require 'shell'
|
||||
|
||||
_ = require 'underscore-plus'
|
||||
{deprecated} = require 'grim'
|
||||
{Model} = require 'theorist'
|
||||
fs = require 'fs-plus'
|
||||
|
||||
@@ -132,6 +132,7 @@ class Atom extends Model
|
||||
initialize: ->
|
||||
window.onerror = =>
|
||||
@openDevTools()
|
||||
@executeJavaScriptInDevTools('InspectorFrontendAPI.showConsole()')
|
||||
@emit 'uncaught-error', arguments...
|
||||
|
||||
@unsubscribe()
|
||||
@@ -180,9 +181,11 @@ class Atom extends Model
|
||||
|
||||
# Deprecated: Callers should be converted to use atom.deserializers
|
||||
registerRepresentationClass: ->
|
||||
deprecated("Callers should be converted to use atom.deserializers")
|
||||
|
||||
# Deprecated: Callers should be converted to use atom.deserializers
|
||||
registerRepresentationClasses: ->
|
||||
deprecated("Callers should be converted to use atom.deserializers")
|
||||
|
||||
setBodyPlatformClass: ->
|
||||
document.body.classList.add("platform-#{process.platform}")
|
||||
@@ -219,12 +222,26 @@ class Atom extends Model
|
||||
else
|
||||
@center()
|
||||
|
||||
storeDefaultWindowDimensions: ->
|
||||
dimensions = JSON.stringify(atom.getWindowDimensions())
|
||||
localStorage.setItem("defaultWindowDimensions", dimensions)
|
||||
|
||||
getDefaultWindowDimensions: ->
|
||||
{windowDimensions} = @getLoadSettings()
|
||||
return windowDimensions if windowDimensions?
|
||||
|
||||
dimensions = null
|
||||
try
|
||||
dimensions = JSON.parse(localStorage.getItem("defaultWindowDimensions"))
|
||||
catch error
|
||||
console.warn "Error parsing default window dimensions", error
|
||||
localStorage.removeItem("defaultWindowDimensions")
|
||||
|
||||
{width, height} = screen.getPrimaryDisplay().workAreaSize
|
||||
dimensions ? {x: 0, y: 0, width: Math.min(1024, width), height: height}
|
||||
|
||||
restoreWindowDimensions: ->
|
||||
workAreaSize = screen.getPrimaryDisplay().workAreaSize
|
||||
windowDimensions = @state.windowDimensions ? {}
|
||||
{initialSize} = @getLoadSettings()
|
||||
windowDimensions.height ?= initialSize?.height ? workAreaSize.height
|
||||
windowDimensions.width ?= initialSize?.width ? Math.min(workAreaSize.width, 1024)
|
||||
windowDimensions = @state.windowDimensions ? @getDefaultWindowDimensions()
|
||||
@setWindowDimensions(windowDimensions)
|
||||
|
||||
storeWindowDimensions: ->
|
||||
@@ -380,6 +397,10 @@ class Atom extends Model
|
||||
toggleDevTools: ->
|
||||
ipc.sendChannel('call-window-method', 'toggleDevTools')
|
||||
|
||||
# Public: Execute code in dev tools.
|
||||
executeJavaScriptInDevTools: (code) ->
|
||||
ipc.sendChannel('call-window-method', 'executeJavaScriptInDevTools', code)
|
||||
|
||||
# Public: Reload the current window.
|
||||
reload: ->
|
||||
ipc.sendChannel('call-window-method', 'restart')
|
||||
@@ -432,7 +453,7 @@ class Atom extends Model
|
||||
exit: (status) ->
|
||||
app = remote.require('app')
|
||||
app.emit('will-exit')
|
||||
app.exit(status)
|
||||
remote.process.exit(status)
|
||||
|
||||
# Public: Is the current window in development mode?
|
||||
inDevMode: ->
|
||||
@@ -462,17 +483,6 @@ class Atom extends Model
|
||||
isReleasedVersion: ->
|
||||
@constructor.isReleasedVersion()
|
||||
|
||||
getGitHubAuthTokenName: ->
|
||||
'Atom GitHub API Token'
|
||||
|
||||
# Public: Set the the github token in the keychain
|
||||
setGitHubAuthToken: (token) ->
|
||||
keytar.replacePassword(@getGitHubAuthTokenName(), 'github', token)
|
||||
|
||||
# Public: Get the github token from the keychain
|
||||
getGitHubAuthToken: ->
|
||||
keytar.getPassword(@getGitHubAuthTokenName(), 'github')
|
||||
|
||||
# Public: Get the directory path to Atom's configuration area.
|
||||
#
|
||||
# Returns the absolute path to ~/.atom
|
||||
|
||||
@@ -12,24 +12,25 @@ class ApplicationMenu
|
||||
constructor: (@version) ->
|
||||
@menu = Menu.buildFromTemplate @getDefaultTemplate()
|
||||
Menu.setApplicationMenu @menu
|
||||
global.atomApplication.autoUpdateManager.on 'state-changed', (state) =>
|
||||
@showUpdateMenuItem(state)
|
||||
|
||||
# Public: Updates the entire menu with the given keybindings.
|
||||
#
|
||||
# * template:
|
||||
# The Object which describes the menu to display.
|
||||
# * keystrokesByCommand:
|
||||
# An Object where the keys are commands and the values are Arrays containing
|
||||
# the keystroke.
|
||||
# template - The Object which describes the menu to display.
|
||||
# keystrokesByCommand - An Object where the keys are commands and the values
|
||||
# are Arrays containing the keystroke.
|
||||
update: (template, keystrokesByCommand) ->
|
||||
@translateTemplate(template, keystrokesByCommand)
|
||||
@substituteVersion(template)
|
||||
@menu = Menu.buildFromTemplate(template)
|
||||
Menu.setApplicationMenu(@menu)
|
||||
|
||||
@showUpdateMenuItem(global.atomApplication.autoUpdateManager.getState())
|
||||
|
||||
# Flattens the given menu and submenu items into an single Array.
|
||||
#
|
||||
# * menu:
|
||||
# A complete menu configuration object for atom-shell's menu API.
|
||||
# menu - A complete menu configuration object for atom-shell's menu API.
|
||||
#
|
||||
# Returns an Array of native menu items.
|
||||
flattenMenuItems: (menu) ->
|
||||
@@ -41,8 +42,7 @@ class ApplicationMenu
|
||||
|
||||
# Flattens the given menu template into an single Array.
|
||||
#
|
||||
# * template:
|
||||
# An object describing the menu item.
|
||||
# template - An object describing the menu item.
|
||||
#
|
||||
# Returns an Array of native menu items.
|
||||
flattenMenuTemplate: (template) ->
|
||||
@@ -54,44 +54,36 @@ class ApplicationMenu
|
||||
|
||||
# Public: Used to make all window related menu items are active.
|
||||
#
|
||||
# * enable:
|
||||
# If true enables all window specific items, if false disables all window
|
||||
# specific items.
|
||||
# enable - If true enables all window specific items, if false disables all
|
||||
# window specific items.
|
||||
enableWindowSpecificItems: (enable) ->
|
||||
for item in @flattenMenuItems(@menu)
|
||||
item.enabled = enable if item.metadata?['windowSpecific']
|
||||
|
||||
# Replaces VERSION with the current version.
|
||||
substituteVersion: (template) ->
|
||||
if (item = _.find(@flattenMenuTemplate(template), (i) -> i.label == 'VERSION'))
|
||||
if (item = _.find(@flattenMenuTemplate(template), ({label}) -> label == 'VERSION'))
|
||||
item.label = "Version #{@version}"
|
||||
|
||||
# Toggles Install Update Item
|
||||
showInstallUpdateItem: (visible=true) ->
|
||||
if visible
|
||||
@showDownloadingUpdateItem(false)
|
||||
@showCheckForUpdateItem(false)
|
||||
# Sets the proper visible state the update menu items
|
||||
showUpdateMenuItem: (state) ->
|
||||
checkForUpdateItem = _.find(@flattenMenuItems(@menu), ({label}) -> label == 'Check for Update')
|
||||
downloadingUpdateItem = _.find(@flattenMenuItems(@menu), ({label}) -> label == 'Downloading Update')
|
||||
installUpdateItem = _.find(@flattenMenuItems(@menu), ({label}) -> label == 'Restart and Install Update')
|
||||
|
||||
if (item = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Restart and Install Update'))
|
||||
item.visible = visible
|
||||
return unless checkForUpdateItem? and downloadingUpdateItem? and installUpdateItem?
|
||||
|
||||
# Toggles Downloading Update Item
|
||||
showDownloadingUpdateItem: (visible=true) ->
|
||||
if visible
|
||||
@showInstallUpdateItem(false)
|
||||
@showCheckForUpdateItem(false)
|
||||
checkForUpdateItem.visible = false
|
||||
downloadingUpdateItem.visible = false
|
||||
installUpdateItem.visible = false
|
||||
|
||||
if (item = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Downloading Update'))
|
||||
item.visible = visible
|
||||
|
||||
# Toggles Check For Update Item
|
||||
showCheckForUpdateItem: (visible=true) ->
|
||||
if visible
|
||||
@showDownloadingUpdateItem(false)
|
||||
@showInstallUpdateItem(false)
|
||||
|
||||
if (item = _.find(@flattenMenuItems(@menu), (i) -> i.label == 'Check for Update'))
|
||||
item.visible = visible
|
||||
switch state
|
||||
when 'idle', 'error', 'no-update-available'
|
||||
checkForUpdateItem.visible = true
|
||||
when 'checking', 'downloading'
|
||||
downloadingUpdateItem.visible = true
|
||||
when 'update-available'
|
||||
installUpdateItem.visible = true
|
||||
|
||||
# Default list of menu items.
|
||||
#
|
||||
@@ -100,6 +92,7 @@ class ApplicationMenu
|
||||
[
|
||||
label: "Atom"
|
||||
submenu: [
|
||||
{ label: "Check for Update", metadata: {autoUpdate: true}}
|
||||
{ label: 'Reload', accelerator: 'Command+R', click: => @focusedWindow()?.reload() }
|
||||
{ label: 'Close Window', accelerator: 'Command+Shift+W', click: => @focusedWindow()?.close() }
|
||||
{ label: 'Toggle Dev Tools', accelerator: 'Command+Alt+I', click: => @focusedWindow()?.toggleDevTools() }
|
||||
@@ -112,17 +105,15 @@ class ApplicationMenu
|
||||
|
||||
# Combines a menu template with the appropriate keystroke.
|
||||
#
|
||||
# * template:
|
||||
# An Object conforming to atom-shell's menu api but lacking accelerator and
|
||||
# click properties.
|
||||
# * keystrokesByCommand:
|
||||
# An Object where the keys are commands and the values are Arrays containing
|
||||
# the keystroke.
|
||||
# template - An Object conforming to atom-shell's menu api but lacking
|
||||
# accelerator and click properties.
|
||||
# keystrokesByCommand - An Object where the keys are commands and the values
|
||||
# are Arrays containing the keystroke.
|
||||
#
|
||||
# Returns a complete menu configuration object for atom-shell's menu API.
|
||||
translateTemplate: (template, keystrokesByCommand) ->
|
||||
template.forEach (item) =>
|
||||
item.metadata = {}
|
||||
item.metadata ?= {}
|
||||
if item.command
|
||||
item.accelerator = @acceleratorForCommand(item.command, keystrokesByCommand)
|
||||
item.click = => global.atomApplication.sendCommand(item.command)
|
||||
@@ -132,11 +123,9 @@ class ApplicationMenu
|
||||
|
||||
# Determine the accelerator for a given command.
|
||||
#
|
||||
# * command:
|
||||
# The name of the command.
|
||||
# * keystrokesByCommand:
|
||||
# An Object where the keys are commands and the values are Arrays containing
|
||||
# the keystroke.
|
||||
# command - The name of the command.
|
||||
# keystrokesByCommand - An Object where the keys are commands and the values
|
||||
# are Arrays containing the keystroke.
|
||||
#
|
||||
# Returns a String containing the keystroke in a format that can be interpreted
|
||||
# by atom shell to provide nice icons where available.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
AtomWindow = require './atom-window'
|
||||
ApplicationMenu = require './application-menu'
|
||||
AtomProtocolHandler = require './atom-protocol-handler'
|
||||
AutoUpdateManager = require './auto-update-manager'
|
||||
BrowserWindow = require 'browser-window'
|
||||
Menu = require 'menu'
|
||||
autoUpdater = require 'auto-updater'
|
||||
app = require 'app'
|
||||
dialog = require 'dialog'
|
||||
fs = require 'fs'
|
||||
@@ -66,13 +66,13 @@ class AtomApplication
|
||||
@pathsToOpen ?= []
|
||||
@windows = []
|
||||
|
||||
@autoUpdateManager = new AutoUpdateManager(@version)
|
||||
@applicationMenu = new ApplicationMenu(@version)
|
||||
@atomProtocolHandler = new AtomProtocolHandler(@resourcePath)
|
||||
|
||||
@listenForArgumentsFromNewProcess()
|
||||
@setupJavaScriptArguments()
|
||||
@handleEvents()
|
||||
@setupAutoUpdater()
|
||||
|
||||
@openWithOptions(options)
|
||||
|
||||
@@ -96,6 +96,8 @@ class AtomApplication
|
||||
addWindow: (window) ->
|
||||
@windows.push window
|
||||
@applicationMenu?.enableWindowSpecificItems(true)
|
||||
window.once 'window:loaded', =>
|
||||
@autoUpdateManager.emitUpdateAvailableEvent(window)
|
||||
|
||||
# Creates server to listen for additional atom application launches.
|
||||
#
|
||||
@@ -127,59 +129,24 @@ class AtomApplication
|
||||
setupJavaScriptArguments: ->
|
||||
app.commandLine.appendSwitch 'js-flags', '--harmony'
|
||||
|
||||
# Enable updates unless running from a local build of Atom.
|
||||
setupAutoUpdater: ->
|
||||
return if /\w{7}/.test(@version) # Only released versions should check for updates.
|
||||
|
||||
autoUpdater.setFeedUrl "https://atom.io/api/updates?version=#{@version}"
|
||||
|
||||
autoUpdater.on 'checking-for-update', =>
|
||||
@applicationMenu.showDownloadingUpdateItem(false)
|
||||
@applicationMenu.showInstallUpdateItem(false)
|
||||
@applicationMenu.showCheckForUpdateItem(false)
|
||||
|
||||
autoUpdater.on 'update-not-available', =>
|
||||
@applicationMenu.showCheckForUpdateItem(true)
|
||||
|
||||
autoUpdater.on 'update-available', =>
|
||||
@applicationMenu.showDownloadingUpdateItem(true)
|
||||
|
||||
autoUpdater.on 'update-downloaded', (event, releaseNotes, releaseVersion, releaseDate, releaseURL) =>
|
||||
atomWindow.sendCommand('window:update-available', [releaseVersion, releaseNotes]) for atomWindow in @windows
|
||||
@applicationMenu.showInstallUpdateItem(true)
|
||||
|
||||
autoUpdater.on 'error', (event, message) =>
|
||||
@applicationMenu.showCheckForUpdateItem(true)
|
||||
|
||||
# Check for update after Atom has fully started and the menus are created
|
||||
setTimeout((-> autoUpdater.checkForUpdates()), 5000)
|
||||
|
||||
checkForUpdate: ->
|
||||
@onUpdateNotAvailable ?= =>
|
||||
autoUpdater.removeListener 'error', @onUpdateError
|
||||
dialog.showMessageBox type: 'info', buttons: ['OK'], message: 'No update available.', detail: "Version #{@version} is the latest version."
|
||||
|
||||
@onUpdateError ?= (event, message) =>
|
||||
autoUpdater.removeListener 'update-not-available', @onUpdateNotAvailable
|
||||
dialog.showMessageBox type: 'warning', buttons: ['OK'], message: 'There was an error checking for updates.', detail: message
|
||||
|
||||
autoUpdater.once 'update-not-available', @onUpdateNotAvailable
|
||||
autoUpdater.once 'error', @onUpdateError
|
||||
autoUpdater.checkForUpdates()
|
||||
|
||||
# Registers basic application commands, non-idempotent.
|
||||
handleEvents: ->
|
||||
@on 'application:run-all-specs', -> @runSpecs(exitWhenDone: false, resourcePath: global.devResourcePath)
|
||||
@on 'application:run-benchmarks', -> @runBenchmarks()
|
||||
@on 'application:quit', -> app.quit()
|
||||
@on 'application:new-window', -> @openPath(initialSize: @getFocusedWindowSize())
|
||||
@on 'application:new-window', -> @openPath(windowDimensions: @focusedWindow()?.getDimensions())
|
||||
@on 'application:new-file', -> (@focusedWindow() ? this).openPath()
|
||||
@on 'application:open', -> @promptForPath()
|
||||
@on 'application:open', -> @promptForPath(type: 'all')
|
||||
@on 'application:open-file', -> @promptForPath(type: 'file')
|
||||
@on 'application:open-folder', -> @promptForPath(type: 'folder')
|
||||
@on 'application:open-dev', -> @promptForPath(devMode: true)
|
||||
@on 'application:inspect', ({x,y}) -> @focusedWindow().browserWindow.inspectElement(x, y)
|
||||
@on 'application:inspect', ({x,y, atomWindow}) ->
|
||||
atomWindow ?= @focusedWindow()
|
||||
atomWindow?.browserWindow.inspectElement(x, y)
|
||||
|
||||
@on 'application:open-documentation', -> shell.openExternal('https://atom.io/docs/latest/?app')
|
||||
@on 'application:install-update', -> autoUpdater.quitAndInstall()
|
||||
@on 'application:check-for-update', => @checkForUpdate()
|
||||
@on 'application:install-update', -> @autoUpdateManager.install()
|
||||
@on 'application:check-for-update', => @autoUpdateManager.check()
|
||||
|
||||
if process.platform is 'darwin'
|
||||
@on 'application:about', -> Menu.sendActionToFirstResponder('orderFrontStandardAboutPanel:')
|
||||
@@ -219,6 +186,10 @@ class AtomApplication
|
||||
event.preventDefault()
|
||||
@openUrl({urlToOpen, @devMode})
|
||||
|
||||
app.on 'activate-with-no-open-windows', (event) =>
|
||||
event.preventDefault()
|
||||
@emit('application:new-window')
|
||||
|
||||
# A request from the associated render process to open a new render process.
|
||||
ipc.on 'open', (processId, routingId, options) =>
|
||||
if options?
|
||||
@@ -250,10 +221,8 @@ class AtomApplication
|
||||
#
|
||||
# If it isn't handled globally, delegate to the currently focused window.
|
||||
#
|
||||
# * command:
|
||||
# The string representing the command.
|
||||
# * args:
|
||||
# The optional arguments to pass along.
|
||||
# command - The string representing the command.
|
||||
# args - The optional arguments to pass along.
|
||||
sendCommand: (command, args...) ->
|
||||
unless @emit(command, args...)
|
||||
focusedWindow = @focusedWindow()
|
||||
@@ -262,6 +231,18 @@ class AtomApplication
|
||||
else
|
||||
@sendCommandToFirstResponder(command)
|
||||
|
||||
# Public: Executes the given command on the given window.
|
||||
#
|
||||
# command - The string representing the command.
|
||||
# atomWindow - The {AtomWindow} to send the command to.
|
||||
# args - The optional arguments to pass along.
|
||||
sendCommandToWindow: (command, atomWindow, args...) ->
|
||||
unless @emit(command, args...)
|
||||
if atomWindow?
|
||||
atomWindow.sendCommand(command, args...)
|
||||
else
|
||||
@sendCommandToFirstResponder(command)
|
||||
|
||||
# Translates the command into OS X action and sends it to application's first
|
||||
# responder.
|
||||
sendCommandToFirstResponder: (command) ->
|
||||
@@ -282,8 +263,8 @@ class AtomApplication
|
||||
#
|
||||
# A new window will be created if there is no currently focused window.
|
||||
#
|
||||
# * eventName: The event to listen for.
|
||||
# * pathToOpen: The path to open when the event is triggered.
|
||||
# eventName - The event to listen for.
|
||||
# pathToOpen - The path to open when the event is triggered.
|
||||
openPathOnEvent: (eventName, pathToOpen) ->
|
||||
@on eventName, ->
|
||||
if window = @focusedWindow()
|
||||
@@ -300,45 +281,25 @@ class AtomApplication
|
||||
focusedWindow: ->
|
||||
_.find @windows, (atomWindow) -> atomWindow.isFocused()
|
||||
|
||||
# Public: Get the height and width of the focused window.
|
||||
#
|
||||
# Returns an object with height and width keys or null if there is no
|
||||
# focused window.
|
||||
getFocusedWindowSize: ->
|
||||
if focusedWindow = @focusedWindow()
|
||||
[width, height] = focusedWindow.getSize()
|
||||
{width, height}
|
||||
else
|
||||
null
|
||||
|
||||
# Public: Opens multiple paths, in existing windows if possible.
|
||||
#
|
||||
# * options
|
||||
# + pathsToOpen:
|
||||
# The array of file paths to open
|
||||
# + pidToKillWhenClosed:
|
||||
# The integer of the pid to kill
|
||||
# + newWindow:
|
||||
# Boolean of whether this should be opened in a new window.
|
||||
# + devMode:
|
||||
# Boolean to control the opened window's dev mode.
|
||||
# options -
|
||||
# :pathsToOpen - The array of file paths to open
|
||||
# :pidToKillWhenClosed - The integer of the pid to kill
|
||||
# :newWindow - Boolean of whether this should be opened in a new window.
|
||||
# :devMode - Boolean to control the opened window's dev mode.
|
||||
openPaths: ({pathsToOpen, pidToKillWhenClosed, newWindow, devMode}) ->
|
||||
@openPath({pathToOpen, pidToKillWhenClosed, newWindow, devMode}) for pathToOpen in pathsToOpen ? []
|
||||
|
||||
# Public: Opens a single path, in an existing window if possible.
|
||||
#
|
||||
# * options
|
||||
# + pathToOpen:
|
||||
# The file path to open
|
||||
# + pidToKillWhenClosed:
|
||||
# The integer of the pid to kill
|
||||
# + newWindow:
|
||||
# Boolean of whether this should be opened in a new window.
|
||||
# + devMode:
|
||||
# Boolean to control the opened window's dev mode.
|
||||
# + initialSize:
|
||||
# Object with height and width keys.
|
||||
openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, initialSize}={}) ->
|
||||
# options -
|
||||
# :pathToOpen - The file path to open
|
||||
# :pidToKillWhenClosed - The integer of the pid to kill
|
||||
# :newWindow - Boolean of whether this should be opened in a new window.
|
||||
# :devMode - Boolean to control the opened window's dev mode.
|
||||
# :windowDimensions - Object with height and width keys.
|
||||
openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, windowDimensions}={}) ->
|
||||
if pathToOpen
|
||||
[basename, initialLine] = path.basename(pathToOpen).split(':')
|
||||
if initialLine
|
||||
@@ -358,7 +319,7 @@ class AtomApplication
|
||||
|
||||
bootstrapScript ?= require.resolve('../window-bootstrap')
|
||||
resourcePath ?= @resourcePath
|
||||
openedWindow = new AtomWindow({pathToOpen, initialLine, bootstrapScript, resourcePath, devMode, initialSize})
|
||||
openedWindow = new AtomWindow({pathToOpen, initialLine, bootstrapScript, resourcePath, devMode, windowDimensions})
|
||||
|
||||
if pidToKillWhenClosed?
|
||||
@pidsToOpenWindows[pidToKillWhenClosed] = openedWindow
|
||||
@@ -390,11 +351,9 @@ class AtomApplication
|
||||
# responsible for opening the URL. A new window will be created with
|
||||
# that package's `urlMain` as the bootstrap script.
|
||||
#
|
||||
# * options
|
||||
# + urlToOpen:
|
||||
# The atom:// url to open.
|
||||
# + devMode:
|
||||
# Boolean to control the opened window's dev mode.
|
||||
# options -
|
||||
# :urlToOpen - The atom:// url to open.
|
||||
# :devMode - Boolean to control the opened window's dev mode.
|
||||
openUrl: ({urlToOpen, devMode}) ->
|
||||
unless @packages?
|
||||
PackageManager = require '../package-manager'
|
||||
@@ -410,7 +369,8 @@ class AtomApplication
|
||||
if pack.urlMain
|
||||
packagePath = @packages.resolvePackagePath(packageName)
|
||||
bootstrapScript = path.resolve(packagePath, pack.urlMain)
|
||||
new AtomWindow({bootstrapScript, @resourcePath, devMode, urlToOpen, initialSize: @getFocusedWindowSize()})
|
||||
windowDimensions = @focusedWindow()?.getDimensions()
|
||||
new AtomWindow({bootstrapScript, @resourcePath, devMode, urlToOpen, windowDimensions})
|
||||
else
|
||||
console.log "Package '#{pack.name}' does not have a url main: #{urlToOpen}"
|
||||
else
|
||||
@@ -418,13 +378,11 @@ class AtomApplication
|
||||
|
||||
# Opens up a new {AtomWindow} to run specs within.
|
||||
#
|
||||
# * options
|
||||
# + exitWhenDone:
|
||||
# A Boolean that if true, will close the window upon completion.
|
||||
# + resourcePath:
|
||||
# The path to include specs from.
|
||||
# + specPath:
|
||||
# The directory to load specs from.
|
||||
# options -
|
||||
# :exitWhenDone - A Boolean that if true, will close the window upon
|
||||
# completion.
|
||||
# :resourcePath - The path to include specs from.
|
||||
# :specPath - The directory to load specs from.
|
||||
runSpecs: ({exitWhenDone, resourcePath, specDirectory, logFile}) ->
|
||||
if resourcePath isnt @resourcePath and not fs.existsSync(resourcePath)
|
||||
resourcePath = @resourcePath
|
||||
@@ -451,10 +409,18 @@ class AtomApplication
|
||||
#
|
||||
# Once paths are selected, they're opened in a new or existing {AtomWindow}s.
|
||||
#
|
||||
# * options
|
||||
# + devMode:
|
||||
# A Boolean which controls whether any newly opened windows should be in
|
||||
# dev mode or not.
|
||||
promptForPath: ({devMode}={}) ->
|
||||
dialog.showOpenDialog title: 'Open', properties: ['openFile', 'openDirectory', 'multiSelections', 'createDirectory'], (pathsToOpen) =>
|
||||
# options -
|
||||
# :type - A String which specifies the type of the dialog, could be 'file',
|
||||
# 'folder' or 'all'. The 'all' is only available on OS X.
|
||||
# :devMode - A Boolean which controls whether any newly opened windows
|
||||
# should be in dev mode or not.
|
||||
promptForPath: ({type, devMode}={}) ->
|
||||
type ?= 'all'
|
||||
properties =
|
||||
switch type
|
||||
when 'file' then ['openFile']
|
||||
when 'folder' then ['openDirectory']
|
||||
when 'all' then ['openFile', 'openDirectory']
|
||||
else throw new Error("#{type} is an invalid type for promptForPath")
|
||||
dialog.showOpenDialog title: 'Open', properties: properties.concat(['multiSelections', 'createDirectory']), (pathsToOpen) =>
|
||||
@openPaths({pathsToOpen, devMode})
|
||||
|
||||
@@ -7,9 +7,12 @@ path = require 'path'
|
||||
fs = require 'fs'
|
||||
url = require 'url'
|
||||
_ = require 'underscore-plus'
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
module.exports =
|
||||
class AtomWindow
|
||||
_.extend @prototype, EventEmitter.prototype
|
||||
|
||||
@iconPath: path.resolve(__dirname, '..', '..', 'resources', 'atom.png')
|
||||
@includeShellLoadTime: true
|
||||
|
||||
@@ -38,7 +41,10 @@ class AtomWindow
|
||||
loadSettings.initialPath = path.dirname(pathToOpen)
|
||||
|
||||
@browserWindow.loadSettings = loadSettings
|
||||
@browserWindow.once 'window:loaded', => @loaded = true
|
||||
@browserWindow.once 'window:loaded', =>
|
||||
@emit 'window:loaded'
|
||||
@loaded = true
|
||||
|
||||
@browserWindow.loadUrl @getUrl(loadSettings)
|
||||
@browserWindow.focusOnWebView() if @isSpec
|
||||
|
||||
@@ -101,7 +107,7 @@ class AtomWindow
|
||||
when 1 then @browserWindow.restart()
|
||||
|
||||
@browserWindow.on 'context-menu', (menuTemplate) =>
|
||||
new ContextMenu(menuTemplate, @browserWindow)
|
||||
new ContextMenu(menuTemplate, this)
|
||||
|
||||
if @isSpec
|
||||
# Spec window's web view should always have focus
|
||||
@@ -132,12 +138,15 @@ class AtomWindow
|
||||
action = if args[0]?.contextCommand then 'context-command' else 'command'
|
||||
ipc.sendChannel @browserWindow.getProcessId(), @browserWindow.getRoutingId(), action, command, args...
|
||||
|
||||
getDimensions: ->
|
||||
[x, y] = @browserWindow.getPosition()
|
||||
[width, height] = @browserWindow.getSize()
|
||||
{x, y, width, height}
|
||||
|
||||
close: -> @browserWindow.close()
|
||||
|
||||
focus: -> @browserWindow.focus()
|
||||
|
||||
getSize: -> @browserWindow.getSize()
|
||||
|
||||
minimize: -> @browserWindow.minimize()
|
||||
|
||||
maximize: -> @browserWindow.maximize()
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
autoUpdater = require 'auto-updater'
|
||||
dialog = require 'dialog'
|
||||
_ = require 'underscore-plus'
|
||||
{EventEmitter} = require 'events'
|
||||
|
||||
IDLE_STATE='idle'
|
||||
CHECKING_STATE='checking'
|
||||
DOWNLOADING_STATE='downloading'
|
||||
UPDATE_AVAILABLE_STATE='update-available'
|
||||
NO_UPDATE_AVAILABLE_STATE='no-update-available'
|
||||
ERROR_STATE='error'
|
||||
|
||||
module.exports =
|
||||
class AutoUpdateManager
|
||||
_.extend @prototype, EventEmitter.prototype
|
||||
|
||||
constructor: (@version) ->
|
||||
@state = IDLE_STATE
|
||||
|
||||
# Only released versions should check for updates.
|
||||
return if /\w{7}/.test(@version)
|
||||
|
||||
autoUpdater.setFeedUrl "https://atom.io/api/updates?version=#{@version}"
|
||||
|
||||
autoUpdater.on 'checking-for-update', =>
|
||||
@setState(CHECKING_STATE)
|
||||
|
||||
autoUpdater.on 'update-not-available', =>
|
||||
@setState(NO_UPDATE_AVAILABLE_STATE)
|
||||
|
||||
autoUpdater.on 'update-available', =>
|
||||
@setState(DOWNLOADING_STATE)
|
||||
|
||||
autoUpdater.on 'error', (event, message) =>
|
||||
@setState(ERROR_STATE)
|
||||
console.error "Error Downloading Update: #{message}"
|
||||
|
||||
autoUpdater.on 'update-downloaded', (event, @releaseNotes, @releaseVersion) =>
|
||||
@setState(UPDATE_AVAILABLE_STATE)
|
||||
@emitUpdateAvailableEvent(@getWindows()...)
|
||||
|
||||
@check(hidePopups: true)
|
||||
|
||||
emitUpdateAvailableEvent: (windows...) ->
|
||||
return unless @releaseVersion? and @releaseNotes
|
||||
for atomWindow in windows
|
||||
atomWindow.sendCommand('window:update-available', [@releaseVersion, @releaseNotes])
|
||||
|
||||
setState: (state) ->
|
||||
return unless @state != state
|
||||
@state = state
|
||||
@emit 'state-changed', @state
|
||||
|
||||
getState: ->
|
||||
@state
|
||||
|
||||
check: ({hidePopups}={})->
|
||||
unless hidePopups
|
||||
autoUpdater.once 'update-not-available', @onUpdateNotAvailable
|
||||
autoUpdater.once 'error', @onUpdateError
|
||||
|
||||
autoUpdater.checkForUpdates()
|
||||
|
||||
install: ->
|
||||
autoUpdater.quitAndInstall()
|
||||
|
||||
onUpdateNotAvailable: =>
|
||||
autoUpdater.removeListener 'error', @onUpdateError
|
||||
dialog.showMessageBox type: 'info', buttons: ['OK'], message: 'No update available.', detail: "Version #{@version} is the latest version."
|
||||
|
||||
onUpdateError: (event, message) =>
|
||||
autoUpdater.removeListener 'update-not-available', @onUpdateNotAvailable
|
||||
dialog.showMessageBox type: 'warning', buttons: ['OK'], message: 'There was an error checking for updates.', detail: message
|
||||
|
||||
getWindows: ->
|
||||
global.atomApplication.windows
|
||||
@@ -2,10 +2,10 @@ Menu = require 'menu'
|
||||
|
||||
module.exports =
|
||||
class ContextMenu
|
||||
constructor: (template, browserWindow) ->
|
||||
constructor: (template, @atomWindow) ->
|
||||
template = @createClickHandlers(template)
|
||||
menu = Menu.buildFromTemplate(template)
|
||||
menu.popup(browserWindow)
|
||||
menu.popup(@atomWindow.browserWindow)
|
||||
|
||||
# It's necessary to build the event handlers in this process, otherwise
|
||||
# closures are drug across processes and failed to be garbage collected
|
||||
@@ -13,7 +13,10 @@ class ContextMenu
|
||||
createClickHandlers: (template) ->
|
||||
for item in template
|
||||
if item.command
|
||||
(item.commandOptions ?= {}).contextCommand = true
|
||||
item.click = do (item) ->
|
||||
=> global.atomApplication.sendCommand(item.command, item.commandOptions)
|
||||
item.commandOptions ?= {}
|
||||
item.commandOptions.contextCommand = true
|
||||
item.commandOptions.atomWindow = @atomWindow
|
||||
do (item) =>
|
||||
item.click = =>
|
||||
global.atomApplication.sendCommandToWindow(item.command, @atomWindow, item.commandOptions)
|
||||
item
|
||||
|
||||
@@ -1,33 +1,29 @@
|
||||
crypto = require 'crypto'
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
|
||||
CoffeeScript = require 'coffee-script'
|
||||
CSON = require 'season'
|
||||
mkdir = require('mkdirp').sync
|
||||
fs = require 'fs-plus'
|
||||
|
||||
tmpDir = if process.platform is 'win32' then os.tmpdir() else '/tmp'
|
||||
cacheDir = path.join(tmpDir, 'atom-compile-cache')
|
||||
cacheDir = path.join(fs.getHomeDirectory(), 'compile-cache')
|
||||
coffeeCacheDir = path.join(cacheDir, 'coffee')
|
||||
CSON.setCacheDir(path.join(cacheDir, 'cson'))
|
||||
|
||||
getCachePath = (coffee) ->
|
||||
digest = crypto.createHash('sha1').update(coffee, 'utf8').digest('hex')
|
||||
path.join(coffeeCacheDir, "#{digest}.coffee")
|
||||
path.join(coffeeCacheDir, "#{digest}.js")
|
||||
|
||||
getCachedJavaScript = (cachePath) ->
|
||||
if stat = fs.statSyncNoException(cachePath)
|
||||
if fs.isFileSync(cachePath)
|
||||
try
|
||||
fs.readFileSync(cachePath, 'utf8') if stat.isFile()
|
||||
fs.readFileSync(cachePath, 'utf8')
|
||||
|
||||
compileCoffeeScript = (coffee, filePath, cachePath) ->
|
||||
{js,v3SourceMap} = CoffeeScript.compile(coffee, filename: filePath, sourceMap: true)
|
||||
{js, v3SourceMap} = CoffeeScript.compile(coffee, filename: filePath, sourceMap: true)
|
||||
# Include source map in the web page environment.
|
||||
if btoa? and JSON? and unescape? and encodeURIComponent?
|
||||
js = "#{js}\n//# sourceMappingURL=data:application/json;base64,#{btoa unescape encodeURIComponent v3SourceMap}\n//# sourceURL=#{filePath}"
|
||||
try
|
||||
mkdir(path.dirname(cachePath))
|
||||
fs.writeFileSync(cachePath, js)
|
||||
js
|
||||
|
||||
|
||||
+41
-20
@@ -18,9 +18,9 @@ pathWatcher = require 'pathwatcher'
|
||||
# ## Example
|
||||
#
|
||||
# ```coffeescript
|
||||
# atom.config.set('myplugin.key', 'value')
|
||||
# atom.config.observe 'myplugin.key', ->
|
||||
# console.log 'My configuration changed:', atom.config.get('myplugin.key')
|
||||
# atom.config.set('my-package.key', 'value')
|
||||
# atom.config.observe 'my-package.key', ->
|
||||
# console.log 'My configuration changed:', atom.config.get('my-package.key')
|
||||
# ```
|
||||
module.exports =
|
||||
class Config
|
||||
@@ -86,9 +86,9 @@ class Config
|
||||
hash = hash[key]
|
||||
|
||||
_.extend hash, defaults
|
||||
@update()
|
||||
@emit 'updated'
|
||||
|
||||
# Public: Get the path to the config file being used.
|
||||
# Public: Get the {String} path to the config file being used.
|
||||
getUserConfigPath: ->
|
||||
@configFilePath
|
||||
|
||||
@@ -98,10 +98,10 @@ class Config
|
||||
|
||||
# Public: Retrieves the setting for the given key.
|
||||
#
|
||||
# keyPath - The {String} name of the key to retrieve
|
||||
# keyPath - The {String} name of the key to retrieve.
|
||||
#
|
||||
# Returns the value from Atom's default settings, the user's configuration file,
|
||||
# or `null` if the key doesn't exist in either.
|
||||
# Returns the value from Atom's default settings, the user's configuration
|
||||
# file, or `null` if the key doesn't exist in either.
|
||||
get: (keyPath) ->
|
||||
value = _.valueForKeyPath(@settings, keyPath) ? _.valueForKeyPath(@defaultSettings, keyPath)
|
||||
_.deepClone(value)
|
||||
@@ -110,8 +110,8 @@ class Config
|
||||
#
|
||||
# keyPath - The {String} name of the key to retrieve
|
||||
#
|
||||
# Returns the value from Atom's default settings, the user's configuration file,
|
||||
# or `NaN` if the key doesn't exist in either.
|
||||
# Returns the value from Atom's default settings, the user's configuration
|
||||
# file, or `NaN` if the key doesn't exist in either.
|
||||
getInt: (keyPath) ->
|
||||
parseInt(@get(keyPath))
|
||||
|
||||
@@ -121,8 +121,8 @@ class Config
|
||||
# defaultValue - The integer {Number} to fall back to if the value isn't
|
||||
# positive, defaults to 0.
|
||||
#
|
||||
# Returns the value from Atom's default settings, the user's configuration file,
|
||||
# or `defaultValue` if the key value isn't greater than zero.
|
||||
# Returns the value from Atom's default settings, the user's configuration
|
||||
# file, or `defaultValue` if the key value isn't greater than zero.
|
||||
getPositiveInt: (keyPath, defaultValue=0) ->
|
||||
Math.max(@getInt(keyPath), 0) or defaultValue
|
||||
|
||||
@@ -130,13 +130,14 @@ class Config
|
||||
#
|
||||
# This value is stored in Atom's internal configuration file.
|
||||
#
|
||||
# keyPath - The {String} name of the key
|
||||
# value - The value of the setting
|
||||
# keyPath - The {String} name of the key.
|
||||
# value - The value of the setting.
|
||||
#
|
||||
# Returns the `value`.
|
||||
set: (keyPath, value) ->
|
||||
if @get(keyPath) != value
|
||||
value = undefined if _.valueForKeyPath(@defaultSettings, keyPath) == value
|
||||
if @get(keyPath) isnt value
|
||||
defaultValue = _.valueForKeyPath(@defaultSettings, keyPath)
|
||||
value = undefined if _.isEqual(defaultValue, value)
|
||||
_.setValueForKeyPath(@settings, keyPath, value)
|
||||
@update()
|
||||
value
|
||||
@@ -146,6 +147,8 @@ class Config
|
||||
# The new value will be `true` if the value is currently falsy and will be
|
||||
# `false` if the value is currently truthy.
|
||||
#
|
||||
# keyPath - The {String} name of the key.
|
||||
#
|
||||
# Returns the new value.
|
||||
toggle: (keyPath) ->
|
||||
@set(keyPath, !@get(keyPath))
|
||||
@@ -158,12 +161,30 @@ class Config
|
||||
restoreDefault: (keyPath) ->
|
||||
@set(keyPath, _.valueForKeyPath(@defaultSettings, keyPath))
|
||||
|
||||
# Public: Get the default value of the key path.
|
||||
#
|
||||
# keyPath - The {String} name of the key.
|
||||
#
|
||||
# Returns the default value.
|
||||
getDefault: (keyPath) ->
|
||||
defaultValue = _.valueForKeyPath(@defaultSettings, keyPath)
|
||||
_.deepClone(defaultValue)
|
||||
|
||||
# Public: Is the key path value its default value?
|
||||
#
|
||||
# keyPath - The {String} name of the key.
|
||||
#
|
||||
# Returns a {Boolean}, `true` if the current value is the default, `false`
|
||||
# otherwise.
|
||||
isDefault: (keyPath) ->
|
||||
not _.valueForKeyPath(@settings, keyPath)?
|
||||
|
||||
# Public: Push the value to the array at the key path.
|
||||
#
|
||||
# keyPath - The {String} key path.
|
||||
# value - The value to push to the array.
|
||||
#
|
||||
# Returns the new array length of the setting.
|
||||
# Returns the new array length {Number} of the setting.
|
||||
pushAtKeyPath: (keyPath, value) ->
|
||||
arrayValue = @get(keyPath) ? []
|
||||
result = arrayValue.push(value)
|
||||
@@ -175,7 +196,7 @@ class Config
|
||||
# keyPath - The {String} key path.
|
||||
# value - The value to shift onto the array.
|
||||
#
|
||||
# Returns the new array length of the setting.
|
||||
# Returns the new array length {Number} of the setting.
|
||||
unshiftAtKeyPath: (keyPath, value) ->
|
||||
arrayValue = @get(keyPath) ? []
|
||||
result = arrayValue.unshift(value)
|
||||
@@ -225,9 +246,9 @@ class Config
|
||||
callback(value) if options.callNow ? true
|
||||
subscription
|
||||
|
||||
# Public: Unobserve all callbacks on a given key
|
||||
# Public: Unobserve all callbacks on a given key.
|
||||
#
|
||||
# keyPath - The {String} name of the key to unobserve
|
||||
# keyPath - The {String} name of the key to unobserve.
|
||||
unobserve: (keyPath) ->
|
||||
@off("updated.#{keyPath.replace(/\./, '-')}")
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ class ContextMenuManager
|
||||
label: 'Inspect Element'
|
||||
command: 'application:inspect'
|
||||
executeAtBuild: (e) ->
|
||||
@.commandOptions = x: e.pageX, y: e.pageY
|
||||
@commandOptions = x: e.pageX, y: e.pageY
|
||||
]
|
||||
|
||||
# Public: Creates menu definitions from the object specified by the menu
|
||||
|
||||
+9
-2
@@ -315,12 +315,14 @@ class Cursor
|
||||
# :includeNonWordCharacters - A {Boolean} indicating whether to include
|
||||
# non-word characters in the default word regex.
|
||||
# Has no effect if wordRegex is set.
|
||||
# :allowPrevious - A {Boolean} indicating whether the beginning of the
|
||||
# previous word can be returned.
|
||||
#
|
||||
# Returns a {Range}.
|
||||
getBeginningOfCurrentWordBufferPosition: (options = {}) ->
|
||||
allowPrevious = options.allowPrevious ? true
|
||||
currentBufferPosition = @getBufferPosition()
|
||||
previousNonBlankRow = @editor.buffer.previousNonBlankRow(currentBufferPosition.row)
|
||||
previousNonBlankRow = @editor.buffer.previousNonBlankRow(currentBufferPosition.row) ? 0
|
||||
scanRange = [[previousNonBlankRow, 0], currentBufferPosition]
|
||||
|
||||
beginningOfWordPosition = null
|
||||
@@ -330,7 +332,12 @@ class Cursor
|
||||
if not beginningOfWordPosition?.isEqual(currentBufferPosition)
|
||||
stop()
|
||||
|
||||
beginningOfWordPosition or currentBufferPosition
|
||||
if beginningOfWordPosition?
|
||||
beginningOfWordPosition
|
||||
else if allowPrevious
|
||||
new Point(0, 0)
|
||||
else
|
||||
currentBufferPosition
|
||||
|
||||
# Public: Retrieves buffer position of previous word boundary. It might be on
|
||||
# the current word, or the previous word.
|
||||
|
||||
@@ -140,10 +140,10 @@ class DisplayBufferMarker
|
||||
@bufferMarker.isDestroyed()
|
||||
|
||||
getAttributes: ->
|
||||
@bufferMarker.getAttributes()
|
||||
@bufferMarker.getProperties()
|
||||
|
||||
setAttributes: (attributes) ->
|
||||
@bufferMarker.setAttributes(attributes)
|
||||
@bufferMarker.setProperties(attributes)
|
||||
|
||||
matchesAttributes: (attributes) ->
|
||||
attributes = @displayBuffer.translateToBufferMarkerParams(attributes)
|
||||
|
||||
@@ -493,8 +493,8 @@ class DisplayBuffer extends Model
|
||||
# options - Options to pass to the {Marker} constructor
|
||||
#
|
||||
# Returns a {Number} representing the new marker's ID.
|
||||
markBufferRange: (args...) ->
|
||||
@getMarker(@buffer.markRange(args...).id)
|
||||
markBufferRange: (range, options) ->
|
||||
@getMarker(@buffer.markRange(range, options).id)
|
||||
|
||||
# Public: Constructs a new marker at the given screen position.
|
||||
#
|
||||
|
||||
+11
-12
@@ -50,7 +50,7 @@ class EditorView extends View
|
||||
showLineNumbers: true
|
||||
autoIndent: true
|
||||
normalizeIndentOnPaste: true
|
||||
nonWordCharacters: "./\\()\"':,.;<>~!@#$%^&*|+=[]{}`~?-"
|
||||
nonWordCharacters: "./\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-"
|
||||
preferredLineLength: 80
|
||||
tabLength: 2
|
||||
softWrap: false
|
||||
@@ -343,7 +343,6 @@ class EditorView extends View
|
||||
@subscribe atom.config.observe 'editor.fontFamily', (fontFamily) => @setFontFamily(fontFamily)
|
||||
@subscribe atom.config.observe 'editor.lineHeight', (lineHeight) => @setLineHeight(lineHeight)
|
||||
|
||||
|
||||
handleEvents: ->
|
||||
@on 'focus', =>
|
||||
@hiddenInput.focus()
|
||||
@@ -528,7 +527,7 @@ class EditorView extends View
|
||||
|
||||
if @editor
|
||||
@saveScrollPositionForEditor()
|
||||
@editor.off(".editor")
|
||||
@unsubscribe(@editor)
|
||||
|
||||
@editor = editor
|
||||
|
||||
@@ -536,34 +535,34 @@ class EditorView extends View
|
||||
|
||||
@editor.setVisible(true)
|
||||
|
||||
@editor.on "destroyed", =>
|
||||
@subscribe @editor, "destroyed", =>
|
||||
@remove()
|
||||
|
||||
@editor.on "contents-conflicted.editor", =>
|
||||
@subscribe @editor, "contents-conflicted", =>
|
||||
@showBufferConflictAlert(@editor)
|
||||
|
||||
@editor.on "path-changed.editor", =>
|
||||
@subscribe @editor, "path-changed", =>
|
||||
@editor.reloadGrammar()
|
||||
@trigger 'editor:path-changed'
|
||||
|
||||
@editor.on "grammar-changed.editor", =>
|
||||
@subscribe @editor, "grammar-changed", =>
|
||||
@trigger 'editor:grammar-changed'
|
||||
|
||||
@editor.on 'selection-added.editor', (selection) =>
|
||||
@subscribe @editor, 'selection-added', (selection) =>
|
||||
@newCursors.push(selection.cursor)
|
||||
@newSelections.push(selection)
|
||||
@requestDisplayUpdate()
|
||||
|
||||
@editor.on 'screen-lines-changed.editor', (e) =>
|
||||
@subscribe @editor, 'screen-lines-changed', (e) =>
|
||||
@handleScreenLinesChange(e)
|
||||
|
||||
@editor.on 'scroll-top-changed.editor', (scrollTop) =>
|
||||
@subscribe @editor, 'scroll-top-changed', (scrollTop) =>
|
||||
@scrollTop(scrollTop)
|
||||
|
||||
@editor.on 'scroll-left-changed.editor', (scrollLeft) =>
|
||||
@subscribe @editor, 'scroll-left-changed', (scrollLeft) =>
|
||||
@scrollLeft(scrollLeft)
|
||||
|
||||
@editor.on 'soft-wrap-changed.editor', (softWrap) =>
|
||||
@subscribe @editor, 'soft-wrap-changed', (softWrap) =>
|
||||
@setSoftWrap(softWrap)
|
||||
|
||||
@trigger 'editor:path-changed'
|
||||
|
||||
+28
-12
@@ -2,6 +2,7 @@ _ = require 'underscore-plus'
|
||||
path = require 'path'
|
||||
Serializable = require 'serializable'
|
||||
Delegator = require 'delegato'
|
||||
{deprecate} = require 'grim'
|
||||
{Model} = require 'theorist'
|
||||
{Point, Range} = require 'text-buffer'
|
||||
LanguageMode = require './language-mode'
|
||||
@@ -181,7 +182,7 @@ class Editor extends Model
|
||||
@subscribe @$scrollTop, (scrollTop) => @emit 'scroll-top-changed', scrollTop
|
||||
@subscribe @$scrollLeft, (scrollLeft) => @emit 'scroll-left-changed', scrollLeft
|
||||
|
||||
atom.project.addEditor(this) if registerEditor
|
||||
atom.workspace?.editorAdded(this) if registerEditor
|
||||
|
||||
serializeParams: ->
|
||||
id: @id
|
||||
@@ -224,19 +225,17 @@ class Editor extends Model
|
||||
@buffer.release()
|
||||
@displayBuffer.destroy()
|
||||
@languageMode.destroy()
|
||||
atom.project?.removeEditor(this)
|
||||
|
||||
# Create an {Editor} with its initial state based on this object
|
||||
copy: ->
|
||||
tabLength = @getTabLength()
|
||||
displayBuffer = @displayBuffer.copy()
|
||||
softTabs = @getSoftTabs()
|
||||
newEditor = new Editor({@buffer, displayBuffer, tabLength, softTabs, suppressCursorCreation: true})
|
||||
newEditor = new Editor({@buffer, displayBuffer, tabLength, softTabs, suppressCursorCreation: true, registerEditor: true})
|
||||
newEditor.setScrollTop(@getScrollTop())
|
||||
newEditor.setScrollLeft(@getScrollLeft())
|
||||
for marker in @findMarkers(editorId: @id)
|
||||
marker.copy(editorId: newEditor.id, preserveFolds: true)
|
||||
atom.project.addEditor(newEditor)
|
||||
newEditor
|
||||
|
||||
# Public: Get the title the editor's title for display in other parts of the
|
||||
@@ -382,7 +381,7 @@ class Editor extends Model
|
||||
else
|
||||
endColumn = @lineForBufferRow(bufferRow).match(/^\s*/)[0].length
|
||||
newIndentString = @buildIndentString(newLevel)
|
||||
@buffer.change([[bufferRow, 0], [bufferRow, endColumn]], newIndentString)
|
||||
@buffer.setTextInRange([[bufferRow, 0], [bufferRow, endColumn]], newIndentString)
|
||||
|
||||
# Public: Get the indentation level of the given line of text.
|
||||
#
|
||||
@@ -457,8 +456,8 @@ class Editor extends Model
|
||||
# {Delegates to: TextBuffer.nextNonBlankRow}
|
||||
nextNonBlankBufferRow: (bufferRow) -> @buffer.nextNonBlankRow(bufferRow)
|
||||
|
||||
# {Delegates to: TextBuffer.getEofPosition}
|
||||
getEofBufferPosition: -> @buffer.getEofPosition()
|
||||
# {Delegates to: TextBuffer.getEndPosition}
|
||||
getEofBufferPosition: -> @buffer.getEndPosition()
|
||||
|
||||
# Public: Returns a {Number} representing the last zero-indexed buffer row
|
||||
# number of the editor.
|
||||
@@ -622,11 +621,20 @@ class Editor extends Model
|
||||
# Public: For each cursor, insert a newline at the end of the preceding line.
|
||||
insertNewlineAbove: ->
|
||||
@transact =>
|
||||
onFirstLine = @getCursorBufferPosition().row is 0
|
||||
bufferRow = @getCursorBufferPosition().row
|
||||
indentLevel = @indentationForBufferRow(bufferRow)
|
||||
onFirstLine = bufferRow is 0
|
||||
|
||||
@moveCursorToBeginningOfLine()
|
||||
@moveCursorLeft()
|
||||
@insertNewline()
|
||||
@moveCursorUp() if onFirstLine
|
||||
|
||||
if @shouldAutoIndent() and @indentationForBufferRow(bufferRow) < indentLevel
|
||||
@setIndentationForBufferRow(bufferRow, indentLevel)
|
||||
|
||||
if onFirstLine
|
||||
@moveCursorUp()
|
||||
@moveCursorToEndOfLine()
|
||||
|
||||
# Indent all lines intersecting selections. See {Selection::indent} for more
|
||||
# information.
|
||||
@@ -905,7 +913,7 @@ class Editor extends Model
|
||||
for foldedRow in foldedRows when 0 <= foldedRow <= @getLastBufferRow()
|
||||
@foldBufferRow(foldedRow)
|
||||
|
||||
@setSelectedBufferRange(selection.translate([-insertDelta]), preserveFolds: true)
|
||||
@setSelectedBufferRange(selection.translate([-insertDelta]), preserveFolds: true, autoscroll: true)
|
||||
|
||||
# Move lines intersecting the most recent selection down by one row in screen
|
||||
# coordinates.
|
||||
@@ -961,7 +969,7 @@ class Editor extends Model
|
||||
for foldedRow in foldedRows when 0 <= foldedRow <= @getLastBufferRow()
|
||||
@foldBufferRow(foldedRow)
|
||||
|
||||
@setSelectedBufferRange(selection.translate([insertDelta]), preserveFolds: true)
|
||||
@setSelectedBufferRange(selection.translate([insertDelta]), preserveFolds: true, autoscroll: true)
|
||||
|
||||
# Duplicate the most recent cursor's current line.
|
||||
duplicateLines: ->
|
||||
@@ -991,8 +999,15 @@ class Editor extends Model
|
||||
|
||||
# Deprecated: Use {::duplicateLines} instead.
|
||||
duplicateLine: ->
|
||||
deprecate("Use Editor::duplicateLines() instead")
|
||||
@duplicateLines()
|
||||
|
||||
# Public: Mutate the text of all the selections in a single transaction.
|
||||
#
|
||||
# All the changes made inside the given {Function} can be reverted with a
|
||||
# single call to {::undo}.
|
||||
#
|
||||
# fn - A {Function} that will be called with each {Selection}.
|
||||
mutateSelectedText: (fn) ->
|
||||
@transact => fn(selection) for selection in @getSelections()
|
||||
|
||||
@@ -1333,7 +1348,7 @@ class Editor extends Model
|
||||
# text - A {String}
|
||||
#
|
||||
# Returns the {Range} of the newly-inserted text.
|
||||
setTextInBufferRange: (range, text) -> @getBuffer().change(range, text)
|
||||
setTextInBufferRange: (range, text) -> @getBuffer().setTextInRange(range, text)
|
||||
|
||||
# Public: Get the {Range} of the paragraph surrounding the most recently added
|
||||
# cursor.
|
||||
@@ -1758,4 +1773,5 @@ class Editor extends Model
|
||||
|
||||
# Deprecated: Call {::joinLines} instead.
|
||||
joinLine: ->
|
||||
deprecate("Use Editor::joinLines() instead")
|
||||
@joinLines()
|
||||
|
||||
@@ -71,6 +71,9 @@ class Git
|
||||
|
||||
@statuses = {}
|
||||
@upstream = {ahead: 0, behind: 0}
|
||||
for submodulePath, submoduleRepo of @repo.submodules
|
||||
submoduleRepo.upstream = {ahead: 0, behind: 0}
|
||||
|
||||
{@project, refreshOnWindowFocus} = options
|
||||
|
||||
refreshOnWindowFocus ?= true
|
||||
|
||||
@@ -53,11 +53,11 @@ class LanguageMode
|
||||
buffer.transact ->
|
||||
columnStart = startMatch[1].length
|
||||
columnEnd = columnStart + startMatch[2].length
|
||||
buffer.change([[start, columnStart], [start, columnEnd]], "")
|
||||
buffer.setTextInRange([[start, columnStart], [start, columnEnd]], "")
|
||||
|
||||
endLength = buffer.lineLengthForRow(end) - endMatch[2].length
|
||||
endColumn = endLength - endMatch[1].length
|
||||
buffer.change([[end, endColumn], [end, endLength]], "")
|
||||
buffer.setTextInRange([[end, endColumn], [end, endLength]], "")
|
||||
else
|
||||
buffer.transact ->
|
||||
buffer.insert([start, 0], commentStartString)
|
||||
@@ -72,9 +72,12 @@ class LanguageMode
|
||||
if match = commentStartRegex.search(buffer.lineForRow(row))
|
||||
columnStart = match[1].length
|
||||
columnEnd = columnStart + match[2].length
|
||||
buffer.change([[row, columnStart], [row, columnEnd]], "")
|
||||
buffer.setTextInRange([[row, columnStart], [row, columnEnd]], "")
|
||||
else
|
||||
indent = @minIndentLevelForRowRange(start, end)
|
||||
if start is end
|
||||
indent = @editor.indentationForBufferRow(start)
|
||||
else
|
||||
indent = @minIndentLevelForRowRange(start, end)
|
||||
indentString = @editor.buildIndentString(indent)
|
||||
tabLength = @editor.getTabLength()
|
||||
indentRegex = new RegExp("(\t|[ ]{#{tabLength}}){#{Math.floor(indent)}}")
|
||||
@@ -83,7 +86,7 @@ class LanguageMode
|
||||
if indentLength = line.match(indentRegex)?[0].length
|
||||
buffer.insert([row, indentLength], commentStartString)
|
||||
else
|
||||
buffer.change([[row, 0], [row, indentString.length]], indentString + commentStartString)
|
||||
buffer.setTextInRange([[row, 0], [row, indentString.length]], indentString + commentStartString)
|
||||
|
||||
# Folds all the foldable lines in the buffer.
|
||||
foldAll: ->
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
fs = require 'fs-plus'
|
||||
LessCache = require 'less-cache'
|
||||
{Subscriber} = require 'emissary'
|
||||
|
||||
tmpDir = if process.platform is 'win32' then os.tmpdir() else '/tmp'
|
||||
|
||||
# {LessCache} wrapper used by {ThemeManager} to read stylesheets.
|
||||
module.exports =
|
||||
class LessCompileCache
|
||||
Subscriber.includeInto(this)
|
||||
|
||||
@cacheDir: path.join(tmpDir, 'atom-compile-cache', 'less')
|
||||
@cacheDir: path.join(fs.getHomeDirectory(), 'compile-cache', 'less')
|
||||
|
||||
constructor: ({resourcePath, importPaths}) ->
|
||||
@lessSearchPaths = [
|
||||
|
||||
@@ -78,7 +78,7 @@ class MenuManager
|
||||
keystrokesByCommand = {}
|
||||
for binding in atom.keymaps.getKeyBindings() when @includeSelector(binding.selector)
|
||||
keystrokesByCommand[binding.command] ?= []
|
||||
keystrokesByCommand[binding.command].unshift binding.keystroke
|
||||
keystrokesByCommand[binding.command].unshift binding.keystrokes
|
||||
@sendToBrowserProcess(@template, keystrokesByCommand)
|
||||
|
||||
loadPlatformItems: ->
|
||||
@@ -92,10 +92,10 @@ class MenuManager
|
||||
merge: (menu, item) ->
|
||||
item = _.deepClone(item)
|
||||
|
||||
if item.submenu? and match = _.find(menu, (i) => i.submenu? and @normalizeLabel(i.label) == @normalizeLabel(item.label))
|
||||
if item.submenu? and match = _.find(menu, ({label, submenu}) => submenu? and label and @normalizeLabel(label) is @normalizeLabel(item.label))
|
||||
@merge(match.submenu, i) for i in item.submenu
|
||||
else
|
||||
menu.push(item) unless _.find(menu, (i) => @normalizeLabel(i.label) == @normalizeLabel(item.label))
|
||||
menu.push(item) unless _.find(menu, ({label}) => label and @normalizeLabel(label) is @normalizeLabel(item.label))
|
||||
|
||||
# OSX can't handle displaying accelerators for multiple keystrokes.
|
||||
# If they are sent across, it will stop processing accelerators for the rest
|
||||
|
||||
@@ -7,7 +7,7 @@ fs = require 'fs-plus'
|
||||
{Emitter} = require 'emissary'
|
||||
Q = require 'q'
|
||||
|
||||
{$} = require './space-pen-extensions'
|
||||
$ = null # Defer require in case this is in the window-less browser process
|
||||
ScopedProperties = require './scoped-properties'
|
||||
|
||||
# Loads and activates a package's main module and resources such as
|
||||
@@ -286,6 +286,7 @@ class Package
|
||||
handleActivationEvent: (event) =>
|
||||
bubblePathEventHandlers = @disableEventHandlersOnBubblePath(event)
|
||||
@activateNow()
|
||||
$ ?= require('./space-pen-extensions').$
|
||||
$(event.target).trigger(event)
|
||||
@restoreEventHandlersOnBubblePath(bubblePathEventHandlers)
|
||||
@unsubscribeFromActivationEvents()
|
||||
@@ -303,6 +304,7 @@ class Package
|
||||
disableEventHandlersOnBubblePath: (event) ->
|
||||
bubblePathEventHandlers = []
|
||||
disabledHandler = ->
|
||||
$ ?= require('./space-pen-extensions').$
|
||||
element = $(event.target)
|
||||
while element.length
|
||||
if eventHandlers = element.handlers()?[event.type]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{deprecate} = require 'grim'
|
||||
Delegator = require 'delegato'
|
||||
{$, View} = require './space-pen-extensions'
|
||||
PaneView = require './pane-view'
|
||||
@@ -54,9 +55,9 @@ class PaneContainerView extends View
|
||||
|
||||
confirmClose: ->
|
||||
saved = true
|
||||
for pane in @getPaneViews()
|
||||
for item in pane.getItems()
|
||||
if not pane.promptToSaveItem(item)
|
||||
for paneView in @getPaneViews()
|
||||
for item in paneView.getItems()
|
||||
if not paneView.promptToSaveItem(item)
|
||||
saved = false
|
||||
break
|
||||
saved
|
||||
@@ -64,29 +65,33 @@ class PaneContainerView extends View
|
||||
getPaneViews: ->
|
||||
@find('.pane').views()
|
||||
|
||||
indexOfPane: (pane) ->
|
||||
@getPaneViews().indexOf(pane.view())
|
||||
indexOfPane: (paneView) ->
|
||||
@getPaneViews().indexOf(paneView.view())
|
||||
|
||||
paneAtIndex: (index) ->
|
||||
@getPaneViews()[index]
|
||||
|
||||
eachPaneView: (callback) ->
|
||||
callback(pane) for pane in @getPaneViews()
|
||||
paneAttached = (e) -> callback($(e.target).view())
|
||||
@on 'pane:attached', paneAttached
|
||||
off: => @off 'pane:attached', paneAttached
|
||||
callback(paneView) for paneView in @getPaneViews()
|
||||
paneViewAttached = (e) -> callback($(e.target).view())
|
||||
@on 'pane:attached', paneViewAttached
|
||||
off: => @off 'pane:attached', paneViewAttached
|
||||
|
||||
getFocusedPane: ->
|
||||
@find('.pane:has(:focus)').view()
|
||||
|
||||
getActivePane: ->
|
||||
deprecate("Use PaneContainerView::getActivePaneView instead.")
|
||||
@getActivePaneView()
|
||||
|
||||
getActivePaneView: ->
|
||||
@viewForModel(@model.activePane)
|
||||
|
||||
getActivePaneItem: ->
|
||||
@model.activePaneItem
|
||||
|
||||
getActiveView: ->
|
||||
@getActivePane()?.activeView
|
||||
@getActivePaneView()?.activeView
|
||||
|
||||
paneForUri: (uri) ->
|
||||
@viewForModel(@model.paneForUri(uri))
|
||||
@@ -115,29 +120,29 @@ class PaneContainerView extends View
|
||||
y = pointB.y - pointA.y
|
||||
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))
|
||||
|
||||
pane = @getActivePane()
|
||||
box = @boundingBoxForPane(pane)
|
||||
panes = @getPaneViews()
|
||||
.filter (otherPane) =>
|
||||
otherBox = @boundingBoxForPane(otherPane)
|
||||
paneView = @getActivePaneView()
|
||||
box = @boundingBoxForPaneView(paneView)
|
||||
paneViews = @getPaneViews()
|
||||
.filter (otherPaneView) =>
|
||||
otherBox = @boundingBoxForPaneView(otherPaneView)
|
||||
switch direction
|
||||
when 'left' then otherBox.right.x <= box.left.x
|
||||
when 'right' then otherBox.left.x >= box.right.x
|
||||
when 'above' then otherBox.bottom.y <= box.top.y
|
||||
when 'below' then otherBox.top.y >= box.bottom.y
|
||||
.sort (paneA, paneB) =>
|
||||
boxA = @boundingBoxForPane(paneA)
|
||||
boxB = @boundingBoxForPane(paneB)
|
||||
.sort (paneViewA, paneViewB) =>
|
||||
boxA = @boundingBoxForPaneView(paneViewA)
|
||||
boxB = @boundingBoxForPaneView(paneViewB)
|
||||
switch direction
|
||||
when 'left' then distance(box.left, boxA.right) - distance(box.left, boxB.right)
|
||||
when 'right' then distance(box.right, boxA.left) - distance(box.right, boxB.left)
|
||||
when 'above' then distance(box.top, boxA.bottom) - distance(box.top, boxB.bottom)
|
||||
when 'below' then distance(box.bottom, boxA.top) - distance(box.bottom, boxB.top)
|
||||
|
||||
panes[0]
|
||||
paneViews[0]
|
||||
|
||||
boundingBoxForPane: (pane) ->
|
||||
boundingBox = pane[0].getBoundingClientRect()
|
||||
boundingBoxForPaneView: (paneView) ->
|
||||
boundingBox = paneView[0].getBoundingClientRect()
|
||||
|
||||
left: {x: boundingBox.left, y: boundingBox.top}
|
||||
right: {x: boundingBox.right, y: boundingBox.top}
|
||||
@@ -146,4 +151,5 @@ class PaneContainerView extends View
|
||||
|
||||
# Deprecated
|
||||
getPanes: ->
|
||||
deprecate("Use PaneContainerView::getPaneViews() instead")
|
||||
@getPaneViews()
|
||||
|
||||
@@ -39,6 +39,9 @@ class PaneContainer extends Model
|
||||
getPanes: ->
|
||||
@root?.getPanes() ? []
|
||||
|
||||
getActivePane: ->
|
||||
@activePane
|
||||
|
||||
paneForUri: (uri) ->
|
||||
find @getPanes(), (pane) -> pane.itemForUri(uri)?
|
||||
|
||||
|
||||
+19
-6
@@ -1,5 +1,6 @@
|
||||
{$, View} = require './space-pen-extensions'
|
||||
Delegator = require 'delegato'
|
||||
{deprecate} = require 'grim'
|
||||
PropertyAccessors = require 'property-accessors'
|
||||
|
||||
Pane = require './pane'
|
||||
@@ -81,22 +82,34 @@ class PaneView extends View
|
||||
@command 'pane:close-other-items', => @destroyInactiveItems()
|
||||
|
||||
# Deprecated: Use ::destroyItem
|
||||
removeItem: (item) -> @destroyItem(item)
|
||||
removeItem: (item) ->
|
||||
deprecate("Use PaneView::destroyItem instead")
|
||||
@destroyItem(item)
|
||||
|
||||
# Deprecated: Use ::activateItem
|
||||
showItem: (item) -> @activateItem(item)
|
||||
showItem: (item) ->
|
||||
deprecate("Use PaneView::activateItem instead")
|
||||
@activateItem(item)
|
||||
|
||||
# Deprecated: Use ::activateItemForUri
|
||||
showItemForUri: (item) -> @activateItemForUri(item)
|
||||
showItemForUri: (item) ->
|
||||
deprecate("Use PaneView::activateItemForUri instead")
|
||||
@activateItemForUri(item)
|
||||
|
||||
# Deprecated: Use ::activateItemAtIndex
|
||||
showItemAtIndex: (index) -> @activateItemAtIndex(index)
|
||||
showItemAtIndex: (index) ->
|
||||
deprecate("Use PaneView::activateItemAtIndex instead")
|
||||
@activateItemAtIndex(index)
|
||||
|
||||
# Deprecated: Use ::activateNextItem
|
||||
showNextItem: -> @activateNextItem()
|
||||
showNextItem: ->
|
||||
deprecate("Use PaneView::destroyItem instead")
|
||||
@activateNextItem()
|
||||
|
||||
# Deprecated: Use ::activatePreviousItem
|
||||
showPreviousItem: -> @activatePreviousItem()
|
||||
showPreviousItem: ->
|
||||
deprecate("Use PaneView::activatePreviousItem instead")
|
||||
@activatePreviousItem()
|
||||
|
||||
afterAttach: (onDom) ->
|
||||
@focus() if @model.focused and onDom
|
||||
|
||||
+13
-20
@@ -4,6 +4,7 @@ url = require 'url'
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
Q = require 'q'
|
||||
{deprecate} = require 'grim'
|
||||
{Model} = require 'theorist'
|
||||
{Emitter, Subscriber} = require 'emissary'
|
||||
Serializable = require 'serializable'
|
||||
@@ -30,13 +31,11 @@ class Project extends Model
|
||||
|
||||
constructor: ({path, @buffers}={}) ->
|
||||
@buffers ?= []
|
||||
@openers = []
|
||||
|
||||
for buffer in @buffers
|
||||
do (buffer) =>
|
||||
buffer.once 'destroyed', => @removeBuffer(buffer)
|
||||
|
||||
@editors = []
|
||||
@setPath(path)
|
||||
|
||||
serializeParams: ->
|
||||
@@ -48,7 +47,6 @@ class Project extends Model
|
||||
params
|
||||
|
||||
destroyed: ->
|
||||
editor.destroy() for editor in @getEditors()
|
||||
buffer.destroy() for buffer in @getBuffers()
|
||||
@destroyRepo()
|
||||
|
||||
@@ -127,18 +125,10 @@ class Project extends Model
|
||||
|
||||
# Deprecated
|
||||
openSync: (filePath, options={}) ->
|
||||
deprecate("Use Project::open instead")
|
||||
filePath = @resolve(filePath)
|
||||
@buildEditorForBuffer(@bufferForPathSync(filePath), options)
|
||||
|
||||
# Add the given {Editor}.
|
||||
addEditor: (editor) ->
|
||||
@editors.push editor
|
||||
@emit 'editor-created', editor
|
||||
|
||||
# Return and removes the given {Editor}.
|
||||
removeEditor: (editor) ->
|
||||
_.remove(@editors, editor)
|
||||
|
||||
# Retrieves all the {TextBuffer}s in the project; that is, the
|
||||
# buffers for all open files.
|
||||
#
|
||||
@@ -151,7 +141,7 @@ class Project extends Model
|
||||
@findBufferForPath(@resolve(filePath))?.isModified()
|
||||
|
||||
findBufferForPath: (filePath) ->
|
||||
_.find @buffers, (buffer) -> buffer.getPath() == filePath
|
||||
_.find @buffers, (buffer) -> buffer.getPath() == filePath
|
||||
|
||||
# Only to be used in specs
|
||||
bufferForPathSync: (filePath) ->
|
||||
@@ -177,6 +167,7 @@ class Project extends Model
|
||||
|
||||
# DEPRECATED
|
||||
buildBufferSync: (absoluteFilePath) ->
|
||||
deprecate("Use Project::buildBuffer instead")
|
||||
buffer = new TextBuffer({filePath: absoluteFilePath})
|
||||
@addBuffer(buffer)
|
||||
buffer.loadSync()
|
||||
@@ -301,8 +292,7 @@ class Project extends Model
|
||||
deferred.promise
|
||||
|
||||
buildEditorForBuffer: (buffer, editorOptions) ->
|
||||
editor = new Editor(_.extend({buffer}, editorOptions))
|
||||
@addEditor(editor)
|
||||
editor = new Editor(_.extend({buffer, registerEditor: true}, editorOptions))
|
||||
editor
|
||||
|
||||
eachBuffer: (args...) ->
|
||||
@@ -317,17 +307,20 @@ class Project extends Model
|
||||
|
||||
# Deprecated: delegate
|
||||
registerOpener: (opener) ->
|
||||
@openers.push(opener)
|
||||
deprecate("Use Workspace::registerOpener instead")
|
||||
atom.workspace.registerOpener(opener)
|
||||
|
||||
# Deprecated: delegate
|
||||
unregisterOpener: (opener) ->
|
||||
_.remove(@openers, opener)
|
||||
deprecate("Use Workspace::unregisterOpener instead")
|
||||
atom.workspace.unregisterOpener(opener)
|
||||
|
||||
# Deprecated: delegate
|
||||
eachEditor: (callback) ->
|
||||
callback(editor) for editor in @getEditors()
|
||||
@on 'editor-created', (editor) -> callback(editor)
|
||||
deprecate("Use Workspace::eachEditor instead")
|
||||
atom.workspace.eachEditor(callback)
|
||||
|
||||
# Deprecated: delegate
|
||||
getEditors: ->
|
||||
new Array(@editors...)
|
||||
deprecate("Use Workspace::getEditors instead")
|
||||
atom.workspace.getEditors()
|
||||
|
||||
@@ -74,7 +74,7 @@ class Selection
|
||||
setBufferRange: (bufferRange, options={}) ->
|
||||
bufferRange = Range.fromObject(bufferRange)
|
||||
@needsAutoscroll = options.autoscroll
|
||||
options.isReversed ?= @isReversed()
|
||||
options.reversed ?= @isReversed()
|
||||
@editor.destroyFoldsIntersectingBufferRange(bufferRange) unless options.preserveFolds
|
||||
@modifySelection =>
|
||||
@cursor.needsAutoscroll = false if options.autoscroll?
|
||||
@@ -99,6 +99,7 @@ class Selection
|
||||
clear: ->
|
||||
@marker.setAttributes(goalBufferRange: null)
|
||||
@marker.clearTail() unless @retainSelection
|
||||
@finalize()
|
||||
|
||||
# Public: Modifies the selection to encompass the current word.
|
||||
#
|
||||
@@ -292,7 +293,7 @@ class Selection
|
||||
if options.indentBasis? and not options.autoIndent
|
||||
text = @normalizeIndents(text, options.indentBasis)
|
||||
|
||||
newBufferRange = @editor.buffer.change(oldBufferRange, text, pick(options, 'undo'))
|
||||
newBufferRange = @editor.buffer.setTextInRange(oldBufferRange, text, pick(options, 'undo'))
|
||||
if options.select
|
||||
@setBufferRange(newBufferRange, isReversed: wasReversed)
|
||||
else
|
||||
|
||||
@@ -26,7 +26,7 @@ humanizeKeystrokes = (keystroke) ->
|
||||
|
||||
getKeystroke = (bindings) ->
|
||||
if bindings?.length
|
||||
"<span class=\"keystroke\">#{humanizeKeystrokes(bindings[0].keystroke)}</span>"
|
||||
"<span class=\"keystroke\">#{humanizeKeystrokes(bindings[0].keystrokes)}</span>"
|
||||
else
|
||||
''
|
||||
|
||||
@@ -40,9 +40,9 @@ jQuery.fn.setTooltip = (tooltipOptions, {command, commandElement}={}) ->
|
||||
tooltipOptions = {title: tooltipOptions} if _.isString(tooltipOptions)
|
||||
|
||||
if commandElement
|
||||
bindings = atom.keymaps.keyBindingsForCommandMatchingElement(command, commandElement)
|
||||
bindings = atom.keymaps.findKeyBindings(command: command, target: commandElement[0])
|
||||
else if command
|
||||
bindings = atom.keymaps.keyBindingsForCommand(command)
|
||||
bindings = atom.keymaps.findKeyBindings(command: command)
|
||||
|
||||
tooltipOptions.title = "#{tooltipOptions.title} #{getKeystroke(bindings)}"
|
||||
|
||||
|
||||
+5
-2
@@ -1,4 +1,5 @@
|
||||
_ = require 'underscore-plus'
|
||||
{deprecate} = require 'grim'
|
||||
{specificity} = require 'clear-cut'
|
||||
{Subscriber} = require 'emissary'
|
||||
{GrammarRegistry, ScopeSelector} = require 'first-mate'
|
||||
@@ -26,7 +27,7 @@ class Syntax extends GrammarRegistry
|
||||
syntax
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
super(maxTokensPerLine: 100)
|
||||
@propertyStore = new ScopedPropertyStore
|
||||
|
||||
serialize: ->
|
||||
@@ -35,7 +36,9 @@ class Syntax extends GrammarRegistry
|
||||
createToken: (value, scopes) -> new Token({value, scopes})
|
||||
|
||||
# Deprecated: Used by settings-view to display snippets for packages
|
||||
@::accessor 'scopedProperties', -> @propertyStore.propertySets
|
||||
@::accessor 'scopedProperties', ->
|
||||
deprecate("Use Syntax::getProperty instead")
|
||||
@propertyStore.propertySets
|
||||
|
||||
addProperties: (args...) ->
|
||||
name = args.shift() if args.length > 2
|
||||
|
||||
@@ -48,6 +48,8 @@ class ThemeManager
|
||||
getEnabledThemeNames: ->
|
||||
themeNames = atom.config.get('core.themes') ? []
|
||||
themeNames = [themeNames] unless _.isArray(themeNames)
|
||||
themeNames = themeNames.filter (themeName) ->
|
||||
themeName and typeof themeName is 'string'
|
||||
|
||||
# Reverse so the first (top) theme is loaded after the others. We want
|
||||
# the first/top theme to override later themes in the stack.
|
||||
|
||||
@@ -37,25 +37,28 @@ class WindowEventHandler
|
||||
@reloadRequested = false
|
||||
confirmed
|
||||
|
||||
@subscribe $(window), 'blur unload', ->
|
||||
atom.storeDefaultWindowDimensions()
|
||||
|
||||
@subscribe $(window), 'unload', ->
|
||||
atom.storeWindowDimensions()
|
||||
|
||||
@subscribeToCommand $(window), 'window:toggle-full-screen', => atom.toggleFullScreen()
|
||||
@subscribeToCommand $(window), 'window:toggle-full-screen', -> atom.toggleFullScreen()
|
||||
|
||||
@subscribeToCommand $(window), 'window:close', => atom.close()
|
||||
@subscribeToCommand $(window), 'window:close', -> atom.close()
|
||||
|
||||
@subscribeToCommand $(window), 'window:reload', =>
|
||||
@reloadRequested = true
|
||||
atom.reload()
|
||||
|
||||
@subscribeToCommand $(window), 'window:toggle-dev-tools', => atom.toggleDevTools()
|
||||
@subscribeToCommand $(window), 'window:toggle-dev-tools', -> atom.toggleDevTools()
|
||||
|
||||
@subscribeToCommand $(document), 'core:focus-next', @focusNext
|
||||
|
||||
@subscribeToCommand $(document), 'core:focus-previous', @focusPrevious
|
||||
|
||||
@subscribe $(document), 'keydown', (event) ->
|
||||
atom.keymaps.handleKeyEvent(event)
|
||||
atom.keymaps.handleKeyboardEvent(event.originalEvent)
|
||||
|
||||
@subscribe $(document), 'drop', (e) ->
|
||||
e.preventDefault()
|
||||
@@ -92,7 +95,7 @@ class WindowEventHandler
|
||||
bindCommandToAction('core:redo', 'redo:')
|
||||
bindCommandToAction('core:select-all', 'selectAll:')
|
||||
|
||||
openLink: (event) =>
|
||||
openLink: (event) ->
|
||||
location = $(event.target).attr('href')
|
||||
if location and location[0] isnt '#' and /^https?:\/\//.test(location)
|
||||
shell.openExternal(location)
|
||||
|
||||
@@ -3,6 +3,7 @@ path = require 'path'
|
||||
Q = require 'q'
|
||||
_ = require 'underscore-plus'
|
||||
Delegator = require 'delegato'
|
||||
{deprecate, logDeprecationWarnings} = require 'grim'
|
||||
scrollbarStyle = require 'scrollbar-style'
|
||||
{$, $$, View} = require './space-pen-extensions'
|
||||
fs = require 'fs-plus'
|
||||
@@ -115,6 +116,8 @@ class WorkspaceView extends View
|
||||
@command 'application:new-window', -> ipc.sendChannel('command', 'application:new-window')
|
||||
@command 'application:new-file', -> ipc.sendChannel('command', 'application:new-file')
|
||||
@command 'application:open', -> ipc.sendChannel('command', 'application:open')
|
||||
@command 'application:open-file', -> ipc.sendChannel('command', 'application:open-file')
|
||||
@command 'application:open-folder', -> ipc.sendChannel('command', 'application:open-folder')
|
||||
@command 'application:open-dev', -> ipc.sendChannel('command', 'application:open-dev')
|
||||
@command 'application:minimize', -> ipc.sendChannel('command', 'application:minimize')
|
||||
@command 'application:zoom', -> ipc.sendChannel('command', 'application:zoom')
|
||||
@@ -140,15 +143,15 @@ class WorkspaceView extends View
|
||||
@command 'window:focus-pane-on-left', => @focusPaneViewOnLeft()
|
||||
@command 'window:focus-pane-on-right', => @focusPaneViewOnRight()
|
||||
@command 'window:save-all', => @saveAll()
|
||||
@command 'window:toggle-invisibles', =>
|
||||
atom.config.toggle("editor.showInvisibles")
|
||||
@command 'window:toggle-invisibles', -> atom.config.toggle("editor.showInvisibles")
|
||||
@command 'window:log-deprecation-warnings', -> logDeprecationWarnings()
|
||||
|
||||
@command 'window:toggle-auto-indent', =>
|
||||
atom.config.toggle("editor.autoIndent")
|
||||
|
||||
@command 'pane:reopen-closed-item', => @reopenItemSync()
|
||||
|
||||
@command 'core:close', => if @getActivePaneItem()? then @destroyActivePaneItem() else @destroyActivePane()
|
||||
@command 'core:close', => if @getModel().getActivePaneItem()? then @destroyActivePaneItem() else @destroyActivePane()
|
||||
@command 'core:save', => @saveActivePaneItem()
|
||||
@command 'core:save-as', => @saveActivePaneItemAs()
|
||||
|
||||
@@ -179,8 +182,8 @@ class WorkspaceView extends View
|
||||
detailedMessage: "The shell commands `atom` and `apm` are installed."
|
||||
|
||||
handleFocus: ->
|
||||
if @getActivePane()
|
||||
@getActivePane().focus()
|
||||
if @getActivePaneView()
|
||||
@getActivePaneView().focus()
|
||||
false
|
||||
else
|
||||
@updateTitle()
|
||||
@@ -202,7 +205,7 @@ class WorkspaceView extends View
|
||||
# Updates the application's title, based on whichever file is open.
|
||||
updateTitle: ->
|
||||
if projectPath = atom.project.getPath()
|
||||
if item = @getActivePaneItem()
|
||||
if item = @getModel().getActivePaneItem()
|
||||
@setTitle("#{item.getTitle?() ? 'untitled'} - #{projectPath}")
|
||||
else
|
||||
@setTitle(projectPath)
|
||||
@@ -269,7 +272,7 @@ class WorkspaceView extends View
|
||||
#
|
||||
# Returns a {PaneView}.
|
||||
getActivePaneView: ->
|
||||
@panes.getActivePane()
|
||||
@panes.getActivePaneView()
|
||||
|
||||
# Public: Get the view associated with the active pane item.
|
||||
#
|
||||
@@ -313,7 +316,7 @@ class WorkspaceView extends View
|
||||
#
|
||||
# Returns an Array of all open {PaneView}s.
|
||||
getPaneViews: ->
|
||||
@panes.getPanes()
|
||||
@panes.getPaneViews()
|
||||
|
||||
# Public: Register a function to be called for every current and future
|
||||
# editor view in the workspace.
|
||||
@@ -334,16 +337,20 @@ class WorkspaceView extends View
|
||||
|
||||
# Deprecated
|
||||
eachPane: (callback) ->
|
||||
deprecate("Use WorkspaceView::eachPaneView instead")
|
||||
@eachPaneView(callback)
|
||||
|
||||
# Deprecated
|
||||
getPanes: ->
|
||||
deprecate("Use WorkspaceView::getPaneViews instead")
|
||||
@getPaneViews()
|
||||
|
||||
# Deprecated
|
||||
getActivePane: ->
|
||||
deprecate("Use WorkspaceView::getActivePaneView instead")
|
||||
@getActivePaneView()
|
||||
|
||||
# Deprecated: Call {Workspace::getActivePaneItem} instead.
|
||||
getActivePaneItem: ->
|
||||
deprecate("Use Workspace::getActivePaneItem instead")
|
||||
@model.activePaneItem
|
||||
|
||||
+28
-7
@@ -1,9 +1,11 @@
|
||||
{remove, last} = require 'underscore-plus'
|
||||
{deprecate} = require 'grim'
|
||||
_ = require 'underscore-plus'
|
||||
{join} = require 'path'
|
||||
{Model} = require 'theorist'
|
||||
Q = require 'q'
|
||||
Serializable = require 'serializable'
|
||||
Delegator = require 'delegato'
|
||||
Editor = require './editor'
|
||||
PaneContainer = require './pane-container'
|
||||
Pane = require './pane'
|
||||
|
||||
@@ -27,6 +29,9 @@ class Workspace extends Model
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
@openers = []
|
||||
|
||||
@subscribe @paneContainer, 'item-destroyed', @onPaneItemDestroyed
|
||||
@registerOpener (filePath) =>
|
||||
switch filePath
|
||||
@@ -49,6 +54,9 @@ class Workspace extends Model
|
||||
paneContainer: @paneContainer.serialize()
|
||||
fullScreen: atom.isFullScreen()
|
||||
|
||||
editorAdded: (editor) ->
|
||||
@emit 'editor-created', editor
|
||||
|
||||
# Public: Register a function to be called for every current and future
|
||||
# {Editor} in the workspace.
|
||||
#
|
||||
@@ -57,13 +65,18 @@ class Workspace extends Model
|
||||
# Returns a subscription object with an `.off` method that you can call to
|
||||
# unregister the callback.
|
||||
eachEditor: (callback) ->
|
||||
atom.project.eachEditor(callback)
|
||||
callback(editor) for editor in @getEditors()
|
||||
@subscribe this, 'editor-created', (editor) -> callback(editor)
|
||||
|
||||
# Public: Get all current editors in the workspace.
|
||||
#
|
||||
# Returns an {Array} of {Editor}s.
|
||||
getEditors: ->
|
||||
atom.project.getEditors()
|
||||
editors = []
|
||||
for pane in @paneContainer.getPanes()
|
||||
editors.push(item) for item in pane.getItems() when item instanceof Editor
|
||||
|
||||
editors
|
||||
|
||||
# Public: Open a given a URI in Atom asynchronously.
|
||||
#
|
||||
@@ -114,6 +127,8 @@ class Workspace extends Model
|
||||
# :activatePane - A {Boolean} indicating whether to call {Pane::activate} on
|
||||
# the containing pane. Defaults to `true`.
|
||||
openSync: (uri='', options={}) ->
|
||||
deprecate("Don't use the `changeFocus` option") if options.changeFocus?
|
||||
|
||||
{initialLine} = options
|
||||
# TODO: Remove deprecated changeFocus option
|
||||
activatePane = options.activatePane ? options.changeFocus ? true
|
||||
@@ -169,14 +184,14 @@ class Workspace extends Model
|
||||
#
|
||||
# opener - A {Function} to be called when a path is being opened.
|
||||
registerOpener: (opener) ->
|
||||
atom.project.registerOpener(opener)
|
||||
@openers.push(opener)
|
||||
|
||||
# Public: Unregister an opener registered with {::registerOpener}.
|
||||
unregisterOpener: (opener) ->
|
||||
atom.project.unregisterOpener(opener)
|
||||
_.remove(@openers, opener)
|
||||
|
||||
getOpeners: ->
|
||||
atom.project.openers
|
||||
@openers
|
||||
|
||||
# Public: Get the active {Pane}.
|
||||
#
|
||||
@@ -208,6 +223,12 @@ class Workspace extends Model
|
||||
paneForUri: (uri) ->
|
||||
@paneContainer.paneForUri(uri)
|
||||
|
||||
# Public: Get the active {Pane}'s active item.
|
||||
#
|
||||
# Returns an pane item {Object}.
|
||||
getActivePaneItem: ->
|
||||
@paneContainer.getActivePane().getActiveItem()
|
||||
|
||||
# Public: Save the active pane item.
|
||||
#
|
||||
# If the active pane item currently has a URI according to the item's
|
||||
@@ -259,7 +280,7 @@ class Workspace extends Model
|
||||
# Removes the item's uri from the list of potential items to reopen.
|
||||
itemOpened: (item) ->
|
||||
if uri = item.getUri?()
|
||||
remove(@destroyedItemUris, uri)
|
||||
_.remove(@destroyedItemUris, uri)
|
||||
|
||||
# Adds the destroyed item's uri to the list of items to reopen.
|
||||
onPaneItemDestroyed: (item) =>
|
||||
|
||||
externo
+1
-1
Submodule vendor/apm updated: 8c4957c489...d349e45263
Referência em uma Nova Issue
Bloquear um usuário