Comparar commits
181 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 0adae86b4d | |||
| 92283cabfa | |||
| a4774ada84 | |||
| e6bcf7ec6e | |||
| 27ef1f8749 | |||
| 8ee1c2b591 | |||
| f6f659aec6 | |||
| 61372241f7 | |||
| d398d89de9 | |||
| af4a2340c4 | |||
| 2d9791d61a | |||
| f874ec7cb6 | |||
| 9e4baad701 | |||
| 59b711447c | |||
| 2bb4866e1a | |||
| 72ceaf772d | |||
| 2da9ee0cee | |||
| 9c070cd71d | |||
| 6f068f14fd | |||
| 67d8db8b9a | |||
| 03b9a25897 | |||
| 645fc1511a | |||
| ae1d3b1e80 | |||
| 627a839779 | |||
| 5151faea3d | |||
| eb1bed118f | |||
| e9f4820dd4 | |||
| 03d4fdb890 | |||
| 1cdec9386c | |||
| ba8f6bccec | |||
| 22c8746ed6 | |||
| 96503f74e4 | |||
| 7fb3396f65 | |||
| 66fa40b29e | |||
| b5aefc6f5e | |||
| cf590685b9 | |||
| a604bfcdf1 | |||
| c389bccfa0 | |||
| ce02dcf5a5 | |||
| d3d38c0312 | |||
| 95d097dd7b | |||
| 47f3b562b5 | |||
| 5eb12e671b | |||
| 023cb2ea55 | |||
| 98ea42d808 | |||
| 4e3a46ee71 | |||
| 9ebc5fa30e | |||
| 810ca750cd | |||
| 424652e27c | |||
| 831beceaac | |||
| 2daf026967 | |||
| dbd6a98bbe | |||
| a4ffdeb842 | |||
| 9b6194c5a4 | |||
| 8e4573677d | |||
| 61e9befbe7 | |||
| 0f50c40a93 | |||
| 907f8c34ac | |||
| c178d4c874 | |||
| 233fd44b01 | |||
| ab88edaa02 | |||
| 50c25d9e44 | |||
| 9be593d390 | |||
| 318c43931c | |||
| 244fc33f49 | |||
| f83f5263a9 | |||
| 3266dde2e3 | |||
| 3428ee335a | |||
| db6b4d7b81 | |||
| 1c195987c1 | |||
| 4913714a61 | |||
| 8e2856465c | |||
| 868c7a3908 | |||
| afaf91ebde | |||
| c92fe1452b | |||
| 2bde128fed | |||
| 89461505b5 | |||
| 85df5e61e5 | |||
| 5e477ff984 | |||
| 2baf9eda61 | |||
| 7d6d8175b9 | |||
| 0fdda032cc | |||
| c82d0f8c1c | |||
| 65ff108615 | |||
| 075611eb65 | |||
| b82537b020 | |||
| 06fee4636a | |||
| 5fe1af3239 | |||
| bf6cc3d384 | |||
| b4a4ba91b0 | |||
| 271776944a | |||
| b1d5a3d75f | |||
| bd68790a10 | |||
| f0a7663447 | |||
| db627d65c7 | |||
| a9f581797a | |||
| 763291230d | |||
| 55a77a34bd | |||
| f4f975c6b7 | |||
| 2d26382510 | |||
| c5cd56a99e | |||
| 24943dd526 | |||
| 8b32e30ee7 | |||
| 72c99be0f2 | |||
| 10ac1f6ae8 | |||
| 524170534c | |||
| d542f35336 | |||
| 697ba53c6b | |||
| 148a8bad2e | |||
| 7a344b91aa | |||
| 5783350484 | |||
| 9fce23d5ac | |||
| 7c17c99b9e | |||
| ff560bc3a3 | |||
| 61f01f4713 | |||
| 2e8c0234bb | |||
| 8e62d772b3 | |||
| 532cfb5775 | |||
| f912eb805d | |||
| 6838ff8ea2 | |||
| 8aa2c40bbf | |||
| c2d603769e | |||
| 3710d85e63 | |||
| 12a72302d9 | |||
| 2c70f0dc27 | |||
| 6165c65a51 | |||
| 3ea3f64214 | |||
| 08601d32a3 | |||
| 0ae1f6858c | |||
| f2e5b480e1 | |||
| 19ab197bc1 | |||
| 8bf1464b64 | |||
| 0ee3421cbc | |||
| a18536e8a4 | |||
| cc2e1eecd3 | |||
| 87b95128f9 | |||
| 344a56b47a | |||
| da8d055817 | |||
| c07272633f | |||
| b26e0d42d5 | |||
| 8ee4e927a1 | |||
| 7eaa3cb2b6 | |||
| 696928540c | |||
| b33f36d30a | |||
| 179b392a49 | |||
| 857f19c382 | |||
| 8a333208a2 | |||
| ff23f62c3e | |||
| dcdc9d6b90 | |||
| 3d28f957c7 | |||
| 2eb2aa5bef | |||
| 371820fd59 | |||
| 596c584ef1 | |||
| 27a1577021 | |||
| 8f2745c248 | |||
| 1c964d05f8 | |||
| 2dcbf7f751 | |||
| 067f73da38 | |||
| ae324c13a6 | |||
| 9a488adbb9 | |||
| 4c0f1efec6 | |||
| 8974cb5f34 | |||
| cb303a3149 | |||
| c44628a5b1 | |||
| fb1effc654 | |||
| 5ab213b854 | |||
| bbf738635c | |||
| 705d3e9fbc | |||
| 6bd3728548 | |||
| 7d997f6d9a | |||
| e919eb3eba | |||
| c2b2096c8c | |||
| 46638d2ea1 | |||
| fdb08517d3 | |||
| f272962562 | |||
| 9e661d8a99 | |||
| 43c0b79273 | |||
| 96e96c3c7f | |||
| 15c51b4417 | |||
| 6c93ca0e42 | |||
| a3cb98a3d3 |
+57
-18
@@ -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
|
||||
|
||||
@@ -20,7 +18,11 @@ while getopts ":wtfvhs-:" opt; do
|
||||
wait)
|
||||
WAIT=1
|
||||
;;
|
||||
help|version|foreground|test)
|
||||
help|version)
|
||||
REDIRECT_STDERR=1
|
||||
EXPECT_OUTPUT=1
|
||||
;;
|
||||
foreground|test)
|
||||
EXPECT_OUTPUT=1
|
||||
;;
|
||||
esac
|
||||
@@ -28,17 +30,54 @@ while getopts ":wtfvhs-:" opt; do
|
||||
w)
|
||||
WAIT=1
|
||||
;;
|
||||
h|v|f|t)
|
||||
h|v)
|
||||
REDIRECT_STDERR=1
|
||||
EXPECT_OUTPUT=1
|
||||
;;
|
||||
f|t)
|
||||
EXPECT_OUTPUT=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
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 [ $REDIRECT_STDERR ]; then
|
||||
exec 2> /dev/null
|
||||
fi
|
||||
|
||||
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
|
||||
SCRIPT=`readlink -f "$0"`
|
||||
USR_DIRECTORY=`readlink -f $(dirname $SCRIPT)/..`
|
||||
ATOM_PATH="$USR_DIRECTORY/share/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 2>&1 &
|
||||
fi
|
||||
fi
|
||||
|
||||
# Exits this process when Atom is used as $EDITOR
|
||||
|
||||
@@ -39,25 +39,33 @@ module.exports = (grunt) ->
|
||||
if process.platform is 'win32'
|
||||
appName = 'Atom'
|
||||
tmpDir = os.tmpdir()
|
||||
installRoot = process.env.ProgramFiles
|
||||
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 = path.join(os.tmpdir(), 'atom-cached-atom-shells')
|
||||
else
|
||||
installDir = path.join(process.env.ProgramFiles, appName)
|
||||
else if process.platform is 'darwin'
|
||||
appName = 'Atom.app'
|
||||
tmpDir = '/tmp'
|
||||
installRoot = '/Applications'
|
||||
buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'atom-build')
|
||||
symbolsDir = path.join(buildDir, 'Atom.breakpad.syms')
|
||||
shellAppDir = path.join(buildDir, appName)
|
||||
contentsDir = path.join(shellAppDir, 'Contents')
|
||||
appDir = path.join(contentsDir, 'Resources', 'app')
|
||||
atomShellDownloadDir = '/tmp/atom-cached-atom-shells'
|
||||
|
||||
installDir = path.join(installRoot, appName)
|
||||
installDir = path.join('/Applications', appName)
|
||||
else
|
||||
appName = 'Atom'
|
||||
tmpDir = '/tmp'
|
||||
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 = process.env.INSTALL_PREFIX ? '/usr/local'
|
||||
|
||||
coffeeConfig =
|
||||
options:
|
||||
@@ -227,4 +235,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)
|
||||
|
||||
@@ -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",
|
||||
@@ -26,13 +26,14 @@
|
||||
"harmony-collections": "~0.3.8",
|
||||
"json-front-matter": "~0.1.3",
|
||||
"legal-eagle": "~0.3.0",
|
||||
"minidump": "0.4.x",
|
||||
"minidump": "0.5.x",
|
||||
"rcedit": "~0.1.2",
|
||||
"request": "~2.27.0",
|
||||
"rimraf": "~2.2.2",
|
||||
"runas": "0.5.x",
|
||||
"underscore-plus": "1.x",
|
||||
"unzip": "~0.1.9",
|
||||
"vm-compatibility-layer": "~0.1.0"
|
||||
"vm-compatibility-layer": "~0.1.0",
|
||||
"npm": "~1.4.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -143,6 +143,8 @@ downloadFileFromRepo = ({repo, file}, callback) ->
|
||||
|
||||
downloadIncludes = (callback) ->
|
||||
includes = [
|
||||
{repo: 'atom-keymap', file: 'src/keymap.coffee'}
|
||||
{repo: 'atom-keymap', file: 'src/key-binding.coffee'}
|
||||
{repo: 'first-mate', file: 'src/grammar.coffee'}
|
||||
{repo: 'first-mate', file: 'src/grammar-registry.coffee'}
|
||||
{repo: 'node-pathwatcher', file: 'src/directory.coffee'}
|
||||
|
||||
@@ -15,7 +15,16 @@ module.exports = (grunt) ->
|
||||
|
||||
createShortcut = path.resolve 'script', 'create-shortcut.cmd'
|
||||
runas('cmd', ['/c', createShortcut, path.join(installDir, 'atom.exe'), 'Atom'])
|
||||
else
|
||||
else if process.platform is 'darwin'
|
||||
rm installDir
|
||||
mkdir path.dirname(installDir)
|
||||
cp shellAppDir, installDir
|
||||
else
|
||||
binDir = path.join(installDir, 'bin')
|
||||
shareDir = path.join(installDir, 'share', 'atom')
|
||||
|
||||
mkdir binDir
|
||||
cp 'atom.sh', path.join(binDir, 'atom')
|
||||
rm shareDir
|
||||
mkdir path.dirname(shareDir)
|
||||
cp shellAppDir, shareDir
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
fillTemplate = (filePath, data) ->
|
||||
template = _.template(String(fs.readFileSync(filePath + '.in')))
|
||||
filled = template(data)
|
||||
fs.writeFileSync(filePath, filled)
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{spawn} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'mkdeb', 'Create debian package', ->
|
||||
done = @async()
|
||||
|
||||
{name, version, description} = grunt.file.readJSON('package.json')
|
||||
section = 'devel'
|
||||
arch = 'amd64'
|
||||
maintainer = 'GitHub <support@github.com>'
|
||||
data = {name, version, description, section, arch, maintainer}
|
||||
|
||||
control = path.join('resources', 'linux', 'debian', 'control')
|
||||
fillTemplate(control, data)
|
||||
desktop = path.join('resources', 'linux', 'Atom.desktop')
|
||||
fillTemplate(desktop, data)
|
||||
icon = path.join('resources', 'atom.png')
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
|
||||
cmd = path.join('script', 'mkdeb')
|
||||
args = [version, control, desktop, icon, buildDir]
|
||||
spawn({cmd, args}, done)
|
||||
@@ -48,3 +48,5 @@ module.exports = (grunt) ->
|
||||
|
||||
rcedit = require('rcedit')
|
||||
rcedit(shellExePath, {'version-string': strings}, done)
|
||||
else
|
||||
done()
|
||||
|
||||
@@ -19,7 +19,7 @@ module.exports =
|
||||
activate: (state) ->
|
||||
@myObject =
|
||||
if state
|
||||
deserialize(state)
|
||||
atom.deserializers.deserialize(state)
|
||||
else
|
||||
new MyObject("Hello")
|
||||
|
||||
@@ -31,7 +31,8 @@ module.exports =
|
||||
|
||||
```coffee-script
|
||||
class MyObject
|
||||
registerDeserializer(this)
|
||||
atom.deserializers.add(this)
|
||||
|
||||
@deserialize: ({data}) -> new MyObject(data)
|
||||
constructor: (@data) ->
|
||||
serialize: -> { deserializer: 'MyObject', data: @data }
|
||||
@@ -50,8 +51,8 @@ class-level method on the same class that implements `serialize`. This method's
|
||||
job is to convert a state object returned from a previous call `serialize` back
|
||||
into a genuine object.
|
||||
|
||||
#### registerDeserializer(klass)
|
||||
You need to call the global `registerDeserializer` method with your class in
|
||||
#### atom.deserializers.add(klass)
|
||||
You need to call the `atom.deserializers.add` method with your class in
|
||||
order to make it available to the deserialization system. Now you can call the
|
||||
global `deserialize` method with state returned from `serialize`, and your
|
||||
class's `deserialize` method will be selected automatically.
|
||||
@@ -60,14 +61,15 @@ class's `deserialize` method will be selected automatically.
|
||||
|
||||
```coffee-script
|
||||
class MyObject
|
||||
atom.deserializers.add(this)
|
||||
|
||||
@version: 2
|
||||
@deserialize: (state) -> ...
|
||||
serialize: -> { version: MyObject.version, ... }
|
||||
serialize: -> { version: @constructor.version, ... }
|
||||
```
|
||||
|
||||
Your serializable class can optionally have a class-level `@version` property
|
||||
and include a `version` key in its serialized state. When deserializing, Atom
|
||||
will only attempt to call deserialize if the two versions match, and otherwise
|
||||
return undefined. We plan on implementing a migration system in the future, but
|
||||
this at least protects you from improperly deserializing old state. If you find
|
||||
yourself in dire need of the migration system, let us know.
|
||||
this at least protects you from improperly deserializing old state.
|
||||
|
||||
@@ -51,7 +51,7 @@ editor such as comments, strings and the line numbers in the gutter.
|
||||
|
||||
As an example, let's make the `.gutter` `background-color` into `@red`.
|
||||
|
||||
Reload Atom by pressing `cmd-alt-option-L` to see the changes you made reflected
|
||||
Reload Atom by pressing `cmd-alt-ctrl-l` to see the changes you made reflected
|
||||
in your Atom window. Pretty neat!
|
||||
|
||||
__Tip:__ You can avoid reloading to see changes you make by opening an atom
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# '.editor':
|
||||
# 'enter': 'editor:newline'
|
||||
#
|
||||
# 'body':
|
||||
# '.workspace':
|
||||
# 'ctrl-P': 'core:move-up'
|
||||
# 'ctrl-p': 'core:move-down'
|
||||
#
|
||||
|
||||
@@ -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!'
|
||||
@@ -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' }
|
||||
]
|
||||
}
|
||||
]
|
||||
+38
-38
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.72.0",
|
||||
"version": "0.78.0",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -11,32 +12,31 @@
|
||||
"url": "https://github.com/atom/atom/issues"
|
||||
},
|
||||
"license": "All Rights Reserved",
|
||||
"atomShellVersion": "0.10.7",
|
||||
"atomShellVersion": "0.11.3",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^0.11.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.x",
|
||||
"emissary": "^1.2",
|
||||
"first-mate": ">=1.4.2 <2.0",
|
||||
"fs-plus": ">=2.0.4 < 3.0",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "~1.1",
|
||||
"git-utils": "1.x",
|
||||
"git-utils": "^1.1.1",
|
||||
"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",
|
||||
"loophole": "^0.3.0",
|
||||
"mixto": "1.x",
|
||||
"nslog": "0.5.0",
|
||||
"oniguruma": ">=1.0.3 <2.0",
|
||||
"oniguruma": "^1.0.4",
|
||||
"optimist": "0.4.0",
|
||||
"pathwatcher": "0.19.0",
|
||||
"pegjs": "0.8.0",
|
||||
"pathwatcher": "^1.1",
|
||||
"property-accessors": "1.x",
|
||||
"q": "^1.0.1",
|
||||
"random-words": "0.0.1",
|
||||
@@ -48,84 +48,84 @@
|
||||
"serializable": "1.x",
|
||||
"space-pen": "3.1.1",
|
||||
"temp": "0.5.0",
|
||||
"text-buffer": "^1.4.4",
|
||||
"text-buffer": "^1.4.5",
|
||||
"theorist": "1.x",
|
||||
"underscore-plus": ">=1.0.5 <2.0",
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
},
|
||||
"packageDependencies": {
|
||||
"atom-dark-syntax": "0.15.0",
|
||||
"atom-dark-ui": "0.25.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",
|
||||
"solarized-dark-syntax": "0.14.0",
|
||||
"solarized-light-syntax": "0.7.0",
|
||||
"archive-view": "0.29.0",
|
||||
"archive-view": "0.30.0",
|
||||
"autocomplete": "0.27.0",
|
||||
"autoflow": "0.15.0",
|
||||
"autosave": "0.13.0",
|
||||
"background-tips": "0.9.0",
|
||||
"bookmarks": "0.21.0",
|
||||
"bracket-matcher": "0.25.0",
|
||||
"bookmarks": "0.22.0",
|
||||
"bracket-matcher": "0.26.0",
|
||||
"command-palette": "0.19.0",
|
||||
"dev-live-reload": "0.29.0",
|
||||
"dev-live-reload": "0.30.0",
|
||||
"exception-reporting": "0.17.0",
|
||||
"feedback": "0.28.0",
|
||||
"find-and-replace": "0.91.0",
|
||||
"fuzzy-finder": "0.41.0",
|
||||
"find-and-replace": "0.92.0",
|
||||
"fuzzy-finder": "0.42.0",
|
||||
"git-diff": "0.25.0",
|
||||
"go-to-line": "0.18.0",
|
||||
"grammar-selector": "0.23.0",
|
||||
"image-view": "0.30.0",
|
||||
"keybinding-resolver": "0.11.0",
|
||||
"image-view": "0.32.0",
|
||||
"keybinding-resolver": "0.12.0",
|
||||
"link": "0.20.0",
|
||||
"markdown-preview": "0.49.0",
|
||||
"markdown-preview": "0.51.0",
|
||||
"metrics": "0.32.0",
|
||||
"open-on-github": "0.23.0",
|
||||
"package-generator": "0.30.0",
|
||||
"release-notes": "0.26.0",
|
||||
"settings-view": "0.93.0",
|
||||
"snippets": "0.37.0",
|
||||
"settings-view": "0.97.0",
|
||||
"snippets": "0.40.0",
|
||||
"spell-check": "0.28.0",
|
||||
"status-bar": "0.36.0",
|
||||
"status-bar": "0.37.0",
|
||||
"styleguide": "0.26.0",
|
||||
"symbols-view": "0.44.0",
|
||||
"tabs": "0.30.0",
|
||||
"symbols-view": "0.46.0",
|
||||
"tabs": "0.31.0",
|
||||
"timecop": "0.17.0",
|
||||
"tree-view": "0.80.0",
|
||||
"tree-view": "0.83.0",
|
||||
"update-package-dependencies": "0.6.0",
|
||||
"welcome": "0.11.0",
|
||||
"whitespace": "0.20.0",
|
||||
"whitespace": "0.21.0",
|
||||
"wrap-guide": "0.18.0",
|
||||
"language-c": "0.13.0",
|
||||
"language-coffee-script": "0.16.0",
|
||||
"language-css": "0.13.0",
|
||||
"language-gfm": "0.19.0",
|
||||
"language-gfm": "0.25.0",
|
||||
"language-git": "0.9.0",
|
||||
"language-go": "0.7.0",
|
||||
"language-html": "0.11.0",
|
||||
"language-hyperlink": "0.8.0",
|
||||
"language-html": "0.15.0",
|
||||
"language-hyperlink": "0.9.0",
|
||||
"language-java": "0.9.0",
|
||||
"language-javascript": "0.20.0",
|
||||
"language-javascript": "0.21.0",
|
||||
"language-json": "0.8.0",
|
||||
"language-less": "0.6.0",
|
||||
"language-make": "0.9.0",
|
||||
"language-objective-c": "0.10.0",
|
||||
"language-objective-c": "0.11.0",
|
||||
"language-perl": "0.8.0",
|
||||
"language-php": "0.11.0",
|
||||
"language-php": "0.13.0",
|
||||
"language-property-list": "0.7.0",
|
||||
"language-python": "0.12.0",
|
||||
"language-ruby": "0.16.0",
|
||||
"language-ruby-on-rails": "0.10.0",
|
||||
"language-ruby": "0.17.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-text": "0.6.0",
|
||||
"language-todo": "0.7.0",
|
||||
"language-toml": "0.11.0",
|
||||
"language-xml": "0.8.0",
|
||||
"language-todo": "0.9.0",
|
||||
"language-toml": "0.12.0",
|
||||
"language-xml": "0.9.0",
|
||||
"language-yaml": "0.6.0"
|
||||
},
|
||||
"private": true,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[Desktop Entry]
|
||||
Name=Atom
|
||||
Comment=<%= description %>
|
||||
Exec=/usr/share/atom/atom %U
|
||||
Icon=atom
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Utility;TextEditor;
|
||||
@@ -0,0 +1,8 @@
|
||||
Package: <%= name %>
|
||||
Version: <%= version %>
|
||||
Section: <%= section %>
|
||||
Priority: optional
|
||||
Architecture: <%= arch %>
|
||||
Installed-Size: `du -ks usr|cut -f 1`
|
||||
Maintainer: <%= maintainer %>
|
||||
Description: <%= description %>
|
||||
@@ -32,6 +32,8 @@
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>AtomApplication</string>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
<key>SUPublicDSAKeyFile</key>
|
||||
<string>speakeasy.pem</string>
|
||||
<key>SUScheduledCheckInterval</key>
|
||||
|
||||
+16
-5
@@ -1,4 +1,11 @@
|
||||
#!/usr/bin/env node --harmony_collections
|
||||
#!/usr/bin/env node
|
||||
|
||||
var nodeMinorVersion = process.versions.node.split('.')[1]
|
||||
if (nodeMinorVersion !== '10') {
|
||||
console.warn("You must run script/bootstrap and script/build with node v0.10.x");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var safeExec = require('./utils/child-process-wrapper.js').safeExec;
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
@@ -27,15 +34,19 @@ if (!fs.existsSync(path.join(apmInstallPath, 'node_modules')))
|
||||
|
||||
var apmPath = 'apm/node_modules/atom-package-manager/bin/apm'
|
||||
var apmFlags = process.env.JANKY_SHA1 || process.argv.indexOf('--no-color') !== -1 ? '--no-color' : '';
|
||||
|
||||
var npmPath = path.resolve(__dirname, '..', 'build', 'node_modules', '.bin', 'npm');
|
||||
var npmFlags = ' --userconfig=' + path.resolve('.npmrc') + ' ';
|
||||
|
||||
var packagesToDedupe = ['fs-plus', 'humanize-plus', 'oniguruma', 'roaster', 'season'];
|
||||
var npmCommand = 'npm --userconfig=' + path.resolve('.npmrc') + ' ';
|
||||
var echoNewLine = process.platform == 'win32' ? 'echo.' : 'echo';
|
||||
|
||||
var commands = [
|
||||
'git submodule --quiet sync',
|
||||
'git submodule --quiet update --recursive --init',
|
||||
{command: npmCommand + 'install --quiet', options: {cwd: path.resolve(__dirname, '..', 'build'), ignoreStdout: true}},
|
||||
{command: npmCommand + 'install --quiet', options: {cwd: apmVendorPath, ignoreStdout: true}},
|
||||
{command: npmCommand + 'install --quiet ' + apmVendorPath, options: {cwd: apmInstallPath, ignoreStdout: true}},
|
||||
{command: 'npm' + npmFlags + 'install --quiet', options: {cwd: path.resolve(__dirname, '..', 'build'), ignoreStdout: true}},
|
||||
{command: npmPath + npmFlags + 'install --quiet', options: {cwd: apmVendorPath, ignoreStdout: true}},
|
||||
{command: npmPath + npmFlags + 'install --quiet ' + apmVendorPath, options: {cwd: apmInstallPath, ignoreStdout: true}},
|
||||
echoNewLine,
|
||||
apmPath + ' clean ' + apmFlags,
|
||||
apmPath + ' install --quiet ' + apmFlags,
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env node --harmony_collections
|
||||
#!/usr/bin/env node
|
||||
var cp = require('./utils/child-process-wrapper.js');
|
||||
var path = require('path');
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env node --harmony_collections
|
||||
#!/usr/bin/env node
|
||||
var cp = require('./utils/child-process-wrapper.js');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env node --harmony_collections
|
||||
#!/usr/bin/env node
|
||||
var cp = require('./utils/child-process-wrapper.js');
|
||||
var path = require('path');
|
||||
var os = require('os');
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env node --harmony_collections
|
||||
#!/usr/bin/env node
|
||||
var cp = require('./utils/child-process-wrapper.js');
|
||||
var path = require('path');
|
||||
|
||||
|
||||
Arquivo executável
+31
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
# mkdeb version control-file-path deb-file-path
|
||||
|
||||
SCRIPT=`readlink -f "$0"`
|
||||
ROOT=`readlink -f $(dirname $SCRIPT)/..`
|
||||
cd $ROOT
|
||||
|
||||
VERSION="$1"
|
||||
CONTROL_FILE="$2"
|
||||
DESKTOP_FILE="$3"
|
||||
ICON_FILE="$4"
|
||||
DEB_PATH="$5"
|
||||
|
||||
TARGET_ROOT="`mktemp -d`"
|
||||
TARGET="$TARGET_ROOT/atom-$VERSION"
|
||||
|
||||
mkdir -p "$TARGET/usr"
|
||||
env INSTALL_PREFIX="$TARGET/usr" script/grunt install
|
||||
|
||||
mkdir -p "$TARGET/DEBIAN"
|
||||
mv "$CONTROL_FILE" "$TARGET/DEBIAN/control"
|
||||
|
||||
mkdir -p "$TARGET/usr/share/applications"
|
||||
mv "$DESKTOP_FILE" "$TARGET/usr/share/applications"
|
||||
|
||||
mkdir -p "$TARGET/usr/share/pixmaps"
|
||||
cp "$ICON_FILE" "$TARGET/usr/share/pixmaps"
|
||||
|
||||
dpkg-deb -b "$TARGET"
|
||||
mv "$TARGET_ROOT/atom-$VERSION.deb" "$DEB_PATH"
|
||||
rm -rf $TARGET_ROOT
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env node --harmony_collections
|
||||
#!/usr/bin/env node
|
||||
var safeExec = require('./utils/child-process-wrapper.js').safeExec;
|
||||
var path = require('path');
|
||||
|
||||
|
||||
@@ -2506,7 +2506,7 @@ describe "Editor", ->
|
||||
|
||||
describe "when the line preceding the newline does't add a level of indentation", ->
|
||||
it "indents the new line to the same level a as the preceding line", ->
|
||||
editor.setCursorBufferPosition([5, 13])
|
||||
editor.setCursorBufferPosition([5, 14])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(6)).toBe editor.indentationForBufferRow(5)
|
||||
|
||||
@@ -2529,6 +2529,16 @@ describe "Editor", ->
|
||||
expect(editor.indentationForBufferRow(1)).toBe 1
|
||||
expect(editor.indentationForBufferRow(2)).toBe 1
|
||||
|
||||
describe "when the cursor is before whitespace", ->
|
||||
it "retains the whitespace following the cursor on the new line", ->
|
||||
editor.setText(" var sort = function() {}")
|
||||
editor.setCursorScreenPosition([0, 23])
|
||||
editor.insertNewline()
|
||||
|
||||
expect(buffer.lineForRow(0)).toBe ' var sort = function()'
|
||||
expect(buffer.lineForRow(1)).toBe ' {}'
|
||||
expect(editor.getCursorScreenPosition()).toEqual [1, 2]
|
||||
|
||||
describe "when inserted text matches a decrease indent pattern", ->
|
||||
describe "when the preceding line matches an increase indent pattern", ->
|
||||
it "decreases the indentation to match that of the preceding line", ->
|
||||
|
||||
@@ -2922,6 +2922,30 @@ describe "EditorView", ->
|
||||
editorView.pixelPositionForScreenPosition([1, 5])
|
||||
expect(editorView.measureToColumn.callCount).toBe 0
|
||||
|
||||
describe "when stylesheets are changed", ->
|
||||
afterEach ->
|
||||
atom.themes.removeStylesheet 'line-height'
|
||||
atom.themes.removeStylesheet 'char-width'
|
||||
|
||||
it "updates the editor if the line height or character width changes due to a stylesheet change", ->
|
||||
editorView.attachToDom()
|
||||
editor.setCursorScreenPosition([1, 3])
|
||||
expect(editorView.pixelPositionForScreenPosition([1, 3])).toEqual {top: 20, left: 30}
|
||||
expect(editorView.getCursorView().position()).toEqual {top: 20, left: 30}
|
||||
|
||||
atom.themes.applyStylesheet 'line-height', """
|
||||
.editor { line-height: 2; }
|
||||
"""
|
||||
|
||||
expect(editorView.pixelPositionForScreenPosition([1, 3])).toEqual {top: 20, left: 30}
|
||||
expect(editorView.getCursorView().position()).toEqual {top: 20, left: 30}
|
||||
|
||||
atom.themes.applyStylesheet 'char-width', """
|
||||
.editor { letter-spacing: 2px; }
|
||||
"""
|
||||
expect(editorView.pixelPositionForScreenPosition([1, 3])).toEqual {top: 20, left: 36}
|
||||
expect(editorView.getCursorView().position()).toEqual {top: 20, left: 36}
|
||||
|
||||
describe "when the editor contains hard tabs", ->
|
||||
it "correctly calculates the the position left for a column", ->
|
||||
editor.setText('\ttest')
|
||||
|
||||
@@ -1,454 +0,0 @@
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
Keymap = require '../src/keymap'
|
||||
{$, $$, WorkspaceView} = require 'atom'
|
||||
|
||||
describe "Keymap", ->
|
||||
fragment = null
|
||||
keymap = null
|
||||
resourcePath = atom.getLoadSettings().resourcePath
|
||||
configDirPath = null
|
||||
|
||||
beforeEach ->
|
||||
configDirPath = temp.mkdirSync('atom')
|
||||
keymap = new Keymap({configDirPath, resourcePath})
|
||||
fragment = $ """
|
||||
<div class="command-mode">
|
||||
<div class="child-node">
|
||||
<div class="grandchild-node"/>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
|
||||
afterEach ->
|
||||
keymap.destroy()
|
||||
|
||||
describe ".handleKeyEvent(event)", ->
|
||||
deleteCharHandler = null
|
||||
insertCharHandler = null
|
||||
commandZHandler = null
|
||||
|
||||
beforeEach ->
|
||||
keymap.bindKeys 'name', '.command-mode', 'x': 'deleteChar'
|
||||
keymap.bindKeys 'name', '.insert-mode', 'x': 'insertChar'
|
||||
keymap.bindKeys 'name', '.command-mode', 'cmd-z': 'commandZPressed'
|
||||
|
||||
deleteCharHandler = jasmine.createSpy('deleteCharHandler')
|
||||
insertCharHandler = jasmine.createSpy('insertCharHandler')
|
||||
commandZHandler = jasmine.createSpy('commandZHandler')
|
||||
fragment.on 'deleteChar', deleteCharHandler
|
||||
fragment.on 'insertChar', insertCharHandler
|
||||
fragment.on 'commandZPressed', commandZHandler
|
||||
|
||||
describe "when no binding matches the event's keystroke", ->
|
||||
it "does not return false so the event continues to propagate", ->
|
||||
expect(keymap.handleKeyEvent(keydownEvent('0', target: fragment[0]))).not.toBe false
|
||||
|
||||
describe "when a non-English keyboard language is used", ->
|
||||
it "uses the physical character pressed instead of the character it maps to in the current language", ->
|
||||
event = keydownEvent('U+03B6', metaKey: true, which: 122, target: fragment[0]) # This is the 'z' key using the Greek keyboard layout
|
||||
result = keymap.handleKeyEvent(event)
|
||||
|
||||
expect(result).toBe(false)
|
||||
expect(commandZHandler).toHaveBeenCalled()
|
||||
|
||||
describe "when at least one binding fully matches the event's keystroke", ->
|
||||
describe "when the event's target node matches a selector with a matching binding", ->
|
||||
it "triggers the command event associated with that binding on the target node and returns false", ->
|
||||
result = keymap.handleKeyEvent(keydownEvent('x', target: fragment[0]))
|
||||
expect(result).toBe(false)
|
||||
expect(deleteCharHandler).toHaveBeenCalled()
|
||||
expect(insertCharHandler).not.toHaveBeenCalled()
|
||||
|
||||
deleteCharHandler.reset()
|
||||
fragment.removeClass('command-mode').addClass('insert-mode')
|
||||
|
||||
event = keydownEvent('x', target: fragment[0])
|
||||
keymap.handleKeyEvent(event)
|
||||
expect(deleteCharHandler).not.toHaveBeenCalled()
|
||||
expect(insertCharHandler).toHaveBeenCalled()
|
||||
|
||||
describe "when the event's target node *descends* from a selector with a matching binding", ->
|
||||
it "triggers the command event associated with that binding on the target node and returns false", ->
|
||||
target = fragment.find('.child-node')[0]
|
||||
result = keymap.handleKeyEvent(keydownEvent('x', target: target))
|
||||
expect(result).toBe(false)
|
||||
expect(deleteCharHandler).toHaveBeenCalled()
|
||||
expect(insertCharHandler).not.toHaveBeenCalled()
|
||||
|
||||
deleteCharHandler.reset()
|
||||
fragment.removeClass('command-mode').addClass('insert-mode')
|
||||
|
||||
keymap.handleKeyEvent(keydownEvent('x', target: target))
|
||||
expect(deleteCharHandler).not.toHaveBeenCalled()
|
||||
expect(insertCharHandler).toHaveBeenCalled()
|
||||
|
||||
describe "when the event's target node descends from multiple nodes that match selectors with a binding", ->
|
||||
beforeEach ->
|
||||
keymap.bindKeys 'name', '.child-node', 'x': 'foo'
|
||||
|
||||
it "only triggers bindings on selectors associated with the closest ancestor node", ->
|
||||
fooHandler = jasmine.createSpy 'fooHandler'
|
||||
fragment.on 'foo', fooHandler
|
||||
|
||||
target = fragment.find('.grandchild-node')[0]
|
||||
keymap.handleKeyEvent(keydownEvent('x', target: target))
|
||||
expect(fooHandler).toHaveBeenCalled()
|
||||
expect(deleteCharHandler).not.toHaveBeenCalled()
|
||||
expect(insertCharHandler).not.toHaveBeenCalled()
|
||||
|
||||
describe "when 'abortKeyBinding' is called on the triggered event", ->
|
||||
[fooHandler1, fooHandler2] = []
|
||||
|
||||
beforeEach ->
|
||||
fooHandler1 = jasmine.createSpy('fooHandler1').andCallFake (e) ->
|
||||
expect(deleteCharHandler).not.toHaveBeenCalled()
|
||||
e.abortKeyBinding()
|
||||
fooHandler2 = jasmine.createSpy('fooHandler2')
|
||||
|
||||
fragment.find('.child-node').on 'foo', fooHandler1
|
||||
fragment.on 'foo', fooHandler2
|
||||
|
||||
it "aborts the current event and tries again with the next-most-specific key binding", ->
|
||||
target = fragment.find('.grandchild-node')[0]
|
||||
keymap.handleKeyEvent(keydownEvent('x', target: target))
|
||||
expect(fooHandler1).toHaveBeenCalled()
|
||||
expect(fooHandler2).not.toHaveBeenCalled()
|
||||
expect(deleteCharHandler).toHaveBeenCalled()
|
||||
|
||||
it "does not throw an exception if the event was not triggered by the keymap", ->
|
||||
fragment.find('.grandchild-node').trigger 'foo'
|
||||
|
||||
describe "when the event bubbles to a node that matches multiple selectors", ->
|
||||
describe "when the matching selectors differ in specificity", ->
|
||||
it "triggers the binding for the most specific selector", ->
|
||||
keymap.bindKeys 'name', 'div .child-node', 'x': 'foo'
|
||||
keymap.bindKeys 'name', '.command-mode .child-node !important', 'x': 'baz'
|
||||
keymap.bindKeys 'name', '.command-mode .child-node', 'x': 'quux'
|
||||
keymap.bindKeys 'name', '.child-node', 'x': 'bar'
|
||||
|
||||
fooHandler = jasmine.createSpy 'fooHandler'
|
||||
barHandler = jasmine.createSpy 'barHandler'
|
||||
bazHandler = jasmine.createSpy 'bazHandler'
|
||||
fragment.on 'foo', fooHandler
|
||||
fragment.on 'bar', barHandler
|
||||
fragment.on 'baz', bazHandler
|
||||
|
||||
target = fragment.find('.grandchild-node')[0]
|
||||
keymap.handleKeyEvent(keydownEvent('x', target: target))
|
||||
|
||||
expect(fooHandler).not.toHaveBeenCalled()
|
||||
expect(barHandler).not.toHaveBeenCalled()
|
||||
expect(bazHandler).toHaveBeenCalled()
|
||||
|
||||
describe "when the matching selectors have the same specificity", ->
|
||||
it "triggers the bindings for the most recently declared selector", ->
|
||||
keymap.bindKeys 'name', '.child-node', 'x': 'foo', 'y': 'baz'
|
||||
keymap.bindKeys 'name', '.child-node', 'x': 'bar'
|
||||
|
||||
fooHandler = jasmine.createSpy 'fooHandler'
|
||||
barHandler = jasmine.createSpy 'barHandler'
|
||||
bazHandler = jasmine.createSpy 'bazHandler'
|
||||
fragment.on 'foo', fooHandler
|
||||
fragment.on 'bar', barHandler
|
||||
fragment.on 'baz', bazHandler
|
||||
|
||||
target = fragment.find('.grandchild-node')[0]
|
||||
keymap.handleKeyEvent(keydownEvent('x', target: target))
|
||||
|
||||
expect(barHandler).toHaveBeenCalled()
|
||||
expect(fooHandler).not.toHaveBeenCalled()
|
||||
|
||||
keymap.handleKeyEvent(keydownEvent('y', target: target))
|
||||
expect(bazHandler).toHaveBeenCalled()
|
||||
|
||||
describe "when the event's target is the document body", ->
|
||||
it "triggers the mapped event on the workspaceView", ->
|
||||
atom.workspaceView = new WorkspaceView
|
||||
atom.workspaceView.attachToDom()
|
||||
keymap.bindKeys 'name', 'body', 'x': 'foo'
|
||||
fooHandler = jasmine.createSpy("fooHandler")
|
||||
atom.workspaceView.on 'foo', fooHandler
|
||||
|
||||
result = keymap.handleKeyEvent(keydownEvent('x', target: document.body))
|
||||
expect(result).toBe(false)
|
||||
expect(fooHandler).toHaveBeenCalled()
|
||||
expect(deleteCharHandler).not.toHaveBeenCalled()
|
||||
expect(insertCharHandler).not.toHaveBeenCalled()
|
||||
|
||||
describe "when the event matches a 'native!' binding", ->
|
||||
it "returns true, allowing the browser's native key handling to process the event", ->
|
||||
keymap.bindKeys 'name', '.grandchild-node', 'x': 'native!'
|
||||
nativeHandler = jasmine.createSpy("nativeHandler")
|
||||
fragment.on 'native!', nativeHandler
|
||||
expect(keymap.handleKeyEvent(keydownEvent('x', target: fragment.find('.grandchild-node')[0]))).toBe true
|
||||
expect(nativeHandler).not.toHaveBeenCalled()
|
||||
|
||||
describe "when at least one binding partially matches the event's keystroke", ->
|
||||
[quitHandler, closeOtherWindowsHandler] = []
|
||||
|
||||
beforeEach ->
|
||||
keymap.bindKeys 'name', "*",
|
||||
'ctrl-x ctrl-c': 'quit'
|
||||
'ctrl-x 1': 'close-other-windows'
|
||||
|
||||
quitHandler = jasmine.createSpy('quitHandler')
|
||||
closeOtherWindowsHandler = jasmine.createSpy('closeOtherWindowsHandler')
|
||||
fragment.on 'quit', quitHandler
|
||||
fragment.on 'close-other-windows', closeOtherWindowsHandler
|
||||
|
||||
it "only matches entire keystroke patterns", ->
|
||||
expect(keymap.handleKeyEvent(keydownEvent('c', target: fragment[0]))).not.toBe false
|
||||
|
||||
describe "when the event's target node matches a selector with a partially matching multi-stroke binding", ->
|
||||
describe "when a second keystroke added to the first to match a multi-stroke binding completely", ->
|
||||
it "triggers the event associated with the matched multi-stroke binding", ->
|
||||
expect(keymap.handleKeyEvent(keydownEvent('x', target: fragment[0], ctrlKey: true))).toBeFalsy()
|
||||
expect(keymap.handleKeyEvent(keydownEvent('ctrl', target: fragment[0]))).toBeFalsy() # This simulates actual key event behavior
|
||||
expect(keymap.handleKeyEvent(keydownEvent('c', target: fragment[0], ctrlKey: true))).toBeFalsy()
|
||||
|
||||
expect(quitHandler).toHaveBeenCalled()
|
||||
expect(closeOtherWindowsHandler).not.toHaveBeenCalled()
|
||||
quitHandler.reset()
|
||||
|
||||
expect(keymap.handleKeyEvent(keydownEvent('x', target: fragment[0], ctrlKey: true))).toBeFalsy()
|
||||
expect(keymap.handleKeyEvent(keydownEvent('1', target: fragment[0]))).toBeFalsy()
|
||||
|
||||
expect(quitHandler).not.toHaveBeenCalled()
|
||||
expect(closeOtherWindowsHandler).toHaveBeenCalled()
|
||||
|
||||
describe "when a second keystroke added to the first doesn't match any bindings", ->
|
||||
it "clears the queued keystroke without triggering any events", ->
|
||||
expect(keymap.handleKeyEvent(keydownEvent('x', target: fragment[0], ctrlKey: true))).toBe false
|
||||
expect(keymap.handleKeyEvent(keydownEvent('c', target: fragment[0]))).toBe false
|
||||
expect(quitHandler).not.toHaveBeenCalled()
|
||||
expect(closeOtherWindowsHandler).not.toHaveBeenCalled()
|
||||
|
||||
expect(keymap.handleKeyEvent(keydownEvent('c', target: fragment[0]))).not.toBe false
|
||||
|
||||
describe "when the event's target node descends from multiple nodes that match selectors with a partial binding match", ->
|
||||
it "allows any of the bindings to be triggered upon a second keystroke, favoring the most specific selector", ->
|
||||
keymap.bindKeys 'name', ".grandchild-node", 'ctrl-x ctrl-c': 'more-specific-quit'
|
||||
grandchildNode = fragment.find('.grandchild-node')[0]
|
||||
moreSpecificQuitHandler = jasmine.createSpy('moreSpecificQuitHandler')
|
||||
fragment.on 'more-specific-quit', moreSpecificQuitHandler
|
||||
|
||||
expect(keymap.handleKeyEvent(keydownEvent('x', target: grandchildNode, ctrlKey: true))).toBeFalsy()
|
||||
expect(keymap.handleKeyEvent(keydownEvent('1', target: grandchildNode))).toBeFalsy()
|
||||
expect(quitHandler).not.toHaveBeenCalled()
|
||||
expect(moreSpecificQuitHandler).not.toHaveBeenCalled()
|
||||
expect(closeOtherWindowsHandler).toHaveBeenCalled()
|
||||
closeOtherWindowsHandler.reset()
|
||||
|
||||
expect(keymap.handleKeyEvent(keydownEvent('x', target: grandchildNode, ctrlKey: true))).toBeFalsy()
|
||||
expect(keymap.handleKeyEvent(keydownEvent('c', target: grandchildNode, ctrlKey: true))).toBeFalsy()
|
||||
expect(quitHandler).not.toHaveBeenCalled()
|
||||
expect(closeOtherWindowsHandler).not.toHaveBeenCalled()
|
||||
expect(moreSpecificQuitHandler).toHaveBeenCalled()
|
||||
|
||||
describe "when there is a complete binding with a less specific selector", ->
|
||||
it "favors the more specific partial match", ->
|
||||
|
||||
describe "when there is a complete binding with a more specific selector", ->
|
||||
it "favors the more specific complete match", ->
|
||||
|
||||
describe ".bindKeys(name, selector, bindings)", ->
|
||||
it "normalizes bindings that use shift with lower case alpha char", ->
|
||||
fooHandler = jasmine.createSpy('fooHandler')
|
||||
fragment.on 'foo', fooHandler
|
||||
keymap.bindKeys 'name', '*', 'ctrl-shift-l': 'foo'
|
||||
result = keymap.handleKeyEvent(keydownEvent('l', ctrlKey: true, altKey: false, shiftKey: true, target: fragment[0]))
|
||||
expect(result).toBe(false)
|
||||
expect(fooHandler).toHaveBeenCalled()
|
||||
|
||||
it "normalizes bindings that use shift with upper case alpha char", ->
|
||||
fooHandler = jasmine.createSpy('fooHandler')
|
||||
fragment.on 'foo', fooHandler
|
||||
keymap.bindKeys 'name', '*', 'ctrl-shift-L': 'foo'
|
||||
result = keymap.handleKeyEvent(keydownEvent('l', ctrlKey: true, altKey: false, shiftKey: true, target: fragment[0]))
|
||||
expect(result).toBe(false)
|
||||
expect(fooHandler).toHaveBeenCalled()
|
||||
|
||||
it "normalizes bindings that use an upper case alpha char without shift", ->
|
||||
fooHandler = jasmine.createSpy('fooHandler')
|
||||
fragment.on 'foo', fooHandler
|
||||
keymap.bindKeys 'name', '*', 'ctrl-L': 'foo'
|
||||
result = keymap.handleKeyEvent(keydownEvent('l', ctrlKey: true, altKey: false, shiftKey: true, target: fragment[0]))
|
||||
expect(result).toBe(false)
|
||||
expect(fooHandler).toHaveBeenCalled()
|
||||
|
||||
it "normalizes the key patterns in the hash to put the modifiers in alphabetical order", ->
|
||||
fooHandler = jasmine.createSpy('fooHandler')
|
||||
fragment.on 'foo', fooHandler
|
||||
keymap.bindKeys 'name', '*', 'ctrl-alt-delete': 'foo'
|
||||
result = keymap.handleKeyEvent(keydownEvent('delete', ctrlKey: true, altKey: true, target: fragment[0]))
|
||||
expect(result).toBe(false)
|
||||
expect(fooHandler).toHaveBeenCalled()
|
||||
|
||||
fooHandler.reset()
|
||||
keymap.bindKeys 'name', '*', 'ctrl-alt--': 'foo'
|
||||
result = keymap.handleKeyEvent(keydownEvent('-', ctrlKey: true, altKey: true, target: fragment[0]))
|
||||
expect(result).toBe(false)
|
||||
expect(fooHandler).toHaveBeenCalled()
|
||||
|
||||
describe ".remove(name)", ->
|
||||
it "removes the binding set with the given selector and bindings", ->
|
||||
keymap.add 'nature',
|
||||
'.green':
|
||||
'ctrl-c': 'cultivate'
|
||||
'.brown':
|
||||
'ctrl-h': 'harvest'
|
||||
|
||||
keymap.add 'medical',
|
||||
'.green':
|
||||
'ctrl-v': 'vomit'
|
||||
|
||||
expect(keymap.keyBindingsMatchingElement($$ -> @div class: 'green')).toHaveLength 2
|
||||
expect(keymap.keyBindingsMatchingElement($$ -> @div class: 'brown')).toHaveLength 1
|
||||
|
||||
keymap.remove('nature')
|
||||
|
||||
expect(keymap.keyBindingsMatchingElement($$ -> @div class: 'green')).toHaveLength 1
|
||||
expect(keymap.keyBindingsMatchingElement($$ -> @div class: 'brown')).toEqual []
|
||||
|
||||
describe ".keystrokeStringForEvent(event)", ->
|
||||
describe "when no modifiers are pressed", ->
|
||||
it "returns a string that identifies the key pressed", ->
|
||||
expect(keymap.keystrokeStringForEvent(keydownEvent('a'))).toBe 'a'
|
||||
expect(keymap.keystrokeStringForEvent(keydownEvent('['))).toBe '['
|
||||
expect(keymap.keystrokeStringForEvent(keydownEvent('*'))).toBe '*'
|
||||
expect(keymap.keystrokeStringForEvent(keydownEvent('left'))).toBe 'left'
|
||||
expect(keymap.keystrokeStringForEvent(keydownEvent('\b'))).toBe 'backspace'
|
||||
|
||||
describe "when ctrl, alt or command is pressed with a non-modifier key", ->
|
||||
it "returns a string that identifies the key pressed", ->
|
||||
expect(keymap.keystrokeStringForEvent(keydownEvent('a', altKey: true))).toBe 'alt-a'
|
||||
expect(keymap.keystrokeStringForEvent(keydownEvent('[', metaKey: true))).toBe 'cmd-['
|
||||
expect(keymap.keystrokeStringForEvent(keydownEvent('*', ctrlKey: true))).toBe 'ctrl-*'
|
||||
expect(keymap.keystrokeStringForEvent(keydownEvent('left', ctrlKey: true, metaKey: true, altKey: true))).toBe 'alt-cmd-ctrl-left'
|
||||
|
||||
describe "when shift is pressed when a non-modifer key", ->
|
||||
it "returns a string that identifies the key pressed", ->
|
||||
expect(keymap.keystrokeStringForEvent(keydownEvent('A', shiftKey: true))).toBe 'shift-A'
|
||||
expect(keymap.keystrokeStringForEvent(keydownEvent('{', shiftKey: true))).toBe '{'
|
||||
expect(keymap.keystrokeStringForEvent(keydownEvent('left', shiftKey: true))).toBe 'shift-left'
|
||||
expect(keymap.keystrokeStringForEvent(keydownEvent('Left', shiftKey: true))).toBe 'shift-left'
|
||||
|
||||
describe ".keyBindingsMatchingElement(element)", ->
|
||||
it "returns the matching bindings for the element", ->
|
||||
keymap.bindKeys 'name', '.command-mode', 'c': 'c'
|
||||
keymap.bindKeys 'name', '.grandchild-node', 'g': 'g'
|
||||
|
||||
bindings = keymap.keyBindingsMatchingElement(fragment.find('.grandchild-node'))
|
||||
expect(bindings).toHaveLength 2
|
||||
expect(bindings[0].command).toEqual "g"
|
||||
expect(bindings[1].command).toEqual "c"
|
||||
|
||||
describe "when multiple bindings match a keystroke", ->
|
||||
it "only returns bindings that match the most specific selector", ->
|
||||
keymap.bindKeys 'name', '.command-mode', 'g': 'cmd-mode'
|
||||
keymap.bindKeys 'name', '.command-mode .grandchild-node', 'g': 'cmd-and-grandchild-node'
|
||||
keymap.bindKeys 'name', '.grandchild-node', 'g': 'grandchild-node'
|
||||
|
||||
bindings = keymap.keyBindingsMatchingElement(fragment.find('.grandchild-node'))
|
||||
expect(bindings).toHaveLength 3
|
||||
expect(bindings[0].command).toEqual "cmd-and-grandchild-node"
|
||||
|
||||
describe ".keyBindingsForCommandMatchingElement(element)", ->
|
||||
beforeEach ->
|
||||
keymap.add 'nature',
|
||||
'.green':
|
||||
'ctrl-c': 'cultivate'
|
||||
'.green-2':
|
||||
'ctrl-o': 'cultivate'
|
||||
'.brown':
|
||||
'ctrl-h': 'harvest'
|
||||
'.blue':
|
||||
'ctrl-c': 'fly'
|
||||
|
||||
it "finds a keymap for an element", ->
|
||||
el = $$ -> @div class: 'green'
|
||||
bindings = keymap.keyBindingsForCommandMatchingElement('cultivate', el)
|
||||
expect(bindings).toHaveLength 1
|
||||
expect(bindings[0].keystroke).toEqual "ctrl-c"
|
||||
|
||||
it "no keymap an element without that map", ->
|
||||
el = $$ -> @div class: 'brown'
|
||||
bindings = keymap.keyBindingsForCommandMatchingElement('cultivate', el)
|
||||
expect(bindings).toHaveLength 0
|
||||
|
||||
describe "loading platform specific keybindings", ->
|
||||
customKeymap = null
|
||||
|
||||
beforeEach ->
|
||||
resourcePath = temp.mkdirSync('atom')
|
||||
customKeymap = new Keymap({configDirPath, resourcePath})
|
||||
|
||||
afterEach ->
|
||||
customKeymap.destroy()
|
||||
|
||||
it "doesn't load keybindings from other platforms", ->
|
||||
win32FilePath = path.join(resourcePath, "keymaps", "win32.cson")
|
||||
darwinFilePath = path.join(resourcePath, "keymaps", "darwin.cson")
|
||||
fs.writeFileSync(win32FilePath, '"body": "ctrl-l": "core:win32-move-left"')
|
||||
fs.writeFileSync(darwinFilePath, '"body": "ctrl-l": "core:darwin-move-left"')
|
||||
|
||||
customKeymap.loadBundledKeymaps()
|
||||
keyBindings = customKeymap.keyBindingsForKeystroke('ctrl-l')
|
||||
expect(keyBindings).toHaveLength 1
|
||||
expect(keyBindings[0].command).toBe "core:#{process.platform}-move-left"
|
||||
|
||||
describe "when the user keymap file is changed", ->
|
||||
it "is reloaded", ->
|
||||
keymapFilePath = path.join(configDirPath, "keymap.cson")
|
||||
fs.writeFileSync(keymapFilePath, '"body": "ctrl-l": "core:move-left"')
|
||||
keymap.loadUserKeymap()
|
||||
|
||||
spyOn(keymap, 'loadUserKeymap').andCallThrough()
|
||||
fs.writeFileSync(keymapFilePath, "'body': 'ctrl-l': 'core:move-right'")
|
||||
|
||||
waitsFor ->
|
||||
keymap.loadUserKeymap.callCount > 0
|
||||
|
||||
runs ->
|
||||
keyBinding = keymap.keyBindingsForKeystroke('ctrl-l')[0]
|
||||
expect(keyBinding.command).toBe 'core:move-right'
|
||||
keymap.loadUserKeymap.reset()
|
||||
fs.removeSync(keymapFilePath)
|
||||
|
||||
waitsFor ->
|
||||
keymap.loadUserKeymap.callCount > 0
|
||||
|
||||
runs ->
|
||||
keyBinding = keymap.keyBindingsForKeystroke('ctrl-l')[0]
|
||||
expect(keyBinding).toBeUndefined()
|
||||
|
||||
it "logs a warning when it can't be parsed", ->
|
||||
keymapFilePath = path.join(configDirPath, "keymap.json")
|
||||
fs.writeFileSync(keymapFilePath, '')
|
||||
keymap.loadUserKeymap()
|
||||
|
||||
spyOn(keymap, 'loadUserKeymap').andCallThrough()
|
||||
fs.writeFileSync(keymapFilePath, '}{')
|
||||
spyOn(console, 'warn')
|
||||
|
||||
waitsFor ->
|
||||
keymap.loadUserKeymap.callCount > 0
|
||||
|
||||
runs ->
|
||||
expect(console.warn.callCount).toBe 1
|
||||
expect(console.warn.argsForCall[0][0].length).toBeGreaterThan 0
|
||||
|
||||
describe "when adding a binding with an invalid selector", ->
|
||||
it "logs a warning and does not add it", ->
|
||||
spyOn(console, 'warn')
|
||||
keybinding =
|
||||
'##selector':
|
||||
'cmd-a': 'invalid-command'
|
||||
keymap.add('test', keybinding)
|
||||
|
||||
expect(console.warn.callCount).toBe 1
|
||||
expect(console.warn.argsForCall[0][0].length).toBeGreaterThan 0
|
||||
expect(-> keymap.keyBindingsMatchingElement(document.body)).not.toThrow()
|
||||
expect(keymap.keyBindingsForCommand('invalid:command')).toEqual []
|
||||
@@ -208,6 +208,20 @@ describe "LanguageMode", ->
|
||||
languageMode.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(buffer.lineForRow(0)).toBe "// @color: #4D926F;"
|
||||
|
||||
describe "xml", ->
|
||||
beforeEach ->
|
||||
editor = atom.project.openSync('sample.xml', autoIndent: false)
|
||||
editor.setText("<!-- test -->")
|
||||
{buffer, languageMode} = editor
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-xml')
|
||||
|
||||
describe "when uncommenting lines", ->
|
||||
it "removes the leading whitespace from the comment end pattern match", ->
|
||||
languageMode.toggleLineCommentsForBufferRows(0, 0)
|
||||
expect(buffer.lineForRow(0)).toBe "test"
|
||||
|
||||
describe "folding", ->
|
||||
beforeEach ->
|
||||
editor = atom.project.openSync('sample.js', autoIndent: false)
|
||||
|
||||
@@ -159,14 +159,14 @@ describe "PaneView", ->
|
||||
|
||||
describe "when an unmodifed buffer's path is deleted", ->
|
||||
it "removes the pane item", ->
|
||||
jasmine.unspy(window, 'setTimeout')
|
||||
filePath = temp.openSync('atom').path
|
||||
editor = atom.project.openSync(filePath)
|
||||
pane.activateItem(editor)
|
||||
expect(pane.items).toHaveLength(5)
|
||||
|
||||
fs.removeSync(filePath)
|
||||
waitsFor 30000, ->
|
||||
pane.items.length == 4
|
||||
waitsFor -> pane.items.length == 4
|
||||
|
||||
describe "when a pane is destroyed", ->
|
||||
[pane2, pane2Model] = []
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,8 +6,8 @@ require '../vendor/jasmine-jquery'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
Keymap = require '../src/keymap-extensions'
|
||||
{$, WorkspaceView} = require 'atom'
|
||||
Keymap = require '../src/keymap'
|
||||
Config = require '../src/config'
|
||||
{Point} = require 'text-buffer'
|
||||
Project = require '../src/project'
|
||||
@@ -180,7 +180,15 @@ window.keyIdentifierForKey = (key) ->
|
||||
"U+00" + charCode.toString(16)
|
||||
|
||||
window.keydownEvent = (key, properties={}) ->
|
||||
properties = $.extend({originalEvent: { keyIdentifier: keyIdentifierForKey(key) }}, properties)
|
||||
originalEventProperties = {}
|
||||
originalEventProperties.ctrl = properties.ctrlKey
|
||||
originalEventProperties.alt = properties.altKey
|
||||
originalEventProperties.shift = properties.shiftKey
|
||||
originalEventProperties.cmd = properties.metaKey
|
||||
originalEventProperties.target = properties.target?[0] ? properties.target
|
||||
originalEventProperties.which = properties.which
|
||||
originalEvent = Keymap.keydownEvent(key, originalEventProperties)
|
||||
properties = $.extend({originalEvent}, properties)
|
||||
$.Event("keydown", properties)
|
||||
|
||||
window.mouseEvent = (type, properties) ->
|
||||
|
||||
@@ -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'))
|
||||
|
||||
@@ -170,8 +170,11 @@ describe "ThemeManager", ->
|
||||
expect($(document.body).css('font-weight')).not.toBe("bold")
|
||||
themeManager.requireStylesheet(cssPath)
|
||||
expect($(document.body).css('font-weight')).toBe("bold")
|
||||
|
||||
themeManager.on 'stylesheets-changed', stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
themeManager.removeStylesheet(cssPath)
|
||||
expect($(document.body).css('font-weight')).not.toBe("bold")
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
describe "base stylesheet loading", ->
|
||||
beforeEach ->
|
||||
@@ -204,12 +207,15 @@ describe "ThemeManager", ->
|
||||
fs.writeFileSync(userStylesheetPath, 'body {border-style: dotted !important;}')
|
||||
|
||||
spyOn(themeManager, 'getUserStylesheetPath').andReturn userStylesheetPath
|
||||
themeManager.on 'stylesheets-changed', stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
runs ->
|
||||
expect($(document.body).css('border-style')).toBe 'dotted'
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
stylesheetsChangedHandler.reset()
|
||||
spyOn(themeManager, 'loadUserStylesheet').andCallThrough()
|
||||
fs.writeFileSync(userStylesheetPath, 'body {border-style: dashed}')
|
||||
|
||||
@@ -218,6 +224,8 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
expect($(document.body).css('border-style')).toBe 'dashed'
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
stylesheetsChangedHandler.reset()
|
||||
fs.removeSync(userStylesheetPath)
|
||||
|
||||
waitsFor ->
|
||||
@@ -225,6 +233,7 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
expect($(document.body).css('border-style')).toBe 'none'
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
describe "when a non-existent theme is present in the config", ->
|
||||
it "logs a warning but does not throw an exception (regression)", ->
|
||||
|
||||
+13
-4
@@ -34,6 +34,8 @@ WindowEventHandler = require './window-event-handler'
|
||||
# * `atom.workspaceView` - A {WorkspaceView} instance
|
||||
module.exports =
|
||||
class Atom extends Model
|
||||
@version: 1 # Increment this when the serialization format changes
|
||||
|
||||
# Public: Load or create the Atom environment in the given mode.
|
||||
#
|
||||
# - mode: Pass 'editor' or 'spec' depending on the kind of environment you
|
||||
@@ -41,11 +43,11 @@ class Atom extends Model
|
||||
#
|
||||
# Returns an Atom instance, fully initialized
|
||||
@loadOrCreate: (mode) ->
|
||||
@deserialize(@loadState(mode)) ? new this({mode, version: @getVersion()})
|
||||
@deserialize(@loadState(mode)) ? new this({mode, @version})
|
||||
|
||||
# Deserializes the Atom environment from a state object
|
||||
@deserialize: (state) ->
|
||||
new this(state) if state?.version is @getVersion()
|
||||
new this(state) if state?.version is @version
|
||||
|
||||
# Loads and returns the serialized state corresponding to this window
|
||||
# if it exists; otherwise returns undefined.
|
||||
@@ -110,7 +112,7 @@ class Atom extends Model
|
||||
|
||||
# Get the version of the Atom application.
|
||||
@getVersion: ->
|
||||
@version ?= @getLoadSettings().appVersion
|
||||
@appVersion ?= @getLoadSettings().appVersion
|
||||
|
||||
# Determine whether the current version is an official release.
|
||||
@isReleasedVersion: ->
|
||||
@@ -138,7 +140,7 @@ class Atom extends Model
|
||||
@loadTime = null
|
||||
|
||||
Config = require './config'
|
||||
Keymap = require './keymap'
|
||||
Keymap = require './keymap-extensions'
|
||||
PackageManager = require './package-manager'
|
||||
Clipboard = require './clipboard'
|
||||
Syntax = require './syntax'
|
||||
@@ -148,6 +150,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})
|
||||
@@ -236,6 +244,7 @@ class Atom extends Model
|
||||
WorkspaceView = require './workspace-view'
|
||||
@workspace = Workspace.deserialize(@state.workspace) ? new Workspace
|
||||
@workspaceView = new WorkspaceView(@workspace)
|
||||
@keymap.defaultTarget = @workspaceView[0]
|
||||
$(@workspaceViewParentSelector).append(@workspaceView)
|
||||
|
||||
deserializePackageStates: ->
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -9,12 +9,7 @@ optimist = require 'optimist'
|
||||
nslog = require 'nslog'
|
||||
dialog = require 'dialog'
|
||||
|
||||
console.log = (args...) ->
|
||||
# TODO: Make NSLog work as expected
|
||||
output = args.map((arg) -> JSON.stringify(arg)).join(" ")
|
||||
nslog(output)
|
||||
if process.platform isnt 'darwin'
|
||||
fs.writeFileSync('debug.log', output, flag: 'a')
|
||||
console.log = nslog
|
||||
|
||||
process.on 'uncaughtException', (error={}) ->
|
||||
nslog(error.message) if error.message?
|
||||
@@ -77,7 +72,7 @@ parseCommandLine = ->
|
||||
options.alias('h', 'help').boolean('h').describe('h', 'Print this usage message.')
|
||||
options.alias('l', 'log-file').string('l').describe('l', 'Log all output to file.')
|
||||
options.alias('n', 'new-window').boolean('n').describe('n', 'Open a new window.')
|
||||
options.alias('s', 'spec-directory').string('s').describe('s', 'Set the directory from which specs are loaded (default: Atom\'s spec directory).')
|
||||
options.alias('s', 'spec-directory').string('s').describe('s', 'Set the spec directory (default: Atom\'s spec directory).')
|
||||
options.alias('t', 'test').boolean('t').describe('t', 'Run the specified specs and exit with error code on failures.')
|
||||
options.alias('v', 'version').boolean('v').describe('v', 'Print the version.')
|
||||
options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.')
|
||||
|
||||
+44
-14
@@ -44,6 +44,7 @@ class EditorView extends View
|
||||
@configDefaults:
|
||||
fontFamily: ''
|
||||
fontSize: 16
|
||||
lineHeight: 1.3
|
||||
showInvisibles: false
|
||||
showIndentGuide: false
|
||||
showLineNumbers: true
|
||||
@@ -340,6 +341,8 @@ class EditorView extends View
|
||||
@subscribe atom.config.observe 'editor.invisibles', (invisibles) => @setInvisibles(invisibles)
|
||||
@subscribe atom.config.observe 'editor.fontSize', (fontSize) => @setFontSize(fontSize)
|
||||
@subscribe atom.config.observe 'editor.fontFamily', (fontFamily) => @setFontFamily(fontFamily)
|
||||
@subscribe atom.config.observe 'editor.lineHeight', (lineHeight) => @setLineHeight(lineHeight)
|
||||
|
||||
|
||||
handleEvents: ->
|
||||
@on 'focus', =>
|
||||
@@ -419,6 +422,8 @@ class EditorView extends View
|
||||
@scrollView.on 'overflowchanged', =>
|
||||
updateWidthInChars() if @[0].classList.contains('soft-wrap')
|
||||
|
||||
@subscribe atom.themes, 'stylesheets-changed', => @recalculateDimensions()
|
||||
|
||||
handleInputEvents: ->
|
||||
@on 'cursor:moved', =>
|
||||
return unless @isFocused
|
||||
@@ -467,9 +472,10 @@ class EditorView extends View
|
||||
$(document).off 'mousemove', moveHandler
|
||||
$(document).off 'mouseup', finalizeSelections
|
||||
|
||||
@editor.mergeIntersectingSelections(isReversed: @editor.getLastSelection().isReversed())
|
||||
@editor.finalizeSelections()
|
||||
@syncCursorAnimations()
|
||||
unless @editor.isDestroyed()
|
||||
@editor.mergeIntersectingSelections(isReversed: @editor.getLastSelection().isReversed())
|
||||
@editor.finalizeSelections()
|
||||
@syncCursorAnimations()
|
||||
|
||||
moveHandler = (event = lastMoveEvent) =>
|
||||
return unless event?
|
||||
@@ -744,6 +750,17 @@ class EditorView extends View
|
||||
# Returns a {String} identifying the CSS `font-family`.
|
||||
getFontFamily: -> @css("font-family")
|
||||
|
||||
# Public: Sets the line height of the editor.
|
||||
#
|
||||
# Calling this method has no effect when called on a mini editor.
|
||||
#
|
||||
# lineHeight - A {Number} without a unit suffix identifying the CSS
|
||||
# `line-height`.
|
||||
setLineHeight: (lineHeight) ->
|
||||
return if @mini
|
||||
@css('line-height', lineHeight)
|
||||
@redraw()
|
||||
|
||||
# Public: Redraw the editor
|
||||
redraw: ->
|
||||
return unless @hasParent()
|
||||
@@ -881,7 +898,19 @@ class EditorView extends View
|
||||
fragment.remove()
|
||||
@setHeightInLines()
|
||||
|
||||
updateLayerDimensions: ->
|
||||
recalculateDimensions: ->
|
||||
return unless @attached and @isVisible()
|
||||
|
||||
oldCharWidth = @charWidth
|
||||
oldLineHeight = @lineHeight
|
||||
|
||||
@calculateDimensions()
|
||||
|
||||
unless @charWidth is oldCharWidth and @lineHeight is oldLineHeight
|
||||
@clearCharacterWidthCache()
|
||||
@requestDisplayUpdate()
|
||||
|
||||
updateLayerDimensions: (scrollViewWidth) ->
|
||||
height = @lineHeight * @editor.getScreenLineCount()
|
||||
unless @layerHeight == height
|
||||
@layerHeight = height
|
||||
@@ -891,7 +920,7 @@ class EditorView extends View
|
||||
@verticalScrollbarContent.height(@layerHeight)
|
||||
@scrollBottom(height) if @scrollBottom() > height
|
||||
|
||||
minWidth = Math.max(@charWidth * @editor.getMaxScreenLineLength() + 20, @scrollView.width())
|
||||
minWidth = Math.max(@charWidth * @editor.getMaxScreenLineLength() + 20, scrollViewWidth)
|
||||
unless @layerMinWidth == minWidth
|
||||
@renderedLines.css('min-width', minWidth)
|
||||
@underlayer.css('min-width', minWidth)
|
||||
@@ -925,7 +954,7 @@ class EditorView extends View
|
||||
@setSoftWrap(@editor.getSoftWrap())
|
||||
@newCursors = @editor.getCursors()
|
||||
@newSelections = @editor.getSelections()
|
||||
@updateDisplay(suppressAutoScroll: true)
|
||||
@updateDisplay(suppressAutoscroll: true)
|
||||
|
||||
requestDisplayUpdate: ->
|
||||
return if @pendingDisplayUpdate
|
||||
@@ -935,19 +964,20 @@ class EditorView extends View
|
||||
@updateDisplay()
|
||||
@pendingDisplayUpdate = false
|
||||
|
||||
updateDisplay: (options={}) ->
|
||||
updateDisplay: (options) ->
|
||||
return unless @attached and @editor
|
||||
return if @editor.isDestroyed()
|
||||
unless @isOnDom() and @isVisible()
|
||||
@redrawOnReattach = true
|
||||
return
|
||||
|
||||
@updateRenderedLines()
|
||||
scrollViewWidth = @scrollView.width()
|
||||
@updateRenderedLines(scrollViewWidth)
|
||||
@updatePlaceholderText()
|
||||
@highlightCursorLine()
|
||||
@updateCursorViews()
|
||||
@updateSelectionViews()
|
||||
@autoscroll(options)
|
||||
@autoscroll(options?.suppressAutoscroll ? false)
|
||||
@trigger 'editor:display-updated'
|
||||
|
||||
updateCursorViews: ->
|
||||
@@ -990,14 +1020,14 @@ class EditorView extends View
|
||||
syncCursorAnimations: ->
|
||||
cursorView.resetBlinking() for cursorView in @getCursorViews()
|
||||
|
||||
autoscroll: (options={}) ->
|
||||
autoscroll: (suppressAutoscroll) ->
|
||||
for cursorView in @getCursorViews()
|
||||
if !options.suppressAutoScroll and cursorView.needsAutoscroll()
|
||||
if !suppressAutoscroll and cursorView.needsAutoscroll()
|
||||
@scrollToPixelPosition(cursorView.getPixelPosition())
|
||||
cursorView.clearAutoscroll()
|
||||
|
||||
for selectionView in @getSelectionViews()
|
||||
if !options.suppressAutoScroll and selectionView.needsAutoscroll()
|
||||
if !suppressAutoscroll and selectionView.needsAutoscroll()
|
||||
@scrollToPixelPosition(selectionView.getCenterPixelPosition(), center: true)
|
||||
selectionView.highlight()
|
||||
selectionView.clearAutoscroll()
|
||||
@@ -1013,7 +1043,7 @@ class EditorView extends View
|
||||
else
|
||||
@underlayer.append($('<span/>', class: 'placeholder-text', text: @placeholderText))
|
||||
|
||||
updateRenderedLines: ->
|
||||
updateRenderedLines: (scrollViewWidth) ->
|
||||
firstVisibleScreenRow = @getFirstVisibleScreenRow()
|
||||
lastScreenRowToRender = firstVisibleScreenRow + @heightInLines - 1
|
||||
lastScreenRow = @editor.getLastScreenRow()
|
||||
@@ -1037,7 +1067,7 @@ class EditorView extends View
|
||||
@fillDirtyRanges(intactRanges, renderFrom, renderTo)
|
||||
@firstRenderedScreenRow = renderFrom
|
||||
@lastRenderedScreenRow = renderTo
|
||||
@updateLayerDimensions()
|
||||
@updateLayerDimensions(scrollViewWidth)
|
||||
@updatePaddingOfRenderedLines()
|
||||
|
||||
computeSurroundingEmptyLineChanges: (change) ->
|
||||
|
||||
+9
-3
@@ -373,10 +373,16 @@ class Editor extends Model
|
||||
#
|
||||
# bufferRow - A {Number} indicating the buffer row.
|
||||
# newLevel - A {Number} indicating the new indentation level.
|
||||
setIndentationForBufferRow: (bufferRow, newLevel) ->
|
||||
currentIndentLength = @lineForBufferRow(bufferRow).match(/^\s*/)[0].length
|
||||
# options - An {Object} with the following keys:
|
||||
# :preserveLeadingWhitespace - true to preserve any whitespace already at
|
||||
# the beginning of the line (default: false).
|
||||
setIndentationForBufferRow: (bufferRow, newLevel, {preserveLeadingWhitespace}={}) ->
|
||||
if preserveLeadingWhitespace
|
||||
endColumn = 0
|
||||
else
|
||||
endColumn = @lineForBufferRow(bufferRow).match(/^\s*/)[0].length
|
||||
newIndentString = @buildIndentString(newLevel)
|
||||
@buffer.change([[bufferRow, 0], [bufferRow, currentIndentLength]], newIndentString)
|
||||
@buffer.change([[bufferRow, 0], [bufferRow, endColumn]], newIndentString)
|
||||
|
||||
# Public: Get the indentation level of the given line of text.
|
||||
#
|
||||
|
||||
+88
-17
@@ -10,6 +10,18 @@ GitUtils = require 'git-utils'
|
||||
# `atom.project` global and calling `getRepo()`. Note that this will only be
|
||||
# available when the project is backed by a Git repository.
|
||||
#
|
||||
# This class handles submodules automically by taking a `path` argument to many
|
||||
# of the methods. This `path` argument will determine which underlying
|
||||
# repository is used.
|
||||
#
|
||||
# For a repository with submodules this would have the following outcome:
|
||||
#
|
||||
# ```coffee
|
||||
# repo = atom.project.getRepo()
|
||||
# repo.getShortHead() # 'master'
|
||||
# repo.getShortHead('vendor/path/to/a/submodule') # 'dead1234'
|
||||
# ```
|
||||
#
|
||||
# ## Example
|
||||
#
|
||||
# ```coffeescript
|
||||
@@ -89,10 +101,11 @@ class Git
|
||||
@unsubscribe()
|
||||
|
||||
# Returns the corresponding {Repository}
|
||||
getRepo: ->
|
||||
unless @repo?
|
||||
getRepo: (path) ->
|
||||
if @repo?
|
||||
@repo.submoduleForPath(path) ? @repo
|
||||
else
|
||||
throw new Error("Repository has been destroyed")
|
||||
@repo
|
||||
|
||||
# Reread the index to update any values that have changed since the
|
||||
# last time the index was read.
|
||||
@@ -113,7 +126,8 @@ class Git
|
||||
# {::isStatusModified} or {::isStatusNew} to get more information.
|
||||
getPathStatus: (path) ->
|
||||
currentPathStatus = @statuses[path] ? 0
|
||||
pathStatus = @getRepo().getStatus(@relativize(path)) ? 0
|
||||
repo = @getRepo(path)
|
||||
pathStatus = repo.getStatus(repo.relativize(path)) ? 0
|
||||
if pathStatus > 0
|
||||
@statuses[path] = pathStatus
|
||||
else
|
||||
@@ -153,8 +167,11 @@ class Git
|
||||
# `refs/remotes`. It also shortens the SHA-1 of a detached `HEAD` to 7
|
||||
# characters.
|
||||
#
|
||||
# path - An optional {String} path in the repository to get this information
|
||||
# for, only needed if the repository contains submodules.
|
||||
#
|
||||
# Returns a {String}.
|
||||
getShortHead: -> @getRepo().getShortHead()
|
||||
getShortHead: (path) -> @getRepo(path).getShortHead()
|
||||
|
||||
# Public: Restore the contents of a path in the working directory and index
|
||||
# to the version at `HEAD`.
|
||||
@@ -170,7 +187,8 @@ class Git
|
||||
#
|
||||
# Returns a {Boolean} that's true if the method was successful.
|
||||
checkoutHead: (path) ->
|
||||
headCheckedOut = @getRepo().checkoutHead(@relativize(path))
|
||||
repo = @getRepo(path)
|
||||
headCheckedOut = repo.checkoutHead(repo.relativize(path))
|
||||
@getPathStatus(path) if headCheckedOut
|
||||
headCheckedOut
|
||||
|
||||
@@ -194,14 +212,22 @@ class Git
|
||||
# Returns an {Object} with the following keys:
|
||||
# :added - The {Number} of added lines.
|
||||
# :deleted - The {Number} of deleted lines.
|
||||
getDiffStats: (path) -> @getRepo().getDiffStats(@relativize(path))
|
||||
getDiffStats: (path) ->
|
||||
repo = @getRepo(path)
|
||||
repo.getDiffStats(repo.relativize(path))
|
||||
|
||||
# Public: Is the given path a submodule in the repository?
|
||||
#
|
||||
# path - The {String} path to check.
|
||||
#
|
||||
# Returns a {Boolean}.
|
||||
isSubmodule: (path) -> @getRepo().isSubmodule(@relativize(path))
|
||||
isSubmodule: (path) ->
|
||||
repo = @getRepo(path)
|
||||
if repo.isSubmodule(repo.relativize(path))
|
||||
true
|
||||
else
|
||||
# Check if the path is a working directory in a repo that isn't the root.
|
||||
path is repo.getWorkingDirectory() and repo isnt @getRepo()
|
||||
|
||||
# Public: Get the status of a directory in the repository's working directory.
|
||||
#
|
||||
@@ -232,34 +258,69 @@ class Git
|
||||
# Ignore eol of line differences on windows so that files checked in as
|
||||
# LF don't report every line modified when the text contains CRLF endings.
|
||||
options = ignoreEolWhitespace: process.platform is 'win32'
|
||||
@getRepo().getLineDiffs(@relativize(path), text, options)
|
||||
repo = @getRepo(path)
|
||||
repo.getLineDiffs(repo.relativize(path), text, options)
|
||||
|
||||
# Public: Returns the git configuration value specified by the key.
|
||||
getConfigValue: (key) -> @getRepo().getConfigValue(key)
|
||||
#
|
||||
# path - An optional {String} path in the repository to get this information
|
||||
# for, only needed if the repository has submodules.
|
||||
getConfigValue: (key, path) -> @getRepo(path).getConfigValue(key)
|
||||
|
||||
# Public: Returns the origin url of the repository.
|
||||
getOriginUrl: -> @getConfigValue('remote.origin.url')
|
||||
#
|
||||
# path - An optional {String} path in the repository to get this information
|
||||
# for, only needed if the repository has submodules.
|
||||
getOriginUrl: (path) -> @getConfigValue('remote.origin.url', path)
|
||||
|
||||
# Public: Returns the upstream branch for the current HEAD, or null if there
|
||||
# is no upstream branch for the current HEAD.
|
||||
#
|
||||
# path - An optional {String} path in the repo to get this information for,
|
||||
# only needed if the repository contains submodules.
|
||||
#
|
||||
# Returns a {String} branch name such as `refs/remotes/origin/master`.
|
||||
getUpstreamBranch: -> @getRepo().getUpstreamBranch()
|
||||
getUpstreamBranch: (path) -> @getRepo(path).getUpstreamBranch()
|
||||
|
||||
# Public: Returns the current SHA for the given reference.
|
||||
getReferenceTarget: (reference) -> @getRepo().getReferenceTarget(reference)
|
||||
#
|
||||
# reference - The {String} reference to get the target of.
|
||||
# path - An optional {String} path in the repo to get the reference target
|
||||
# for. Only needed if the repository contains submodules.
|
||||
getReferenceTarget: (reference, path) ->
|
||||
@getRepo(path).getReferenceTarget(reference)
|
||||
|
||||
# Public: Gets all the local and remote references.
|
||||
#
|
||||
# path - An optional {String} path in the repository to get this information
|
||||
# for, only needed if the repository has submodules.
|
||||
#
|
||||
# Returns an {Object} with the following keys:
|
||||
# :heads - An {Array} of head reference names.
|
||||
# :remotes - An {Array} of remote reference names.
|
||||
# :tags - An {Array} of tag reference names.
|
||||
getReferences: -> @getRepo().getReferences()
|
||||
getReferences: (path) -> @getRepo(path).getReferences()
|
||||
|
||||
# Public: Returns the number of commits behind the current branch is from the
|
||||
# its upstream remote branch.
|
||||
getAheadBehindCount: (reference) -> @getRepo().getAheadBehindCount(reference)
|
||||
#
|
||||
# reference - The {String} branch reference name.
|
||||
# path - The {String} path in the repository to get this information for,
|
||||
# only needed if the repository contains submodules.
|
||||
getAheadBehindCount: (reference, path) ->
|
||||
@getRepo(path).getAheadBehindCount(reference)
|
||||
|
||||
# Public: Get the cached ahead/behind commit counts for the current branch's
|
||||
# upstream branch.
|
||||
#
|
||||
# path - An optional {String} path in the repository to get this information
|
||||
# for, only needed if the repository has submodules.
|
||||
#
|
||||
# Returns an {Object} with the following keys:
|
||||
# :ahead - The {Number} of commits ahead.
|
||||
# :behind - The {Number} of commits behind.
|
||||
getCachedUpstreamAheadBehindCount: (path) ->
|
||||
@getRepo(path).upstream ? @upstream
|
||||
|
||||
# Public: Returns true if the given branch exists.
|
||||
hasBranch: (branch) -> @getReferenceTarget("refs/heads/#{branch}")?
|
||||
@@ -267,9 +328,19 @@ class Git
|
||||
# Refreshes the current git status in an outside process and asynchronously
|
||||
# updates the relevant properties.
|
||||
refreshStatus: ->
|
||||
@statusTask = Task.once require.resolve('./repository-status-handler'), @getPath(), ({statuses, upstream, branch}) =>
|
||||
statusesUnchanged = _.isEqual(statuses, @statuses) and _.isEqual(upstream, @upstream) and _.isEqual(branch, @branch)
|
||||
handlerPath = require.resolve('./repository-status-handler')
|
||||
@statusTask = Task.once handlerPath, @getPath(), ({statuses, upstream, branch, submodules}) =>
|
||||
statusesUnchanged = _.isEqual(statuses, @statuses) and
|
||||
_.isEqual(upstream, @upstream) and
|
||||
_.isEqual(branch, @branch) and
|
||||
_.isEqual(submodules, @submodules)
|
||||
|
||||
@statuses = statuses
|
||||
@upstream = upstream
|
||||
@branch = branch
|
||||
@submodules = submodules
|
||||
|
||||
for submodulePath, submoduleRepo of @getRepo().submodules
|
||||
submoduleRepo.upstream = submodules[submodulePath].upstream
|
||||
|
||||
@emit 'statuses-changed' unless statusesUnchanged
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
{specificity} = require 'clear-cut'
|
||||
|
||||
module.exports =
|
||||
class KeyBinding
|
||||
@parser: null
|
||||
@currentIndex: 1
|
||||
@specificities: null
|
||||
|
||||
@calculateSpecificity: (selector) ->
|
||||
@specificities ?= {}
|
||||
value = @specificities[selector]
|
||||
unless value?
|
||||
value = specificity(selector)
|
||||
@specificities[selector] = value
|
||||
value
|
||||
|
||||
@normalizeKeystroke: (keystroke) ->
|
||||
normalizedKeystroke = keystroke.split(/\s+/).map (keystroke) =>
|
||||
keys = @parseKeystroke(keystroke)
|
||||
modifiers = keys[0...-1]
|
||||
modifiers.sort()
|
||||
key = _.last(keys)
|
||||
|
||||
modifiers.push 'shift' if /^[A-Z]$/.test(key) and 'shift' not in modifiers
|
||||
key = key.toUpperCase() if /^[a-z]$/.test(key) and 'shift' in modifiers
|
||||
|
||||
[modifiers..., key].join('-')
|
||||
|
||||
normalizedKeystroke.join(' ')
|
||||
|
||||
@parseKeystroke: (keystroke) ->
|
||||
unless @parser?
|
||||
try
|
||||
@parser = require './keystroke-pattern'
|
||||
catch
|
||||
{allowUnsafeEval} = require 'loophole'
|
||||
keystrokePattern = fs.readFileSync(require.resolve('./keystroke-pattern.pegjs'), 'utf8')
|
||||
PEG = require 'pegjs'
|
||||
allowUnsafeEval => @parser = PEG.buildParser(keystrokePattern)
|
||||
|
||||
@parser.parse(keystroke)
|
||||
|
||||
constructor: (source, command, keystroke, selector) ->
|
||||
@source = source
|
||||
@command = command
|
||||
@keystroke = KeyBinding.normalizeKeystroke(keystroke)
|
||||
@selector = selector.replace(/!important/g, '')
|
||||
@specificity = KeyBinding.calculateSpecificity(selector)
|
||||
@index = KeyBinding.currentIndex++
|
||||
|
||||
matches: (keystroke) ->
|
||||
multiKeystroke = /\s/.test keystroke
|
||||
if multiKeystroke
|
||||
keystroke == @keystroke
|
||||
else
|
||||
keystroke.split(' ')[0] == @keystroke.split(' ')[0]
|
||||
|
||||
compare: (keyBinding) ->
|
||||
if keyBinding.specificity == @specificity
|
||||
keyBinding.index - @index
|
||||
else
|
||||
keyBinding.specificity - @specificity
|
||||
@@ -0,0 +1,27 @@
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
Keymap = require 'atom-keymap'
|
||||
CSON = require 'season'
|
||||
{jQuery} = require 'space-pen'
|
||||
|
||||
Keymap::loadBundledKeymaps = ->
|
||||
@loadKeyBindings(path.join(@resourcePath, 'keymaps'))
|
||||
@emit('bundled-keymaps-loaded')
|
||||
|
||||
Keymap::getUserKeymapPath = ->
|
||||
if userKeymapPath = CSON.resolve(path.join(@configDirPath, 'keymap'))
|
||||
userKeymapPath
|
||||
else
|
||||
path.join(@configDirPath, 'keymap.cson')
|
||||
|
||||
Keymap::loadUserKeymap = ->
|
||||
userKeymapPath = @getUserKeymapPath()
|
||||
if fs.isFileSync(userKeymapPath)
|
||||
@loadKeyBindings(userKeymapPath, watch: true, suppressErrors: true)
|
||||
|
||||
# This enables command handlers registered via jQuery to call
|
||||
# `.abortKeyBinding()` on the `jQuery.Event` object passed to the handler.
|
||||
jQuery.Event::abortKeyBinding = ->
|
||||
@originalEvent?.abortKeyBinding?()
|
||||
|
||||
module.exports = Keymap
|
||||
@@ -1,223 +0,0 @@
|
||||
{$} = require './space-pen-extensions'
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
CSON = require 'season'
|
||||
KeyBinding = require './key-binding'
|
||||
{File} = require 'pathwatcher'
|
||||
{Emitter} = require 'emissary'
|
||||
|
||||
Modifiers = ['alt', 'control', 'ctrl', 'shift', 'cmd']
|
||||
|
||||
# Public: Associates keybindings with commands.
|
||||
#
|
||||
# An instance of this class is always available as the `atom.keymap` global.
|
||||
#
|
||||
# Keymaps are defined in a CSON/JSON format. A typical keymap looks something
|
||||
# like this:
|
||||
#
|
||||
# ```cson
|
||||
# 'body':
|
||||
# 'ctrl-l': 'package:do-something'
|
||||
# '.someClass':
|
||||
# 'enter': 'package:confirm'
|
||||
# ```
|
||||
#
|
||||
# As a key, you define the DOM element you want to work on, using CSS notation.
|
||||
# For that key, you define one or more key:value pairs, associating keystrokes
|
||||
# with a command to execute.
|
||||
module.exports =
|
||||
class Keymap
|
||||
Emitter.includeInto(this)
|
||||
|
||||
constructor: ({@resourcePath, @configDirPath})->
|
||||
@keyBindings = []
|
||||
|
||||
destroy: ->
|
||||
@unwatchUserKeymap()
|
||||
|
||||
# Public: Returns an array of all {KeyBinding}s.
|
||||
getKeyBindings: ->
|
||||
_.clone(@keyBindings)
|
||||
|
||||
# Public: Returns a array of {KeyBinding}s (sorted by selector specificity)
|
||||
# that match a keystroke and element.
|
||||
#
|
||||
# keystroke - The {String} representing the keys pressed (e.g. ctrl-P).
|
||||
# element - The DOM node that will match a {KeyBinding}'s selector.
|
||||
keyBindingsForKeystrokeMatchingElement: (keystroke, element) ->
|
||||
keyBindings = @keyBindingsForKeystroke(keystroke)
|
||||
@keyBindingsMatchingElement(element, keyBindings)
|
||||
|
||||
# Public: Returns a array of {KeyBinding}s (sorted by selector specificity)
|
||||
# that match a command.
|
||||
#
|
||||
# command - The {String} representing the command (tree-view:toggle).
|
||||
# element - The DOM node that will match a {KeyBinding}'s selector.
|
||||
keyBindingsForCommandMatchingElement: (command, element) ->
|
||||
keyBindings = @keyBindingsForCommand(command)
|
||||
@keyBindingsMatchingElement(element, keyBindings)
|
||||
|
||||
# Public: Returns an array of {KeyBinding}s that match a keystroke
|
||||
#
|
||||
# keystroke: The {String} representing the keys pressed (e.g. ctrl-P)
|
||||
keyBindingsForKeystroke: (keystroke) ->
|
||||
keystroke = KeyBinding.normalizeKeystroke(keystroke)
|
||||
@keyBindings.filter (keyBinding) -> keyBinding.matches(keystroke)
|
||||
|
||||
# Public: Returns an array of {KeyBinding}s that match a command
|
||||
#
|
||||
# keystroke - The {String} representing the keys pressed (e.g. ctrl-P)
|
||||
keyBindingsForCommand: (command) ->
|
||||
@keyBindings.filter (keyBinding) -> keyBinding.command == command
|
||||
|
||||
# Public: Returns a array of {KeyBinding}s (sorted by selector specificity)
|
||||
# whos selector matches the element.
|
||||
#
|
||||
# element - The DOM node that will match a {KeyBinding}'s selector.
|
||||
keyBindingsMatchingElement: (element, keyBindings=@keyBindings) ->
|
||||
keyBindings = keyBindings.filter ({selector}) -> $(element).closest(selector).length > 0
|
||||
keyBindings.sort (a, b) -> a.compare(b)
|
||||
|
||||
# Public: Returns a keystroke string derived from an event.
|
||||
#
|
||||
# event - A DOM or jQuery event.
|
||||
# previousKeystroke - An optional string used for multiKeystrokes.
|
||||
keystrokeStringForEvent: (event, previousKeystroke) ->
|
||||
if event.originalEvent.keyIdentifier.indexOf('U+') == 0
|
||||
hexCharCode = event.originalEvent.keyIdentifier[2..]
|
||||
charCode = parseInt(hexCharCode, 16)
|
||||
charCode = event.which if !@isAscii(charCode) and @isAscii(event.which)
|
||||
key = @keyFromCharCode(charCode)
|
||||
else
|
||||
key = event.originalEvent.keyIdentifier.toLowerCase()
|
||||
|
||||
modifiers = []
|
||||
if event.altKey and key not in Modifiers
|
||||
modifiers.push 'alt'
|
||||
if event.metaKey and key not in Modifiers
|
||||
modifiers.push 'cmd'
|
||||
if event.ctrlKey and key not in Modifiers
|
||||
modifiers.push 'ctrl'
|
||||
if event.shiftKey and key not in Modifiers
|
||||
# Don't push the shift modifier on single letter non-alpha keys (e.g. { or ')
|
||||
modifiers.push 'shift' unless /^[^a-z]$/i.test(key)
|
||||
|
||||
if 'shift' in modifiers and /^[a-z]$/i.test(key)
|
||||
key = key.toUpperCase()
|
||||
else
|
||||
key = key.toLowerCase()
|
||||
|
||||
keystroke = [modifiers..., key].join('-')
|
||||
|
||||
if previousKeystroke
|
||||
if keystroke in Modifiers
|
||||
previousKeystroke
|
||||
else
|
||||
"#{previousKeystroke} #{keystroke}"
|
||||
else
|
||||
keystroke
|
||||
|
||||
loadBundledKeymaps: ->
|
||||
@loadDirectory(path.join(@resourcePath, 'keymaps'))
|
||||
@emit('bundled-keymaps-loaded')
|
||||
|
||||
getUserKeymapPath: ->
|
||||
if userKeymapPath = CSON.resolve(path.join(@configDirPath, 'keymap'))
|
||||
userKeymapPath
|
||||
else
|
||||
path.join(@configDirPath, 'keymap.cson')
|
||||
|
||||
unwatchUserKeymap: ->
|
||||
@userKeymapFile?.off()
|
||||
@remove(@userKeymapPath) if @userKeymapPath?
|
||||
|
||||
loadUserKeymap: ->
|
||||
@unwatchUserKeymap()
|
||||
userKeymapPath = @getUserKeymapPath()
|
||||
if fs.isFileSync(userKeymapPath)
|
||||
@userKeymapPath = userKeymapPath
|
||||
@userKeymapFile = new File(userKeymapPath)
|
||||
@userKeymapFile.on 'contents-changed moved removed', => @loadUserKeymap()
|
||||
@add(@userKeymapPath, @readUserKeymap())
|
||||
|
||||
readUserKeymap: ->
|
||||
try
|
||||
CSON.readFileSync(@userKeymapPath) ? {}
|
||||
catch error
|
||||
console.warn("Failed to load your keymap file: #{@userKeymapPath}", error.stack ? error)
|
||||
{}
|
||||
|
||||
loadDirectory: (directoryPath) ->
|
||||
platforms = ['darwin', 'freebsd', 'linux', 'sunos', 'win32']
|
||||
otherPlatforms = platforms.filter (name) -> name != process.platform
|
||||
|
||||
for filePath in fs.listSync(directoryPath, ['.cson', '.json'])
|
||||
continue if path.basename(filePath, path.extname(filePath)) in otherPlatforms
|
||||
@load(filePath)
|
||||
|
||||
load: (path) ->
|
||||
@add(path, CSON.readFileSync(path))
|
||||
|
||||
add: (source, keyMappingsBySelector) ->
|
||||
for selector, keyMappings of keyMappingsBySelector
|
||||
@bindKeys(source, selector, keyMappings)
|
||||
|
||||
remove: (source) ->
|
||||
@keyBindings = @keyBindings.filter (keyBinding) -> keyBinding.source isnt source
|
||||
|
||||
bindKeys: (source, selector, keyMappings) ->
|
||||
for keystroke, command of keyMappings
|
||||
keyBinding = new KeyBinding(source, command, keystroke, selector)
|
||||
try
|
||||
$(keyBinding.selector) # Verify selector is valid before registering
|
||||
@keyBindings.push(keyBinding)
|
||||
catch
|
||||
console.warn("Keybinding '#{keystroke}': '#{command}' in #{source} has an invalid selector: '#{selector}'")
|
||||
|
||||
handleKeyEvent: (event) ->
|
||||
element = event.target
|
||||
element = atom.workspaceView if element == document.body
|
||||
keystroke = @keystrokeStringForEvent(event, @queuedKeystroke)
|
||||
keyBindings = @keyBindingsForKeystrokeMatchingElement(keystroke, element)
|
||||
|
||||
if keyBindings.length == 0 and @queuedKeystroke
|
||||
@queuedKeystroke = null
|
||||
return false
|
||||
else
|
||||
@queuedKeystroke = null
|
||||
|
||||
for keyBinding in keyBindings
|
||||
partialMatch = keyBinding.keystroke isnt keystroke
|
||||
if partialMatch
|
||||
@queuedKeystroke = keystroke
|
||||
shouldBubble = false
|
||||
else
|
||||
if keyBinding.command is 'native!'
|
||||
shouldBubble = true
|
||||
else if @triggerCommandEvent(element, keyBinding.command, event)
|
||||
shouldBubble = false
|
||||
|
||||
break if shouldBubble?
|
||||
|
||||
shouldBubble ? true
|
||||
|
||||
triggerCommandEvent: (element, commandName, event) ->
|
||||
commandEvent = $.Event(commandName)
|
||||
commandEvent.originalEvent = event
|
||||
commandEvent.abortKeyBinding = -> commandEvent.stopImmediatePropagation()
|
||||
$(element).trigger(commandEvent)
|
||||
not commandEvent.isImmediatePropagationStopped()
|
||||
|
||||
isAscii: (charCode) ->
|
||||
0 <= charCode <= 127
|
||||
|
||||
keyFromCharCode: (charCode) ->
|
||||
switch charCode
|
||||
when 8 then 'backspace'
|
||||
when 9 then 'tab'
|
||||
when 13 then 'enter'
|
||||
when 27 then 'escape'
|
||||
when 32 then 'space'
|
||||
when 127 then 'delete'
|
||||
else String.fromCharCode(charCode)
|
||||
@@ -1,3 +0,0 @@
|
||||
keystrokePattern = key:key additionalKeys:additionalKey* { return [key].concat(additionalKeys); }
|
||||
additionalKey = '-' key:key { return key; }
|
||||
key = '-' / chars:[^-]+ { return chars.join('') }
|
||||
@@ -39,13 +39,13 @@ class LanguageMode
|
||||
return unless commentStartString
|
||||
|
||||
buffer = @editor.buffer
|
||||
commentStartRegexString = _.escapeRegExp(commentStartString).replace(/(\s+)$/, '($1)?')
|
||||
commentStartRegexString = _.escapeRegExp(commentStartString).replace(/(\s+)$/, '(?:$1)?')
|
||||
commentStartRegex = new OnigRegExp("^(\\s*)(#{commentStartRegexString})")
|
||||
shouldUncomment = commentStartRegex.test(buffer.lineForRow(start))
|
||||
|
||||
if commentEndString
|
||||
if shouldUncomment
|
||||
commentEndRegexString = _.escapeRegExp(commentEndString).replace(/^(\s+)/, '($1)?')
|
||||
commentEndRegexString = _.escapeRegExp(commentEndString).replace(/^(\s+)/, '(?:$1)?')
|
||||
commentEndRegex = new OnigRegExp("(#{commentEndRegexString})(\\s*)$")
|
||||
startMatch = commentStartRegex.search(buffer.lineForRow(start))
|
||||
endMatch = commentEndRegex.search(buffer.lineForRow(end))
|
||||
@@ -265,10 +265,11 @@ class LanguageMode
|
||||
|
||||
# Given a buffer row, this indents it.
|
||||
#
|
||||
# bufferRow - The row {Number}
|
||||
autoIndentBufferRow: (bufferRow) ->
|
||||
# bufferRow - The row {Number}.
|
||||
# options - An options {Object} to pass through to {Editor::setIndentationForBufferRow}.
|
||||
autoIndentBufferRow: (bufferRow, options) ->
|
||||
indentLevel = @suggestedIndentForBufferRow(bufferRow)
|
||||
@editor.setIndentationForBufferRow(bufferRow, indentLevel)
|
||||
@editor.setIndentationForBufferRow(bufferRow, indentLevel, options)
|
||||
|
||||
# Given a buffer row, this decreases the indentation.
|
||||
#
|
||||
|
||||
@@ -77,7 +77,7 @@ class MenuManager
|
||||
keystrokesByCommand = {}
|
||||
for binding in atom.keymap.getKeyBindings() when @includeSelector(binding.selector)
|
||||
keystrokesByCommand[binding.command] ?= []
|
||||
keystrokesByCommand[binding.command].push binding.keystroke
|
||||
keystrokesByCommand[binding.command].unshift binding.keystroke
|
||||
@sendToBrowserProcess(@template, keystrokesByCommand)
|
||||
|
||||
loadPlatformItems: ->
|
||||
|
||||
@@ -3,17 +3,30 @@ path = require 'path'
|
||||
|
||||
module.exports = (repoPath) ->
|
||||
repo = Git.open(repoPath)
|
||||
|
||||
upstream = {}
|
||||
statuses = {}
|
||||
submodules = {}
|
||||
branch = null
|
||||
|
||||
if repo?
|
||||
# Statuses in main repo
|
||||
workingDirectoryPath = repo.getWorkingDirectory()
|
||||
statuses = {}
|
||||
for filePath, status of repo.getStatus()
|
||||
statuses[path.join(workingDirectoryPath, filePath)] = status
|
||||
|
||||
# Statuses in submodules
|
||||
for submodulePath, submoduleRepo of repo.submodules
|
||||
submodules[submodulePath] =
|
||||
branch: submoduleRepo.getHead()
|
||||
upstream: submoduleRepo.getAheadBehindCount()
|
||||
|
||||
workingDirectoryPath = submoduleRepo.getWorkingDirectory()
|
||||
for filePath, status of submoduleRepo.getStatus()
|
||||
statuses[path.join(workingDirectoryPath, filePath)] = status
|
||||
|
||||
upstream = repo.getAheadBehindCount()
|
||||
branch = repo.getHead()
|
||||
repo.release()
|
||||
else
|
||||
upstream = {}
|
||||
statuses = {}
|
||||
branch = null
|
||||
|
||||
{statuses, upstream, branch}
|
||||
{statuses, upstream, branch, submodules}
|
||||
|
||||
@@ -301,7 +301,7 @@ class Selection
|
||||
if options.autoIndent
|
||||
@editor.autoIndentBufferRow(row) for row in newBufferRange.getRows()
|
||||
else if options.autoIndentNewline and text == '\n'
|
||||
@editor.autoIndentBufferRow(newBufferRange.end.row)
|
||||
@editor.autoIndentBufferRow(newBufferRange.end.row, preserveLeadingWhitespace: true)
|
||||
else if options.autoDecreaseIndent and /\S/.test text
|
||||
@editor.autoDecreaseIndentForBufferRow(newBufferRange.start.row)
|
||||
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ class Task
|
||||
if _.isFunction(callback)
|
||||
@callback = callback
|
||||
else
|
||||
args = arguments
|
||||
args.push(callback)
|
||||
@send({event: 'start', args})
|
||||
|
||||
# Public: Send message to the task.
|
||||
|
||||
@@ -191,6 +191,7 @@ class ThemeManager
|
||||
removeStylesheet: (stylesheetPath) ->
|
||||
fullPath = @resolveStylesheet(stylesheetPath) ? stylesheetPath
|
||||
@stylesheetElementForId(@stringToId(fullPath)).remove()
|
||||
@emit 'stylesheets-changed'
|
||||
|
||||
applyStylesheet: (path, text, ttype = 'bundled', htmlElement=$('html')) ->
|
||||
styleElement = @stylesheetElementForId(@stringToId(path), htmlElement)
|
||||
@@ -201,3 +202,4 @@ class ThemeManager
|
||||
htmlElement.find("head style.#{ttype}:last").after "<style class='#{ttype}' id='#{@stringToId(path)}'>#{text}</style>"
|
||||
else
|
||||
htmlElement.find("head").append "<style class='#{ttype}' id='#{@stringToId(path)}'>#{text}</style>"
|
||||
@emit 'stylesheets-changed'
|
||||
|
||||
externo
+1
-1
Submodule vendor/apm updated: 537ac1ed90...3f0003c60e
Referência em uma Nova Issue
Bloquear um usuário