diff --git a/atom.sh b/atom.sh index d844a946a..cd1137051 100755 --- a/atom.sh +++ b/atom.sh @@ -1,15 +1,13 @@ -#!/bin/sh -ATOM_PATH=${ATOM_PATH:-/Applications} # Set ATOM_PATH unless it is already set -ATOM_APP_NAME=Atom.app +#!/bin/bash -# If ATOM_PATH isn't a executable file, use spotlight to search for Atom -if [ ! -x "$ATOM_PATH/$ATOM_APP_NAME" ]; then - ATOM_PATH=$(mdfind "kMDItemCFBundleIdentifier == 'com.github.atom'" | head -1 | xargs dirname) -fi - -# Exit if Atom can't be found -if [ -z "$ATOM_PATH" ]; then - echo "Cannot locate Atom.app, it is usually located in /Applications. Set the ATOM_PATH environment variable to the directory containing Atom.app." +if [ "`uname`" == 'Darwin' ]; then + OS='Mac' +elif [ "`expr substr $(uname -s) 1 5`" == 'Linux' ]; then + OS='Linux' +elif [ "`expr substr $(uname -s) 1 10`" == 'MINGW32_NT' ]; then + OS='Cygwin' +else + echo "Your platform (`uname -a`) is not supported." exit 1 fi @@ -46,11 +44,37 @@ if [ $REDIRECT_STDERR ]; then exec 2> /dev/null fi -if [ $EXPECT_OUTPUT ]; then - "$ATOM_PATH/$ATOM_APP_NAME/Contents/MacOS/Atom" --executed-from="$(pwd)" --pid=$$ "$@" - exit $? -else - open -a "$ATOM_PATH/$ATOM_APP_NAME" -n --args --executed-from="$(pwd)" --pid=$$ "$@" +if [ $OS == 'Mac' ]; then + ATOM_PATH=${ATOM_PATH:-/Applications} # Set ATOM_PATH unless it is already set + ATOM_APP_NAME=Atom.app + + # If ATOM_PATH isn't a executable file, use spotlight to search for Atom + if [ ! -x "$ATOM_PATH/$ATOM_APP_NAME" ]; then + ATOM_PATH=$(mdfind "kMDItemCFBundleIdentifier == 'com.github.atom'" | head -1 | xargs dirname) + fi + + # Exit if Atom can't be found + if [ -z "$ATOM_PATH" ]; then + echo "Cannot locate Atom.app, it is usually located in /Applications. Set the ATOM_PATH environment variable to the directory containing Atom.app." + exit 1 + fi + + if [ $EXPECT_OUTPUT ]; then + "$ATOM_PATH/$ATOM_APP_NAME/Contents/MacOS/Atom" --executed-from="$(pwd)" --pid=$$ "$@" + exit $? + else + open -a "$ATOM_PATH/$ATOM_APP_NAME" -n --args --executed-from="$(pwd)" --pid=$$ "$@" + fi +elif [ $OS == 'Linux' ]; then + ATOM_PATH='/opt/Atom/atom' + [ -x "$ATOM_PATH" ] || ATOM_PATH='/tmp/atom-build/Atom/atom' + + if [ $EXPECT_OUTPUT ]; then + "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" + exit $? + else + nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > /dev/null & + fi fi # Exits this process when Atom is used as $EDITOR diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index a1e54fe1e..118824f1f 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -46,7 +46,7 @@ module.exports = (grunt) -> contentsDir = shellAppDir appDir = path.join(shellAppDir, 'resources', 'app') atomShellDownloadDir = path.join(os.tmpdir(), 'atom-cached-atom-shells') - else + else if process.platform is 'darwin' appName = 'Atom.app' tmpDir = '/tmp' installRoot = '/Applications' @@ -56,6 +56,16 @@ module.exports = (grunt) -> contentsDir = path.join(shellAppDir, 'Contents') appDir = path.join(contentsDir, 'Resources', 'app') atomShellDownloadDir = '/tmp/atom-cached-atom-shells' + else + appName = 'Atom' + tmpDir = '/tmp' + installRoot = '/opt' + buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'atom-build') + symbolsDir = path.join(buildDir, 'Atom.breakpad.syms') + shellAppDir = path.join(buildDir, appName) + contentsDir = shellAppDir + appDir = path.join(shellAppDir, 'resources', 'app') + atomShellDownloadDir = '/tmp/atom-cached-atom-shells' installDir = path.join(installRoot, appName) @@ -227,4 +237,7 @@ module.exports = (grunt) -> grunt.registerTask('test', ['shell:kill-atom', 'run-specs']) grunt.registerTask('ci', ['output-disk-space', 'download-atom-shell', 'build', 'dump-symbols', 'set-version', 'check-licenses', 'lint', 'test', 'codesign', 'publish-build']) grunt.registerTask('docs', ['markdown:guides', 'build-docs']) - grunt.registerTask('default', ['download-atom-shell', 'build', 'set-version', 'install']) + + defaultTasks = ['download-atom-shell', 'build', 'set-version'] + defaultTasks.push 'install' unless process.platform is 'linux' + grunt.registerTask('default', defaultTasks) diff --git a/build/package.json b/build/package.json index db1e1e62c..37102f6e3 100644 --- a/build/package.json +++ b/build/package.json @@ -18,7 +18,7 @@ "grunt-contrib-coffee": "~0.9.0", "grunt-contrib-less": "~0.8.0", "grunt-cson": "0.8.0", - "grunt-download-atom-shell": "git+https://atom-bot:467bac80a0017b96fb5be5cfc686f5e0cc607b10@github.com/atom/grunt-download-atom-shell#v0.6.0", + "grunt-download-atom-shell": "git+https://atom-bot:467bac80a0017b96fb5be5cfc686f5e0cc607b10@github.com/atom/grunt-download-atom-shell#v0.6.1", "grunt-lesslint": "0.13.0", "grunt-markdown": "~0.4.0", "grunt-peg": "~1.1.0", diff --git a/build/tasks/build-task.coffee b/build/tasks/build-task.coffee index 5197f4cf4..ef6c6c270 100644 --- a/build/tasks/build-task.coffee +++ b/build/tasks/build-task.coffee @@ -14,7 +14,7 @@ module.exports = (grunt) -> if process.platform is 'darwin' cp 'atom-shell/Atom.app', shellAppDir - else if process.platform is 'win32' + else cp 'atom-shell', shellAppDir mkdir appDir diff --git a/build/tasks/set-version-task.coffee b/build/tasks/set-version-task.coffee index bdf6e0c4d..a5fb685b8 100644 --- a/build/tasks/set-version-task.coffee +++ b/build/tasks/set-version-task.coffee @@ -48,3 +48,5 @@ module.exports = (grunt) -> rcedit = require('rcedit') rcedit(shellExePath, {'version-string': strings}, done) + else + done() diff --git a/keymaps/linux.cson b/keymaps/linux.cson new file mode 100644 index 000000000..b9a3364da --- /dev/null +++ b/keymaps/linux.cson @@ -0,0 +1,107 @@ +'body': + # Atom Specific + 'enter': 'core:confirm' + 'escape': 'core:cancel' + 'up': 'core:move-up' + 'down': 'core:move-down' + 'left': 'core:move-left' + 'right': 'core:move-right' + 'ctrl-alt-r': 'window:reload' + 'ctrl-alt-i': 'window:toggle-dev-tools' + 'ctrl-alt-p': 'window:run-package-specs' + 'ctrl-alt-s': 'application:run-all-specs' + + # Sublime Parity + 'ctrl-N': 'application:new-window' + 'ctrl-W': 'window:close' + 'ctrl-o': 'application:open' + 'ctrl-T': 'pane:reopen-closed-item' + 'ctrl-n': 'application:new-file' + 'ctrl-s': 'core:save' + 'ctrl-S': 'core:save-as' + 'ctrl-w': 'core:close' + 'ctrl-z': 'core:undo' + 'ctrl-y': 'core:redo' + 'ctrl-x': 'core:cut' + 'ctrl-c': 'core:copy' + 'ctrl-v': 'core:paste' + 'shift-up': 'core:select-up' + 'shift-down': 'core:select-down' + 'shift-left': 'core:select-left' + 'shift-right': 'core:select-right' + 'delete': 'core:delete' + 'pageup': 'core:page-up' + 'pagedown': 'core:page-down' + 'backspace': 'core:backspace' + 'ctrl-tab': 'pane:show-next-item' + 'ctrl-shift-tab': 'pane:show-previous-item' + 'ctrl-shift-up': 'core:move-up' + 'ctrl-shift-down': 'core:move-down' + 'ctrl-=': 'window:increase-font-size' + 'ctrl-+': 'window:increase-font-size' + 'ctrl--': 'window:decrease-font-size' + 'ctrl-_': 'window:decrease-font-size' + 'ctrl-0': 'window:reset-font-size' + + 'ctrl-k up': 'pane:split-up' # Atom Specific + 'ctrl-k down': 'pane:split-down' # Atom Specific + 'ctrl-k left': 'pane:split-left' # Atom Specific + 'ctrl-k right': 'pane:split-right' # Atom Specific + 'ctrl-k ctrl-w': 'pane:close' # Atom Specific + 'ctrl-k alt-ctrl-w': 'pane:close-other-items' # Atom Specific + 'ctrl-k ctrl-p': 'window:focus-previous-pane' + 'ctrl-k ctrl-n': 'window:focus-next-pane' + 'ctrl-k ctrl-up': 'window:focus-pane-above' + 'ctrl-k ctrl-down': 'window:focus-pane-below' + 'ctrl-k ctrl-left': 'window:focus-pane-on-left' + 'ctrl-k ctrl-right': 'window:focus-pane-on-right' + +'.workspace .editor': + # Windows specific + 'ctrl-delete': 'editor:backspace-to-beginning-of-word' + + # Sublime Parity + 'ctrl-a': 'core:select-all' + 'ctrl-alt-p': 'editor:log-cursor-scope' + 'ctrl-k ctrl-u': 'editor:upper-case' + 'ctrl-k ctrl-l': 'editor:lower-case' + +'.workspace .editor:not(.mini)': + # Atom specific + 'alt-ctrl-z': 'editor:checkout-head-revision' + 'ctrl-<': 'editor:scroll-to-cursor' + 'alt-ctrl-f': 'editor:fold-selection' + + # Sublime Parity + 'ctrl-enter': 'editor:newline-below' + 'ctrl-shift-enter': 'editor:newline-above' + 'ctrl-]': 'editor:indent-selected-rows' + 'ctrl-[': 'editor:outdent-selected-rows' + 'ctrl-up': 'editor:move-line-up' + 'ctrl-down': 'editor:move-line-down' + 'ctrl-/': 'editor:toggle-line-comments' + 'ctrl-j': 'editor:join-lines' + 'ctrl-D': 'editor:duplicate-lines' + + 'ctrl-alt-[': 'editor:fold-current-row' + 'ctrl-alt-]': 'editor:unfold-current-row' + 'ctrl-alt-{': 'editor:fold-all' # Atom Specific + 'ctrl-alt-}': 'editor:unfold-all' # Atom Specific + 'ctrl-k ctrl-0': 'editor:unfold-all' + 'ctrl-k ctrl-1': 'editor:fold-at-indent-level-1' + 'ctrl-k ctrl-2': 'editor:fold-at-indent-level-2' + 'ctrl-k ctrl-3': 'editor:fold-at-indent-level-3' + 'ctrl-k ctrl-4': 'editor:fold-at-indent-level-4' + 'ctrl-k ctrl-5': 'editor:fold-at-indent-level-5' + 'ctrl-k ctrl-6': 'editor:fold-at-indent-level-6' + 'ctrl-k ctrl-7': 'editor:fold-at-indent-level-7' + 'ctrl-k ctrl-8': 'editor:fold-at-indent-level-8' + 'ctrl-k ctrl-9': 'editor:fold-at-indent-level-9' + +# allow standard input fields to work correctly +'body .native-key-bindings': + 'ctrl-z': 'native!' + 'ctrl-Z': 'native!' + 'ctrl-x': 'native!' + 'ctrl-c': 'native!' + 'ctrl-v': 'native!' diff --git a/menus/linux.cson b/menus/linux.cson new file mode 100644 index 000000000..f69ab563c --- /dev/null +++ b/menus/linux.cson @@ -0,0 +1,156 @@ +'menu': [ + { + label: '&File' + submenu: [ + { label: 'New &Window', command: 'application:new-window' } + { label: '&New File', command: 'application:new-file' } + { label: '&Open...', command: 'application:open' } + { label: 'Reopen Last &Item', command: 'pane:reopen-closed-item' } + { type: 'separator' } + { label: '&Preferences...', command: 'application:show-settings' } + { type: 'separator' } + { label: '&Save', command: 'core:save' } + { label: 'Save &As...', command: 'core:save-as' } + { label: 'Save A&ll', command: 'window:save-all' } + { type: 'separator' } + { label: '&Close Buffer', command: 'core:close' } + { label: 'Close All &Buffers', command: 'pane:close' } + { label: 'Clos&e Window', command: 'window:close' } + { type: 'separator' } + { label: 'E&xit', command: 'application:quit' } + ] + } + + { + label: '&Edit' + submenu: [ + { label: '&Undo', command: 'core:undo' } + { label: '&Redo', command: 'core:redo' } + { type: 'separator' } + { label: '&Cut', command: 'core:cut' } + { label: 'C&opy', command: 'core:copy' } + { label: 'Copy Pat&h', command: 'editor:copy-path' } + { label: '&Paste', command: 'core:paste' } + { label: 'Select &All', command: 'core:select-all' } + { type: 'separator' } + { label: '&Toggle Comments', command: 'editor:toggle-line-comments' } + { + label: 'Lines', + submenu: [ + { label: '&Indent', command: 'editor:indent-selected-rows' } + { label: '&Outdent', command: 'editor:outdent-selected-rows' } + { label: '&Auto Indent', command: 'editor:auto-indent' } + { type: 'separator' } + { label: 'Move Line &Up', command: 'editor:move-line-up' } + { label: 'Move Line &Down', command: 'editor:move-line-down' } + { label: 'Du&plicate Lines', command: 'editor:duplicate-lines' } + { label: 'D&elete Line', command: 'editor:delete-line' } + { label: '&Join Lines', command: 'editor:join-lines' } + ] + } + { + label: 'Text', + submenu: [ + { label: '&Upper Case', command: 'editor:upper-case' } + { label: '&Lower Case', command: 'editor:lower-case' } + { type: 'separator' } + { label: 'Delete to End of &Word', command: 'editor:delete-to-end-of-word' } + { label: '&Delete Line', command: 'editor:delete-line' } + { type: 'separator' } + { label: '&Transpose', command: 'editor:transpose' } + ] + } + { + label: 'Folding', + submenu: [ + { label: '&Fold', command: 'editor:fold-current-row' } + { label: '&Unfold', command: 'editor:unfold-current-row' } + { label: 'Unfold &All', command: 'editor:unfold-all' } + { type: 'separator' } + { label: 'Fol&d All', command: 'editor:fold-all' } + { label: 'Fold Level 1', command: 'editor:fold-at-indent-level-1' } + { label: 'Fold Level 2', command: 'editor:fold-at-indent-level-2' } + { label: 'Fold Level 3', command: 'editor:fold-at-indent-level-3' } + { label: 'Fold Level 4', command: 'editor:fold-at-indent-level-4' } + { label: 'Fold Level 5', command: 'editor:fold-at-indent-level-5' } + { label: 'Fold Level 6', command: 'editor:fold-at-indent-level-6' } + { label: 'Fold Level 7', command: 'editor:fold-at-indent-level-7' } + { label: 'Fold Level 8', command: 'editor:fold-at-indent-level-8' } + { label: 'Fold Level 9', command: 'editor:fold-at-indent-level-9' } + ] + } + ] + } + + { + label: '&View' + submenu: [ + { label: '&Reload', command: 'window:reload' } + { label: 'Toggle &Full Screen', command: 'window:toggle-full-screen' } + { + label: 'Developer' + submenu: [ + { label: 'Open In &Dev Mode...', command: 'application:open-dev' } + { label: 'Run &Atom Specs', command: 'application:run-all-specs' } + { label: 'Run Package &Specs', command: 'window:run-package-specs' } + { label: 'Toggle Developer &Tools', command: 'window:toggle-dev-tools' } + ] + } + { type: 'separator' } + { label: 'Toggle Soft &Wrap', command: 'editor:toggle-soft-wrap' } + ] + } + + { + label: '&Selection' + submenu: [ + { label: 'Add Selection &Above', command: 'editor:add-selection-above' } + { label: 'Add Selection &Below', command: 'editor:add-selection-below' } + { label: 'S&plit into Lines', command: 'editor:split-selections-into-lines'} + { type: 'separator' } + { label: 'Select to &Top', command: 'core:select-to-top' } + { label: 'Select to Botto&m', command: 'core:select-to-bottom' } + { type: 'separator' } + { label: 'Select &Line', command: 'editor:select-line' } + { label: 'Select &Word', command: 'editor:select-word' } + { label: 'Select to Beginning of W&ord', command: 'editor:select-to-beginning-of-word' } + { label: 'Select to Beginning of L&ine', command: 'editor:select-to-beginning-of-line' } + { label: 'Select to First &Character of Line', command: 'editor:select-to-first-character-of-line' } + { label: 'Select to End of Wor&d', command: 'editor:select-to-end-of-word' } + { label: 'Select to End of Lin&e', command: 'editor:select-to-end-of-line' } + ] + } + + { + label: 'F&ind' + submenu: [] + } + + { + label: '&Packages' + submenu: [] + } + + { + label: '&Window' + submenu: [ + { label: 'Mi&nimize', command: 'application:minimize' } + { label: 'Ma&ximize', command: 'application:zoom' } + { type: 'separator' } + { label: 'Bring &All to Front', command: 'application:bring-all-windows-to-front' } + ] + } + + { + label: '&Help' + submenu: [ + { label: '&About Atom...', command: 'application:about' } + { label: 'View &License', command: 'application:open-license' } + { label: "VERSION", enabled: false } + { label: "Install &update", command: 'application:install-update', visible: false } + { type: 'separator' } + { label: '&Documentation', command: 'application:open-documentation' } + { type: 'separator' } + ] + } +] diff --git a/package.json b/package.json index f24dab7c6..04a364ca6 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "All Rights Reserved", - "atomShellVersion": "0.10.7", + "atomShellVersion": "0.11.1", "dependencies": { "async": "0.2.6", "atom-keymap": "^0.9.0", @@ -29,7 +29,7 @@ "guid": "0.0.10", "jasmine-tagged": ">=1.1.1 <2.0", "mkdirp": "0.3.5", - "keytar": "0.15.1", + "keytar": "1.x", "less-cache": "0.12.0", "mixto": "1.x", "nslog": "0.5.0", diff --git a/spec/spec-bootstrap.coffee b/spec/spec-bootstrap.coffee index dd34ffdae..7b86a31cc 100644 --- a/spec/spec-bootstrap.coffee +++ b/spec/spec-bootstrap.coffee @@ -1,6 +1,8 @@ # Start the crash reporter before anything else. require('crash-reporter').start(productName: 'Atom', companyName: 'GitHub') +path = require 'path' + try require '../src/window' Atom = require '../src/atom' @@ -12,6 +14,12 @@ try {runSpecSuite} = require './jasmine-helper' + # Add 'src/exports' to module search path. + exportsPath = path.resolve(atom.getLoadSettings().resourcePath, 'exports') + require('module').globalPaths.push(exportsPath) + # Still set NODE_PATH since tasks may need it. + process.env.NODE_PATH = exportsPath + document.title = "Spec Suite" runSpecSuite './spec-suite', atom.getLoadSettings().logFile catch error diff --git a/spec/spec-suite.coffee b/spec/spec-suite.coffee index a82e0289f..568c2132d 100644 --- a/spec/spec-suite.coffee +++ b/spec/spec-suite.coffee @@ -26,6 +26,7 @@ setSpecDirectory = (specDirectory) -> runAllSpecs = -> {resourcePath} = atom.getLoadSettings() + # Only run core specs when resource path is the Atom repository if Git.exists(resourcePath) requireSpecs(path.join(resourcePath, 'spec')) diff --git a/src/atom.coffee b/src/atom.coffee index 5bf5b87d7..12ce6f2c3 100644 --- a/src/atom.coffee +++ b/src/atom.coffee @@ -148,6 +148,12 @@ class Atom extends Model {devMode, resourcePath} = @getLoadSettings() configDirPath = @getConfigDirPath() + # Add 'src/exports' to module search path. + exportsPath = path.resolve(resourcePath, 'exports') + require('module').globalPaths.push(exportsPath) + # Still set NODE_PATH since tasks may need it. + process.env.NODE_PATH = exportsPath + @config = new Config({configDirPath, resourcePath}) @keymap = new Keymap({configDirPath, resourcePath}) @packages = new PackageManager({devMode, configDirPath, resourcePath}) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 130c5c306..d209ffd41 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -196,7 +196,7 @@ class AtomApplication @openPathOnEvent('application:open-your-stylesheet', 'atom://.atom/stylesheet') app.on 'window-all-closed', -> - app.quit() if process.platform is 'win32' + app.quit() if process.platform in ['win32', 'linux'] app.on 'will-quit', => @killAllProcesses() diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 618ed06ef..33389403c 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -21,12 +21,7 @@ class AtomWindow {@resourcePath, pathToOpen, initialLine, @isSpec, @exitWhenDone} = settings global.atomApplication.addWindow(this) - @setupNodePath(@resourcePath) @browserWindow = new BrowserWindow show: false, title: 'Atom', icon: @constructor.iconPath - @browserWindow.restart = _.wrap _.bind(@browserWindow.restart, @browserWindow), (restart) => - @setupNodePath(@resourcePath) - restart() - @handleEvents() loadSettings = _.extend({}, settings) @@ -49,9 +44,6 @@ class AtomWindow @openPath(pathToOpen, initialLine) - setupNodePath: (resourcePath) -> - process.env['NODE_PATH'] = path.resolve(resourcePath, 'exports') - getUrl: (loadSettingsObj) -> # Ignore the windowState when passing loadSettings via URL, since it could # be quite large. diff --git a/vendor/apm b/vendor/apm index 537ac1ed9..093f361f5 160000 --- a/vendor/apm +++ b/vendor/apm @@ -1 +1 @@ -Subproject commit 537ac1ed906cd42aff61aa3b04786cb1f28430a8 +Subproject commit 093f361f5897e0d73230c82c1d973ecc96a6e744