Comparar commits
1 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 0a0e848e7b |
@@ -1 +0,0 @@
|
||||
v0.10.21
|
||||
@@ -11,7 +11,6 @@ pairs:
|
||||
bo: Ben Ogle; benogle
|
||||
jr: Jason Rudolph; jasonrudolph
|
||||
jl: Jessica Lord; jlord
|
||||
dh: Daniel Hengeveld; danielh
|
||||
email:
|
||||
domain: github.com
|
||||
#global: true
|
||||
|
||||
-27
@@ -6,36 +6,10 @@ Visit [atom.io](https://atom.io) to learn more.
|
||||
|
||||
## Installing
|
||||
|
||||
### Mac OS X
|
||||
|
||||
Download the latest [Atom release](https://github.com/atom/atom/releases/latest).
|
||||
|
||||
Atom will automatically update when a new release is available.
|
||||
|
||||
### Windows
|
||||
|
||||
Install the [Atom chocolatey package](https://chocolatey.org/packages/Atom).
|
||||
|
||||
1. Install [chocolatey](https://chocolatey.org).
|
||||
2. Close and reopen your command prompt or PowerShell window.
|
||||
3. Run `cinst Atom`
|
||||
4. In the future run `cup Atom` to upgrade to the latest release.
|
||||
|
||||
You can also download a `.zip` file from the [releases page](https://github.com/atom/atom/releases/latest).
|
||||
The Windows version does not currently automatically update so you will need to
|
||||
manually upgrade to future releases by re-downloading the `.zip` file.
|
||||
|
||||
### Debian Linux (Ubuntu)
|
||||
|
||||
Currently only a 64-bit version is available.
|
||||
|
||||
1. Download `atom-amd64.deb` from the [Atom releases page](https://github.com/atom/atom/releases/latest).
|
||||
2. Run `sudo dpkg --install atom-amd64.deb` on the downloaded package.
|
||||
3. Launch Atom using the installed `atom` command.
|
||||
|
||||
The Linux version does not currently automatically update so you will need to
|
||||
repeat these steps to upgrade to future releases.
|
||||
|
||||
## Building
|
||||
|
||||
* [Linux](docs/build-instructions/linux.md)
|
||||
@@ -44,5 +18,4 @@ repeat these steps to upgrade to future releases.
|
||||
* [Windows](docs/build-instructions/windows.md)
|
||||
|
||||
## Developing
|
||||
|
||||
Check out the [guides](https://atom.io/docs/latest) and the [API reference](https://atom.io/docs/api).
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "atom-bundled-apm",
|
||||
"description": "Atom's bundled apm",
|
||||
"description": "Atom's bundled APM",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "0.101.0"
|
||||
"atom-package-manager": "0.69.0"
|
||||
}
|
||||
}
|
||||
|
||||
+3
-8
@@ -50,7 +50,7 @@ if [ $OS == 'Mac' ]; then
|
||||
|
||||
# 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'" | grep -v ShipIt | head -1 | xargs dirname)
|
||||
ATOM_PATH=$(mdfind "kMDItemCFBundleIdentifier == 'com.github.atom'" | head -1 | xargs dirname)
|
||||
fi
|
||||
|
||||
# Exit if Atom can't be found
|
||||
@@ -69,11 +69,6 @@ elif [ $OS == 'Linux' ]; then
|
||||
SCRIPT=$(readlink -f "$0")
|
||||
USR_DIRECTORY=$(readlink -f $(dirname $SCRIPT)/..)
|
||||
ATOM_PATH="$USR_DIRECTORY/share/atom/atom"
|
||||
DOT_ATOM_DIR="$HOME/.atom"
|
||||
|
||||
if [ ! -d "$DOT_ATOM_DIR" ]; then
|
||||
mkdir -p "$DOT_ATOM_DIR"
|
||||
fi
|
||||
|
||||
: ${TMPDIR:=/tmp}
|
||||
|
||||
@@ -84,9 +79,9 @@ elif [ $OS == 'Linux' ]; then
|
||||
exit $?
|
||||
else
|
||||
(
|
||||
nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > "$DOT_ATOM_DIR/nohup.out" 2>&1
|
||||
nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > "$TMPDIR/atom-nohup.out" 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
cat "$DOT_ATOM_DIR/nohup.out"
|
||||
cat "$TMPDIR/atom-nohup.out"
|
||||
exit $?
|
||||
fi
|
||||
) &
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
require '../src/window'
|
||||
Atom = require '../src/atom'
|
||||
window.atom = Atom.loadOrCreate('spec')
|
||||
atom = new Atom()
|
||||
atom.show() unless atom.getLoadSettings().exitWhenDone
|
||||
window.atom = atom
|
||||
|
||||
@@ -9,4 +9,5 @@ window.atom = atom
|
||||
atom.openDevTools()
|
||||
|
||||
document.title = "Benchmark Suite"
|
||||
runSpecSuite('../benchmark/benchmark-suite', atom.getLoadSettings().logFile)
|
||||
benchmarkSuite = require.resolve('./benchmark-suite')
|
||||
runSpecSuite(benchmarkSuite, true)
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
require '../spec/spec-helper'
|
||||
|
||||
path = require 'path'
|
||||
{$, Point} = require 'atom'
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
{$, _, Point, fs} = require 'atom'
|
||||
Project = require '../src/project'
|
||||
TokenizedBuffer = require '../src/tokenized-buffer'
|
||||
|
||||
@@ -103,7 +101,7 @@ $.fn.resultOfTrigger = (type) ->
|
||||
event.result
|
||||
|
||||
$.fn.enableKeymap = ->
|
||||
@on 'keydown', (e) -> window.keymap.handleKeyEvent(e)
|
||||
@on 'keydown', (e) => window.keymap.handleKeyEvent(e)
|
||||
|
||||
$.fn.attachToDom = ->
|
||||
$('#jasmine-content').append(this)
|
||||
|
||||
@@ -7,7 +7,7 @@ describe "editorView.", ->
|
||||
|
||||
beforeEach ->
|
||||
atom.workspaceViewParentSelector = '#jasmine-content'
|
||||
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView = new WorkspaceView
|
||||
atom.workspaceView.attachToDom()
|
||||
|
||||
atom.workspaceView.width(1024)
|
||||
@@ -53,7 +53,7 @@ describe "editorView.", ->
|
||||
|
||||
describe "at-end.", ->
|
||||
beforeEach ->
|
||||
editorView.moveToBottom()
|
||||
editorView.moveCursorToBottom()
|
||||
|
||||
benchmark "insert-delete", ->
|
||||
editorView.insertText('"')
|
||||
@@ -62,8 +62,8 @@ describe "editorView.", ->
|
||||
describe "empty-vs-set-innerHTML.", ->
|
||||
[firstRow, lastRow] = []
|
||||
beforeEach ->
|
||||
firstRow = editorView.getModel().getFirstVisibleScreenRow()
|
||||
lastRow = editorView.getModel().getLastVisibleScreenRow()
|
||||
firstRow = editorView.getFirstVisibleScreenRow()
|
||||
lastRow = editorView.getLastVisibleScreenRow()
|
||||
|
||||
benchmark "build-gutter-html.", 1000, ->
|
||||
editorView.gutter.renderLineNumbers(null, firstRow, lastRow)
|
||||
@@ -97,13 +97,13 @@ describe "editorView.", ->
|
||||
describe "multiple-lines.", ->
|
||||
[firstRow, lastRow] = []
|
||||
beforeEach ->
|
||||
firstRow = editorView.getModel().getFirstVisibleScreenRow()
|
||||
lastRow = editorView.getModel().getLastVisibleScreenRow()
|
||||
firstRow = editorView.getFirstVisibleScreenRow()
|
||||
lastRow = editorView.getLastVisibleScreenRow()
|
||||
|
||||
benchmark "cache-entire-visible-area", 100, ->
|
||||
for i in [firstRow..lastRow]
|
||||
line = editorView.lineElementForScreenRow(i)[0]
|
||||
editorView.positionLeftForLineAndColumn(line, i, Math.max(0, editorView.getModel().lineTextForBufferRow(i).length))
|
||||
editorView.positionLeftForLineAndColumn(line, i, Math.max(0, editorView.lineLengthForBufferRow(i)))
|
||||
|
||||
describe "text-rendering.", ->
|
||||
beforeEach ->
|
||||
@@ -178,7 +178,7 @@ describe "editorView.", ->
|
||||
atom.workspaceView.openSync('huge.js')
|
||||
|
||||
benchmark "moving-to-eof.", 1, ->
|
||||
editorView.moveToBottom()
|
||||
editorView.moveCursorToBottom()
|
||||
|
||||
describe "on-first-line.", ->
|
||||
benchmark "inserting-newline", 5, ->
|
||||
@@ -195,11 +195,11 @@ describe "editorView.", ->
|
||||
endPosition = null
|
||||
|
||||
beforeEach ->
|
||||
editorView.moveToBottom()
|
||||
editorView.moveCursorToBottom()
|
||||
endPosition = editorView.getCursorScreenPosition()
|
||||
|
||||
benchmark "move-to-beginning-of-word", ->
|
||||
editorView.moveToBeginningOfWord()
|
||||
editorView.moveCursorToBeginningOfWord()
|
||||
editorView.setCursorScreenPosition(endPosition)
|
||||
|
||||
benchmark "insert", ->
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
#!/usr/bin/env coffee
|
||||
|
||||
{spawn, exec} = require 'child_process'
|
||||
fs = require 'fs'
|
||||
os = require 'os'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
temp = require 'temp'
|
||||
|
||||
directoryToOpen = temp.mkdirSync('browser-process-startup-')
|
||||
socketPath = path.join(os.tmpdir(), 'atom.sock')
|
||||
numberOfRuns = 10
|
||||
|
||||
deleteSocketFile = ->
|
||||
try
|
||||
fs.unlinkSync(socketPath) if fs.existsSync(socketPath)
|
||||
catch error
|
||||
console.error(error)
|
||||
|
||||
launchAtom = (callback) ->
|
||||
deleteSocketFile()
|
||||
|
||||
cmd = 'atom'
|
||||
args = ['--safe', '--new-window', '--foreground', directoryToOpen]
|
||||
atomProcess = spawn(cmd, args)
|
||||
|
||||
output = ''
|
||||
startupTimes = []
|
||||
dataListener = (data) ->
|
||||
output += data
|
||||
if match = /App load time: (\d+)/.exec(output)
|
||||
startupTime = parseInt(match[1])
|
||||
atomProcess.stderr.removeListener 'data', dataListener
|
||||
atomProcess.kill()
|
||||
exec 'pkill -9 Atom', (error) ->
|
||||
console.error(error) if error?
|
||||
callback(startupTime)
|
||||
|
||||
atomProcess.stderr.on 'data', dataListener
|
||||
|
||||
startupTimes = []
|
||||
collector = (startupTime) ->
|
||||
startupTimes.push(startupTime)
|
||||
if startupTimes.length < numberOfRuns
|
||||
launchAtom(collector)
|
||||
else
|
||||
maxTime = _.max(startupTimes)
|
||||
minTime = _.min(startupTimes)
|
||||
totalTime = startupTimes.reduce (previousValue=0, currentValue) -> previousValue + currentValue
|
||||
console.log "Startup Runs: #{startupTimes.length}"
|
||||
console.log "First run time: #{startupTimes[0]}ms"
|
||||
console.log "Max time: #{maxTime}ms"
|
||||
console.log "Min time: #{minTime}ms"
|
||||
console.log "Average time: #{Math.round(totalTime/startupTimes.length)}ms"
|
||||
|
||||
launchAtom(collector)
|
||||
+12
-29
@@ -39,31 +39,21 @@ module.exports = (grunt) ->
|
||||
tmpDir = os.tmpdir()
|
||||
appName = if process.platform is 'darwin' then 'Atom.app' else 'Atom'
|
||||
buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'atom-build')
|
||||
buildDir = path.resolve(buildDir)
|
||||
installDir = grunt.option('install-dir')
|
||||
|
||||
home = if process.platform is 'win32' then process.env.USERPROFILE else process.env.HOME
|
||||
atomShellDownloadDir = path.join(home, '.atom', 'atom-shell')
|
||||
|
||||
atomShellDownloadDir = path.join(os.tmpdir(), 'atom-cached-atom-shells')
|
||||
symbolsDir = path.join(buildDir, 'Atom.breakpad.syms')
|
||||
shellAppDir = path.join(buildDir, appName)
|
||||
if process.platform is 'win32'
|
||||
contentsDir = shellAppDir
|
||||
appDir = path.join(shellAppDir, 'resources', 'app')
|
||||
installDir ?= path.join(process.env.ProgramFiles, appName)
|
||||
killCommand = 'taskkill /F /IM atom.exe'
|
||||
installDir = path.join(process.env.ProgramFiles, appName)
|
||||
else if process.platform is 'darwin'
|
||||
contentsDir = path.join(shellAppDir, 'Contents')
|
||||
appDir = path.join(contentsDir, 'Resources', 'app')
|
||||
installDir ?= path.join('/Applications', appName)
|
||||
killCommand = 'pkill -9 Atom'
|
||||
installDir = path.join('/Applications', appName)
|
||||
else
|
||||
contentsDir = shellAppDir
|
||||
appDir = path.join(shellAppDir, 'resources', 'app')
|
||||
installDir ?= process.env.INSTALL_PREFIX ? '/usr/local'
|
||||
killCommand ='pkill -9 atom'
|
||||
|
||||
installDir = path.resolve(installDir)
|
||||
installDir = process.env.INSTALL_PREFIX ? '/usr/local'
|
||||
|
||||
coffeeConfig =
|
||||
glob_to_multiple:
|
||||
@@ -99,8 +89,6 @@ module.exports = (grunt) ->
|
||||
csonConfig =
|
||||
options:
|
||||
rootObject: true
|
||||
cachePath: path.join(home, '.atom', 'compile-cache', 'grunt-cson')
|
||||
|
||||
glob_to_multiple:
|
||||
expand: true
|
||||
src: [
|
||||
@@ -133,8 +121,6 @@ module.exports = (grunt) ->
|
||||
|
||||
atom: {appDir, appName, symbolsDir, buildDir, contentsDir, installDir, shellAppDir}
|
||||
|
||||
docsOutputDir: 'docs/output'
|
||||
|
||||
coffee: coffeeConfig
|
||||
|
||||
less: lessConfig
|
||||
@@ -147,7 +133,12 @@ module.exports = (grunt) ->
|
||||
|
||||
coffeelint:
|
||||
options:
|
||||
configFile: 'coffeelint.json'
|
||||
no_empty_param_list:
|
||||
level: 'error'
|
||||
max_line_length:
|
||||
level: 'ignore'
|
||||
indentation:
|
||||
level: 'ignore'
|
||||
src: [
|
||||
'dot-atom/**/*.coffee'
|
||||
'exports/**/*.coffee'
|
||||
@@ -219,7 +210,7 @@ module.exports = (grunt) ->
|
||||
|
||||
shell:
|
||||
'kill-atom':
|
||||
command: killCommand
|
||||
command: 'pkill -9 Atom'
|
||||
options:
|
||||
stdout: false
|
||||
stderr: false
|
||||
@@ -228,17 +219,9 @@ module.exports = (grunt) ->
|
||||
grunt.registerTask('compile', ['coffee', 'prebuild-less', 'cson', 'peg'])
|
||||
grunt.registerTask('lint', ['coffeelint', 'csslint', 'lesslint'])
|
||||
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'])
|
||||
|
||||
ciTasks = ['output-disk-space', 'download-atom-shell', 'build']
|
||||
ciTasks.push('dump-symbols') if process.platform isnt 'win32'
|
||||
ciTasks.push('set-version', 'check-licenses', 'lint')
|
||||
ciTasks.push('mkdeb') if process.platform is 'linux'
|
||||
ciTasks.push('test') if process.platform is 'darwin'
|
||||
ciTasks.push('codesign')
|
||||
ciTasks.push('publish-build')
|
||||
grunt.registerTask('ci', ciTasks)
|
||||
|
||||
defaultTasks = ['download-atom-shell', 'build', 'set-version']
|
||||
defaultTasks.push 'install' unless process.platform is 'linux'
|
||||
grunt.registerTask('default', defaultTasks)
|
||||
|
||||
+10
-12
@@ -7,17 +7,17 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "~0.2.9",
|
||||
"donna": "1.0.1",
|
||||
"biscotto": ">=2.1.1 <3.0",
|
||||
"formidable": "~1.0.14",
|
||||
"fs-plus": "2.x",
|
||||
"github-releases": "~0.2.0",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-cli": "~0.1.9",
|
||||
"grunt-coffeelint": "git+https://github.com/atom/grunt-coffeelint.git#cfb99aa99811d52687969532bd5a98011ed95bfe",
|
||||
"grunt-contrib-coffee": "~0.9.0",
|
||||
"grunt-coffeelint": "git://github.com/atom/grunt-coffeelint.git",
|
||||
"grunt-contrib-csslint": "~0.1.2",
|
||||
"grunt-contrib-coffee": "~0.9.0",
|
||||
"grunt-contrib-less": "~0.8.0",
|
||||
"grunt-cson": "0.10.0",
|
||||
"grunt-cson": "0.8.0",
|
||||
"grunt-download-atom-shell": "~0.8.0",
|
||||
"grunt-lesslint": "0.13.0",
|
||||
"grunt-markdown": "~0.4.0",
|
||||
@@ -26,18 +26,16 @@
|
||||
"harmony-collections": "~0.3.8",
|
||||
"json-front-matter": "~0.1.3",
|
||||
"legal-eagle": "~0.4.0",
|
||||
"minidump": "~0.8",
|
||||
"normalize-package-data": "0.2.12",
|
||||
"npm": "~1.4.5",
|
||||
"rcedit": "~0.1.2",
|
||||
"minidump": "~0.7",
|
||||
"read-package-json": "1.1.8",
|
||||
"normalize-package-data": "0.2.12",
|
||||
"rcedit": "~0.1.2",
|
||||
"request": "~2.27.0",
|
||||
"rimraf": "~2.2.2",
|
||||
"runas": "~1.0.1",
|
||||
"tello": "1.0.3",
|
||||
"temp": "~0.8.1",
|
||||
"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,9 +14,9 @@ module.exports = (grunt) ->
|
||||
mkdir path.dirname(buildDir)
|
||||
|
||||
if process.platform is 'darwin'
|
||||
cp 'atom-shell/Atom.app', shellAppDir, filter: /default_app/
|
||||
cp 'atom-shell/Atom.app', shellAppDir
|
||||
else
|
||||
cp 'atom-shell', shellAppDir, filter: /default_app/
|
||||
cp 'atom-shell', shellAppDir
|
||||
|
||||
mkdir appDir
|
||||
|
||||
@@ -45,45 +45,19 @@ module.exports = (grunt) ->
|
||||
path.join('git-utils', 'deps')
|
||||
path.join('oniguruma', 'deps')
|
||||
path.join('less', 'dist')
|
||||
path.join('less', 'test')
|
||||
path.join('bootstrap', 'docs')
|
||||
path.join('bootstrap', '_config.yml')
|
||||
path.join('bootstrap', '_includes')
|
||||
path.join('bootstrap', '_layouts')
|
||||
path.join('npm', 'doc')
|
||||
path.join('npm', 'html')
|
||||
path.join('npm', 'man')
|
||||
path.join('npm', 'node_modules', '.bin', 'beep')
|
||||
path.join('npm', 'node_modules', '.bin', 'clear')
|
||||
path.join('npm', 'node_modules', '.bin', 'starwars')
|
||||
path.join('bootstrap', 'examples')
|
||||
path.join('pegjs', 'examples')
|
||||
path.join('plist', 'tests')
|
||||
path.join('xmldom', 'test')
|
||||
path.join('jasmine-reporters', 'ext')
|
||||
path.join('jasmine-node', 'node_modules', 'gaze')
|
||||
path.join('jasmine-node', 'spec')
|
||||
path.join('node_modules', 'nan')
|
||||
path.join('build', 'binding.Makefile')
|
||||
path.join('build', 'config.gypi')
|
||||
path.join('build', 'gyp-mac-tool')
|
||||
path.join('build', 'Makefile')
|
||||
path.join('build', 'Release', 'obj.target')
|
||||
path.join('build', 'Release', 'obj')
|
||||
path.join('build', 'Release', '.deps')
|
||||
path.join('vendor', 'apm')
|
||||
path.join('resources', 'mac')
|
||||
path.join('resources', 'win')
|
||||
|
||||
# These are only require in dev mode when the grammar isn't precompiled
|
||||
path.join('atom-keymap', 'node_modules', 'loophole')
|
||||
path.join('atom-keymap', 'node_modules', 'pegjs')
|
||||
path.join('atom-keymap', 'node_modules', '.bin', 'pegjs')
|
||||
path.join('snippets', 'node_modules', 'loophole')
|
||||
path.join('snippets', 'node_modules', 'pegjs')
|
||||
path.join('snippets', 'node_modules', '.bin', 'pegjs')
|
||||
|
||||
'.DS_Store'
|
||||
'.jshintrc'
|
||||
'.npmignore'
|
||||
'.pairs'
|
||||
'.travis.yml'
|
||||
]
|
||||
ignoredPaths = ignoredPaths.map (ignoredPath) -> _.escapeRegExp(ignoredPath)
|
||||
|
||||
@@ -91,56 +65,21 @@ module.exports = (grunt) ->
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('spellchecker', 'vendor', 'hunspell') + path.sep)}.*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('build', 'Release') + path.sep)}.*\\.pdb"
|
||||
|
||||
# Ignore *.cc and *.h files from native modules
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('ctags', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('git-utils', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('keytar', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('nslog', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('oniguruma', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('pathwatcher', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('runas', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('scrollbar-style', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('spellchecker', 'src') + path.sep)}.*\\.(cc|h)*"
|
||||
|
||||
# Ignore build files
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.sep)}binding\\.gyp$"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.sep)}.+\\.target.mk$"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.sep)}linker\\.lock$"
|
||||
ignoredPaths.push "#{_.escapeRegExp(path.join('build', 'Release') + path.sep)}.+\\.node\\.dSYM"
|
||||
|
||||
# Hunspell dictionaries are only not needed on OS X.
|
||||
if process.platform is 'darwin'
|
||||
ignoredPaths.push path.join('spellchecker', 'vendor', 'hunspell_dictionaries')
|
||||
ignoredPaths = ignoredPaths.map (ignoredPath) -> "(#{ignoredPath})"
|
||||
|
||||
testFolderPattern = new RegExp("#{_.escapeRegExp(path.sep)}te?sts?#{_.escapeRegExp(path.sep)}")
|
||||
exampleFolderPattern = new RegExp("#{_.escapeRegExp(path.sep)}examples?#{_.escapeRegExp(path.sep)}")
|
||||
benchmarkFolderPattern = new RegExp("#{_.escapeRegExp(path.sep)}benchmarks?#{_.escapeRegExp(path.sep)}")
|
||||
|
||||
nodeModulesFilter = new RegExp(ignoredPaths.join('|'))
|
||||
filterNodeModule = (pathToCopy) ->
|
||||
return true if benchmarkFolderPattern.test(pathToCopy)
|
||||
|
||||
pathToCopy = path.resolve(pathToCopy)
|
||||
nodeModulesFilter.test(pathToCopy) or testFolderPattern.test(pathToCopy) or exampleFolderPattern.test(pathToCopy)
|
||||
|
||||
packageFilter = new RegExp("(#{ignoredPaths.join('|')})|(.+\\.(cson|coffee)$)")
|
||||
filterPackage = (pathToCopy) ->
|
||||
return true if benchmarkFolderPattern.test(pathToCopy)
|
||||
|
||||
pathToCopy = path.resolve(pathToCopy)
|
||||
packageFilter.test(pathToCopy) or testFolderPattern.test(pathToCopy) or exampleFolderPattern.test(pathToCopy)
|
||||
|
||||
for directory in nonPackageDirectories
|
||||
cp directory, path.join(appDir, directory), filter: filterNodeModule
|
||||
|
||||
cp directory, path.join(appDir, directory), filter: nodeModulesFilter
|
||||
for directory in packageDirectories
|
||||
cp directory, path.join(appDir, directory), filter: filterPackage
|
||||
cp directory, path.join(appDir, directory), filter: packageFilter
|
||||
|
||||
cp 'spec', path.join(appDir, 'spec')
|
||||
cp 'src', path.join(appDir, 'src'), filter: /.+\.(cson|coffee)$/
|
||||
cp 'static', path.join(appDir, 'static')
|
||||
cp 'apm', path.join(appDir, 'apm'), filter: filterNodeModule
|
||||
cp 'apm', path.join(appDir, 'apm'), filter: nodeModulesFilter
|
||||
|
||||
if process.platform is 'darwin'
|
||||
grunt.file.recurse path.join('resources', 'mac'), (sourcePath, rootDirectory, subDirectory='', filename) ->
|
||||
@@ -148,10 +87,8 @@ module.exports = (grunt) ->
|
||||
grunt.file.copy(sourcePath, path.resolve(appDir, '..', subDirectory, filename))
|
||||
|
||||
if process.platform is 'win32'
|
||||
# Set up chocolatey ignore and gui files
|
||||
fs.writeFileSync path.join(appDir, 'apm', 'node_modules', 'atom-package-manager', 'bin', 'node.exe.ignore'), ''
|
||||
fs.writeFileSync path.join(appDir, 'node_modules', 'symbols-view', 'vendor', 'ctags-win32.exe.ignore'), ''
|
||||
fs.writeFileSync path.join(shellAppDir, 'atom.exe.gui'), ''
|
||||
cp path.join('resources', 'win', 'msvcp100.dll'), path.join(shellAppDir, 'msvcp100.dll')
|
||||
cp path.join('resources', 'win', 'msvcr100.dll'), path.join(shellAppDir, 'msvcr100.dll')
|
||||
|
||||
dependencies = ['compile', "generate-license:save"]
|
||||
dependencies.push('copy-info-plist') if process.platform is 'darwin'
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{spawn} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'codesign', 'Codesign the app', ->
|
||||
return unless process.platform is 'darwin'
|
||||
|
||||
done = @async()
|
||||
|
||||
if process.platform is 'darwin' and process.env.XCODE_KEYCHAIN
|
||||
if process.env.XCODE_KEYCHAIN
|
||||
unlockKeychain (error) ->
|
||||
if error?
|
||||
done(error)
|
||||
@@ -23,24 +22,6 @@ module.exports = (grunt) ->
|
||||
spawn {cmd, args}, (error) -> callback(error)
|
||||
|
||||
signApp = (callback) ->
|
||||
switch process.platform
|
||||
when 'darwin'
|
||||
cmd = 'codesign'
|
||||
args = ['--deep', '--force', '--verbose', '--sign', 'Developer ID Application: GitHub', grunt.config.get('atom.shellAppDir')]
|
||||
spawn {cmd, args}, (error) -> callback(error)
|
||||
when 'win32'
|
||||
spawn {cmd: 'taskkill', args: ['/F', '/IM', 'atom.exe']}, ->
|
||||
cmd = process.env.JANKY_SIGNTOOL ? 'signtool'
|
||||
args = [path.join(grunt.config.get('atom.shellAppDir'), 'atom.exe')]
|
||||
|
||||
spawn {cmd, args}, (error) ->
|
||||
return callback(error) if error?
|
||||
|
||||
setupExePath = path.join(grunt.config.get('atom.shellAppDir'), '..', 'Releases', 'setup.exe')
|
||||
if fs.isFileSync(setupExePath)
|
||||
args = [setupExePath]
|
||||
spawn {cmd, args}, (error) -> callback(error)
|
||||
else
|
||||
callback()
|
||||
else
|
||||
callback()
|
||||
cmd = 'codesign'
|
||||
args = ['-f', '-v', '-s', 'Developer ID Application: GitHub', grunt.config.get('atom.shellAppDir')]
|
||||
spawn {cmd, args}, (error) -> callback(error)
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{spawn, rm} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'create-installer', 'Create the Windows installer', ->
|
||||
return unless process.platform is 'win32'
|
||||
|
||||
done = @async()
|
||||
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
atomDir = path.join(buildDir, 'Atom')
|
||||
|
||||
packageInfo = grunt.file.readJSON(path.join(atomDir, 'resources', 'app', 'package.json'))
|
||||
inputTemplate = grunt.file.read(path.join('build', 'windows', 'atom.nuspec.erb'))
|
||||
|
||||
# NB: Build server has some sort of stamp on the version number
|
||||
packageInfo.version = packageInfo.version.replace(/-.*$/, '')
|
||||
|
||||
targetNuspecPath = path.join(buildDir, 'atom.nuspec')
|
||||
grunt.file.write(targetNuspecPath, _.template(inputTemplate, packageInfo))
|
||||
|
||||
cmd = 'build/windows/nuget.exe'
|
||||
args = ['pack', targetNuspecPath, '-BasePath', atomDir, '-OutputDirectory', buildDir]
|
||||
|
||||
spawn {cmd, args}, (error, result, code) ->
|
||||
return done(error) if error?
|
||||
|
||||
pkgs = pkg for pkg in fs.readdirSync(buildDir) when path.extname(pkg) is '.nupkg'
|
||||
|
||||
releasesDir = path.join(buildDir, 'Releases')
|
||||
|
||||
# NB: Gonna clear Releases for now, in the future we need to pull down
|
||||
# the existing version
|
||||
rm(releasesDir)
|
||||
|
||||
cmd = 'build/windows/update.com'
|
||||
args = ['--releasify', path.join(buildDir, pkgs), '-r', releasesDir, '-g', 'build/windows/install-spinner.gif']
|
||||
spawn {cmd, args}, (error, result, code) -> done(error)
|
||||
+150
-30
@@ -1,40 +1,160 @@
|
||||
path = require 'path'
|
||||
|
||||
async = require 'async'
|
||||
fs = require 'fs-plus'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
donna = require 'donna'
|
||||
tello = require 'tello'
|
||||
request = require 'request'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
getClassesToInclude = ->
|
||||
modulesPath = path.resolve(__dirname, '..', '..', 'node_modules')
|
||||
classes = {}
|
||||
fs.traverseTreeSync modulesPath, (modulePath) ->
|
||||
return false if modulePath.match(/node_modules/g).length > 1 # dont need the dependencies of the dependencies
|
||||
return true unless path.basename(modulePath) is 'package.json'
|
||||
return true unless fs.isFileSync(modulePath)
|
||||
{rm} = require('./task-helpers')(grunt)
|
||||
|
||||
apiPath = path.join(path.dirname(modulePath), 'api.json')
|
||||
if fs.isFileSync(apiPath)
|
||||
_.extend(classes, grunt.file.readJSON(apiPath).classes)
|
||||
true
|
||||
classes
|
||||
|
||||
sortClasses = (classes) ->
|
||||
sortedClasses = {}
|
||||
for className in Object.keys(classes).sort()
|
||||
sortedClasses[className] = classes[className]
|
||||
sortedClasses
|
||||
cmd = path.join('node_modules', '.bin', 'coffee')
|
||||
commonArgs = [path.join('build', 'node_modules', '.bin', 'biscotto'), '--']
|
||||
opts =
|
||||
stdio: 'inherit'
|
||||
|
||||
grunt.registerTask 'build-docs', 'Builds the API docs in src', ->
|
||||
docsOutputDir = grunt.config.get('docsOutputDir')
|
||||
done = @async()
|
||||
|
||||
metadata = donna.generateMetadata(['.'])
|
||||
api = tello.digest(metadata)
|
||||
_.extend(api.classes, getClassesToInclude())
|
||||
api.classes = sortClasses(api.classes)
|
||||
downloadIncludes (error, includePaths) ->
|
||||
if error?
|
||||
done(error)
|
||||
else
|
||||
rm('docs/output/api')
|
||||
args = [
|
||||
commonArgs...
|
||||
'--title', 'Atom API Documentation'
|
||||
'-o', 'docs/output/api'
|
||||
'-r', 'docs/README.md'
|
||||
'--stability', '1'
|
||||
'src/'
|
||||
includePaths...
|
||||
]
|
||||
grunt.util.spawn({cmd, args, opts}, done)
|
||||
|
||||
apiJson = JSON.stringify(api, null, 2)
|
||||
apiJsonPath = path.join(docsOutputDir, 'api.json')
|
||||
grunt.file.write(apiJsonPath, apiJson)
|
||||
grunt.registerTask 'lint-docs', 'Generate stats about the doc coverage', ->
|
||||
done = @async()
|
||||
downloadIncludes (error, includePaths) ->
|
||||
if error?
|
||||
done(error)
|
||||
else
|
||||
args = [
|
||||
commonArgs...
|
||||
'--noOutput'
|
||||
'src/'
|
||||
includePaths...
|
||||
]
|
||||
grunt.util.spawn({cmd, args, opts}, done)
|
||||
|
||||
grunt.registerTask 'missing-docs', 'Generate stats about the doc coverage', ->
|
||||
done = @async()
|
||||
downloadIncludes (error, includePaths) ->
|
||||
if error?
|
||||
done(error)
|
||||
else
|
||||
args = [
|
||||
commonArgs...
|
||||
'--noOutput'
|
||||
'--missing'
|
||||
'src/'
|
||||
includePaths...
|
||||
]
|
||||
grunt.util.spawn({cmd, args, opts}, done)
|
||||
|
||||
grunt.registerTask 'copy-docs', 'Copies over latest API docs to atom-docs', ->
|
||||
done = @async()
|
||||
|
||||
fetchTag = (args..., callback) ->
|
||||
cmd = 'git'
|
||||
args = ['describe', '--abbrev=0', '--tags']
|
||||
grunt.util.spawn {cmd, args}, (error, result) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
callback(null, String(result).trim())
|
||||
|
||||
copyDocs = (tag, callback) ->
|
||||
cmd = 'cp'
|
||||
args = ['-r', 'docs/output/', "../atom.io/public/docs/api/#{tag}/"]
|
||||
|
||||
fs.exists "../atom.io/public/docs/api/", (exists) ->
|
||||
if exists
|
||||
grunt.util.spawn {cmd, args}, (error, result) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
callback(null, tag)
|
||||
else
|
||||
grunt.log.error "../atom.io/public/docs/api/ doesn't exist"
|
||||
return false
|
||||
|
||||
grunt.util.async.waterfall [fetchTag, copyDocs], done
|
||||
|
||||
grunt.registerTask 'deploy-docs', 'Publishes latest API docs to atom-docs.githubapp.com', ->
|
||||
done = @async()
|
||||
docsRepoArgs = ['--work-tree=../atom-docs/', '--git-dir=../atom-docs/.git/']
|
||||
|
||||
fetchTag = (args..., callback) ->
|
||||
cmd = 'git'
|
||||
args = ['describe', '--abbrev=0', '--tags']
|
||||
grunt.util.spawn {cmd, args}, (error, result) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
callback(null, String(result).trim().split('.')[0..1].join('.'))
|
||||
|
||||
stageDocs = (tag, callback) ->
|
||||
cmd = 'git'
|
||||
args = [docsRepoArgs..., 'add', "public/#{tag}"]
|
||||
grunt.util.spawn({cmd, args, opts}, callback)
|
||||
|
||||
fetchSha = (args..., callback) ->
|
||||
cmd = 'git'
|
||||
args = ['rev-parse', 'HEAD']
|
||||
grunt.util.spawn {cmd, args}, (error, result) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
callback(null, String(result).trim())
|
||||
|
||||
commitChanges = (sha, callback) ->
|
||||
cmd = 'git'
|
||||
args = [docsRepoArgs..., 'commit', "-m Update API docs to #{sha}"]
|
||||
grunt.util.spawn({cmd, args, opts}, callback)
|
||||
|
||||
pushOrigin = (args..., callback) ->
|
||||
cmd = 'git'
|
||||
args = [docsRepoArgs..., 'push', 'origin', 'master']
|
||||
grunt.util.spawn({cmd, args, opts}, callback)
|
||||
|
||||
pushHeroku = (args..., callback) ->
|
||||
cmd = 'git'
|
||||
args = [docsRepoArgs..., 'push', 'heroku', 'master']
|
||||
grunt.util.spawn({cmd, args, opts}, callback)
|
||||
|
||||
grunt.util.async.waterfall [fetchTag, stageDocs, fetchSha, commitChanges, pushOrigin, pushHeroku], done
|
||||
|
||||
downloadFileFromRepo = ({repo, file}, callback) ->
|
||||
uri = "https://raw.github.com/atom/#{repo}/master/#{file}"
|
||||
request uri, (error, response, contents) ->
|
||||
return callback(error) if error?
|
||||
downloadPath = path.join('docs', 'includes', repo, file)
|
||||
fs.writeFile downloadPath, contents, (error) ->
|
||||
callback(error, downloadPath)
|
||||
|
||||
downloadIncludes = (callback) ->
|
||||
includes = [
|
||||
{repo: 'atom-keymap', file: 'src/keymap-manager.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'}
|
||||
{repo: 'node-pathwatcher', file: 'src/file.coffee'}
|
||||
{repo: 'space-pen', file: 'src/space-pen.coffee'}
|
||||
{repo: 'text-buffer', file: 'src/marker.coffee'}
|
||||
{repo: 'text-buffer', file: 'src/point.coffee'}
|
||||
{repo: 'text-buffer', file: 'src/range.coffee'}
|
||||
{repo: 'text-buffer', file: 'src/text-buffer.coffee'}
|
||||
{repo: 'theorist', file: 'src/model.coffee'}
|
||||
]
|
||||
|
||||
async.map(includes, downloadFileFromRepo, callback)
|
||||
|
||||
@@ -3,7 +3,11 @@ path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
runas = null
|
||||
temp = require 'temp'
|
||||
|
||||
fillTemplate = (filePath, data) ->
|
||||
template = _.template(String(fs.readFileSync(filePath + '.in')))
|
||||
filled = template(data)
|
||||
fs.writeFileSync(filePath, filled)
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{cp, mkdir, rm} = require('./task-helpers')(grunt)
|
||||
@@ -11,7 +15,6 @@ module.exports = (grunt) ->
|
||||
grunt.registerTask 'install', 'Install the built application', ->
|
||||
installDir = grunt.config.get('atom.installDir')
|
||||
shellAppDir = grunt.config.get('atom.shellAppDir')
|
||||
|
||||
if process.platform is 'win32'
|
||||
runas ?= require 'runas'
|
||||
copyFolder = path.resolve 'script', 'copy-folder.cmd'
|
||||
@@ -23,16 +26,13 @@ module.exports = (grunt) ->
|
||||
else if process.platform is 'darwin'
|
||||
rm installDir
|
||||
mkdir path.dirname(installDir)
|
||||
|
||||
tempFolder = temp.path()
|
||||
mkdir tempFolder
|
||||
cp shellAppDir, tempFolder
|
||||
fs.renameSync(tempFolder, installDir)
|
||||
cp shellAppDir, installDir
|
||||
else
|
||||
binDir = path.join(installDir, 'bin')
|
||||
shareDir = path.join(installDir, 'share', 'atom')
|
||||
|
||||
iconName = path.join(shareDir,'resources','app','resources','atom.png')
|
||||
desktopFile = path.join('resources', 'linux', 'Atom.desktop')
|
||||
|
||||
mkdir binDir
|
||||
cp 'atom.sh', path.join(binDir, 'atom')
|
||||
@@ -40,19 +40,13 @@ module.exports = (grunt) ->
|
||||
mkdir path.dirname(shareDir)
|
||||
cp shellAppDir, shareDir
|
||||
|
||||
# Create Atom.desktop if installation not in temporary folder
|
||||
# Create Atom.desktop if installation in '/usr/local'
|
||||
applicationsDir = path.join('/usr','share','applications')
|
||||
tmpDir = if process.env.TMPDIR? then process.env.TMPDIR else '/tmp'
|
||||
if installDir.indexOf(tmpDir) isnt 0
|
||||
desktopFile = path.join('resources', 'linux', 'Atom.desktop.in')
|
||||
desktopInstallFile = path.join(installDir, 'share', 'applications', 'Atom.desktop')
|
||||
|
||||
if installDir.indexOf(tmpDir) isnt 0 and fs.isDirectorySync(applicationsDir)
|
||||
{description} = grunt.file.readJSON('package.json')
|
||||
iconName = path.join(shareDir, 'resources', 'app', 'resources', 'atom.png')
|
||||
installDir = path.join(installDir, '.') # To prevent "Exec=/usr/local//share/atom/atom"
|
||||
template = _.template(String(fs.readFileSync(desktopFile)))
|
||||
filled = template({description, installDir, iconName})
|
||||
|
||||
grunt.file.write(desktopInstallFile, filled)
|
||||
fillTemplate(desktopFile, {description, installDir, iconName})
|
||||
cp desktopFile, path.join(applicationsDir,'Atom.desktop')
|
||||
|
||||
# Create relative symbol link for apm.
|
||||
process.chdir(binDir)
|
||||
|
||||
@@ -2,27 +2,16 @@ 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)
|
||||
|
||||
fillTemplate = (filePath, data) ->
|
||||
template = _.template(String(fs.readFileSync("#{filePath}.in")))
|
||||
filled = template(data)
|
||||
|
||||
outputPath = path.join(grunt.config.get('atom.buildDir'), path.basename(filePath))
|
||||
grunt.file.write(outputPath, filled)
|
||||
outputPath
|
||||
|
||||
getInstalledSize = (buildDir, callback) ->
|
||||
cmd = 'du'
|
||||
args = ['-sk', path.join(buildDir, 'Atom')]
|
||||
spawn {cmd, args}, (error, {stdout}) ->
|
||||
installedSize = stdout.split(/\s+/)?[0] or '200000' # default to 200MB
|
||||
callback(null, installedSize)
|
||||
|
||||
grunt.registerTask 'mkdeb', 'Create debian package', ->
|
||||
done = @async()
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
|
||||
if process.arch is 'ia32'
|
||||
arch = 'i386'
|
||||
@@ -36,17 +25,15 @@ module.exports = (grunt) ->
|
||||
maintainer = 'GitHub <atom@github.com>'
|
||||
installDir = '/usr'
|
||||
iconName = 'atom'
|
||||
getInstalledSize buildDir, (error, installedSize) ->
|
||||
data = {name, version, description, section, arch, maintainer, installDir, iconName, installedSize}
|
||||
controlFilePath = fillTemplate(path.join('resources', 'linux', 'debian', 'control'), data)
|
||||
desktopFilePath = fillTemplate(path.join('resources', 'linux', 'Atom.desktop'), data)
|
||||
icon = path.join('resources', 'atom.png')
|
||||
data = {name, version, description, section, arch, maintainer, installDir, iconName}
|
||||
|
||||
cmd = path.join('script', 'mkdeb')
|
||||
args = [version, arch, controlFilePath, desktopFilePath, icon, buildDir]
|
||||
spawn {cmd, args}, (error) ->
|
||||
if error?
|
||||
done(error)
|
||||
else
|
||||
grunt.log.ok "Created #{buildDir}/atom-#{version}-#{arch}.deb"
|
||||
done()
|
||||
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, arch, control, desktop, icon, buildDir]
|
||||
spawn({cmd, args}, done)
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
path = require 'path'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
grunt.registerTask 'output-build-filetypes', 'Log counts for each filetype in the built application', ->
|
||||
shellAppDir = grunt.config.get('atom.shellAppDir')
|
||||
|
||||
types = {}
|
||||
grunt.file.recurse shellAppDir, (absolutePath, rootPath, relativePath, fileName) ->
|
||||
extension = path.extname(fileName) or fileName
|
||||
types[extension] ?= 0
|
||||
types[extension]++
|
||||
|
||||
extensions = Object.keys(types).sort (extension1, extension2) ->
|
||||
diff = types[extension2] - types[extension1]
|
||||
if diff is 0
|
||||
extension1.toLowerCase().localeCompare(extension2.toLowerCase())
|
||||
else
|
||||
diff
|
||||
|
||||
extensions.forEach (extension) ->
|
||||
grunt.log.error "#{extension}: #{types[extension]}"
|
||||
@@ -1,18 +0,0 @@
|
||||
path = require 'path'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
grunt.registerTask 'output-long-paths', 'Log long paths in the built application', ->
|
||||
shellAppDir = grunt.config.get('atom.shellAppDir')
|
||||
|
||||
longPaths = []
|
||||
grunt.file.recurse shellAppDir, (absolutePath, rootPath, relativePath, fileName) ->
|
||||
if relativePath
|
||||
fullPath = path.join(relativePath, fileName)
|
||||
else
|
||||
fullPath = fileName
|
||||
longPaths.push(fullPath) if fullPath.length >= 200
|
||||
|
||||
longPaths.sort (longPath1, longPath2) -> longPath2.length - longPath1.length
|
||||
|
||||
longPaths.forEach (longPath) ->
|
||||
grunt.log.error "#{longPath.length} character path: #{longPath}"
|
||||
@@ -9,12 +9,10 @@ module.exports = (grunt) ->
|
||||
['atom-dark-ui', 'atom-light-syntax']
|
||||
['atom-dark-ui', 'solarized-dark-syntax']
|
||||
['atom-dark-ui', 'base16-tomorrow-dark-theme']
|
||||
['atom-dark-ui', 'base16-tomorrow-light-theme']
|
||||
['atom-light-ui', 'atom-light-syntax']
|
||||
['atom-light-ui', 'atom-dark-syntax']
|
||||
['atom-light-ui', 'solarized-dark-syntax']
|
||||
['atom-light-ui', 'base16-tomorrow-dark-theme']
|
||||
['atom-light-ui', 'base16-tomorrow-light-theme']
|
||||
]
|
||||
|
||||
directory = path.join(grunt.config.get('atom.appDir'), 'less-compile-cache')
|
||||
|
||||
@@ -9,6 +9,16 @@ request = require 'request'
|
||||
|
||||
grunt = null
|
||||
|
||||
if process.platform is 'darwin'
|
||||
assets = [
|
||||
{assetName: 'atom-mac.zip', sourceName: 'Atom.app'}
|
||||
{assetName: 'atom-mac-symbols.zip', sourceName: 'Atom.breakpad.syms'}
|
||||
]
|
||||
else
|
||||
assets = [
|
||||
{assetName: 'atom-windows.zip', sourceName: 'Atom'}
|
||||
]
|
||||
|
||||
commitSha = process.env.JANKY_SHA1
|
||||
token = process.env.ATOM_ACCESS_TOKEN
|
||||
defaultHeaders =
|
||||
@@ -17,25 +27,14 @@ defaultHeaders =
|
||||
|
||||
module.exports = (gruntObject) ->
|
||||
grunt = gruntObject
|
||||
{cp} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'publish-build', 'Publish the built app', ->
|
||||
return if process.env.JANKY_SHA1 and process.env.JANKY_BRANCH isnt 'master'
|
||||
tasks = ['upload-assets']
|
||||
tasks.unshift('build-docs', 'prepare-docs') if process.platform is 'darwin'
|
||||
grunt.task.run(tasks)
|
||||
|
||||
grunt.registerTask 'prepare-docs', 'Move api.json to atom-api.json', ->
|
||||
docsOutputDir = grunt.config.get('docsOutputDir')
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
cp path.join(docsOutputDir, 'api.json'), path.join(buildDir, 'atom-api.json')
|
||||
|
||||
grunt.registerTask 'upload-assets', 'Upload the assets to a GitHub release', ->
|
||||
done = @async()
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
assets = getAssets()
|
||||
|
||||
zipAssets buildDir, assets, (error) ->
|
||||
zipApps buildDir, assets, (error) ->
|
||||
return done(error) if error?
|
||||
getAtomDraftRelease (error, release) ->
|
||||
return done(error) if error?
|
||||
@@ -44,55 +43,26 @@ module.exports = (gruntObject) ->
|
||||
return done(error) if error?
|
||||
uploadAssets(release, buildDir, assets, done)
|
||||
|
||||
getAssets = ->
|
||||
switch process.platform
|
||||
when 'darwin'
|
||||
[
|
||||
{assetName: 'atom-mac.zip', sourcePath: 'Atom.app'}
|
||||
{assetName: 'atom-mac-symbols.zip', sourcePath: 'Atom.breakpad.syms'}
|
||||
{assetName: 'atom-api.json', sourcePath: 'atom-api.json'}
|
||||
]
|
||||
when 'win32'
|
||||
[
|
||||
{assetName: 'atom-windows.zip', sourcePath: 'Atom'}
|
||||
]
|
||||
when 'linux'
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
if process.arch is 'ia32'
|
||||
arch = 'i386'
|
||||
else
|
||||
arch = 'amd64'
|
||||
{version} = grunt.file.readJSON('package.json')
|
||||
sourcePath = "#{buildDir}/atom-#{version}-#{arch}.deb"
|
||||
assetName = "atom-#{arch}.deb"
|
||||
|
||||
{cp} = require('./task-helpers')(grunt)
|
||||
cp sourcePath, path.join(buildDir, assetName)
|
||||
|
||||
[
|
||||
{assetName, sourcePath}
|
||||
]
|
||||
|
||||
logError = (message, error, details) ->
|
||||
grunt.log.error(message)
|
||||
grunt.log.error(error.message ? error) if error?
|
||||
grunt.log.error(details) if details
|
||||
|
||||
zipAssets = (buildDir, assets, callback) ->
|
||||
zip = (directory, sourcePath, assetName, callback) ->
|
||||
zipApps = (buildDir, assets, callback) ->
|
||||
zip = (directory, sourceName, assetName, callback) ->
|
||||
if process.platform is 'win32'
|
||||
zipCommand = "C:/psmodules/7z.exe a -r #{assetName} #{sourcePath}"
|
||||
zipCommand = "C:/psmodules/7z.exe a -r #{assetName} #{sourceName}"
|
||||
else
|
||||
zipCommand = "zip -r --symlinks #{assetName} #{sourcePath}"
|
||||
zipCommand = "zip -r --symlinks #{assetName} #{sourceName}"
|
||||
options = {cwd: directory, maxBuffer: Infinity}
|
||||
child_process.exec zipCommand, options, (error, stdout, stderr) ->
|
||||
logError("Zipping #{sourcePath} failed", error, stderr) if error?
|
||||
logError("Zipping #{sourceName} failed", error, stderr) if error?
|
||||
callback(error)
|
||||
|
||||
tasks = []
|
||||
for {assetName, sourcePath} in assets when path.extname(assetName) is '.zip'
|
||||
for {assetName, sourceName} in assets
|
||||
fs.removeSync(path.join(buildDir, assetName))
|
||||
tasks.push(zip.bind(this, buildDir, sourcePath, assetName))
|
||||
tasks.push(zip.bind(this, buildDir, sourceName, assetName))
|
||||
async.parallel(tasks, callback)
|
||||
|
||||
getAtomDraftRelease = (callback) ->
|
||||
@@ -157,7 +127,7 @@ uploadAssets = (release, buildDir, assets, callback) ->
|
||||
fs.createReadStream(assetPath).pipe(assetRequest)
|
||||
|
||||
tasks = []
|
||||
for {assetName} in assets
|
||||
for {assetName, sourceName} in assets
|
||||
assetPath = path.join(buildDir, assetName)
|
||||
tasks.push(upload.bind(this, release, assetName, assetPath))
|
||||
async.parallel(tasks, callback)
|
||||
|
||||
@@ -45,8 +45,8 @@ module.exports = (grunt) ->
|
||||
|
||||
strings =
|
||||
CompanyName: 'GitHub, Inc.'
|
||||
FileDescription: 'Atom'
|
||||
LegalCopyright: 'Copyright (C) 2014 GitHub, Inc. All rights reserved'
|
||||
FileDescription: 'The hackable editor'
|
||||
LegalCopyright: 'Copyright (C) 2013 GitHub, Inc. All rights reserved'
|
||||
ProductName: 'Atom'
|
||||
ProductVersion: version
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ fs = require 'fs'
|
||||
path = require 'path'
|
||||
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
async = require 'async'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
@@ -9,27 +10,18 @@ module.exports = (grunt) ->
|
||||
|
||||
packageSpecQueue = null
|
||||
|
||||
getAppPath = ->
|
||||
contentsDir = grunt.config.get('atom.contentsDir')
|
||||
switch process.platform
|
||||
when 'darwin'
|
||||
path.join(contentsDir, 'MacOS', 'Atom')
|
||||
when 'linux'
|
||||
path.join(contentsDir, 'atom')
|
||||
when 'win32'
|
||||
path.join(contentsDir, 'atom.exe')
|
||||
|
||||
runPackageSpecs = (callback) ->
|
||||
failedPackages = []
|
||||
rootDir = grunt.config.get('atom.shellAppDir')
|
||||
contentsDir = grunt.config.get('atom.contentsDir')
|
||||
resourcePath = process.cwd()
|
||||
appPath = getAppPath()
|
||||
|
||||
# Ensure application is executable on Linux
|
||||
fs.chmodSync(appPath, '755') if process.platform is 'linux'
|
||||
if process.platform is 'darwin'
|
||||
appPath = path.join(contentsDir, 'MacOS', 'Atom')
|
||||
else if process.platform is 'win32'
|
||||
appPath = path.join(contentsDir, 'atom.exe')
|
||||
|
||||
packageSpecQueue = async.queue (packagePath, callback) ->
|
||||
if process.platform in ['darwin', 'linux']
|
||||
if process.platform is 'darwin'
|
||||
options =
|
||||
cmd: appPath
|
||||
args: ['--test', "--resource-path=#{resourcePath}", "--spec-directory=#{path.join(packagePath, 'spec')}"]
|
||||
@@ -61,15 +53,21 @@ module.exports = (grunt) ->
|
||||
continue unless isAtomPackage(packagePath)
|
||||
packageSpecQueue.push(packagePath)
|
||||
|
||||
packageSpecQueue.concurrency = 1
|
||||
# TODO: Restore concurrency on Windows
|
||||
packageSpecQueue.concurrency = 1 unless process.platform is 'win32'
|
||||
|
||||
packageSpecQueue.drain = -> callback(null, failedPackages)
|
||||
|
||||
runCoreSpecs = (callback) ->
|
||||
appPath = getAppPath()
|
||||
contentsDir = grunt.config.get('atom.contentsDir')
|
||||
if process.platform is 'darwin'
|
||||
appPath = path.join(contentsDir, 'MacOS', 'Atom')
|
||||
else if process.platform is 'win32'
|
||||
appPath = path.join(contentsDir, 'atom.exe')
|
||||
resourcePath = process.cwd()
|
||||
coreSpecsPath = path.resolve('spec')
|
||||
|
||||
if process.platform in ['darwin', 'linux']
|
||||
if process.platform is 'darwin'
|
||||
options =
|
||||
cmd: appPath
|
||||
args: ['--test', "--resource-path=#{resourcePath}", "--spec-directory=#{coreSpecsPath}"]
|
||||
@@ -94,7 +92,7 @@ module.exports = (grunt) ->
|
||||
|
||||
# TODO: This should really be parallel on both platforms, however our
|
||||
# fixtures step on each others toes currently.
|
||||
if process.platform in ['darwin', 'linux']
|
||||
if process.platform is 'darwin'
|
||||
method = async.parallel
|
||||
else if process.platform is 'win32'
|
||||
method = async.series
|
||||
@@ -107,8 +105,4 @@ module.exports = (grunt) ->
|
||||
failures.push "atom core" if coreSpecFailed
|
||||
|
||||
grunt.log.error("[Error]".red + " #{failures.join(', ')} spec(s) failed") if failures.length > 0
|
||||
|
||||
if process.platform is 'win32' and process.env.JANKY_SHA1
|
||||
done()
|
||||
else
|
||||
done(!coreSpecFailed and failedPackages.length == 0)
|
||||
done(!coreSpecFailed and failedPackages.length == 0)
|
||||
|
||||
@@ -7,7 +7,7 @@ module.exports = (grunt) ->
|
||||
grunt.fatal("Cannot copy non-existent #{source.cyan} to #{destination.cyan}")
|
||||
|
||||
copyFile = (sourcePath, destinationPath) ->
|
||||
return if filter?(sourcePath) or filter?.test?(sourcePath)
|
||||
return if filter?.test(sourcePath)
|
||||
|
||||
stats = fs.lstatSync(sourcePath)
|
||||
if stats.isSymbolicLink()
|
||||
@@ -53,9 +53,8 @@ module.exports = (grunt) ->
|
||||
proc = childProcess.spawn(options.cmd, options.args, options.opts)
|
||||
proc.stdout.on 'data', (data) -> stdout.push(data.toString())
|
||||
proc.stderr.on 'data', (data) -> stderr.push(data.toString())
|
||||
proc.on 'error', (processError) -> error ?= processError
|
||||
proc.on 'close', (exitCode, signal) ->
|
||||
error ?= new Error(signal) if exitCode != 0
|
||||
error = new Error(signal) if exitCode != 0
|
||||
results = {stderr: stderr.join(''), stdout: stdout.join(''), code: exitCode}
|
||||
grunt.log.error results.stderr if exitCode != 0
|
||||
callback(error, results, exitCode)
|
||||
|
||||
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
@@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id><%= name %></id>
|
||||
<version><%= version %></version>
|
||||
<authors>The Atom Community</authors>
|
||||
<owners>The Atom Community</owners>
|
||||
<iconUrl>https://raw.githubusercontent.com/atom/atom/master/resources/win/atom.ico</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description><%= description %></description>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="locales\**" target="lib\net45\locales" />
|
||||
<file src="resources\**" target="lib\net45\resources" />
|
||||
<file src="*.pak" target="lib\net45" />
|
||||
|
||||
<file src="atom.exe" target="lib\net45\atom.exe" />
|
||||
<file src="atom.exe.gui" target="lib\net45\atom.exe.gui" />
|
||||
<file src="chromiumcontent.dll" target="lib\net45\chromiumcontent.dll" />
|
||||
<file src="d3dcompiler_43.dll" target="lib\net45\d3dcompiler_43.dll" />
|
||||
<file src="ffmpegsumo.dll" target="lib\net45\ffmpegsumo.dll" />
|
||||
<file src="icudtl.dat" target="lib\net45\icudtl.dat" />
|
||||
<file src="libEGL.dll" target="lib\net45\libEGL.dll" />
|
||||
<file src="libGLESv2.dll" target="lib\net45\libGLESv2.dll" />
|
||||
<file src="LICENSE" target="lib\net45\LICENSE" />
|
||||
<file src="msvcp120.dll" target="lib\net45\msvcp120.dll" />
|
||||
<file src="msvcr120.dll" target="lib\net45\msvcr120.dll" />
|
||||
<file src="vccorlib120.dll" target="lib\net45\vccorlib120.dll" />
|
||||
<file src="version" target="lib\net45\version" />
|
||||
<file src="xinput1_3.dll" target="lib\net45\xinput1_3.dll" />
|
||||
</files>
|
||||
</package>
|
||||
Arquivo binário não exibido.
|
Antes Largura: | Altura: | Tamanho: 43 KiB |
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"max_line_length": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"no_empty_param_list": {
|
||||
"level": "error"
|
||||
},
|
||||
"arrow_spacing": {
|
||||
"level": "error"
|
||||
},
|
||||
"no_interpolation_in_single_quotes": {
|
||||
"level": "error"
|
||||
},
|
||||
"no_debugger": {
|
||||
"level": "error"
|
||||
}
|
||||
}
|
||||
@@ -11,31 +11,41 @@ value of a namespaced config key with `atom.config.get`:
|
||||
@showInvisibles() if atom.config.get "editor.showInvisibles"
|
||||
```
|
||||
|
||||
Or you can use the `::subscribe` with `atom.config.observe` to track changes
|
||||
from any view object.
|
||||
Or you can use the `::observeConfig` to track changes from any view object.
|
||||
|
||||
```coffeescript
|
||||
class MyView extends View
|
||||
initialize: ->
|
||||
@subscribe atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
|
||||
@observeConfig 'editor.fontSize', () =>
|
||||
@adjustFontSize()
|
||||
```
|
||||
|
||||
The `atom.config.observe` method will call the given callback immediately with
|
||||
the current value for the specified key path, and it will also call it in the
|
||||
future whenever the value of that key path changes.
|
||||
The `::observeConfig` method will call the given callback immediately with the
|
||||
current value for the specified key path, and it will also call it in the future
|
||||
whenever the value of that key path changes.
|
||||
|
||||
Subscriptions made with `::subscribe` are automatically canceled when the
|
||||
Subscriptions made with `observeConfig` are automatically canceled when the
|
||||
view is removed. You can cancel config subscriptions manually via the
|
||||
`off` method on the subscription object that `atom.config.observe` returns.
|
||||
`unobserveConfig` method.
|
||||
|
||||
```coffeescript
|
||||
fontSizeSubscription = atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
|
||||
@adjustFontSize()
|
||||
view1.unobserveConfig() # unobserve all properties
|
||||
```
|
||||
|
||||
# ... later on
|
||||
You can add the ability to observe config values to non-view classes by
|
||||
extending their prototype with the `ConfigObserver` mixin:
|
||||
|
||||
fontSizeSubscription.off() # Stop observing
|
||||
```coffeescript
|
||||
{ConfigObserver} = require 'atom'
|
||||
|
||||
class MyClass
|
||||
ConfigObserver.includeInto(this)
|
||||
|
||||
constructor: ->
|
||||
@observeConfig 'editor.showInvisibles', -> # ...
|
||||
|
||||
destroy: ->
|
||||
@unobserveConfig()
|
||||
```
|
||||
|
||||
### Writing Config Settings
|
||||
@@ -48,6 +58,15 @@ but you can programmatically write to it with `atom.config.set`:
|
||||
atom.config.set("core.showInvisibles", true)
|
||||
```
|
||||
|
||||
You should never mutate the value of a config key, because that would circumvent
|
||||
the notification of observers. You can however use methods like `pushAtKeyPath`,
|
||||
`unshiftAtKeyPath`, and `removeAtKeyPath` to manipulate mutable config values.
|
||||
|
||||
```coffeescript
|
||||
atom.config.pushAtKeyPath("core.disabledPackages", "wrap-guide")
|
||||
atom.config.removeAtKeyPath("core.disabledPackages", "terminal")
|
||||
```
|
||||
|
||||
You can also use `setDefaults`, which will assign default values for keys that
|
||||
are always overridden by values assigned with `set`. Defaults are not written
|
||||
out to the the `config.json` file to prevent it from becoming cluttered.
|
||||
|
||||
@@ -56,7 +56,7 @@ character of the current line:
|
||||
class EditorView
|
||||
listenForEvents: ->
|
||||
@command 'editor:move-to-first-character-of-line', =>
|
||||
@editor.moveToFirstCharacterOfLine()
|
||||
@editor.moveCursorToFirstCharacterOfLine()
|
||||
```
|
||||
|
||||
The `::command` method is basically an enhanced version of jQuery's `::on`
|
||||
|
||||
+10
-65
@@ -1,4 +1,4 @@
|
||||
# Atom.io package and update API
|
||||
## Atom.io package and update API
|
||||
|
||||
This guide describes the web API used by [apm](https://github.com/atom/apm) and
|
||||
Atom. The vast majority of use cases are met by the `apm` command-line tool,
|
||||
@@ -8,8 +8,6 @@ and making sure you have pushed your git tag. In fact, Atom itself shells out to
|
||||
uses `apm`, see the [PackageManager class](https://github.com/atom/settings-view/blob/master/lib/package-manager.coffee)
|
||||
in the `settings-view` package.
|
||||
|
||||
*This API should be considered pre-release and is subject to change (though significant breaking changes are unlikely).*
|
||||
|
||||
### Authorization
|
||||
|
||||
For calls to the API that require authentication, provide a valid token from your
|
||||
@@ -19,18 +17,12 @@ For calls to the API that require authentication, provide a valid token from you
|
||||
|
||||
All requests that take parameters require `application/json`.
|
||||
|
||||
# API Resources
|
||||
## Resources
|
||||
|
||||
## Packages
|
||||
|
||||
### Listing packages
|
||||
### Packages
|
||||
|
||||
#### GET /api/packages
|
||||
|
||||
Parameters:
|
||||
|
||||
- **page** (optional)
|
||||
|
||||
Returns a list of all packages in the following format:
|
||||
```json
|
||||
[
|
||||
@@ -48,17 +40,6 @@ Returns a list of all packages in the following format:
|
||||
]
|
||||
```
|
||||
|
||||
Results are paginated 30 at a time, and links to the next and last pages are
|
||||
provided in the `Link` header:
|
||||
|
||||
```
|
||||
Link: <https://www.atom.io/api/packages?page=1>; rel="self",
|
||||
<https://www.atom.io/api/packages?page=41>; rel="last",
|
||||
<https://www.atom.io/api/packages?page=2>; rel="next"
|
||||
```
|
||||
|
||||
### Showing package details
|
||||
|
||||
#### GET /api/packages/:package_name
|
||||
|
||||
Returns package details and versions for a single package
|
||||
@@ -87,8 +68,6 @@ Returns:
|
||||
}
|
||||
```
|
||||
|
||||
### Creating a package
|
||||
|
||||
#### POST /api/packages
|
||||
|
||||
Create a new package; requires authentication.
|
||||
@@ -113,7 +92,6 @@ Returns:
|
||||
- The package.json at owner/repo isn't valid
|
||||
- **409** - A package by that name already exists
|
||||
|
||||
### Deleting a package
|
||||
|
||||
#### DELETE /api/packages/:package_name
|
||||
|
||||
@@ -125,13 +103,6 @@ Returns:
|
||||
- **400** - Repository is inaccessible
|
||||
- **401** - Unauthorized
|
||||
|
||||
### Renaming a package
|
||||
|
||||
Packages are renamed by publishing a new version with the name changed in `package.json`
|
||||
See [Creating a new package version](#creating-a-new-package-version) for details.
|
||||
|
||||
Requests made to the previous name will forward to the new name.
|
||||
|
||||
### Package Versions
|
||||
|
||||
#### GET /api/packages/:package_name/versions/:version_name
|
||||
@@ -173,9 +144,7 @@ Returns `package.json` with `dist` key added for e.g. tarball download:
|
||||
|
||||
#### POST /api/packages/:package_name/versions
|
||||
|
||||
Creates a new package version from a git tag; requires authentication. If `rename`
|
||||
is not `true`, the `name` field in `package.json` *must* match the current package
|
||||
name.
|
||||
Creates a new package version from a git tag; requires authentication.
|
||||
|
||||
#### Parameters
|
||||
|
||||
@@ -183,15 +152,14 @@ name.
|
||||
that the version name will not be taken from the tag, but from the `version`
|
||||
key in the `package.json` file at that ref. The authenticating user *must* have
|
||||
access to the package repository.
|
||||
- **rename** - Boolean indicating whether this version contains a new name for the package.
|
||||
|
||||
#### Returns
|
||||
|
||||
- **201** - Successfully created. Returns created version.
|
||||
- **400** - Git tag not found / Repository inaccessible / package.json invalid
|
||||
- **400** - Git tag not found / Repository inaccessible
|
||||
- **409** - Version exists
|
||||
|
||||
### Deleting a version
|
||||
### Delete a version
|
||||
|
||||
#### DELETE /api/packages/:package_name/versions/:version_name
|
||||
|
||||
@@ -204,9 +172,7 @@ you'll need to increment the version when republishing.
|
||||
Returns 204 No Content
|
||||
|
||||
|
||||
## Stars
|
||||
|
||||
### Listing user stars
|
||||
### Stars
|
||||
|
||||
#### GET /api/users/:login/stars
|
||||
|
||||
@@ -220,40 +186,19 @@ List the authenticated user's starred packages; requires authentication.
|
||||
|
||||
Return value is similar to **GET /api/packages**
|
||||
|
||||
### Starring a package
|
||||
|
||||
#### POST /api/packages/:name/star
|
||||
|
||||
Star a package; requires authentication.
|
||||
|
||||
Returns a package.
|
||||
|
||||
### Unstarring a package
|
||||
|
||||
#### DELETE /api/packages/:name/star
|
||||
|
||||
Unstar a package; requires authentication.
|
||||
|
||||
Returns 204 No Content.
|
||||
|
||||
### Listing a package's stargazers
|
||||
|
||||
#### GET /api/packages/:name/stargazers
|
||||
|
||||
List the users that have starred a package.
|
||||
|
||||
Returns a list of user objects:
|
||||
|
||||
```json
|
||||
[
|
||||
{"login":"aperson"},
|
||||
{"login":"anotherperson"},
|
||||
]
|
||||
```
|
||||
|
||||
## Atom updates
|
||||
|
||||
### Listing Atom updates
|
||||
### Atom updates
|
||||
|
||||
#### GET /api/updates
|
||||
|
||||
@@ -261,10 +206,10 @@ Atom update feed, following the format expected by [Squirrel](https://github.com
|
||||
|
||||
Returns:
|
||||
|
||||
```json
|
||||
```
|
||||
{
|
||||
"name": "0.96.0",
|
||||
"notes": "[HTML release notes]",
|
||||
"notes": "[HTML release notes]"
|
||||
"pub_date": "2014-05-19T15:52:06.000Z",
|
||||
"url": "https://www.atom.io/api/updates/download"
|
||||
}
|
||||
|
||||
@@ -6,85 +6,38 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
|
||||
|
||||
* OS with 64-bit or 32-bit architecture
|
||||
* C++ toolchain
|
||||
* [Git](http://git-scm.com/)
|
||||
* [Node.js](http://nodejs.org/download/) v0.10.x
|
||||
* [npm](http://www.npmjs.org/) v1.4.x (bundled with Node.js)
|
||||
* `npm -v` to check the version.
|
||||
* `npm config set python /usr/bin/python2 -g` to ensure that gyp uses python2.
|
||||
* You might need to run this command as `sudo`, depending on how you have set up [npm](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
|
||||
* development headers for [GNOME Keyring](https://wiki.gnome.org/Projects/GnomeKeyring)
|
||||
|
||||
### Ubuntu / Debian
|
||||
|
||||
* `sudo apt-get install build-essential git libgnome-keyring-dev`
|
||||
* Instructions for [Node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
|
||||
|
||||
### Fedora
|
||||
|
||||
* `sudo yum --assumeyes install make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel`
|
||||
* Instructions for [Node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#fedora).
|
||||
|
||||
### Arch
|
||||
|
||||
* `sudo pacman -S base-devel git nodejs libgnome-keyring`
|
||||
* `export PYTHON=/usr/bin/python2` before building Atom.
|
||||
* on Ubuntu/Debian: `sudo apt-get install build-essential`
|
||||
* on Fedora: `sudo yum --assumeyes install make gcc gcc-c++ glibc-devel`
|
||||
* [node.js](http://nodejs.org/download/) v0.10.x
|
||||
* [Ubuntu/Debian/Mint instructions](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os)
|
||||
* [Fedora instructions](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#fedora)
|
||||
* [npm](http://www.npmjs.org/) v1.4.x
|
||||
* `npm` comes with node.js so no explicit installation is needed here.
|
||||
* You can check `npm` 1.4 or above is installed by running `npm -v`.
|
||||
* libgnome-keyring-dev
|
||||
* on Ubuntu/Debian: `sudo apt-get install libgnome-keyring-dev`
|
||||
* on Fedora: `sudo yum --assumeyes install libgnome-keyring-devel`
|
||||
* on other distributions refer to the manual on how to install packages
|
||||
* `npm config set python /usr/bin/python2 -g` to ensure that gyp uses Python 2
|
||||
* This command may require `sudo` depending on how you have
|
||||
[configured npm](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
|
||||
* Git
|
||||
* on Ubuntu/Debian: `sudo apt-get install git`
|
||||
* on Fedora: `sudo yum install git-core`
|
||||
|
||||
## Instructions
|
||||
|
||||
If you have problems with permissions don't forget to prefix with `sudo`
|
||||
|
||||
1. Clone the Atom repository:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/atom/atom
|
||||
cd atom
|
||||
script/build # Creates application at $TMPDIR/atom-build/Atom
|
||||
sudo script/grunt install # Installs command to /usr/local/bin/atom
|
||||
script/grunt mkdeb # Generates a .deb package at $TMPDIR/atom-build
|
||||
```
|
||||
|
||||
2. Checkout the latest Atom release:
|
||||
|
||||
```sh
|
||||
git fetch
|
||||
git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
|
||||
```
|
||||
|
||||
3. Build Atom:
|
||||
|
||||
```sh
|
||||
script/build
|
||||
```
|
||||
|
||||
This will create the atom application at `$TMPDIR/atom-build/Atom`.
|
||||
|
||||
4. Install the `atom` and `apm` commands to `/usr/local/bin` by executing:
|
||||
|
||||
```sh
|
||||
sudo script/grunt install
|
||||
```
|
||||
|
||||
5. *Optionally*, you may generate a `.deb` package at `$TMPDIR/atom-build`:
|
||||
|
||||
```sh
|
||||
script/grunt mkdeb
|
||||
```
|
||||
|
||||
Use the newly installed Atom by fully quitting Atom and then reopening.
|
||||
|
||||
## Advanced Options
|
||||
|
||||
### Custom install directory
|
||||
|
||||
```sh
|
||||
sudo script/grunt install --install-dir /install/atom/here
|
||||
```
|
||||
|
||||
### Custom build directory
|
||||
|
||||
```sh
|
||||
script/build --build-dir /build/atom/here
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
### Exception: "TypeError: Unable to watch path"
|
||||
|
||||
If you get following error with a big traceback right after Atom starts:
|
||||
@@ -103,27 +56,11 @@ this is the reason for this error you can issue
|
||||
and restart Atom. If Atom now works fine, you can make this setting permanent:
|
||||
|
||||
```sh
|
||||
echo 32768 | sudo tee -a /proc/sys/fs/inotify/max_user_watches
|
||||
echo 32768 > /proc/sys/fs/inotify/max_user_watches
|
||||
```
|
||||
|
||||
See also https://github.com/atom/atom/issues/2082.
|
||||
|
||||
### /usr/bin/env: node: No such file or directory
|
||||
|
||||
If you get this notice when attempting to `script/build`, you either do not
|
||||
have Node.js installed, or node isn't identified as Node.js on your machine.
|
||||
If it's the latter, entering `sudo ln -s /usr/bin/nodejs /usr/bin/node` into
|
||||
your terminal may fix the issue.
|
||||
|
||||
#### You can also use Alternatives
|
||||
|
||||
On some variants (mostly Debian based distros) it's preferable for you to use
|
||||
Alternatives so that changes to the binary paths can be fixed or altered easily:
|
||||
|
||||
```sh
|
||||
sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 1 --slave /usr/bin/js js /usr/bin/nodejs
|
||||
```
|
||||
|
||||
### Linux build error reports in atom/atom
|
||||
* Use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Alinux&type=Issues)
|
||||
to get a list of reports about build errors on Linux.
|
||||
|
||||
@@ -35,14 +35,10 @@
|
||||
|
||||
## Why do I have to use GitHub for Windows?
|
||||
|
||||
You don't. You can use your existing Git! GitHub for Windows's Git Shell is just
|
||||
easier to set up.
|
||||
|
||||
If you _prefer_ using your existing Git installation, make sure git's cmd directory is in your PATH env variable (e.g. `C:\Program Files (x86)\Git\cmd`) before you open your powershell or command window.
|
||||
Note that you may have to open your command window as administrator. For powershell that doesn't seem to always be the case, though.
|
||||
|
||||
If none of this works, do install Github for Windows and use its Git shell. Makes life easier.
|
||||
|
||||
You don't, You can use your existing Git! GitHub for Windows's Git Shell is just
|
||||
easier to set up. You need to have Posix tools in your `%PATH%` (i.e. `grep`,
|
||||
`sed`, et al.), which isn't the default configuration when you install Git. To
|
||||
fix this, you probably need to fiddle with your system PATH.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -66,24 +62,5 @@ If none of this works, do install Github for Windows and use its Git shell. Make
|
||||
* https://github.com/TooTallNate/node-gyp/issues/297
|
||||
* https://code.google.com/p/gyp/issues/detail?id=393
|
||||
|
||||
* `script/build` stops at installing runas with 'Failed at the runas@0.5.4 install script.'
|
||||
|
||||
See the next item.
|
||||
|
||||
* `error MSB8020: The build tools for Visual Studio 2010 (Platform Toolset = 'v100') cannot be found.`
|
||||
|
||||
* If you're building atom with Visual Studio 2013 try executing the following
|
||||
command in your Git shell and then re-run `script/build`:
|
||||
|
||||
```
|
||||
$env:GYP_MSVS_VERSION=2013
|
||||
```
|
||||
|
||||
* Other `node-gyp` errors on first build attempt, even though the right node and python versions are installed.
|
||||
* Do try the build command one more time, as experience shows it often works on second try in many of these cases.
|
||||
|
||||
|
||||
### Windows build error reports in atom/atom
|
||||
* If all fails, use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Awindows&type=Issues) to get a list of reports about build errors on Windows, and see if yours has already been reported.
|
||||
|
||||
* If it hasn't, please open a new issue with your Windows version 32/64bit and a print/screenshot of your build output, incl. the node and python versions.
|
||||
* Use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Awindows&type=Issues) to get a list of reports about build errors on Windows.
|
||||
|
||||
@@ -207,44 +207,36 @@ specific parts of the interface, like adding a file in the tree-view:
|
||||
|
||||
```coffeescript
|
||||
'context-menu':
|
||||
'.tree-view': [
|
||||
{label: 'Add file', command: 'tree-view:add-file'}
|
||||
]
|
||||
'.workspace': [
|
||||
{label: 'Inspect Element', command: 'core:inspect'}
|
||||
]
|
||||
'.tree-view':
|
||||
'Add file': 'tree-view:add-file'
|
||||
'.workspace':
|
||||
'Inspect Element': 'core:inspect'
|
||||
```
|
||||
|
||||
To add your own item to the application menu simply create a top level
|
||||
`context-menu` key in any menu configuration file in _menus_. This can be a
|
||||
JSON or [CSON] file.
|
||||
|
||||
Context menus are created by determining which element was selected and then
|
||||
adding all of the menu items whose selectors match that element (in the order
|
||||
which they were loaded). The process is then repeated for the elements until
|
||||
reaching the top of the DOM tree.
|
||||
Context menus are created by determining which element was selected and
|
||||
then adding all of the menu items whose selectors match that element (in
|
||||
the order which they were loaded). The process is then repeated for the
|
||||
elements until reaching the top of the DOM tree.
|
||||
|
||||
In the example above, the `Add file` item will only appear when the focused item
|
||||
or one of its parents has the `tree-view` class applied to it.
|
||||
|
||||
You can also add separators and submenus to your context menus. To add a
|
||||
submenu, provide a `submenu` key instead of a command. To add a separator, add
|
||||
an item with a single `type: 'separator'` key/value pair.
|
||||
submenu, pass in another object instead of a command. To add a separator, use
|
||||
`-` for the name and command of the item.
|
||||
|
||||
```coffeescript
|
||||
'context-menu':
|
||||
'.workspace': [
|
||||
{
|
||||
label: 'Text'
|
||||
submenu: [
|
||||
{label: 'Inspect Element', command: 'core:inspect'}
|
||||
{type: 'separator'}
|
||||
{label: 'Selector All', command: 'core:select-all'}
|
||||
{type: 'separator'}
|
||||
{label: 'Deleted Selected Text', command: 'core:delete'}
|
||||
]
|
||||
}
|
||||
]
|
||||
'.workspace':
|
||||
'Inspect Element': 'core:inspect'
|
||||
'-': '-'
|
||||
'Text':
|
||||
'Select All': 'core:select-all'
|
||||
'Deleted Selected Text': 'core:delete'
|
||||
```
|
||||
|
||||
## Snippets
|
||||
@@ -328,29 +320,6 @@ extensions your grammar supports:
|
||||
]
|
||||
```
|
||||
|
||||
## Adding Configuration Settings
|
||||
|
||||
You can support config settings in your package that are editable in the
|
||||
settings view. Specify a `config` key in your package main:
|
||||
|
||||
```coffeescript
|
||||
module.exports =
|
||||
# Your config schema!
|
||||
config:
|
||||
someInt:
|
||||
type: 'integer'
|
||||
default: 23
|
||||
minimum: 1
|
||||
activate: (state) -> # ...
|
||||
# ...
|
||||
```
|
||||
|
||||
To define the configuration, we use [json schema][json-schema] which allows you
|
||||
to indicate the type your value should be, its default, etc.
|
||||
|
||||
See the [Config API Docs](https://atom.io/docs/api/latest/Config) for more
|
||||
details specifying your configuration.
|
||||
|
||||
## Bundle External Resources
|
||||
|
||||
It's common to ship external resources like images and fonts in the package, to
|
||||
@@ -422,4 +391,3 @@ all the other available commands.
|
||||
[first-package]: your-first-package.html
|
||||
[convert-bundle]: converting-a-text-mate-bundle.html
|
||||
[convert-theme]: converting-a-text-mate-theme.html
|
||||
[json-schema]: http://json-schema.org/
|
||||
|
||||
@@ -169,7 +169,7 @@ For example, to change the color of the cursor, you could add the following
|
||||
rule to your _~/.atom/styles.less_ file:
|
||||
|
||||
```less
|
||||
.editor.is-focused .cursor {
|
||||
.editor .cursor {
|
||||
border-color: pink;
|
||||
}
|
||||
```
|
||||
|
||||
+1
-69
@@ -38,7 +38,7 @@ Atom uses [Jasmine](http://jasmine.github.io/2.0/introduction.html) as its spec
|
||||
|
||||
0. Add one or more expectations
|
||||
|
||||
The best way to learn about expectations is to read the [jasmine documentation](http://jasmine.github.io/1.3/introduction.html#section-Expectations) about them. Below is a simple example.
|
||||
The best way to learn about expectations is to read the [jasmine documentation](http://jasmine.github.io/2.0/introduction.html#section-Expectations) about them. Below is a simple example.
|
||||
|
||||
```coffee
|
||||
describe "when a test is written", ->
|
||||
@@ -47,74 +47,6 @@ Atom uses [Jasmine](http://jasmine.github.io/2.0/introduction.html) as its spec
|
||||
expect("oranges").not.toEqual("apples")
|
||||
```
|
||||
|
||||
## Asynchronous specs
|
||||
|
||||
Writing Asynchronous specs can be tricky at first. Some examples.
|
||||
|
||||
0. Promises
|
||||
|
||||
Working with promises is rather easy in Atom. You can use our `waitsForPromise` function.
|
||||
|
||||
```coffee
|
||||
describe "when we open a file", ->
|
||||
it "should be opened in an editor", ->
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('c.coffee').then (editor) ->
|
||||
expect(editor.getPath()).toContain 'c.coffee'
|
||||
```
|
||||
|
||||
This method can be used in the `describe`, `it`, `beforeEach` and `afterEach` functions.
|
||||
|
||||
```coffee
|
||||
describe "when we open a file", ->
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.workspace.open 'c.coffee'
|
||||
|
||||
it "should be opened in an editor", ->
|
||||
expect(atom.workspace.getActiveEditor().getPath()).toContain 'c.coffee'
|
||||
|
||||
```
|
||||
|
||||
If you need to wait for multiple promises use a new `waitsForPromise` function for each promise. (Caution: Without `beforeEach` this example will fail!)
|
||||
|
||||
```coffee
|
||||
describe "waiting for the packages to load", ->
|
||||
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.js')
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('tabs')
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('tree-view')
|
||||
|
||||
it 'should have waited long enough', ->
|
||||
expect(atom.packages.isPackageActive('tabs')).toBe true
|
||||
expect(atom.packages.isPackageActive('tree-view')).toBe true
|
||||
```
|
||||
|
||||
0. Asynchronous functions with callbacks
|
||||
|
||||
Specs for asynchronous functions can be done using the `waitsFor` and `runs` functions. A simple example.
|
||||
|
||||
```coffee
|
||||
describe "fs.readdir(path, cb)", ->
|
||||
it "is async", ->
|
||||
spy = jasmine.createSpy('fs.readdirSpy')
|
||||
|
||||
fs.readdir('/tmp/example', spy)
|
||||
waitsFor ->
|
||||
spy.callCount > 0
|
||||
runs ->
|
||||
exp = [null, ['example.coffee']]
|
||||
expect(spy.mostRecentCall.args).toEqual exp
|
||||
expect(spy).toHaveBeenCalledWith(null, ['example.coffee'])
|
||||
```
|
||||
|
||||
For a more detailed documentation on asynchronous tests please visit the [jasmine documentation](http://jasmine.github.io/1.3/introduction.html#section-Asynchronous_Support).
|
||||
|
||||
|
||||
## Running specs
|
||||
|
||||
Most of the time you'll want to run specs by triggering the `window:run-package-specs` command. This command is not only to run package specs, it is also for Atom core specs. This will run all the specs in the current project's spec directory. If you want to run the Atom core specs and **all** the default package specs trigger the `window:run-all-specs` command.
|
||||
|
||||
@@ -53,7 +53,7 @@ module.exports =
|
||||
|
||||
convert: ->
|
||||
# This assumes the active pane item is an editor
|
||||
editor = atom.workspace.getActivePaneItem()
|
||||
editor = atom.workspace.activePaneItem
|
||||
editor.insertText('Hello, World!')
|
||||
```
|
||||
|
||||
@@ -131,8 +131,8 @@ inserting 'Hello, World!' convert the selected text to ASCII art.
|
||||
```coffeescript
|
||||
convert: ->
|
||||
# This assumes the active pane item is an editor
|
||||
editor = atom.workspace.getActivePaneItem()
|
||||
selection = editor.getLastSelection()
|
||||
editor = atom.workspace.activePaneItem
|
||||
selection = editor.getSelection()
|
||||
|
||||
figlet = require 'figlet'
|
||||
figlet selection.getText(), {font: "Larry 3D 2"}, (error, asciiArt) ->
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
# atom.workspaceView.eachEditorView (editorView) ->
|
||||
# editor = editorView.getEditor()
|
||||
# if path.extname(editor.getPath()) is '.md'
|
||||
# editor.setSoftWrapped(true)
|
||||
# editor.setSoftWrap(true)
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
# 'enter': 'editor:newline'
|
||||
#
|
||||
# '.workspace':
|
||||
# 'ctrl-shift-p': 'core:move-up'
|
||||
# 'ctrl-P': 'core:move-up'
|
||||
# 'ctrl-p': 'core:move-down'
|
||||
#
|
||||
# You can find more information about keymaps in these guides:
|
||||
# * https://atom.io/docs/latest/customizing-atom#customizing-key-bindings
|
||||
# * https://atom.io/docs/latest/advanced/keymaps
|
||||
|
||||
+2
-13
@@ -1,10 +1,9 @@
|
||||
{Point, Range} = require 'text-buffer'
|
||||
{deprecate} = require 'grim'
|
||||
|
||||
module.exports =
|
||||
BufferedNodeProcess: require '../src/buffered-node-process'
|
||||
BufferedProcess: require '../src/buffered-process'
|
||||
GitRepository: require '../src/git-repository'
|
||||
Git: require '../src/git'
|
||||
Point: Point
|
||||
Range: Range
|
||||
|
||||
@@ -16,20 +15,10 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
module.exports.$ = $
|
||||
module.exports.$$ = $$
|
||||
module.exports.$$$ = $$$
|
||||
module.exports.TextEditorView = require '../src/text-editor-view'
|
||||
module.exports.EditorView = require '../src/editor-view'
|
||||
module.exports.ScrollView = require '../src/scroll-view'
|
||||
module.exports.SelectListView = require '../src/select-list-view'
|
||||
module.exports.Task = require '../src/task'
|
||||
module.exports.View = View
|
||||
module.exports.WorkspaceView = require '../src/workspace-view'
|
||||
module.exports.Workspace = require '../src/workspace'
|
||||
module.exports.React = require 'react-atom-fork'
|
||||
module.exports.Reactionary = require 'reactionary-atom-fork'
|
||||
|
||||
Object.defineProperty module.exports, 'Git', get: ->
|
||||
deprecate "Please require `GitRepository` instead of `Git`: `{GitRepository} = require 'atom'`"
|
||||
module.exports.GitRepository
|
||||
|
||||
Object.defineProperty module.exports, 'EditorView', get: ->
|
||||
deprecate "Please require `TextEditorView` instead of `EditorView`: `{TextEditorView} = require 'atom'`"
|
||||
module.exports.TextEditorView
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
# Sublime Parity
|
||||
'tab': 'editor:indent'
|
||||
'enter': 'editor:newline'
|
||||
'num-enter': 'editor:newline'
|
||||
'shift-tab': 'editor:outdent-selected-rows'
|
||||
'ctrl-K': 'editor:delete-line'
|
||||
|
||||
@@ -26,6 +27,7 @@
|
||||
'tab': 'core:focus-next'
|
||||
'shift-tab': 'core:focus-previous'
|
||||
'enter': 'native!'
|
||||
'num-enter': 'native!'
|
||||
'backspace': 'native!'
|
||||
'shift-backspace': 'native!'
|
||||
'delete': 'native!'
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
'cmd-O': 'application:open-dev'
|
||||
'cmd-alt-ctrl-s': 'application:run-all-specs'
|
||||
'enter': 'core:confirm'
|
||||
'num-enter': 'core:confirm'
|
||||
'escape': 'core:cancel'
|
||||
'up': 'core:move-up'
|
||||
'down': 'core:move-down'
|
||||
@@ -68,8 +69,6 @@
|
||||
'cmd-}': 'pane:show-next-item'
|
||||
'cmd-alt-left': 'pane:show-previous-item'
|
||||
'cmd-alt-right': 'pane:show-next-item'
|
||||
'ctrl-pageup': 'pane:show-previous-item'
|
||||
'ctrl-pagedown': 'pane:show-next-item'
|
||||
'ctrl-tab': 'pane:show-next-item'
|
||||
'ctrl-shift-tab': 'pane:show-previous-item'
|
||||
'cmd-=': 'window:increase-font-size'
|
||||
@@ -119,7 +118,7 @@
|
||||
'cmd-shift-right': 'editor:select-to-end-of-line'
|
||||
'alt-backspace': 'editor:delete-to-beginning-of-word'
|
||||
'alt-delete': 'editor:delete-to-end-of-word'
|
||||
'ctrl-a': 'editor:move-to-first-character-of-line'
|
||||
'ctrl-a': 'editor:move-to-beginning-of-line'
|
||||
'ctrl-e': 'editor:move-to-end-of-line'
|
||||
'ctrl-k': 'editor:cut-to-end-of-line'
|
||||
|
||||
@@ -143,8 +142,6 @@
|
||||
# Sublime Parity
|
||||
'cmd-enter': 'editor:newline-below'
|
||||
'cmd-shift-enter': 'editor:newline-above'
|
||||
'alt-enter': 'editor:newline'
|
||||
'shift-enter': 'editor:newline'
|
||||
'cmd-]': 'editor:indent-selected-rows'
|
||||
'cmd-[': 'editor:outdent-selected-rows'
|
||||
'ctrl-cmd-up': 'editor:move-line-up'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'body':
|
||||
# Atom Specific
|
||||
'enter': 'core:confirm'
|
||||
'num-enter': 'core:confirm'
|
||||
'escape': 'core:cancel'
|
||||
'up': 'core:move-up'
|
||||
'down': 'core:move-down'
|
||||
@@ -10,12 +11,10 @@
|
||||
'ctrl-shift-i': 'window:toggle-dev-tools'
|
||||
'ctrl-alt-p': 'window:run-package-specs'
|
||||
'ctrl-alt-s': 'application:run-all-specs'
|
||||
'ctrl-alt-o': 'application:open-dev'
|
||||
'ctrl-shift-o': 'application:open-folder'
|
||||
'ctrl-shift-o': 'application:open-dev'
|
||||
'F11': 'window:toggle-full-screen'
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-,': 'application:show-settings'
|
||||
'ctrl-N': 'application:new-window'
|
||||
'ctrl-W': 'window:close'
|
||||
'ctrl-o': 'application:open-file'
|
||||
@@ -27,7 +26,6 @@
|
||||
'ctrl-w': 'core:close'
|
||||
'ctrl-z': 'core:undo'
|
||||
'ctrl-y': 'core:redo'
|
||||
'ctrl-shift-z': 'core:redo'
|
||||
'ctrl-x': 'core:cut'
|
||||
'ctrl-c': 'core:copy'
|
||||
'ctrl-v': 'core:paste'
|
||||
@@ -40,15 +38,13 @@
|
||||
'shift-pageup': 'core:select-page-up'
|
||||
'shift-pagedown': 'core:select-page-down'
|
||||
'delete': 'core:delete'
|
||||
'shift-delete': 'core:cut'
|
||||
'shift-delete': 'core:delete'
|
||||
'pageup': 'core:page-up'
|
||||
'pagedown': 'core:page-down'
|
||||
'backspace': 'core:backspace'
|
||||
'shift-backspace': 'core:backspace'
|
||||
'ctrl-tab': 'pane:show-next-item'
|
||||
'ctrl-shift-tab': 'pane:show-previous-item'
|
||||
'ctrl-pageup': 'pane:show-previous-item'
|
||||
'ctrl-pagedown': 'pane:show-next-item'
|
||||
'ctrl-shift-up': 'core:move-up'
|
||||
'ctrl-shift-down': 'core:move-down'
|
||||
'ctrl-=': 'window:increase-font-size'
|
||||
@@ -97,7 +93,6 @@
|
||||
'ctrl-alt-shift-p': 'editor:log-cursor-scope'
|
||||
'ctrl-k ctrl-u': 'editor:upper-case'
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'.workspace .editor:not(.mini)':
|
||||
# Atom specific
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
# Atom Specific
|
||||
'enter': 'core:confirm'
|
||||
'num-enter': 'core:confirm'
|
||||
'escape': 'core:cancel'
|
||||
'up': 'core:move-up'
|
||||
'down': 'core:move-down'
|
||||
@@ -17,7 +18,6 @@
|
||||
'F11': 'window:toggle-full-screen'
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-,': 'application:show-settings'
|
||||
'ctrl-N': 'application:new-window'
|
||||
'ctrl-W': 'window:close'
|
||||
'ctrl-o': 'application:open-file'
|
||||
@@ -25,10 +25,8 @@
|
||||
'ctrl-n': 'application:new-file'
|
||||
'ctrl-s': 'core:save'
|
||||
'ctrl-S': 'core:save-as'
|
||||
'ctrl-f4': 'core:close'
|
||||
'ctrl-w': 'core:close'
|
||||
'ctrl-z': 'core:undo'
|
||||
'ctrl-shift-z': 'core:redo'
|
||||
'ctrl-y': 'core:redo'
|
||||
'ctrl-x': 'core:cut'
|
||||
'ctrl-c': 'core:copy'
|
||||
@@ -42,15 +40,13 @@
|
||||
'shift-pageup': 'core:select-page-up'
|
||||
'shift-pagedown': 'core:select-page-down'
|
||||
'delete': 'core:delete'
|
||||
'shift-delete': 'core:cut'
|
||||
'shift-delete': 'core:delete'
|
||||
'pageup': 'core:page-up'
|
||||
'pagedown': 'core:page-down'
|
||||
'backspace': 'core:backspace'
|
||||
'shift-backspace': 'core:backspace'
|
||||
'ctrl-tab': 'pane:show-next-item'
|
||||
'ctrl-shift-tab': 'pane:show-previous-item'
|
||||
'ctrl-pageup': 'pane:show-previous-item'
|
||||
'ctrl-pagedown': 'pane:show-next-item'
|
||||
'ctrl-shift-up': 'core:move-up'
|
||||
'ctrl-shift-down': 'core:move-down'
|
||||
'ctrl-alt-up': 'editor:add-selection-above'
|
||||
@@ -84,15 +80,12 @@
|
||||
'ctrl-delete': 'editor:delete-to-end-of-word'
|
||||
'ctrl-home': 'core:move-to-top'
|
||||
'ctrl-end': 'core:move-to-bottom'
|
||||
'ctrl-shift-home': 'core:select-to-top'
|
||||
'ctrl-shift-end': 'core:select-to-bottom'
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-a': 'core:select-all'
|
||||
'ctrl-alt-shift-p': 'editor:log-cursor-scope'
|
||||
'ctrl-k ctrl-u': 'editor:upper-case'
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'.workspace .editor:not(.mini)':
|
||||
# Atom specific
|
||||
|
||||
+1
-29
@@ -18,8 +18,6 @@
|
||||
{ type: 'separator' }
|
||||
{ label: 'Install Shell Commands', command: 'window:install-shell-commands' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Services', submenu: [] }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Hide Atom', command: 'application:hide' }
|
||||
{ label: 'Hide Others', command: 'application:hide-other-applications' }
|
||||
{ label: 'Show All', command: 'application:unhide-all-applications' }
|
||||
@@ -39,7 +37,7 @@
|
||||
{ label: 'Save As...', command: 'core:save-as' }
|
||||
{ label: 'Save All', command: 'window:save-all' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Close Tab', command: 'core:close' }
|
||||
{ label: 'Close Buffer', command: 'core:close' }
|
||||
{ label: 'Close Pane', command: 'pane:close' }
|
||||
{ label: 'Close Window', command: 'window:close' }
|
||||
]
|
||||
@@ -194,29 +192,3 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer': [
|
||||
{label: 'Undo', command: 'core:undo'}
|
||||
{label: 'Redo', command: 'core:redo'}
|
||||
{type: 'separator'}
|
||||
{label: 'Cut', command: 'core:cut'}
|
||||
{label: 'Copy', command: 'core:copy'}
|
||||
{label: 'Paste', command: 'core:paste'}
|
||||
{label: 'Delete', command: 'core:delete'}
|
||||
{label: 'Select All', command: 'core:select-all'}
|
||||
{type: 'separator'}
|
||||
{label: 'Split Up', command: 'pane:split-up'}
|
||||
{label: 'Split Down', command: 'pane:split-down'}
|
||||
{label: 'Split Left', command: 'pane:split-left'}
|
||||
{label: 'Split Right', command: 'pane:split-right'}
|
||||
{type: 'separator'}
|
||||
]
|
||||
'.pane': [
|
||||
{type: 'separator'}
|
||||
{label: 'Split Up', command: 'pane:split-up'}
|
||||
{label: 'Split Down', command: 'pane:split-down'}
|
||||
{label: 'Split Left', command: 'pane:split-left'}
|
||||
{label: 'Split Right', command: 'pane:split-right'}
|
||||
{type: 'separator'}
|
||||
]
|
||||
|
||||
+14
-36
@@ -8,12 +8,14 @@
|
||||
{ label: 'Open Folder...', command: 'application:open-folder' }
|
||||
{ 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 Tab', command: 'core:close' }
|
||||
{ label: 'Close &Pane', command: 'pane:close' }
|
||||
{ label: '&Close Buffer', command: 'core:close' }
|
||||
{ label: 'Close All &Buffers', command: 'pane:close' }
|
||||
{ label: 'Clos&e Window', command: 'window:close' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Quit', command: 'application:quit' }
|
||||
@@ -78,14 +80,6 @@
|
||||
{ label: 'Fold Level 9', command: 'editor:fold-at-indent-level-9' }
|
||||
]
|
||||
}
|
||||
{ type: 'separator' }
|
||||
{ label: '&Preferences', command: 'application:show-settings' }
|
||||
{ label: 'Open Your Config', command: 'application:open-your-config' }
|
||||
{ label: 'Open Your Init Script', command: 'application:open-your-init-script' }
|
||||
{ label: 'Open Your Keymap', command: 'application:open-your-keymap' }
|
||||
{ label: 'Open Your Snippets', command: 'application:open-your-snippets' }
|
||||
{ label: 'Open Your Stylesheet', command: 'application:open-your-stylesheet' }
|
||||
{ type: 'separator' }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -139,6 +133,16 @@
|
||||
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: [
|
||||
@@ -151,29 +155,3 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer': [
|
||||
{label: 'Undo', command: 'core:undo'}
|
||||
{label: 'Redo', command: 'core:redo'}
|
||||
{type: 'separator'}
|
||||
{label: 'Cut', command: 'core:cut'}
|
||||
{label: 'Copy', command: 'core:copy'}
|
||||
{label: 'Paste', command: 'core:paste'}
|
||||
{label: 'Delete', command: 'core:delete'}
|
||||
{label: 'Select All', command: 'core:select-all'}
|
||||
{type: 'separator'}
|
||||
{label: 'Split Up', command: 'pane:split-up'}
|
||||
{label: 'Split Down', command: 'pane:split-down'}
|
||||
{label: 'Split Left', command: 'pane:split-left'}
|
||||
{label: 'Split Right', command: 'pane:split-right'}
|
||||
{type: 'separator'}
|
||||
]
|
||||
'.pane': [
|
||||
{type: 'separator'}
|
||||
{label: 'Split Up', command: 'pane:split-up'}
|
||||
{label: 'Split Down', command: 'pane:split-down'}
|
||||
{label: 'Split Left', command: 'pane:split-left'}
|
||||
{label: 'Split Right', command: 'pane:split-right'}
|
||||
{type: 'separator'}
|
||||
]
|
||||
|
||||
+14
-35
@@ -9,18 +9,13 @@
|
||||
{ label: 'Reopen Last &Item', command: 'pane:reopen-closed-item' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Se&ttings', command: 'application:show-settings' }
|
||||
{ label: 'Open Your Config', command: 'application:open-your-config' }
|
||||
{ label: 'Open Your Init Script', command: 'application:open-your-init-script' }
|
||||
{ label: 'Open Your Keymap', command: 'application:open-your-keymap' }
|
||||
{ label: 'Open Your Snippets', command: 'application:open-your-snippets' }
|
||||
{ label: 'Open Your Stylesheet', command: 'application:open-your-stylesheet' }
|
||||
{ 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 Tab', command: 'core:close' }
|
||||
{ label: 'Close &Pane', command: 'pane:close' }
|
||||
{ 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' }
|
||||
@@ -33,8 +28,8 @@
|
||||
{ label: '&Undo', command: 'core:undo' }
|
||||
{ label: '&Redo', command: 'core:redo' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Cu&t', command: 'core:cut' }
|
||||
{ label: '&Copy', command: 'core:copy' }
|
||||
{ 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' }
|
||||
@@ -157,6 +152,16 @@
|
||||
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: [
|
||||
@@ -169,29 +174,3 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer': [
|
||||
{label: 'Undo', command: 'core:undo'}
|
||||
{label: 'Redo', command: 'core:redo'}
|
||||
{type: 'separator'}
|
||||
{label: 'Cut', command: 'core:cut'}
|
||||
{label: 'Copy', command: 'core:copy'}
|
||||
{label: 'Paste', command: 'core:paste'}
|
||||
{label: 'Delete', command: 'core:delete'}
|
||||
{label: 'Select All', command: 'core:select-all'}
|
||||
{type: 'separator'}
|
||||
{label: 'Split Up', command: 'pane:split-up'}
|
||||
{label: 'Split Down', command: 'pane:split-down'}
|
||||
{label: 'Split Left', command: 'pane:split-left'}
|
||||
{label: 'Split Right', command: 'pane:split-right'}
|
||||
{type: 'separator'}
|
||||
]
|
||||
'.pane': [
|
||||
{type: 'separator'}
|
||||
{label: 'Split Up', command: 'pane:split-up'}
|
||||
{label: 'Split Down', command: 'pane:split-down'}
|
||||
{label: 'Split Left', command: 'pane:split-left'}
|
||||
{label: 'Split Right', command: 'pane:split-right'}
|
||||
{type: 'separator'}
|
||||
]
|
||||
|
||||
+86
-90
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.136.0",
|
||||
"version": "0.107.0",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
@@ -17,129 +17,125 @@
|
||||
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
|
||||
}
|
||||
],
|
||||
"atomShellVersion": "0.17.1",
|
||||
"atomShellVersion": "0.13.2",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^2.2.0",
|
||||
"atom-keymap": "^0.27.0",
|
||||
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
|
||||
"clear-cut": "0.4.0",
|
||||
"coffee-script": "1.7.0",
|
||||
"coffeestack": "0.7.0",
|
||||
"delegato": "^1",
|
||||
"emissary": "^1.3.1",
|
||||
"event-kit": "0.7.2",
|
||||
"first-mate": "^2.2.0",
|
||||
"fs-plus": "^2.3.1",
|
||||
"emissary": "^1.2.1",
|
||||
"first-mate": "^1.7",
|
||||
"fs-plus": "^2.2.3",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "^2.1",
|
||||
"git-utils": "^2.1.5",
|
||||
"grim": "0.12.0",
|
||||
"fuzzaldrin": "^1.1",
|
||||
"git-utils": "^1.3",
|
||||
"grim": "0.11.0",
|
||||
"guid": "0.0.10",
|
||||
"jasmine-tagged": "^1.1.2",
|
||||
"less-cache": "0.15.0",
|
||||
"less-cache": "0.12.0",
|
||||
"mixto": "^1",
|
||||
"mkdirp": "0.3.5",
|
||||
"nslog": "^1.0.1",
|
||||
"oniguruma": "^3.0.4",
|
||||
"nslog": "0.5.0",
|
||||
"oniguruma": "^1.0.6",
|
||||
"optimist": "0.4.0",
|
||||
"pathwatcher": "^2.1.3",
|
||||
"pathwatcher": "^1.3.2",
|
||||
"property-accessors": "^1",
|
||||
"q": "^1.0.1",
|
||||
"random-words": "0.0.1",
|
||||
"react-atom-fork": "^0.11.1",
|
||||
"reactionary-atom-fork": "^1.0.0",
|
||||
"runas": "1.0.1",
|
||||
"scandal": "1.0.2",
|
||||
"scoped-property-store": "^0.11.0",
|
||||
"scrollbar-style": "^1.0.2",
|
||||
"react-atom-fork": "^0.10.0",
|
||||
"reactionary-atom-fork": "^0.9.0",
|
||||
"runas": "^0.5",
|
||||
"scandal": "0.15.3",
|
||||
"scoped-property-store": "^0.9.0",
|
||||
"scrollbar-style": "^0.4.0",
|
||||
"season": "^1.0.2",
|
||||
"semver": "1.1.4",
|
||||
"serializable": "^1",
|
||||
"space-pen": "3.6.1",
|
||||
"space-pen": "3.2.0",
|
||||
"temp": "0.7.0",
|
||||
"text-buffer": "^3.2.8",
|
||||
"theorist": "^1.0.2",
|
||||
"underscore-plus": "^1.5.1",
|
||||
"text-buffer": "^2.4.2",
|
||||
"theorist": "^1",
|
||||
"underscore-plus": "^1.5.0",
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
},
|
||||
"packageDependencies": {
|
||||
"atom-dark-syntax": "0.19.0",
|
||||
"atom-dark-ui": "0.35.0",
|
||||
"atom-light-syntax": "0.20.0",
|
||||
"atom-light-ui": "0.30.0",
|
||||
"base16-tomorrow-dark-theme": "0.21.0",
|
||||
"base16-tomorrow-light-theme": "0.4.0",
|
||||
"solarized-dark-syntax": "0.22.0",
|
||||
"solarized-light-syntax": "0.12.0",
|
||||
"archive-view": "0.37.0",
|
||||
"autocomplete": "0.32.0",
|
||||
"autoflow": "0.18.0",
|
||||
"autosave": "0.18.0",
|
||||
"background-tips": "0.17.0",
|
||||
"bookmarks": "0.28.0",
|
||||
"bracket-matcher": "0.61.0",
|
||||
"command-palette": "0.27.0",
|
||||
"deprecation-cop": "0.10.0",
|
||||
"dev-live-reload": "0.34.0",
|
||||
"exception-reporting": "0.20.0",
|
||||
"atom-dark-syntax": "0.17.0",
|
||||
"atom-dark-ui": "0.29.0",
|
||||
"atom-light-syntax": "0.18.0",
|
||||
"atom-light-ui": "0.25.0",
|
||||
"base16-tomorrow-dark-theme": "0.17.0",
|
||||
"solarized-dark-syntax": "0.18.0",
|
||||
"solarized-light-syntax": "0.9.0",
|
||||
"archive-view": "0.33.0",
|
||||
"autocomplete": "0.28.0",
|
||||
"autoflow": "0.17.0",
|
||||
"autosave": "0.14.0",
|
||||
"background-tips": "0.14.0",
|
||||
"bookmarks": "0.25.0",
|
||||
"bracket-matcher": "0.47.0",
|
||||
"command-palette": "0.23.0",
|
||||
"deprecation-cop": "0.7.0",
|
||||
"dev-live-reload": "0.31.0",
|
||||
"exception-reporting": "0.18.0",
|
||||
"feedback": "0.33.0",
|
||||
"find-and-replace": "0.139.0",
|
||||
"fuzzy-finder": "0.58.0",
|
||||
"git-diff": "0.39.0",
|
||||
"go-to-line": "0.25.0",
|
||||
"grammar-selector": "0.34.0",
|
||||
"image-view": "0.37.0",
|
||||
"incompatible-packages": "0.9.0",
|
||||
"keybinding-resolver": "0.20.0",
|
||||
"link": "0.25.0",
|
||||
"markdown-preview": "0.103.0",
|
||||
"metrics": "0.36.0",
|
||||
"open-on-github": "0.30.0",
|
||||
"find-and-replace": "0.120.0",
|
||||
"fuzzy-finder": "0.55.0",
|
||||
"git-diff": "0.34.0",
|
||||
"go-to-line": "0.23.0",
|
||||
"grammar-selector": "0.27.0",
|
||||
"image-view": "0.35.0",
|
||||
"keybinding-resolver": "0.18.0",
|
||||
"link": "0.24.0",
|
||||
"markdown-preview": "0.83.0",
|
||||
"metrics": "0.32.0",
|
||||
"open-on-github": "0.28.0",
|
||||
"package-generator": "0.31.0",
|
||||
"release-notes": "0.36.0",
|
||||
"settings-view": "0.149.0",
|
||||
"snippets": "0.55.0",
|
||||
"spell-check": "0.42.0",
|
||||
"status-bar": "0.46.0",
|
||||
"styleguide": "0.30.0",
|
||||
"symbols-view": "0.66.0",
|
||||
"tabs": "0.54.0",
|
||||
"timecop": "0.22.0",
|
||||
"tree-view": "0.128.0",
|
||||
"release-notes": "0.32.0",
|
||||
"settings-view": "0.128.0",
|
||||
"snippets": "0.46.0",
|
||||
"spell-check": "0.38.0",
|
||||
"status-bar": "0.41.0",
|
||||
"styleguide": "0.29.0",
|
||||
"symbols-view": "0.56.0",
|
||||
"tabs": "0.42.0",
|
||||
"timecop": "0.19.0",
|
||||
"tree-view": "0.104.0",
|
||||
"update-package-dependencies": "0.6.0",
|
||||
"welcome": "0.18.0",
|
||||
"whitespace": "0.25.0",
|
||||
"wrap-guide": "0.22.0",
|
||||
"language-c": "0.28.0",
|
||||
"language-coffee-script": "0.35.0",
|
||||
"language-css": "0.18.0",
|
||||
"language-gfm": "0.51.0",
|
||||
"welcome": "0.16.0",
|
||||
"whitespace": "0.22.0",
|
||||
"wrap-guide": "0.19.0",
|
||||
"language-c": "0.21.0",
|
||||
"language-coffee-script": "0.22.0",
|
||||
"language-css": "0.17.0",
|
||||
"language-gfm": "0.40.0",
|
||||
"language-git": "0.9.0",
|
||||
"language-go": "0.18.0",
|
||||
"language-html": "0.26.0",
|
||||
"language-hyperlink": "0.12.0",
|
||||
"language-java": "0.11.0",
|
||||
"language-javascript": "0.40.0",
|
||||
"language-go": "0.12.0",
|
||||
"language-html": "0.22.0",
|
||||
"language-hyperlink": "0.10.0",
|
||||
"language-java": "0.10.0",
|
||||
"language-javascript": "0.28.0",
|
||||
"language-json": "0.8.0",
|
||||
"language-less": "0.15.0",
|
||||
"language-make": "0.12.0",
|
||||
"language-mustache": "0.10.0",
|
||||
"language-less": "0.9.0",
|
||||
"language-make": "0.10.0",
|
||||
"language-objective-c": "0.11.0",
|
||||
"language-perl": "0.9.0",
|
||||
"language-php": "0.16.0",
|
||||
"language-php": "0.15.0",
|
||||
"language-property-list": "0.7.0",
|
||||
"language-python": "0.19.0",
|
||||
"language-ruby": "0.39.0",
|
||||
"language-ruby-on-rails": "0.18.0",
|
||||
"language-sass": "0.22.0",
|
||||
"language-python": "0.18.0",
|
||||
"language-ruby": "0.30.0",
|
||||
"language-ruby-on-rails": "0.14.0",
|
||||
"language-sass": "0.13.0",
|
||||
"language-shellscript": "0.8.0",
|
||||
"language-source": "0.8.0",
|
||||
"language-sql": "0.11.0",
|
||||
"language-source": "0.7.0",
|
||||
"language-sql": "0.8.0",
|
||||
"language-text": "0.6.0",
|
||||
"language-todo": "0.12.0",
|
||||
"language-todo": "0.10.0",
|
||||
"language-toml": "0.12.0",
|
||||
"language-xml": "0.22.0",
|
||||
"language-yaml": "0.18.0"
|
||||
"language-xml": "0.15.0",
|
||||
"language-yaml": "0.7.0"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -5,5 +5,4 @@ Exec=<%= installDir %>/share/atom/atom %U
|
||||
Icon=<%= iconName %>
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Utility;TextEditor;Development;
|
||||
MimeType=text/plain;
|
||||
Categories=GNOME;GTK;Utility;TextEditor;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
Package: <%= name %>
|
||||
Version: <%= version %>
|
||||
Depends: python (>= 2.6), libc6
|
||||
Section: <%= section %>
|
||||
Priority: optional
|
||||
Architecture: <%= arch %>
|
||||
Installed-Size: <%= installedSize %>
|
||||
Installed-Size: `du -ks usr|cut -f 1`
|
||||
Maintainer: <%= maintainer %>
|
||||
Description: <%= description %>
|
||||
Atom is a free and open source text editor that is modern, approachable, and hackable to the core.
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
atom: arch-dependent-file-in-usr-share
|
||||
atom: changelog-file-missing-in-native-package
|
||||
atom: copyright-file-contains-full-apache-2-license
|
||||
atom: copyright-should-refer-to-common-license-file-for-apache-2
|
||||
atom: embedded-library
|
||||
atom: package-installs-python-bytecode
|
||||
atom: unstripped-binary-or-object
|
||||
Arquivo binário não exibido.
Arquivo binário não exibido.
+6
-43
@@ -31,7 +31,7 @@ function bootstrap() {
|
||||
fs.mkdirSync(path.join(apmInstallPath, 'node_modules'));
|
||||
|
||||
var apmPath = path.resolve(__dirname, '..', 'apm', 'node_modules', 'atom-package-manager', 'bin', 'apm')
|
||||
var apmFlags = process.env.JANKY_SHA1 || process.argv.indexOf('--no-color') !== -1 ? ' --no-color' : '';
|
||||
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 initialNpmCommand = fs.existsSync(npmPath) ? npmPath : 'npm';
|
||||
@@ -39,49 +39,12 @@ function bootstrap() {
|
||||
|
||||
var packagesToDedupe = ['fs-plus', 'humanize-plus', 'oniguruma', 'roaster', 'season', 'grim'];
|
||||
|
||||
var buildInstallCommand = initialNpmCommand + npmFlags + 'install';
|
||||
var buildInstallOptions = {cwd: path.resolve(__dirname, '..', 'build')};
|
||||
var apmInstallCommand = npmPath + npmFlags + 'install';
|
||||
var apmInstallOptions = {cwd: apmInstallPath};
|
||||
var moduleInstallCommand = apmPath + ' install' + apmFlags;
|
||||
var dedupeApmCommand = apmPath + ' dedupe' + apmFlags;
|
||||
var dedupeNpmCommand = npmPath + npmFlags + 'dedupe';
|
||||
|
||||
if (process.argv.indexOf('--no-quiet') === -1) {
|
||||
buildInstallCommand += ' --quiet';
|
||||
apmInstallCommand += ' --quiet';
|
||||
moduleInstallCommand += ' --quiet';
|
||||
dedupeApmCommand += ' --quiet';
|
||||
dedupeNpmCommand += ' --quiet';
|
||||
buildInstallOptions.ignoreStdout = true;
|
||||
apmInstallOptions.ignoreStdout = true;
|
||||
}
|
||||
|
||||
// apm ships with 32-bit node so make sure its native modules are compiled
|
||||
// for a 32-bit target architecture
|
||||
if (process.env.JANKY_SHA1 && process.platform === 'win32')
|
||||
apmInstallCommand += ' --arch=ia32';
|
||||
|
||||
var commands = [
|
||||
{
|
||||
command: buildInstallCommand,
|
||||
message: 'Installing build modules...',
|
||||
options: buildInstallOptions
|
||||
},
|
||||
{
|
||||
command: apmInstallCommand,
|
||||
message: 'Installing apm...',
|
||||
options: apmInstallOptions
|
||||
},
|
||||
apmPath + ' clean' + apmFlags,
|
||||
moduleInstallCommand,
|
||||
dedupeApmCommand + ' ' + packagesToDedupe.join(' '),
|
||||
{
|
||||
command: dedupeNpmCommand + ' request semver',
|
||||
options: {
|
||||
cwd: path.resolve(__dirname, '..', 'apm', 'node_modules', 'atom-package-manager')
|
||||
}
|
||||
},
|
||||
{command: initialNpmCommand + npmFlags + 'install --quiet', message: 'Installing build modules...', options: {cwd: path.resolve(__dirname, '..', 'build'), ignoreStdout: true}},
|
||||
{command: npmPath + npmFlags + 'install --quiet', message: 'Installing apm...', options: {cwd: apmInstallPath, ignoreStdout: true}},
|
||||
apmPath + ' clean ' + apmFlags,
|
||||
apmPath + ' install --quiet ' + apmFlags,
|
||||
apmPath + ' dedupe --quiet ' + apmFlags + ' ' + packagesToDedupe.join(' '),
|
||||
];
|
||||
|
||||
process.chdir(path.dirname(__dirname));
|
||||
|
||||
+4
-1
@@ -5,6 +5,9 @@ var path = require('path');
|
||||
|
||||
process.chdir(path.dirname(__dirname));
|
||||
|
||||
if (process.platform == 'linux')
|
||||
throw new Error('cibuild can not run on linux yet!');
|
||||
|
||||
var homeDir = process.platform == 'win32' ? process.env.USERPROFILE : process.env.HOME;
|
||||
|
||||
function loadEnvironmentVariables(filePath) {
|
||||
@@ -24,7 +27,7 @@ function loadEnvironmentVariables(filePath) {
|
||||
function readEnvironmentVariables() {
|
||||
if (process.platform === 'win32')
|
||||
loadEnvironmentVariables(path.resolve('/jenkins/config/atomcredentials'));
|
||||
else if (process.platform === 'darwin') {
|
||||
else {
|
||||
loadEnvironmentVariables('/var/lib/jenkins/config/atomcredentials');
|
||||
loadEnvironmentVariables('/var/lib/jenkins/config/xcodekeychain');
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
export ATOM_ACCESS_TOKEN=$BUILD_ATOM_LINUX_ACCESS_TOKEN
|
||||
|
||||
if [ -d /usr/local/share/nodenv ]; then
|
||||
export NODENV_ROOT=/usr/local/share/nodenv
|
||||
export PATH=/usr/local/share/nodenv/bin:/usr/local/share/nodenv/shims:$PATH
|
||||
export NODENV_VERSION="v0.10.21"
|
||||
fi
|
||||
|
||||
script/cibuild
|
||||
@@ -24,7 +24,6 @@ var commands = [
|
||||
[home, '.atom', 'storage'],
|
||||
[home, '.atom', '.npm'],
|
||||
[home, '.atom', 'compile-cache'],
|
||||
[home, '.atom', 'atom-shell'],
|
||||
[tmpdir, 'atom-build'],
|
||||
[tmpdir, 'atom-cached-atom-shells'],
|
||||
];
|
||||
|
||||
+7
-19
@@ -13,35 +13,23 @@ CONTROL_FILE="$3"
|
||||
DESKTOP_FILE="$4"
|
||||
ICON_FILE="$5"
|
||||
DEB_PATH="$6"
|
||||
FILE_MODE=755
|
||||
|
||||
TARGET_ROOT="`mktemp -d`"
|
||||
chmod $FILE_MODE "$TARGET_ROOT"
|
||||
chmod 755 "$TARGET_ROOT"
|
||||
TARGET="$TARGET_ROOT/atom-$VERSION-$ARCH"
|
||||
|
||||
mkdir -m $FILE_MODE -p "$TARGET/usr"
|
||||
mkdir -p "$TARGET/usr"
|
||||
env INSTALL_PREFIX="$TARGET/usr" script/grunt install
|
||||
|
||||
mkdir -m $FILE_MODE -p "$TARGET/DEBIAN"
|
||||
mkdir -p "$TARGET/DEBIAN"
|
||||
cp "$CONTROL_FILE" "$TARGET/DEBIAN/control"
|
||||
|
||||
mkdir -m $FILE_MODE -p "$TARGET/usr/share/applications"
|
||||
mkdir -p "$TARGET/usr/share/applications"
|
||||
cp "$DESKTOP_FILE" "$TARGET/usr/share/applications"
|
||||
|
||||
mkdir -m $FILE_MODE -p "$TARGET/usr/share/pixmaps"
|
||||
mkdir -p "$TARGET/usr/share/pixmaps"
|
||||
cp "$ICON_FILE" "$TARGET/usr/share/pixmaps"
|
||||
|
||||
# Copy generated LICENSE.md to /usr/share/doc/atom/copyright
|
||||
mkdir -m $FILE_MODE -p "$TARGET/usr/share/doc/atom"
|
||||
cp "$TARGET/usr/share/atom/resources/app/LICENSE.md" "$TARGET/usr/share/doc/atom/copyright"
|
||||
|
||||
# Add lintian overrides
|
||||
mkdir -m $FILE_MODE -p "$TARGET/usr/share/lintian/overrides"
|
||||
cp "$ROOT/resources/linux/debian/lintian-overrides" "$TARGET/usr/share/lintian/overrides/atom"
|
||||
|
||||
# Remove executable bit from .node files
|
||||
find "$TARGET" -type f -name "*.node" -exec chmod a-x {} \;
|
||||
|
||||
fakeroot dpkg-deb -b "$TARGET"
|
||||
dpkg-deb -b "$TARGET"
|
||||
mv "$TARGET_ROOT/atom-$VERSION-$ARCH.deb" "$DEB_PATH"
|
||||
rm -rf "$TARGET_ROOT"
|
||||
rm -rf $TARGET_ROOT
|
||||
|
||||
@@ -31,7 +31,7 @@ function verifyNode(cb) {
|
||||
var nodeMajorVersion = +versionArray[0];
|
||||
var nodeMinorVersion = +versionArray[1];
|
||||
if (nodeMajorVersion === 0 && nodeMinorVersion < 10) {
|
||||
error = "node v0.10 is required to build Atom, node " + nodeVersion + " is installed.";
|
||||
error = "node v0.10 is required to build Atom.";
|
||||
cb(error);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -76,9 +76,6 @@ class AtomReporter extends View
|
||||
@addSpecs(specs)
|
||||
$(document.body).append this
|
||||
|
||||
@on 'click', '.stack-trace', ->
|
||||
$(this).toggleClass('expanded')
|
||||
|
||||
reportRunnerResults: (runner) ->
|
||||
@updateSpecCounts()
|
||||
@status.addClass('alert-success').removeClass('alert-info') if @failedCount is 0
|
||||
@@ -122,14 +119,14 @@ class AtomReporter extends View
|
||||
grim.clearDeprecations()
|
||||
|
||||
handleEvents: ->
|
||||
$(document).on "click", ".spec-toggle", ({currentTarget}) ->
|
||||
$(document).on "click", ".spec-toggle", ({currentTarget}) =>
|
||||
element = $(currentTarget)
|
||||
specFailures = element.parent().find('.spec-failures')
|
||||
specFailures.toggle()
|
||||
element.toggleClass('folded')
|
||||
false
|
||||
|
||||
$(document).on "click", ".deprecation-toggle", ({currentTarget}) ->
|
||||
$(document).on "click", ".deprecation-toggle", ({currentTarget}) =>
|
||||
element = $(currentTarget)
|
||||
deprecationList = $(document).find('.deprecation-list')
|
||||
deprecationList.toggle()
|
||||
|
||||
+518
-35
@@ -6,49 +6,532 @@ ThemeManager = require '../src/theme-manager'
|
||||
|
||||
describe "the `atom` global", ->
|
||||
beforeEach ->
|
||||
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView = new WorkspaceView
|
||||
|
||||
describe 'window sizing methods', ->
|
||||
describe '::getPosition and ::setPosition', ->
|
||||
it 'sets the position of the window, and can retrieve the position just set', ->
|
||||
atom.setPosition(22, 45)
|
||||
expect(atom.getPosition()).toEqual x: 22, y: 45
|
||||
describe "package lifecycle methods", ->
|
||||
describe ".loadPackage(name)", ->
|
||||
it "continues if the package has an invalid package.json", ->
|
||||
spyOn(console, 'warn')
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
expect(-> atom.packages.loadPackage("package-with-broken-package-json")).not.toThrow()
|
||||
|
||||
it "continues if the package has an invalid keymap", ->
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
expect(-> atom.packages.loadPackage("package-with-broken-keymap")).not.toThrow()
|
||||
|
||||
describe ".unloadPackage(name)", ->
|
||||
describe "when the package is active", ->
|
||||
it "throws an error", ->
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-main').then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
|
||||
expect(atom.packages.isPackageActive(pack.name)).toBeTruthy()
|
||||
expect( -> atom.packages.unloadPackage(pack.name)).toThrow()
|
||||
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
|
||||
expect(atom.packages.isPackageActive(pack.name)).toBeTruthy()
|
||||
|
||||
describe "when the package is not loaded", ->
|
||||
it "throws an error", ->
|
||||
expect(atom.packages.isPackageLoaded('unloaded')).toBeFalsy()
|
||||
expect( -> atom.packages.unloadPackage('unloaded')).toThrow()
|
||||
expect(atom.packages.isPackageLoaded('unloaded')).toBeFalsy()
|
||||
|
||||
describe "when the package is loaded", ->
|
||||
it "no longers reports it as being loaded", ->
|
||||
pack = atom.packages.loadPackage('package-with-main')
|
||||
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
|
||||
atom.packages.unloadPackage(pack.name)
|
||||
expect(atom.packages.isPackageLoaded(pack.name)).toBeFalsy()
|
||||
|
||||
describe ".activatePackage(id)", ->
|
||||
describe "atom packages", ->
|
||||
describe "when called multiple times", ->
|
||||
it "it only calls activate on the package once", ->
|
||||
spyOn(Package.prototype, 'activateNow').andCallThrough()
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-index')
|
||||
|
||||
runs ->
|
||||
expect(Package.prototype.activateNow.callCount).toBe 1
|
||||
|
||||
describe "when the package has a main module", ->
|
||||
describe "when the metadata specifies a main module path˜", ->
|
||||
it "requires the module at the specified path", ->
|
||||
mainModule = require('./fixtures/packages/package-with-main/main-module')
|
||||
spyOn(mainModule, 'activate')
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-main').then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(mainModule.activate).toHaveBeenCalled()
|
||||
expect(pack.mainModule).toBe mainModule
|
||||
|
||||
describe "when the metadata does not specify a main module", ->
|
||||
it "requires index.coffee", ->
|
||||
indexModule = require('./fixtures/packages/package-with-index/index')
|
||||
spyOn(indexModule, 'activate')
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-index').then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(indexModule.activate).toHaveBeenCalled()
|
||||
expect(pack.mainModule).toBe indexModule
|
||||
|
||||
it "assigns config defaults from the module", ->
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-config-defaults')
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
|
||||
|
||||
describe "when the package metadata includes activation events", ->
|
||||
[mainModule, promise] = []
|
||||
|
||||
beforeEach ->
|
||||
mainModule = require './fixtures/packages/package-with-activation-events/index'
|
||||
spyOn(mainModule, 'activate').andCallThrough()
|
||||
spyOn(Package.prototype, 'requireMainModule').andCallThrough()
|
||||
|
||||
promise = atom.packages.activatePackage('package-with-activation-events')
|
||||
|
||||
it "defers requiring/activating the main module until an activation event bubbles to the root view", ->
|
||||
expect(promise.isFulfilled()).not.toBeTruthy()
|
||||
atom.workspaceView.trigger 'activation-event'
|
||||
|
||||
waitsForPromise ->
|
||||
promise
|
||||
|
||||
it "triggers the activation event on all handlers registered during activation", ->
|
||||
waitsForPromise ->
|
||||
atom.workspaceView.open()
|
||||
|
||||
runs ->
|
||||
editorView = atom.workspaceView.getActiveView()
|
||||
eventHandler = jasmine.createSpy("activation-event")
|
||||
editorView.command 'activation-event', eventHandler
|
||||
editorView.trigger 'activation-event'
|
||||
expect(mainModule.activate.callCount).toBe 1
|
||||
expect(mainModule.activationEventCallCount).toBe 1
|
||||
expect(eventHandler.callCount).toBe 1
|
||||
editorView.trigger 'activation-event'
|
||||
expect(mainModule.activationEventCallCount).toBe 2
|
||||
expect(eventHandler.callCount).toBe 2
|
||||
expect(mainModule.activate.callCount).toBe 1
|
||||
|
||||
it "activates the package immediately when the events are empty", ->
|
||||
mainModule = require './fixtures/packages/package-with-empty-activation-events/index'
|
||||
spyOn(mainModule, 'activate').andCallThrough()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-empty-activation-events')
|
||||
|
||||
runs ->
|
||||
expect(mainModule.activate.callCount).toBe 1
|
||||
|
||||
describe "when the package has no main module", ->
|
||||
it "does not throw an exception", ->
|
||||
spyOn(console, "error")
|
||||
spyOn(console, "warn").andCallThrough()
|
||||
expect(-> atom.packages.activatePackage('package-without-module')).not.toThrow()
|
||||
expect(console.error).not.toHaveBeenCalled()
|
||||
expect(console.warn).not.toHaveBeenCalled()
|
||||
|
||||
it "passes the activate method the package's previously serialized state if it exists", ->
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-serialization").then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(pack.mainModule.someNumber).not.toBe 77
|
||||
pack.mainModule.someNumber = 77
|
||||
atom.packages.deactivatePackage("package-with-serialization")
|
||||
spyOn(pack.mainModule, 'activate').andCallThrough()
|
||||
atom.packages.activatePackage("package-with-serialization")
|
||||
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
|
||||
|
||||
it "logs warning instead of throwing an exception if the package fails to load", ->
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
spyOn(console, "warn")
|
||||
expect(-> atom.packages.activatePackage("package-that-throws-an-exception")).not.toThrow()
|
||||
expect(console.warn).toHaveBeenCalled()
|
||||
|
||||
describe "keymap loading", ->
|
||||
describe "when the metadata does not contain a 'keymaps' manifest", ->
|
||||
it "loads all the .cson/.json files in the keymaps directory", ->
|
||||
element1 = $$ -> @div class: 'test-1'
|
||||
element2 = $$ -> @div class: 'test-2'
|
||||
element3 = $$ -> @div class: 'test-3'
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])).toHaveLength 0
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
|
||||
|
||||
atom.packages.activatePackage("package-with-keymaps")
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe "test-1"
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])[0].command).toBe "test-2"
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
|
||||
|
||||
describe "when the metadata contains a 'keymaps' manifest", ->
|
||||
it "loads only the keymaps specified by the manifest, in the specified order", ->
|
||||
element1 = $$ -> @div class: 'test-1'
|
||||
element3 = $$ -> @div class: 'test-3'
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0
|
||||
|
||||
atom.packages.activatePackage("package-with-keymaps-manifest")
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe 'keymap-1'
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-n', target:element1[0])[0].command).toBe 'keymap-2'
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-y', target:element3[0])).toHaveLength 0
|
||||
|
||||
describe "menu loading", ->
|
||||
beforeEach ->
|
||||
atom.contextMenu.definitions = []
|
||||
atom.menu.template = []
|
||||
|
||||
describe "when the metadata does not contain a 'menus' manifest", ->
|
||||
it "loads all the .cson/.json files in the menus directory", ->
|
||||
element = ($$ -> @div class: 'test-1')[0]
|
||||
|
||||
expect(atom.contextMenu.definitionsForElement(element)).toEqual []
|
||||
|
||||
atom.packages.activatePackage("package-with-menus")
|
||||
|
||||
expect(atom.menu.template.length).toBe 2
|
||||
expect(atom.menu.template[0].label).toBe "Second to Last"
|
||||
expect(atom.menu.template[1].label).toBe "Last"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[0].label).toBe "Menu item 1"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[1].label).toBe "Menu item 2"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[2].label).toBe "Menu item 3"
|
||||
|
||||
describe "when the metadata contains a 'menus' manifest", ->
|
||||
it "loads only the menus specified by the manifest, in the specified order", ->
|
||||
element = ($$ -> @div class: 'test-1')[0]
|
||||
|
||||
expect(atom.contextMenu.definitionsForElement(element)).toEqual []
|
||||
|
||||
atom.packages.activatePackage("package-with-menus-manifest")
|
||||
|
||||
expect(atom.menu.template[0].label).toBe "Second to Last"
|
||||
expect(atom.menu.template[1].label).toBe "Last"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[0].label).toBe "Menu item 2"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[1].label).toBe "Menu item 1"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[2]).toBeUndefined()
|
||||
|
||||
describe "stylesheet loading", ->
|
||||
describe "when the metadata contains a 'stylesheets' manifest", ->
|
||||
it "loads stylesheets from the stylesheets directory as specified by the manifest", ->
|
||||
one = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css")
|
||||
two = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less")
|
||||
three = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css")
|
||||
|
||||
one = atom.themes.stringToId(one)
|
||||
two = atom.themes.stringToId(two)
|
||||
three = atom.themes.stringToId(three)
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
|
||||
|
||||
atom.packages.activatePackage("package-with-stylesheets-manifest")
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).toExist()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toExist()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
|
||||
expect($('#jasmine-content').css('font-size')).toBe '1px'
|
||||
|
||||
describe "when the metadata does not contain a 'stylesheets' manifest", ->
|
||||
it "loads all stylesheets from the stylesheets directory", ->
|
||||
one = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/1.css")
|
||||
two = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/2.less")
|
||||
three = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/3.css")
|
||||
|
||||
|
||||
one = atom.themes.stringToId(one)
|
||||
two = atom.themes.stringToId(two)
|
||||
three = atom.themes.stringToId(three)
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
|
||||
|
||||
atom.packages.activatePackage("package-with-stylesheets")
|
||||
expect(atom.themes.stylesheetElementForId(one)).toExist()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toExist()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toExist()
|
||||
expect($('#jasmine-content').css('font-size')).toBe '3px'
|
||||
|
||||
describe "grammar loading", ->
|
||||
it "loads the package's grammars", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-grammars')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Alot'
|
||||
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Alittle'
|
||||
|
||||
describe "scoped-property loading", ->
|
||||
it "loads the scoped properties", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
|
||||
|
||||
describe "converted textmate packages", ->
|
||||
it "loads the package's grammars", ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
|
||||
it "loads the translated scoped properties", ->
|
||||
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBe '# '
|
||||
|
||||
describe ".deactivatePackage(id)", ->
|
||||
describe "atom packages", ->
|
||||
it "calls `deactivate` on the package's main module if activate was successful", ->
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-deactivate").then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.isPackageActive("package-with-deactivate")).toBeTruthy()
|
||||
spyOn(pack.mainModule, 'deactivate').andCallThrough()
|
||||
|
||||
atom.packages.deactivatePackage("package-with-deactivate")
|
||||
expect(pack.mainModule.deactivate).toHaveBeenCalled()
|
||||
expect(atom.packages.isPackageActive("package-with-module")).toBeFalsy()
|
||||
|
||||
spyOn(console, 'warn')
|
||||
|
||||
badPack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.isPackageActive("package-that-throws-on-activate")).toBeTruthy()
|
||||
spyOn(badPack.mainModule, 'deactivate').andCallThrough()
|
||||
|
||||
atom.packages.deactivatePackage("package-that-throws-on-activate")
|
||||
expect(badPack.mainModule.deactivate).not.toHaveBeenCalled()
|
||||
expect(atom.packages.isPackageActive("package-that-throws-on-activate")).toBeFalsy()
|
||||
|
||||
it "does not serialize packages that have not been activated called on their main module", ->
|
||||
spyOn(console, 'warn')
|
||||
badPack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p
|
||||
|
||||
runs ->
|
||||
spyOn(badPack.mainModule, 'serialize').andCallThrough()
|
||||
|
||||
atom.packages.deactivatePackage("package-that-throws-on-activate")
|
||||
expect(badPack.mainModule.serialize).not.toHaveBeenCalled()
|
||||
|
||||
it "absorbs exceptions that are thrown by the package module's serialize methods", ->
|
||||
spyOn(console, 'error')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-serialize-error')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-serialization')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackages()
|
||||
expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined()
|
||||
expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
|
||||
it "removes the package's grammars", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-grammars')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('package-with-grammars')
|
||||
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Null Grammar'
|
||||
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Null Grammar'
|
||||
|
||||
it "removes the package's keymaps", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-keymaps')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('package-with-keymaps')
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target: ($$ -> @div class: 'test-1')[0])).toHaveLength 0
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target: ($$ -> @div class: 'test-2')[0])).toHaveLength 0
|
||||
|
||||
it "removes the package's stylesheets", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-stylesheets')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('package-with-stylesheets')
|
||||
one = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css")
|
||||
two = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less")
|
||||
three = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css")
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
|
||||
|
||||
it "removes the package's scoped-properties", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
|
||||
atom.packages.deactivatePackage("package-with-scoped-properties")
|
||||
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBeUndefined()
|
||||
|
||||
describe "textmate packages", ->
|
||||
it "removes the package's grammars", ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
atom.packages.deactivatePackage('language-ruby')
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
it "removes the package's scoped properties", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('language-ruby')
|
||||
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
|
||||
|
||||
describe ".activate()", ->
|
||||
packageActivator = null
|
||||
themeActivator = null
|
||||
|
||||
describe '::getSize and ::setSize', ->
|
||||
originalSize = null
|
||||
beforeEach ->
|
||||
originalSize = atom.getSize()
|
||||
afterEach ->
|
||||
atom.setSize(originalSize.width, originalSize.height)
|
||||
spyOn(console, 'warn')
|
||||
atom.packages.loadPackages()
|
||||
|
||||
it 'sets the size of the window, and can retrieve the size just set', ->
|
||||
atom.setSize(100, 400)
|
||||
expect(atom.getSize()).toEqual width: 100, height: 400
|
||||
loadedPackages = atom.packages.getLoadedPackages()
|
||||
expect(loadedPackages.length).toBeGreaterThan 0
|
||||
|
||||
packageActivator = spyOn(atom.packages, 'activatePackages')
|
||||
themeActivator = spyOn(atom.themes, 'activatePackages')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
Syntax = require '../src/syntax'
|
||||
atom.syntax = window.syntax = new Syntax()
|
||||
|
||||
it "activates all the packages, and none of the themes", ->
|
||||
atom.packages.activate()
|
||||
|
||||
expect(packageActivator).toHaveBeenCalled()
|
||||
expect(themeActivator).toHaveBeenCalled()
|
||||
|
||||
packages = packageActivator.mostRecentCall.args[0]
|
||||
expect(['atom', 'textmate']).toContain(pack.getType()) for pack in packages
|
||||
|
||||
themes = themeActivator.mostRecentCall.args[0]
|
||||
expect(['theme']).toContain(theme.getType()) for theme in themes
|
||||
|
||||
describe ".enablePackage() and disablePackage()", ->
|
||||
describe "with packages", ->
|
||||
it ".enablePackage() enables a disabled package", ->
|
||||
packageName = 'package-with-main'
|
||||
atom.config.pushAtKeyPath('core.disabledPackages', packageName)
|
||||
atom.packages.observeDisabledPackages()
|
||||
expect(atom.config.get('core.disabledPackages')).toContain packageName
|
||||
|
||||
pack = atom.packages.enablePackage(packageName)
|
||||
loadedPackages = atom.packages.getLoadedPackages()
|
||||
activatedPackages = null
|
||||
waitsFor ->
|
||||
activatedPackages = atom.packages.getActivePackages()
|
||||
activatedPackages.length > 0
|
||||
|
||||
runs ->
|
||||
expect(loadedPackages).toContain(pack)
|
||||
expect(activatedPackages).toContain(pack)
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
it ".disablePackage() disables an enabled package", ->
|
||||
packageName = 'package-with-main'
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage(packageName)
|
||||
|
||||
runs ->
|
||||
atom.packages.observeDisabledPackages()
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
pack = atom.packages.disablePackage(packageName)
|
||||
|
||||
activatedPackages = atom.packages.getActivePackages()
|
||||
expect(activatedPackages).not.toContain(pack)
|
||||
expect(atom.config.get('core.disabledPackages')).toContain packageName
|
||||
|
||||
describe "with themes", ->
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.themes.activateThemes()
|
||||
|
||||
afterEach ->
|
||||
atom.themes.deactivateThemes()
|
||||
atom.config.unobserve('core.themes')
|
||||
|
||||
it ".enablePackage() and .disablePackage() enables and disables a theme", ->
|
||||
packageName = 'theme-with-package-file'
|
||||
|
||||
expect(atom.config.get('core.themes')).not.toContain packageName
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
# enabling of theme
|
||||
pack = atom.packages.enablePackage(packageName)
|
||||
|
||||
waitsFor ->
|
||||
pack in atom.packages.getActivePackages()
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get('core.themes')).toContain packageName
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
# disabling of theme
|
||||
pack = atom.packages.disablePackage(packageName)
|
||||
|
||||
waitsFor ->
|
||||
not (pack in atom.packages.getActivePackages())
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get('core.themes')).not.toContain packageName
|
||||
expect(atom.config.get('core.themes')).not.toContain packageName
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
describe ".isReleasedVersion()", ->
|
||||
it "returns false if the version is a SHA and true otherwise", ->
|
||||
version = '0.1.0'
|
||||
spyOn(atom, 'getVersion').andCallFake -> version
|
||||
spyOn(atom.constructor, 'getVersion').andCallFake -> version
|
||||
expect(atom.isReleasedVersion()).toBe true
|
||||
version = '36b5518'
|
||||
expect(atom.isReleasedVersion()).toBe false
|
||||
|
||||
describe "window:update-available", ->
|
||||
it "is triggered when the auto-updater sends the update-downloaded event", ->
|
||||
updateAvailableHandler = jasmine.createSpy("update-available-handler")
|
||||
atom.workspaceView.on 'window:update-available', updateAvailableHandler
|
||||
autoUpdater = require('remote').require('auto-updater')
|
||||
autoUpdater.emit 'update-downloaded', null, "notes", "version"
|
||||
|
||||
waitsFor ->
|
||||
updateAvailableHandler.callCount > 0
|
||||
|
||||
runs ->
|
||||
[event, version, notes] = updateAvailableHandler.mostRecentCall.args
|
||||
expect(notes).toBe 'notes'
|
||||
expect(version).toBe 'version'
|
||||
|
||||
describe "loading default config", ->
|
||||
it 'loads the default core config', ->
|
||||
expect(atom.config.get('core.excludeVcsIgnoredPaths')).toBe true
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe false
|
||||
|
||||
@@ -20,7 +20,7 @@ describe "install(commandPath, callback)", ->
|
||||
|
||||
installDone = false
|
||||
installError = null
|
||||
installer.createSymlink commandFilePath, false, (error) ->
|
||||
installer.install commandFilePath, false, (error) ->
|
||||
installDone = true
|
||||
installError = error
|
||||
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
CommandRegistry = require '../src/command-registry'
|
||||
|
||||
describe "CommandRegistry", ->
|
||||
[registry, parent, child, grandchild] = []
|
||||
|
||||
beforeEach ->
|
||||
parent = document.createElement("div")
|
||||
child = document.createElement("div")
|
||||
grandchild = document.createElement("div")
|
||||
parent.classList.add('parent')
|
||||
child.classList.add('child')
|
||||
grandchild.classList.add('grandchild')
|
||||
child.appendChild(grandchild)
|
||||
parent.appendChild(child)
|
||||
document.querySelector('#jasmine-content').appendChild(parent)
|
||||
|
||||
registry = new CommandRegistry(parent)
|
||||
|
||||
describe "command dispatch", ->
|
||||
it "invokes callbacks with selectors matching the target", ->
|
||||
called = false
|
||||
registry.add '.grandchild', 'command', (event) ->
|
||||
expect(this).toBe grandchild
|
||||
expect(event.type).toBe 'command'
|
||||
expect(event.eventPhase).toBe Event.BUBBLING_PHASE
|
||||
expect(event.target).toBe grandchild
|
||||
expect(event.currentTarget).toBe grandchild
|
||||
called = true
|
||||
|
||||
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
|
||||
expect(called).toBe true
|
||||
|
||||
it "invokes callbacks with selectors matching ancestors of the target", ->
|
||||
calls = []
|
||||
|
||||
registry.add '.child', 'command', (event) ->
|
||||
expect(this).toBe child
|
||||
expect(event.target).toBe grandchild
|
||||
expect(event.currentTarget).toBe child
|
||||
calls.push('child')
|
||||
|
||||
registry.add '.parent', 'command', (event) ->
|
||||
expect(this).toBe parent
|
||||
expect(event.target).toBe grandchild
|
||||
expect(event.currentTarget).toBe parent
|
||||
calls.push('parent')
|
||||
|
||||
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
|
||||
expect(calls).toEqual ['child', 'parent']
|
||||
|
||||
it "orders multiple matching listeners for an element by selector specificity", ->
|
||||
child.classList.add('foo', 'bar')
|
||||
calls = []
|
||||
|
||||
registry.add '.foo.bar', 'command', -> calls.push('.foo.bar')
|
||||
registry.add '.foo', 'command', -> calls.push('.foo')
|
||||
registry.add '.bar', 'command', -> calls.push('.bar') # specificity ties favor commands added later, like CSS
|
||||
|
||||
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
|
||||
expect(calls).toEqual ['.foo.bar', '.bar', '.foo']
|
||||
|
||||
it "stops bubbling through ancestors when .stopPropagation() is called on the event", ->
|
||||
calls = []
|
||||
|
||||
registry.add '.parent', 'command', -> calls.push('parent')
|
||||
registry.add '.child', 'command', -> calls.push('child-2')
|
||||
registry.add '.child', 'command', (event) -> calls.push('child-1'); event.stopPropagation()
|
||||
|
||||
dispatchedEvent = new CustomEvent('command', bubbles: true)
|
||||
spyOn(dispatchedEvent, 'stopPropagation')
|
||||
grandchild.dispatchEvent(dispatchedEvent)
|
||||
expect(calls).toEqual ['child-1', 'child-2']
|
||||
expect(dispatchedEvent.stopPropagation).toHaveBeenCalled()
|
||||
|
||||
it "stops invoking callbacks when .stopImmediatePropagation() is called on the event", ->
|
||||
calls = []
|
||||
|
||||
registry.add '.parent', 'command', -> calls.push('parent')
|
||||
registry.add '.child', 'command', -> calls.push('child-2')
|
||||
registry.add '.child', 'command', (event) -> calls.push('child-1'); event.stopImmediatePropagation()
|
||||
|
||||
dispatchedEvent = new CustomEvent('command', bubbles: true)
|
||||
spyOn(dispatchedEvent, 'stopImmediatePropagation')
|
||||
grandchild.dispatchEvent(dispatchedEvent)
|
||||
expect(calls).toEqual ['child-1']
|
||||
expect(dispatchedEvent.stopImmediatePropagation).toHaveBeenCalled()
|
||||
|
||||
it "forwards .preventDefault() calls from the synthetic event to the original", ->
|
||||
calls = []
|
||||
|
||||
registry.add '.child', 'command', (event) -> event.preventDefault()
|
||||
|
||||
dispatchedEvent = new CustomEvent('command', bubbles: true)
|
||||
spyOn(dispatchedEvent, 'preventDefault')
|
||||
grandchild.dispatchEvent(dispatchedEvent)
|
||||
expect(dispatchedEvent.preventDefault).toHaveBeenCalled()
|
||||
|
||||
it "allows listeners to be removed via a disposable returned by ::add", ->
|
||||
calls = []
|
||||
|
||||
disposable1 = registry.add '.parent', 'command', -> calls.push('parent')
|
||||
disposable2 = registry.add '.child', 'command', -> calls.push('child')
|
||||
|
||||
disposable1.dispose()
|
||||
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
|
||||
expect(calls).toEqual ['child']
|
||||
|
||||
calls = []
|
||||
disposable2.dispose()
|
||||
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
|
||||
expect(calls).toEqual []
|
||||
|
||||
it "allows multiple commands to be registered under one selector when called with an object", ->
|
||||
calls = []
|
||||
|
||||
disposable = registry.add '.child',
|
||||
'command-1': -> calls.push('command-1')
|
||||
'command-2': -> calls.push('command-2')
|
||||
|
||||
grandchild.dispatchEvent(new CustomEvent('command-1', bubbles: true))
|
||||
grandchild.dispatchEvent(new CustomEvent('command-2', bubbles: true))
|
||||
|
||||
expect(calls).toEqual ['command-1', 'command-2']
|
||||
|
||||
calls = []
|
||||
disposable.dispose()
|
||||
grandchild.dispatchEvent(new CustomEvent('command-1', bubbles: true))
|
||||
grandchild.dispatchEvent(new CustomEvent('command-2', bubbles: true))
|
||||
expect(calls).toEqual []
|
||||
|
||||
describe "::findCommands({target})", ->
|
||||
it "returns commands that can be invoked on the target or its ancestors", ->
|
||||
registry.add '.parent', 'namespace:command-1', ->
|
||||
registry.add '.child', 'namespace:command-2', ->
|
||||
registry.add '.grandchild', 'namespace:command-3', ->
|
||||
registry.add '.grandchild.no-match', 'namespace:command-4', ->
|
||||
|
||||
expect(registry.findCommands(target: grandchild)[0..2]).toEqual [
|
||||
{name: 'namespace:command-3', displayName: 'Namespace: Command 3'}
|
||||
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
|
||||
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
|
||||
]
|
||||
|
||||
describe "::dispatch(target, commandName)", ->
|
||||
it "simulates invocation of the given command ", ->
|
||||
called = false
|
||||
registry.add '.grandchild', 'command', (event) ->
|
||||
expect(this).toBe grandchild
|
||||
expect(event.type).toBe 'command'
|
||||
expect(event.eventPhase).toBe Event.BUBBLING_PHASE
|
||||
expect(event.target).toBe grandchild
|
||||
expect(event.currentTarget).toBe grandchild
|
||||
called = true
|
||||
|
||||
registry.dispatch(grandchild, 'command')
|
||||
expect(called).toBe true
|
||||
|
||||
it "returns a boolean indicating whether any listeners matched the command", ->
|
||||
registry.add '.grandchild', 'command', ->
|
||||
|
||||
expect(registry.dispatch(grandchild, 'command')).toBe true
|
||||
expect(registry.dispatch(grandchild, 'bogus')).toBe false
|
||||
expect(registry.dispatch(parent, 'command')).toBe false
|
||||
|
||||
describe "::getSnapshot and ::restoreSnapshot", ->
|
||||
it "removes all command handlers except for those in the snapshot", ->
|
||||
registry.add '.parent', 'namespace:command-1', ->
|
||||
registry.add '.child', 'namespace:command-2', ->
|
||||
snapshot = registry.getSnapshot()
|
||||
registry.add '.grandchild', 'namespace:command-3', ->
|
||||
|
||||
expect(registry.findCommands(target: grandchild)[0..2]).toEqual [
|
||||
{name: 'namespace:command-3', displayName: 'Namespace: Command 3'}
|
||||
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
|
||||
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
|
||||
]
|
||||
|
||||
registry.restoreSnapshot(snapshot)
|
||||
|
||||
expect(registry.findCommands(target: grandchild)[0..1]).toEqual [
|
||||
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
|
||||
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
|
||||
]
|
||||
|
||||
registry.add '.grandchild', 'namespace:command-3', ->
|
||||
registry.restoreSnapshot(snapshot)
|
||||
|
||||
expect(registry.findCommands(target: grandchild)[0..1]).toEqual [
|
||||
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
|
||||
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
|
||||
]
|
||||
+19
-617
@@ -12,7 +12,7 @@ describe "Config", ->
|
||||
|
||||
describe ".get(keyPath)", ->
|
||||
it "allows a key path's value to be read", ->
|
||||
expect(atom.config.set("foo.bar.baz", 42)).toBe true
|
||||
expect(atom.config.set("foo.bar.baz", 42)).toBe 42
|
||||
expect(atom.config.get("foo.bar.baz")).toBe 42
|
||||
expect(atom.config.get("bogus.key.path")).toBeUndefined()
|
||||
|
||||
@@ -23,21 +23,9 @@ describe "Config", ->
|
||||
retrievedValue.array[1].b = 2.1
|
||||
expect(atom.config.get('value')).toEqual(array: [1, b: 2, 3])
|
||||
|
||||
it "merges defaults into the returned value if both the assigned value and the default value are objects", ->
|
||||
atom.config.setDefaults("foo", a: 1, b: 2)
|
||||
atom.config.set("foo", a: 3)
|
||||
expect(atom.config.get("foo")).toEqual {a: 3, b: 2}
|
||||
|
||||
atom.config.set("foo", 7)
|
||||
expect(atom.config.get("foo")).toBe 7
|
||||
|
||||
atom.config.set("bar.baz", a: 3)
|
||||
atom.config.setDefaults("bar", baz: 7)
|
||||
expect(atom.config.get("bar.baz")).toEqual {a: 3}
|
||||
|
||||
describe ".set(keyPath, value)", ->
|
||||
it "allows a key path's value to be written", ->
|
||||
expect(atom.config.set("foo.bar.baz", 42)).toBe true
|
||||
expect(atom.config.set("foo.bar.baz", 42)).toBe 42
|
||||
expect(atom.config.get("foo.bar.baz")).toBe 42
|
||||
|
||||
it "updates observers and saves when a key path is set", ->
|
||||
@@ -48,7 +36,7 @@ describe "Config", ->
|
||||
atom.config.set("foo.bar.baz", 42)
|
||||
|
||||
expect(atom.config.save).toHaveBeenCalled()
|
||||
expect(observeHandler).toHaveBeenCalledWith 42
|
||||
expect(observeHandler).toHaveBeenCalledWith 42, {previous: undefined}
|
||||
|
||||
describe "when the value equals the default value", ->
|
||||
it "does not store the value", ->
|
||||
@@ -139,7 +127,7 @@ describe "Config", ->
|
||||
|
||||
expect(atom.config.pushAtKeyPath("foo.bar.baz", "b")).toBe 2
|
||||
expect(atom.config.get("foo.bar.baz")).toEqual ["a", "b"]
|
||||
expect(observeHandler).toHaveBeenCalledWith atom.config.get("foo.bar.baz")
|
||||
expect(observeHandler).toHaveBeenCalledWith atom.config.get("foo.bar.baz"), {previous: ['a']}
|
||||
|
||||
describe ".unshiftAtKeyPath(keyPath, value)", ->
|
||||
it "unshifts the given value to the array at the key path and updates observers", ->
|
||||
@@ -150,7 +138,7 @@ describe "Config", ->
|
||||
|
||||
expect(atom.config.unshiftAtKeyPath("foo.bar.baz", "a")).toBe 2
|
||||
expect(atom.config.get("foo.bar.baz")).toEqual ["a", "b"]
|
||||
expect(observeHandler).toHaveBeenCalledWith atom.config.get("foo.bar.baz")
|
||||
expect(observeHandler).toHaveBeenCalledWith atom.config.get("foo.bar.baz"), {previous: ['b']}
|
||||
|
||||
describe ".removeAtKeyPath(keyPath, value)", ->
|
||||
it "removes the given value from the array at the key path and updates observers", ->
|
||||
@@ -161,22 +149,16 @@ describe "Config", ->
|
||||
|
||||
expect(atom.config.removeAtKeyPath("foo.bar.baz", "b")).toEqual ["a", "c"]
|
||||
expect(atom.config.get("foo.bar.baz")).toEqual ["a", "c"]
|
||||
expect(observeHandler).toHaveBeenCalledWith atom.config.get("foo.bar.baz")
|
||||
expect(observeHandler).toHaveBeenCalledWith atom.config.get("foo.bar.baz"), {previous: ['a', 'b', 'c']}
|
||||
|
||||
describe ".getPositiveInt(keyPath, defaultValue)", ->
|
||||
it "returns the proper coerced value", ->
|
||||
it "returns the proper current or default value", ->
|
||||
atom.config.set('editor.preferredLineLength', 0)
|
||||
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 1
|
||||
|
||||
it "returns the proper coerced value", ->
|
||||
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 80
|
||||
atom.config.set('editor.preferredLineLength', -1234)
|
||||
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 1
|
||||
|
||||
it "returns the default value when a string is passed in", ->
|
||||
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 80
|
||||
atom.config.set('editor.preferredLineLength', 'abcd')
|
||||
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 80
|
||||
|
||||
it "returns the default value when null is passed in", ->
|
||||
atom.config.set('editor.preferredLineLength', null)
|
||||
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 80
|
||||
|
||||
@@ -232,54 +214,11 @@ describe "Config", ->
|
||||
|
||||
it "emits an updated event", ->
|
||||
updatedCallback = jasmine.createSpy('updated')
|
||||
atom.config.onDidChange('foo.bar.baz.a', updatedCallback)
|
||||
atom.config.observe('foo.bar.baz.a', callNow: false, updatedCallback)
|
||||
expect(updatedCallback.callCount).toBe 0
|
||||
atom.config.setDefaults("foo.bar.baz", a: 2)
|
||||
expect(updatedCallback.callCount).toBe 1
|
||||
|
||||
describe ".onDidChange(keyPath)", ->
|
||||
[observeHandler, observeSubscription] = []
|
||||
|
||||
describe 'when a keyPath is specified', ->
|
||||
beforeEach ->
|
||||
observeHandler = jasmine.createSpy("observeHandler")
|
||||
atom.config.set("foo.bar.baz", "value 1")
|
||||
observeSubscription = atom.config.onDidChange "foo.bar.baz", observeHandler
|
||||
|
||||
it "does not fire the given callback with the current value at the keypath", ->
|
||||
expect(observeHandler).not.toHaveBeenCalled()
|
||||
|
||||
it "fires the callback every time the observed value changes", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
atom.config.set('foo.bar.baz', "value 2")
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1', keyPath: 'foo.bar.baz'})
|
||||
observeHandler.reset()
|
||||
|
||||
atom.config.set('foo.bar.baz', "value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2', keyPath: 'foo.bar.baz'})
|
||||
|
||||
describe 'when a keyPath is not specified', ->
|
||||
beforeEach ->
|
||||
observeHandler = jasmine.createSpy("observeHandler")
|
||||
atom.config.set("foo.bar.baz", "value 1")
|
||||
observeSubscription = atom.config.onDidChange observeHandler
|
||||
|
||||
it "does not fire the given callback initially", ->
|
||||
expect(observeHandler).not.toHaveBeenCalled()
|
||||
|
||||
it "fires the callback every time any value changes", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
atom.config.set('foo.bar.baz', "value 2")
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1', keyPath: 'foo.bar.baz'})
|
||||
|
||||
observeHandler.reset()
|
||||
atom.config.set('foo.bar.baz', "value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2', keyPath: 'foo.bar.baz'})
|
||||
|
||||
observeHandler.reset()
|
||||
atom.config.set('foo.bar.int', 1)
|
||||
expect(observeHandler).toHaveBeenCalledWith({newValue: 1, oldValue: undefined, keyPath: 'foo.bar.int'})
|
||||
|
||||
describe ".observe(keyPath)", ->
|
||||
[observeHandler, observeSubscription] = []
|
||||
|
||||
@@ -294,25 +233,26 @@ describe "Config", ->
|
||||
it "fires the callback every time the observed value changes", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
atom.config.set('foo.bar.baz', "value 2")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 2")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 2", {previous: 'value 1'})
|
||||
observeHandler.reset()
|
||||
|
||||
atom.config.set('foo.bar.baz', "value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 1", {previous: 'value 2'})
|
||||
|
||||
it "fires the callback when the observed value is deleted", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
atom.config.set('foo.bar.baz', undefined)
|
||||
expect(observeHandler).toHaveBeenCalledWith(undefined)
|
||||
expect(observeHandler).toHaveBeenCalledWith(undefined, {previous: 'value 1'})
|
||||
|
||||
it "fires the callback when the full key path goes into and out of existence", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
atom.config.set("foo.bar", undefined)
|
||||
expect(observeHandler).toHaveBeenCalledWith(undefined)
|
||||
|
||||
expect(observeHandler).toHaveBeenCalledWith(undefined, {previous: 'value 1'})
|
||||
observeHandler.reset()
|
||||
|
||||
atom.config.set("foo.bar.baz", "i'm back")
|
||||
expect(observeHandler).toHaveBeenCalledWith("i'm back")
|
||||
expect(observeHandler).toHaveBeenCalledWith("i'm back", {previous: undefined})
|
||||
|
||||
it "does not fire the callback once the observe subscription is off'ed", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
@@ -359,19 +299,11 @@ describe "Config", ->
|
||||
describe "when the config file contains valid cson", ->
|
||||
beforeEach ->
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: bar: 'baz'")
|
||||
atom.config.loadUserConfig()
|
||||
|
||||
it "updates the config data based on the file contents", ->
|
||||
atom.config.loadUserConfig()
|
||||
expect(atom.config.get("foo.bar")).toBe 'baz'
|
||||
|
||||
it "notifies observers for updated keypaths on load", ->
|
||||
observeHandler = jasmine.createSpy("observeHandler")
|
||||
observeSubscription = atom.config.observe "foo.bar", observeHandler
|
||||
|
||||
atom.config.loadUserConfig()
|
||||
|
||||
expect(observeHandler).toHaveBeenCalledWith 'baz'
|
||||
|
||||
describe "when the config file contains invalid cson", ->
|
||||
beforeEach ->
|
||||
spyOn(console, 'error')
|
||||
@@ -390,43 +322,10 @@ describe "Config", ->
|
||||
expect(fs.existsSync(atom.config.configFilePath)).toBe true
|
||||
expect(CSON.readFileSync(atom.config.configFilePath)).toEqual {}
|
||||
|
||||
describe "when a schema is specified", ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: 'object'
|
||||
properties:
|
||||
bar:
|
||||
type: 'string'
|
||||
default: 'def'
|
||||
int:
|
||||
type: 'integer'
|
||||
default: 12
|
||||
|
||||
atom.config.setSchema('foo', schema)
|
||||
|
||||
describe "when the config file contains values that do not adhere to the schema", ->
|
||||
warnSpy = null
|
||||
beforeEach ->
|
||||
warnSpy = spyOn console, 'warn'
|
||||
fs.writeFileSync atom.config.configFilePath, """
|
||||
foo:
|
||||
bar: 'baz'
|
||||
int: 'bad value'
|
||||
"""
|
||||
atom.config.loadUserConfig()
|
||||
|
||||
it "updates the only the settings that have values matching the schema", ->
|
||||
expect(atom.config.get("foo.bar")).toBe 'baz'
|
||||
expect(atom.config.get("foo.int")).toBe 12
|
||||
|
||||
expect(warnSpy).toHaveBeenCalled()
|
||||
expect(warnSpy.mostRecentCall.args[0]).toContain "'foo.int' could not be set"
|
||||
|
||||
describe ".observeUserConfig()", ->
|
||||
updatedHandler = null
|
||||
|
||||
beforeEach ->
|
||||
atom.config.setDefaults('foo', bar: 'def')
|
||||
atom.config.configDirPath = dotAtomPath
|
||||
atom.config.configFilePath = path.join(atom.config.configDirPath, "atom.config.cson")
|
||||
expect(fs.existsSync(atom.config.configDirPath)).toBeFalsy()
|
||||
@@ -434,7 +333,7 @@ describe "Config", ->
|
||||
atom.config.loadUserConfig()
|
||||
atom.config.observeUserConfig()
|
||||
updatedHandler = jasmine.createSpy("updatedHandler")
|
||||
atom.config.onDidChange updatedHandler
|
||||
atom.config.on 'updated', updatedHandler
|
||||
|
||||
afterEach ->
|
||||
atom.config.unobserveUserConfig()
|
||||
@@ -448,60 +347,6 @@ describe "Config", ->
|
||||
expect(atom.config.get('foo.bar')).toBe 'quux'
|
||||
expect(atom.config.get('foo.baz')).toBe 'bar'
|
||||
|
||||
it "does not fire a change event for paths that did not change", ->
|
||||
atom.config.onDidChange 'foo.bar', noChangeSpy = jasmine.createSpy()
|
||||
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: 'baz', omg: 'ok'}")
|
||||
waitsFor 'update event', -> updatedHandler.callCount > 0
|
||||
runs ->
|
||||
expect(noChangeSpy).not.toHaveBeenCalled()
|
||||
expect(atom.config.get('foo.bar')).toBe 'baz'
|
||||
expect(atom.config.get('foo.omg')).toBe 'ok'
|
||||
|
||||
describe 'when the default value is a complex value', ->
|
||||
beforeEach ->
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: ['baz', 'ok']}")
|
||||
waitsFor 'update event', -> updatedHandler.callCount > 0
|
||||
runs -> updatedHandler.reset()
|
||||
|
||||
it "does not fire a change event for paths that did not change", ->
|
||||
atom.config.onDidChange 'foo.bar', noChangeSpy = jasmine.createSpy()
|
||||
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: ['baz', 'ok'], omg: 'another'}")
|
||||
waitsFor 'update event', -> updatedHandler.callCount > 0
|
||||
runs ->
|
||||
expect(noChangeSpy).not.toHaveBeenCalled()
|
||||
expect(atom.config.get('foo.bar')).toEqual ['baz', 'ok']
|
||||
expect(atom.config.get('foo.omg')).toBe 'another'
|
||||
|
||||
describe "when the config file changes to omit a setting with a default", ->
|
||||
it "resets the setting back to the default", ->
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: { baz: 'new'}")
|
||||
waitsFor 'update event', -> updatedHandler.callCount > 0
|
||||
runs ->
|
||||
expect(atom.config.get('foo.bar')).toBe 'def'
|
||||
expect(atom.config.get('foo.baz')).toBe 'new'
|
||||
|
||||
describe "when the config file changes to be empty", ->
|
||||
beforeEach ->
|
||||
fs.writeFileSync(atom.config.configFilePath, "")
|
||||
waitsFor 'update event', -> updatedHandler.callCount > 0
|
||||
|
||||
it "resets all settings back to the defaults", ->
|
||||
expect(updatedHandler.callCount).toBe 1
|
||||
expect(atom.config.get('foo.bar')).toBe 'def'
|
||||
atom.config.set("hair", "blonde") # trigger a save
|
||||
expect(atom.config.save).toHaveBeenCalled()
|
||||
|
||||
describe "when the config file subsequently changes again to contain configuration", ->
|
||||
beforeEach ->
|
||||
updatedHandler.reset()
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: bar: 'newVal'")
|
||||
waitsFor 'update event', -> updatedHandler.callCount > 0
|
||||
|
||||
it "sets the setting to the value specified in the config file", ->
|
||||
expect(atom.config.get('foo.bar')).toBe 'newVal'
|
||||
|
||||
describe "when the config file changes to contain invalid cson", ->
|
||||
beforeEach ->
|
||||
spyOn(console, 'error')
|
||||
@@ -516,452 +361,9 @@ describe "Config", ->
|
||||
|
||||
describe "when the config file subsequently changes again to contain valid cson", ->
|
||||
beforeEach ->
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: bar: 'newVal'")
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: bar: 'baz'")
|
||||
waitsFor 'update event', -> updatedHandler.callCount > 0
|
||||
|
||||
it "updates the config data and resumes saving", ->
|
||||
atom.config.set("hair", "blonde")
|
||||
expect(atom.config.save).toHaveBeenCalled()
|
||||
|
||||
describe "when a schema is specified", ->
|
||||
schema = null
|
||||
|
||||
describe '.setSchema(keyPath, schema)', ->
|
||||
it 'creates a properly nested schema', ->
|
||||
schema =
|
||||
type: 'object'
|
||||
properties:
|
||||
anInt:
|
||||
type: 'integer'
|
||||
default: 12
|
||||
|
||||
atom.config.setSchema('foo.bar', schema)
|
||||
|
||||
expect(atom.config.getSchema('foo')).toEqual
|
||||
type: 'object'
|
||||
properties:
|
||||
bar:
|
||||
type: 'object'
|
||||
properties:
|
||||
anInt:
|
||||
type: 'integer'
|
||||
default: 12
|
||||
|
||||
it 'sets defaults specified by the schema', ->
|
||||
schema =
|
||||
type: 'object'
|
||||
properties:
|
||||
anInt:
|
||||
type: 'integer'
|
||||
default: 12
|
||||
anObject:
|
||||
type: 'object'
|
||||
properties:
|
||||
nestedInt:
|
||||
type: 'integer'
|
||||
default: 24
|
||||
nestedObject:
|
||||
type: 'object'
|
||||
properties:
|
||||
superNestedInt:
|
||||
type: 'integer'
|
||||
default: 36
|
||||
|
||||
atom.config.setSchema('foo.bar', schema)
|
||||
expect(atom.config.get("foo.bar.anInt")).toBe 12
|
||||
expect(atom.config.get("foo.bar.anObject")).toEqual
|
||||
nestedInt: 24
|
||||
nestedObject:
|
||||
superNestedInt: 36
|
||||
|
||||
it 'can set a non-object schema', ->
|
||||
schema =
|
||||
type: 'integer'
|
||||
default: 12
|
||||
|
||||
atom.config.setSchema('foo.bar.anInt', schema)
|
||||
expect(atom.config.get("foo.bar.anInt")).toBe 12
|
||||
expect(atom.config.getSchema('foo.bar.anInt')).toEqual
|
||||
type: 'integer'
|
||||
default: 12
|
||||
|
||||
describe '.getSchema(keyPath)', ->
|
||||
schema =
|
||||
type: 'object'
|
||||
properties:
|
||||
anInt:
|
||||
type: 'integer'
|
||||
default: 12
|
||||
|
||||
atom.config.setSchema('foo.bar', schema)
|
||||
|
||||
expect(atom.config.getSchema('foo.bar')).toEqual
|
||||
type: 'object'
|
||||
properties:
|
||||
anInt:
|
||||
type: 'integer'
|
||||
default: 12
|
||||
|
||||
expect(atom.config.getSchema('foo.bar.anInt')).toEqual
|
||||
type: 'integer'
|
||||
default: 12
|
||||
|
||||
describe 'when the value has an "integer" type', ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: 'integer'
|
||||
default: 12
|
||||
atom.config.setSchema('foo.bar.anInt', schema)
|
||||
|
||||
it 'coerces a string to an int', ->
|
||||
atom.config.set('foo.bar.anInt', '123')
|
||||
expect(atom.config.get('foo.bar.anInt')).toBe 123
|
||||
|
||||
it 'does not allow infinity', ->
|
||||
atom.config.set('foo.bar.anInt', Infinity)
|
||||
expect(atom.config.get('foo.bar.anInt')).toBe 12
|
||||
|
||||
it 'coerces a float to an int', ->
|
||||
atom.config.set('foo.bar.anInt', 12.3)
|
||||
expect(atom.config.get('foo.bar.anInt')).toBe 12
|
||||
|
||||
it 'will not set non-integers', ->
|
||||
atom.config.set('foo.bar.anInt', null)
|
||||
expect(atom.config.get('foo.bar.anInt')).toBe 12
|
||||
|
||||
atom.config.set('foo.bar.anInt', 'nope')
|
||||
expect(atom.config.get('foo.bar.anInt')).toBe 12
|
||||
|
||||
describe 'when the minimum and maximum keys are used', ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: 'integer'
|
||||
minimum: 10
|
||||
maximum: 20
|
||||
default: 12
|
||||
atom.config.setSchema('foo.bar.anInt', schema)
|
||||
|
||||
it 'keeps the specified value within the specified range', ->
|
||||
atom.config.set('foo.bar.anInt', '123')
|
||||
expect(atom.config.get('foo.bar.anInt')).toBe 20
|
||||
|
||||
atom.config.set('foo.bar.anInt', '1')
|
||||
expect(atom.config.get('foo.bar.anInt')).toBe 10
|
||||
|
||||
describe 'when the value has an "integer" and "string" type', ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: ['integer', 'string']
|
||||
default: 12
|
||||
atom.config.setSchema('foo.bar.anInt', schema)
|
||||
|
||||
it 'can coerce an int, and fallback to a string', ->
|
||||
atom.config.set('foo.bar.anInt', '123')
|
||||
expect(atom.config.get('foo.bar.anInt')).toBe 123
|
||||
|
||||
atom.config.set('foo.bar.anInt', 'cats')
|
||||
expect(atom.config.get('foo.bar.anInt')).toBe 'cats'
|
||||
|
||||
describe 'when the value has an "string" and "boolean" type', ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: ['string', 'boolean']
|
||||
default: 'def'
|
||||
atom.config.setSchema('foo.bar', schema)
|
||||
|
||||
it 'can set a string, a boolean, and revert back to the default', ->
|
||||
atom.config.set('foo.bar', 'ok')
|
||||
expect(atom.config.get('foo.bar')).toBe 'ok'
|
||||
|
||||
atom.config.set('foo.bar', false)
|
||||
expect(atom.config.get('foo.bar')).toBe false
|
||||
|
||||
atom.config.set('foo.bar', undefined)
|
||||
expect(atom.config.get('foo.bar')).toBe 'def'
|
||||
|
||||
describe 'when the value has a "number" type', ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: 'number'
|
||||
default: 12.1
|
||||
atom.config.setSchema('foo.bar.aFloat', schema)
|
||||
|
||||
it 'coerces a string to a float', ->
|
||||
atom.config.set('foo.bar.aFloat', '12.23')
|
||||
expect(atom.config.get('foo.bar.aFloat')).toBe 12.23
|
||||
|
||||
it 'will not set non-numbers', ->
|
||||
atom.config.set('foo.bar.aFloat', null)
|
||||
expect(atom.config.get('foo.bar.aFloat')).toBe 12.1
|
||||
|
||||
atom.config.set('foo.bar.aFloat', 'nope')
|
||||
expect(atom.config.get('foo.bar.aFloat')).toBe 12.1
|
||||
|
||||
describe 'when the minimum and maximum keys are used', ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: 'number'
|
||||
minimum: 11.2
|
||||
maximum: 25.4
|
||||
default: 12.1
|
||||
atom.config.setSchema('foo.bar.aFloat', schema)
|
||||
|
||||
it 'keeps the specified value within the specified range', ->
|
||||
atom.config.set('foo.bar.aFloat', '123.2')
|
||||
expect(atom.config.get('foo.bar.aFloat')).toBe 25.4
|
||||
|
||||
atom.config.set('foo.bar.aFloat', '1.0')
|
||||
expect(atom.config.get('foo.bar.aFloat')).toBe 11.2
|
||||
|
||||
describe 'when the value has a "boolean" type', ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: 'boolean'
|
||||
default: true
|
||||
atom.config.setSchema('foo.bar.aBool', schema)
|
||||
|
||||
it 'coerces various types to a boolean', ->
|
||||
atom.config.set('foo.bar.aBool', 'true')
|
||||
expect(atom.config.get('foo.bar.aBool')).toBe true
|
||||
atom.config.set('foo.bar.aBool', 'false')
|
||||
expect(atom.config.get('foo.bar.aBool')).toBe false
|
||||
atom.config.set('foo.bar.aBool', 'TRUE')
|
||||
expect(atom.config.get('foo.bar.aBool')).toBe true
|
||||
atom.config.set('foo.bar.aBool', 'FALSE')
|
||||
expect(atom.config.get('foo.bar.aBool')).toBe false
|
||||
atom.config.set('foo.bar.aBool', 1)
|
||||
expect(atom.config.get('foo.bar.aBool')).toBe false
|
||||
atom.config.set('foo.bar.aBool', 0)
|
||||
expect(atom.config.get('foo.bar.aBool')).toBe false
|
||||
atom.config.set('foo.bar.aBool', {})
|
||||
expect(atom.config.get('foo.bar.aBool')).toBe false
|
||||
atom.config.set('foo.bar.aBool', null)
|
||||
expect(atom.config.get('foo.bar.aBool')).toBe false
|
||||
|
||||
it 'reverts back to the default value when undefined is passed to set', ->
|
||||
atom.config.set('foo.bar.aBool', 'false')
|
||||
expect(atom.config.get('foo.bar.aBool')).toBe false
|
||||
|
||||
atom.config.set('foo.bar.aBool', undefined)
|
||||
expect(atom.config.get('foo.bar.aBool')).toBe true
|
||||
|
||||
describe 'when the value has an "string" type', ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: 'string'
|
||||
default: 'ok'
|
||||
atom.config.setSchema('foo.bar.aString', schema)
|
||||
|
||||
it 'allows strings', ->
|
||||
atom.config.set('foo.bar.aString', 'yep')
|
||||
expect(atom.config.get('foo.bar.aString')).toBe 'yep'
|
||||
|
||||
it 'will only set strings', ->
|
||||
expect(atom.config.set('foo.bar.aString', 123)).toBe false
|
||||
expect(atom.config.get('foo.bar.aString')).toBe 'ok'
|
||||
|
||||
expect(atom.config.set('foo.bar.aString', true)).toBe false
|
||||
expect(atom.config.get('foo.bar.aString')).toBe 'ok'
|
||||
|
||||
expect(atom.config.set('foo.bar.aString', null)).toBe false
|
||||
expect(atom.config.get('foo.bar.aString')).toBe 'ok'
|
||||
|
||||
expect(atom.config.set('foo.bar.aString', [])).toBe false
|
||||
expect(atom.config.get('foo.bar.aString')).toBe 'ok'
|
||||
|
||||
expect(atom.config.set('foo.bar.aString', nope: 'nope')).toBe false
|
||||
expect(atom.config.get('foo.bar.aString')).toBe 'ok'
|
||||
|
||||
describe 'when the value has an "object" type', ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: 'object'
|
||||
properties:
|
||||
anInt:
|
||||
type: 'integer'
|
||||
default: 12
|
||||
nestedObject:
|
||||
type: 'object'
|
||||
properties:
|
||||
nestedBool:
|
||||
type: 'boolean'
|
||||
default: false
|
||||
atom.config.setSchema('foo.bar', schema)
|
||||
|
||||
it 'converts and validates all the children', ->
|
||||
atom.config.set 'foo.bar',
|
||||
anInt: '23'
|
||||
nestedObject:
|
||||
nestedBool: 'true'
|
||||
expect(atom.config.get('foo.bar')).toEqual
|
||||
anInt: 23
|
||||
nestedObject:
|
||||
nestedBool: true
|
||||
|
||||
it 'will set only the values that adhere to the schema', ->
|
||||
expect(atom.config.set 'foo.bar',
|
||||
anInt: 'nope'
|
||||
nestedObject:
|
||||
nestedBool: true
|
||||
).toBe true
|
||||
expect(atom.config.get('foo.bar.anInt')).toEqual 12
|
||||
expect(atom.config.get('foo.bar.nestedObject.nestedBool')).toEqual true
|
||||
|
||||
describe 'when the value has an "array" type', ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: 'array'
|
||||
default: [1, 2, 3]
|
||||
items:
|
||||
type: 'integer'
|
||||
atom.config.setSchema('foo.bar', schema)
|
||||
|
||||
it 'converts an array of strings to an array of ints', ->
|
||||
atom.config.set 'foo.bar', ['2', '3', '4']
|
||||
expect(atom.config.get('foo.bar')).toEqual [2, 3, 4]
|
||||
|
||||
describe 'when the `enum` key is used', ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: 'object'
|
||||
properties:
|
||||
str:
|
||||
type: 'string'
|
||||
default: 'ok'
|
||||
enum: ['ok', 'one', 'two']
|
||||
int:
|
||||
type: 'integer'
|
||||
default: 2
|
||||
enum: [2, 3, 5]
|
||||
arr:
|
||||
type: 'array'
|
||||
default: ['one', 'two']
|
||||
items:
|
||||
type: 'string'
|
||||
enum: ['one', 'two', 'three']
|
||||
|
||||
atom.config.setSchema('foo.bar', schema)
|
||||
|
||||
it 'will only set a string when the string is in the enum values', ->
|
||||
expect(atom.config.set('foo.bar.str', 'nope')).toBe false
|
||||
expect(atom.config.get('foo.bar.str')).toBe 'ok'
|
||||
|
||||
expect(atom.config.set('foo.bar.str', 'one')).toBe true
|
||||
expect(atom.config.get('foo.bar.str')).toBe 'one'
|
||||
|
||||
it 'will only set an integer when the integer is in the enum values', ->
|
||||
expect(atom.config.set('foo.bar.int', '400')).toBe false
|
||||
expect(atom.config.get('foo.bar.int')).toBe 2
|
||||
|
||||
expect(atom.config.set('foo.bar.int', '3')).toBe true
|
||||
expect(atom.config.get('foo.bar.int')).toBe 3
|
||||
|
||||
it 'will only set an array when the array values are in the enum values', ->
|
||||
expect(atom.config.set('foo.bar.arr', ['one', 'five'])).toBe true
|
||||
expect(atom.config.get('foo.bar.arr')).toEqual ['one']
|
||||
|
||||
expect(atom.config.set('foo.bar.arr', ['two', 'three'])).toBe true
|
||||
expect(atom.config.get('foo.bar.arr')).toEqual ['two', 'three']
|
||||
|
||||
describe "scoped settings", ->
|
||||
describe ".get(scopeDescriptor, keyPath)", ->
|
||||
it "returns the property with the most specific scope selector", ->
|
||||
atom.config.addScopedSettings(".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
atom.config.addScopedSettings(".source .string.quoted.double", foo: bar: baz: 22)
|
||||
atom.config.addScopedSettings(".source", foo: bar: baz: 11)
|
||||
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
|
||||
expect(atom.config.get([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBe 22
|
||||
expect(atom.config.get([".source.js", ".variable.assignment.js"], "foo.bar.baz")).toBe 11
|
||||
expect(atom.config.get([".text"], "foo.bar.baz")).toBeUndefined()
|
||||
|
||||
it "favors the most recently added properties in the event of a specificity tie", ->
|
||||
atom.config.addScopedSettings(".source.coffee .string.quoted.single", foo: bar: baz: 42)
|
||||
atom.config.addScopedSettings(".source.coffee .string.quoted.double", foo: bar: baz: 22)
|
||||
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.single"], "foo.bar.baz")).toBe 42
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.single.double"], "foo.bar.baz")).toBe 22
|
||||
|
||||
describe 'when there are global defaults', ->
|
||||
it 'falls back to the global when there is no scoped property specified', ->
|
||||
atom.config.setDefaults("foo", hasDefault: 'ok')
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.single"], "foo.hasDefault")).toBe 'ok'
|
||||
|
||||
describe ".set(scope, keyPath, value)", ->
|
||||
it "sets the value and overrides the others", ->
|
||||
atom.config.addScopedSettings(".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
atom.config.addScopedSettings(".source .string.quoted.double", foo: bar: baz: 22)
|
||||
atom.config.addScopedSettings(".source", foo: bar: baz: 11)
|
||||
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
|
||||
|
||||
expect(atom.config.set(".source.coffee .string.quoted.double.coffee", "foo.bar.baz", 100)).toBe true
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 100
|
||||
|
||||
describe ".removeScopedSettingsForName(name)", ->
|
||||
it "allows properties to be removed by name", ->
|
||||
disposable1 = atom.config.addScopedSettings("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
disposable2 = atom.config.addScopedSettings("b", ".source .string.quoted.double", foo: bar: baz: 22)
|
||||
|
||||
disposable2.dispose()
|
||||
expect(atom.config.get([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBeUndefined()
|
||||
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
|
||||
|
||||
describe ".observe(scopeDescriptor, keyPath)", ->
|
||||
it 'calls the supplied callback when the value at the descriptor/keypath changes', ->
|
||||
atom.config.observe [".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz", changeSpy = jasmine.createSpy()
|
||||
expect(changeSpy).toHaveBeenCalledWith(undefined)
|
||||
changeSpy.reset()
|
||||
|
||||
atom.config.set("foo.bar.baz", 12)
|
||||
expect(changeSpy).toHaveBeenCalledWith(12)
|
||||
changeSpy.reset()
|
||||
|
||||
disposable1 = atom.config.addScopedSettings(".source .string.quoted.double", foo: bar: baz: 22)
|
||||
expect(changeSpy).toHaveBeenCalledWith(22)
|
||||
changeSpy.reset()
|
||||
|
||||
disposable2 = atom.config.addScopedSettings("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
expect(changeSpy).toHaveBeenCalledWith(42)
|
||||
changeSpy.reset()
|
||||
|
||||
disposable2.dispose()
|
||||
expect(changeSpy).toHaveBeenCalledWith(22)
|
||||
changeSpy.reset()
|
||||
|
||||
disposable1.dispose()
|
||||
expect(changeSpy).toHaveBeenCalledWith(12)
|
||||
changeSpy.reset()
|
||||
|
||||
atom.config.set("foo.bar.baz", undefined)
|
||||
expect(changeSpy).toHaveBeenCalledWith(undefined)
|
||||
changeSpy.reset()
|
||||
|
||||
describe ".onDidChange(scopeDescriptor, keyPath)", ->
|
||||
it 'calls the supplied callback when the value at the descriptor/keypath changes', ->
|
||||
keyPath = "foo.bar.baz"
|
||||
atom.config.onDidChange [".source.coffee", ".string.quoted.double.coffee"], keyPath, changeSpy = jasmine.createSpy()
|
||||
|
||||
atom.config.set("foo.bar.baz", 12)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: undefined, newValue: 12, keyPath})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable1 = atom.config.addScopedSettings(".source .string.quoted.double", foo: bar: baz: 22)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: 22, keyPath})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable2 = atom.config.addScopedSettings("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 42, keyPath})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable2.dispose()
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 42, newValue: 22, keyPath})
|
||||
changeSpy.reset()
|
||||
|
||||
disposable1.dispose()
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 12, keyPath})
|
||||
changeSpy.reset()
|
||||
|
||||
atom.config.set("foo.bar.baz", undefined)
|
||||
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: undefined, keyPath})
|
||||
changeSpy.reset()
|
||||
|
||||
@@ -3,172 +3,135 @@
|
||||
ContextMenuManager = require '../src/context-menu-manager'
|
||||
|
||||
describe "ContextMenuManager", ->
|
||||
[contextMenu, parent, child, grandchild] = []
|
||||
[contextMenu] = []
|
||||
|
||||
beforeEach ->
|
||||
{resourcePath} = atom.getLoadSettings()
|
||||
contextMenu = new ContextMenuManager({resourcePath})
|
||||
contextMenu = new ContextMenuManager
|
||||
|
||||
parent = document.createElement("div")
|
||||
child = document.createElement("div")
|
||||
grandchild = document.createElement("div")
|
||||
parent.classList.add('parent')
|
||||
child.classList.add('child')
|
||||
grandchild.classList.add('grandchild')
|
||||
child.appendChild(grandchild)
|
||||
parent.appendChild(child)
|
||||
describe "adding definitions", ->
|
||||
it 'loads', ->
|
||||
contextMenu.add 'file-path',
|
||||
'.selector':
|
||||
'label': 'command'
|
||||
|
||||
describe "::add(itemsBySelector)", ->
|
||||
it "can add top-level menu items that can be removed with the returned disposable", ->
|
||||
disposable = contextMenu.add
|
||||
'.parent': [{label: 'A', command: 'a'}]
|
||||
'.child': [{label: 'B', command: 'b'}]
|
||||
'.grandchild': [{label: 'C', command: 'c'}]
|
||||
expect(contextMenu.definitions['.selector'][0].label).toEqual 'label'
|
||||
expect(contextMenu.definitions['.selector'][0].command).toEqual 'command'
|
||||
|
||||
expect(contextMenu.templateForElement(grandchild)).toEqual [
|
||||
{label: 'C', command: 'c'}
|
||||
{label: 'B', command: 'b'}
|
||||
{label: 'A', command: 'a'}
|
||||
]
|
||||
it "loads submenus", ->
|
||||
contextMenu.add 'file-path',
|
||||
'.selector':
|
||||
'parent':
|
||||
'child-1': 'child-1:trigger'
|
||||
'child-2': 'child-2:trigger'
|
||||
'parent-2': 'parent-2:trigger'
|
||||
|
||||
disposable.dispose()
|
||||
expect(contextMenu.templateForElement(grandchild)).toEqual []
|
||||
expect(contextMenu.definitions['.selector'].length).toBe 2
|
||||
expect(contextMenu.definitions['.selector'][0].label).toEqual 'parent'
|
||||
expect(contextMenu.definitions['.selector'][0].submenu.length).toBe 2
|
||||
expect(contextMenu.definitions['.selector'][0].submenu[0].label).toBe 'child-1'
|
||||
expect(contextMenu.definitions['.selector'][0].submenu[0].command).toBe 'child-1:trigger'
|
||||
expect(contextMenu.definitions['.selector'][0].submenu[1].label).toBe 'child-2'
|
||||
expect(contextMenu.definitions['.selector'][0].submenu[1].command).toBe 'child-2:trigger'
|
||||
|
||||
it "can add submenu items to existing menus that can be removed with the returned disposable", ->
|
||||
disposable1 = contextMenu.add
|
||||
'.grandchild': [{label: 'A', submenu: [{label: 'B', command: 'b'}]}]
|
||||
disposable2 = contextMenu.add
|
||||
'.grandchild': [{label: 'A', submenu: [{label: 'C', command: 'c'}]}]
|
||||
describe 'dev mode', ->
|
||||
it 'loads', ->
|
||||
contextMenu.add 'file-path',
|
||||
'.selector':
|
||||
'label': 'command'
|
||||
, devMode: true
|
||||
|
||||
expect(contextMenu.templateForElement(grandchild)).toEqual [{
|
||||
label: 'A',
|
||||
submenu: [
|
||||
{label: 'B', command: 'b'}
|
||||
{label: 'C', command: 'c'}
|
||||
expect(contextMenu.devModeDefinitions['.selector'][0].label).toEqual 'label'
|
||||
expect(contextMenu.devModeDefinitions['.selector'][0].command).toEqual 'command'
|
||||
|
||||
describe "building a menu template", ->
|
||||
beforeEach ->
|
||||
contextMenu.definitions = {
|
||||
'.parent':[
|
||||
label: 'parent'
|
||||
command: 'command-p'
|
||||
]
|
||||
'.child': [
|
||||
label: 'child'
|
||||
command: 'command-c'
|
||||
]
|
||||
}]
|
||||
|
||||
disposable2.dispose()
|
||||
expect(contextMenu.templateForElement(grandchild)).toEqual [{
|
||||
label: 'A',
|
||||
submenu: [
|
||||
{label: 'B', command: 'b'}
|
||||
]
|
||||
}]
|
||||
|
||||
disposable1.dispose()
|
||||
expect(contextMenu.templateForElement(grandchild)).toEqual []
|
||||
|
||||
it "favors the most specific / recently added item in the case of a duplicate label", ->
|
||||
grandchild.classList.add('foo')
|
||||
|
||||
disposable1 = contextMenu.add
|
||||
'.grandchild': [{label: 'A', command: 'a'}]
|
||||
disposable2 = contextMenu.add
|
||||
'.grandchild.foo': [{label: 'A', command: 'b'}]
|
||||
disposable3 = contextMenu.add
|
||||
'.grandchild': [{label: 'A', command: 'c'}]
|
||||
disposable4 = contextMenu.add
|
||||
'.child': [{label: 'A', command: 'd'}]
|
||||
|
||||
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'b'}]
|
||||
|
||||
disposable2.dispose()
|
||||
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'c'}]
|
||||
|
||||
disposable3.dispose()
|
||||
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'a'}]
|
||||
|
||||
disposable1.dispose()
|
||||
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'd'}]
|
||||
|
||||
it "allows multiple separators, but not adjacent to each other", ->
|
||||
contextMenu.add
|
||||
'.grandchild': [
|
||||
{label: 'A', command: 'a'},
|
||||
{type: 'separator'},
|
||||
{type: 'separator'},
|
||||
{label: 'B', command: 'b'},
|
||||
{type: 'separator'},
|
||||
{type: 'separator'},
|
||||
{label: 'C', command: 'c'}
|
||||
]
|
||||
|
||||
expect(contextMenu.templateForElement(grandchild)).toEqual [
|
||||
{label: 'A', command: 'a'},
|
||||
{type: 'separator'},
|
||||
{label: 'B', command: 'b'},
|
||||
{type: 'separator'},
|
||||
{label: 'C', command: 'c'}
|
||||
]
|
||||
|
||||
it "excludes items marked for display in devMode unless in dev mode", ->
|
||||
disposable1 = contextMenu.add
|
||||
'.grandchild': [{label: 'A', command: 'a', devMode: true}, {label: 'B', command: 'b', devMode: false}]
|
||||
|
||||
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'B', command: 'b'}]
|
||||
|
||||
contextMenu.devMode = true
|
||||
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'a'}, {label: 'B', command: 'b'}]
|
||||
|
||||
it "allows items to be associated with `created` hooks which are invoked on template construction with the item and event", ->
|
||||
createdEvent = null
|
||||
|
||||
item = {
|
||||
label: 'A',
|
||||
command: 'a',
|
||||
created: (event) ->
|
||||
@command = 'b'
|
||||
createdEvent = event
|
||||
}
|
||||
|
||||
contextMenu.add('.grandchild': [item])
|
||||
contextMenu.devModeDefinitions =
|
||||
'.parent': [
|
||||
label: 'dev-label'
|
||||
command: 'dev-command'
|
||||
]
|
||||
|
||||
dispatchedEvent = {target: grandchild}
|
||||
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual [{label: 'A', command: 'b'}]
|
||||
expect(item.command).toBe 'a' # doesn't modify original item template
|
||||
expect(createdEvent).toBe dispatchedEvent
|
||||
describe "on a single element", ->
|
||||
[element] = []
|
||||
|
||||
it "allows items to be associated with `shouldDisplay` hooks which are invoked on construction to determine whether the item should be included", ->
|
||||
shouldDisplayEvent = null
|
||||
shouldDisplay = true
|
||||
beforeEach ->
|
||||
element = ($$ -> @div class: 'parent')[0]
|
||||
|
||||
item = {
|
||||
label: 'A',
|
||||
command: 'a',
|
||||
shouldDisplay: (event) ->
|
||||
@foo = 'bar'
|
||||
shouldDisplayEvent = event
|
||||
shouldDisplay
|
||||
}
|
||||
contextMenu.add('.grandchild': [item])
|
||||
it "creates a menu with a single item", ->
|
||||
menu = contextMenu.combinedMenuTemplateForElement(element)
|
||||
|
||||
dispatchedEvent = {target: grandchild}
|
||||
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual [{label: 'A', command: 'a'}]
|
||||
expect(item.foo).toBeUndefined() # doesn't modify original item template
|
||||
expect(shouldDisplayEvent).toBe dispatchedEvent
|
||||
expect(menu[0].label).toEqual 'parent'
|
||||
expect(menu[0].command).toEqual 'command-p'
|
||||
expect(menu[1]).toBeUndefined()
|
||||
|
||||
shouldDisplay = false
|
||||
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual []
|
||||
describe "in devMode", ->
|
||||
beforeEach -> contextMenu.devMode = true
|
||||
|
||||
it "allows items to be specified in the legacy format for now", ->
|
||||
contextMenu.add '.parent':
|
||||
'A': 'a'
|
||||
'Separator 1': '-'
|
||||
'B':
|
||||
'C': 'c'
|
||||
'Separator 2': '-'
|
||||
'D': 'd'
|
||||
it "creates a menu with development items", ->
|
||||
menu = contextMenu.combinedMenuTemplateForElement(element)
|
||||
|
||||
expect(contextMenu.templateForElement(parent)).toEqual [
|
||||
{label: 'A', command: 'a'}
|
||||
{type: 'separator'}
|
||||
{
|
||||
label: 'B'
|
||||
submenu: [
|
||||
{label: 'C', command: 'c'}
|
||||
{type: 'separator'}
|
||||
{label: 'D', command: 'd'}
|
||||
]
|
||||
}
|
||||
expect(menu[0].label).toEqual 'parent'
|
||||
expect(menu[0].command).toEqual 'command-p'
|
||||
expect(menu[1].type).toEqual 'separator'
|
||||
expect(menu[2].label).toEqual 'dev-label'
|
||||
expect(menu[2].command).toEqual 'dev-command'
|
||||
|
||||
|
||||
describe "on multiple elements", ->
|
||||
[element] = []
|
||||
|
||||
beforeEach ->
|
||||
element = $$ ->
|
||||
@div class: 'parent', =>
|
||||
@div class: 'child'
|
||||
|
||||
element = element.find('.child')[0]
|
||||
|
||||
it "creates a menu with a two items", ->
|
||||
menu = contextMenu.combinedMenuTemplateForElement(element)
|
||||
|
||||
expect(menu[0].label).toEqual 'child'
|
||||
expect(menu[0].command).toEqual 'command-c'
|
||||
expect(menu[1].label).toEqual 'parent'
|
||||
expect(menu[1].command).toEqual 'command-p'
|
||||
expect(menu[2]).toBeUndefined()
|
||||
|
||||
describe "in devMode", ->
|
||||
beforeEach -> contextMenu.devMode = true
|
||||
|
||||
xit "creates a menu with development items", ->
|
||||
menu = contextMenu.combinedMenuTemplateForElement(element)
|
||||
|
||||
expect(menu[0].label).toEqual 'child'
|
||||
expect(menu[0].command).toEqual 'command-c'
|
||||
expect(menu[1].label).toEqual 'parent'
|
||||
expect(menu[1].command).toEqual 'command-p'
|
||||
expect(menu[2].label).toEqual 'dev-label'
|
||||
expect(menu[2].command).toEqual 'dev-command'
|
||||
expect(menu[3]).toBeUndefined()
|
||||
|
||||
describe "executeBuildHandlers", ->
|
||||
menuTemplate = [
|
||||
label: 'label'
|
||||
executeAtBuild: ->
|
||||
]
|
||||
event =
|
||||
target: null
|
||||
|
||||
it 'should invoke the executeAtBuild fn', ->
|
||||
buildFn = spyOn(menuTemplate[0], 'executeAtBuild')
|
||||
contextMenu.executeBuildHandlers(event, menuTemplate)
|
||||
|
||||
expect(buildFn).toHaveBeenCalled()
|
||||
expect(buildFn.mostRecentCall.args[0]).toBe event
|
||||
|
||||
@@ -1,44 +1,33 @@
|
||||
DeserializerManager = require '../src/deserializer-manager'
|
||||
|
||||
describe "DeserializerManager", ->
|
||||
manager = null
|
||||
describe ".deserialize(state)", ->
|
||||
deserializer = null
|
||||
|
||||
class Foo
|
||||
@deserialize: ({name}) -> new Foo(name)
|
||||
constructor: (@name) ->
|
||||
|
||||
beforeEach ->
|
||||
manager = new DeserializerManager
|
||||
deserializer = new DeserializerManager()
|
||||
deserializer.add(Foo)
|
||||
|
||||
describe "::add(deserializer)", ->
|
||||
it "returns a disposable that can be used to remove the manager", ->
|
||||
disposable = manager.add(Foo)
|
||||
expect(manager.deserialize({deserializer: 'Foo', name: 'Bar'})).toBeDefined()
|
||||
disposable.dispose()
|
||||
spyOn(console, 'warn')
|
||||
expect(manager.deserialize({deserializer: 'Foo', name: 'Bar'})).toBeUndefined()
|
||||
it "calls deserialize on the deserializer for the given state object, or returns undefined if one can't be found", ->
|
||||
spyOn(console, 'warn')
|
||||
object = deserializer.deserialize({ deserializer: 'Foo', name: 'Bar' })
|
||||
expect(object.name).toBe 'Bar'
|
||||
expect(deserializer.deserialize({ deserializer: 'Bogus' })).toBeUndefined()
|
||||
|
||||
describe "::deserialize(state)", ->
|
||||
describe "when the deserializer has a version", ->
|
||||
beforeEach ->
|
||||
manager.add(Foo)
|
||||
Foo.version = 2
|
||||
|
||||
it "calls deserialize on the manager for the given state object, or returns undefined if one can't be found", ->
|
||||
spyOn(console, 'warn')
|
||||
object = manager.deserialize({deserializer: 'Foo', name: 'Bar'})
|
||||
expect(object.name).toBe 'Bar'
|
||||
expect(manager.deserialize({deserializer: 'Bogus'})).toBeUndefined()
|
||||
describe "when the deserialized state has a matching version", ->
|
||||
it "attempts to deserialize the state", ->
|
||||
object = deserializer.deserialize({ deserializer: 'Foo', version: 2, name: 'Bar' })
|
||||
expect(object.name).toBe 'Bar'
|
||||
|
||||
describe "when the manager has a version", ->
|
||||
beforeEach ->
|
||||
Foo.version = 2
|
||||
|
||||
describe "when the deserialized state has a matching version", ->
|
||||
it "attempts to deserialize the state", ->
|
||||
object = manager.deserialize({deserializer: 'Foo', version: 2, name: 'Bar'})
|
||||
expect(object.name).toBe 'Bar'
|
||||
|
||||
describe "when the deserialized state has a non-matching version", ->
|
||||
it "returns undefined", ->
|
||||
expect(manager.deserialize({deserializer: 'Foo', version: 3, name: 'Bar'})).toBeUndefined()
|
||||
expect(manager.deserialize({deserializer: 'Foo', version: 1, name: 'Bar'})).toBeUndefined()
|
||||
expect(manager.deserialize({deserializer: 'Foo', name: 'Bar'})).toBeUndefined()
|
||||
describe "when the deserialized state has a non-matching version", ->
|
||||
it "returns undefined", ->
|
||||
expect(deserializer.deserialize({ deserializer: 'Foo', version: 3, name: 'Bar' })).toBeUndefined()
|
||||
expect(deserializer.deserialize({ deserializer: 'Foo', version: 1, name: 'Bar' })).toBeUndefined()
|
||||
expect(deserializer.deserialize({ deserializer: 'Foo', name: 'Bar' })).toBeUndefined()
|
||||
|
||||
+128
-267
@@ -9,7 +9,7 @@ describe "DisplayBuffer", ->
|
||||
buffer = atom.project.bufferForPathSync('sample.js')
|
||||
displayBuffer = new DisplayBuffer({buffer, tabLength})
|
||||
changeHandler = jasmine.createSpy 'changeHandler'
|
||||
displayBuffer.onDidChange changeHandler
|
||||
displayBuffer.on 'changed', changeHandler
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-javascript')
|
||||
@@ -47,18 +47,9 @@ describe "DisplayBuffer", ->
|
||||
buffer.insert([0,0], oneHundredLines)
|
||||
expect(displayBuffer.getLineCount()).toBe 100 + originalLineCount
|
||||
|
||||
it "reassigns the scrollTop if it exceeds the max possible value after lines are removed", ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setHeight(50)
|
||||
displayBuffer.setLineHeightInPixels(10)
|
||||
displayBuffer.setScrollTop(80)
|
||||
|
||||
buffer.delete([[8, 0], [10, 0]])
|
||||
expect(displayBuffer.getScrollTop()).toBe 60
|
||||
|
||||
describe "soft wrapping", ->
|
||||
beforeEach ->
|
||||
displayBuffer.setSoftWrapped(true)
|
||||
displayBuffer.setSoftWrap(true)
|
||||
displayBuffer.setEditorWidthInChars(50)
|
||||
changeHandler.reset()
|
||||
|
||||
@@ -67,48 +58,48 @@ describe "DisplayBuffer", ->
|
||||
it "uses the preferred line length as the soft wrap column when it is less than the configured soft wrap column", ->
|
||||
atom.config.set('editor.preferredLineLength', 100)
|
||||
atom.config.set('editor.softWrapAtPreferredLineLength', true)
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' return '
|
||||
expect(displayBuffer.lineForRow(10).text).toBe ' return '
|
||||
|
||||
atom.config.set('editor.preferredLineLength', 5)
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe 'funct'
|
||||
expect(displayBuffer.lineForRow(10).text).toBe 'funct'
|
||||
|
||||
atom.config.set('editor.softWrapAtPreferredLineLength', false)
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' return '
|
||||
expect(displayBuffer.lineForRow(10).text).toBe ' return '
|
||||
|
||||
describe "when the line is shorter than the max line length", ->
|
||||
it "renders the line unchanged", ->
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe buffer.lineForRow(0)
|
||||
expect(displayBuffer.lineForRow(0).text).toBe buffer.lineForRow(0)
|
||||
|
||||
describe "when the line is empty", ->
|
||||
it "renders the empty line", ->
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(13).text).toBe ''
|
||||
expect(displayBuffer.lineForRow(13).text).toBe ''
|
||||
|
||||
describe "when there is a non-whitespace character at the max length boundary", ->
|
||||
describe "when there is whitespace before the boundary", ->
|
||||
it "wraps the line at the end of the first whitespace preceding the boundary", ->
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' return '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(11).text).toBe 'sort(left).concat(pivot).concat(sort(right));'
|
||||
expect(displayBuffer.lineForRow(10).text).toBe ' return '
|
||||
expect(displayBuffer.lineForRow(11).text).toBe 'sort(left).concat(pivot).concat(sort(right));'
|
||||
|
||||
describe "when there is no whitespace before the boundary", ->
|
||||
it "wraps the line exactly at the boundary since there's no more graceful place to wrap it", ->
|
||||
buffer.setTextInRange([[0, 0], [1, 0]], 'abcdefghijklmnopqrstuvwxyz\n')
|
||||
displayBuffer.setEditorWidthInChars(10)
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe 'abcdefghij'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe 'klmnopqrst'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe 'uvwxyz'
|
||||
expect(displayBuffer.lineForRow(0).text).toBe 'abcdefghij'
|
||||
expect(displayBuffer.lineForRow(1).text).toBe 'klmnopqrst'
|
||||
expect(displayBuffer.lineForRow(2).text).toBe 'uvwxyz'
|
||||
|
||||
describe "when there is a whitespace character at the max length boundary", ->
|
||||
it "wraps the line at the first non-whitespace character following the boundary", ->
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe ' var pivot = items.shift(), current, left = [], '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe 'right = [];'
|
||||
expect(displayBuffer.lineForRow(3).text).toBe ' var pivot = items.shift(), current, left = [], '
|
||||
expect(displayBuffer.lineForRow(4).text).toBe 'right = [];'
|
||||
|
||||
describe "when there are hard tabs", ->
|
||||
beforeEach ->
|
||||
buffer.setText(buffer.getText().replace(new RegExp(' ', 'g'), '\t'))
|
||||
|
||||
it "correctly tokenizes the hard tabs", ->
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).tokens[0].isHardTab).toBeTruthy()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).tokens[1].isHardTab).toBeTruthy()
|
||||
expect(displayBuffer.lineForRow(3).tokens[0].isHardTab).toBeTruthy()
|
||||
expect(displayBuffer.lineForRow(3).tokens[1].isHardTab).toBeTruthy()
|
||||
|
||||
describe "when the buffer changes", ->
|
||||
describe "when buffer lines are updated", ->
|
||||
@@ -121,57 +112,57 @@ describe "DisplayBuffer", ->
|
||||
describe "when the update makes a soft-wrapped line shorter than the max line length", ->
|
||||
it "rewraps the line and emits a change event", ->
|
||||
buffer.delete([[6, 24], [6, 42]])
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(7).text).toBe ' current < pivot ? : right.push(current);'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(8).text).toBe ' }'
|
||||
expect(displayBuffer.lineForRow(7).text).toBe ' current < pivot ? : right.push(current);'
|
||||
expect(displayBuffer.lineForRow(8).text).toBe ' }'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[[event]]= changeHandler.argsForCall
|
||||
|
||||
expect(event).toEqual(start: 7, end: 8, screenDelta: -1, bufferDelta: 0)
|
||||
|
||||
describe "when the update causes a line to soft wrap an additional time", ->
|
||||
describe "when the update causes a line to softwrap an additional time", ->
|
||||
it "rewraps the line and emits a change event", ->
|
||||
buffer.insert([6, 28], '1234567890')
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(7).text).toBe ' current < pivot ? '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(8).text).toBe 'left1234567890.push(current) : '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(9).text).toBe 'right.push(current);'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' }'
|
||||
expect(displayBuffer.lineForRow(7).text).toBe ' current < pivot ? '
|
||||
expect(displayBuffer.lineForRow(8).text).toBe 'left1234567890.push(current) : '
|
||||
expect(displayBuffer.lineForRow(9).text).toBe 'right.push(current);'
|
||||
expect(displayBuffer.lineForRow(10).text).toBe ' }'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 7, end: 8, screenDelta: 1, bufferDelta: 0)
|
||||
|
||||
describe "when buffer lines are inserted", ->
|
||||
it "inserts / updates wrapped lines and emits a change event", ->
|
||||
buffer.insert([6, 21], '1234567890 abcdefghij 1234567890\nabcdefghij')
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(7).text).toBe ' current < pivot1234567890 abcdefghij '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(8).text).toBe '1234567890'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(9).text).toBe 'abcdefghij ? left.push(current) : '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe 'right.push(current);'
|
||||
expect(displayBuffer.lineForRow(7).text).toBe ' current < pivot1234567890 abcdefghij '
|
||||
expect(displayBuffer.lineForRow(8).text).toBe '1234567890'
|
||||
expect(displayBuffer.lineForRow(9).text).toBe 'abcdefghij ? left.push(current) : '
|
||||
expect(displayBuffer.lineForRow(10).text).toBe 'right.push(current);'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 7, end: 8, screenDelta: 2, bufferDelta: 1)
|
||||
|
||||
describe "when buffer lines are removed", ->
|
||||
it "removes lines and emits a change event", ->
|
||||
buffer.setTextInRange([[3, 21], [7, 5]], ';')
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe ' var pivot = items;'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe ' return '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(5).text).toBe 'sort(left).concat(pivot).concat(sort(right));'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(6).text).toBe ' };'
|
||||
expect(displayBuffer.lineForRow(3).text).toBe ' var pivot = items;'
|
||||
expect(displayBuffer.lineForRow(4).text).toBe ' return '
|
||||
expect(displayBuffer.lineForRow(5).text).toBe 'sort(left).concat(pivot).concat(sort(right));'
|
||||
expect(displayBuffer.lineForRow(6).text).toBe ' };'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 3, end: 9, screenDelta: -6, bufferDelta: -4)
|
||||
|
||||
describe "when a newline is inserted, deleted, and re-inserted at the end of a wrapped line (regression)", ->
|
||||
it "correctly renders the original wrapped line", ->
|
||||
buffer = atom.project.buildBufferSync(null, '')
|
||||
displayBuffer = new DisplayBuffer({buffer, tabLength, editorWidthInChars: 30, softWrapped: true})
|
||||
displayBuffer = new DisplayBuffer({buffer, tabLength, editorWidthInChars: 30, softWrap: true})
|
||||
|
||||
buffer.insert([0, 0], "the quick brown fox jumps over the lazy dog.")
|
||||
buffer.insert([0, Infinity], '\n')
|
||||
buffer.delete([[0, Infinity], [1, 0]])
|
||||
buffer.insert([0, Infinity], '\n')
|
||||
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "the quick brown fox jumps over "
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "the lazy dog."
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe ""
|
||||
expect(displayBuffer.lineForRow(0).text).toBe "the quick brown fox jumps over "
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "the lazy dog."
|
||||
expect(displayBuffer.lineForRow(2).text).toBe ""
|
||||
|
||||
describe "position translation", ->
|
||||
it "translates positions accounting for wrapped lines", ->
|
||||
@@ -204,9 +195,9 @@ describe "DisplayBuffer", ->
|
||||
describe ".setEditorWidthInChars(length)", ->
|
||||
it "changes the length at which lines are wrapped and emits a change event for all screen lines", ->
|
||||
displayBuffer.setEditorWidthInChars(40)
|
||||
expect(tokensText displayBuffer.tokenizedLineForScreenRow(4).tokens).toBe 'left = [], right = [];'
|
||||
expect(tokensText displayBuffer.tokenizedLineForScreenRow(5).tokens).toBe ' while(items.length > 0) {'
|
||||
expect(tokensText displayBuffer.tokenizedLineForScreenRow(12).tokens).toBe 'sort(left).concat(pivot).concat(sort(rig'
|
||||
expect(tokensText displayBuffer.lineForRow(4).tokens).toBe 'left = [], right = [];'
|
||||
expect(tokensText displayBuffer.lineForRow(5).tokens).toBe ' while(items.length > 0) {'
|
||||
expect(tokensText displayBuffer.lineForRow(12).tokens).toBe 'sort(left).concat(pivot).concat(sort(rig'
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 0, end: 15, screenDelta: 3, bufferDelta: 0)
|
||||
|
||||
it "only allows positive widths to be assigned", ->
|
||||
@@ -215,26 +206,13 @@ describe "DisplayBuffer", ->
|
||||
displayBuffer.setEditorWidthInChars(-1)
|
||||
expect(displayBuffer.editorWidthInChars).not.toBe -1
|
||||
|
||||
it "sets ::scrollLeft to 0 and keeps it there when soft wrapping is enabled", ->
|
||||
displayBuffer.setDefaultCharWidth(10)
|
||||
displayBuffer.setWidth(50)
|
||||
displayBuffer.manageScrollPosition = true
|
||||
|
||||
displayBuffer.setSoftWrapped(false)
|
||||
displayBuffer.setScrollLeft(Infinity)
|
||||
expect(displayBuffer.getScrollLeft()).toBeGreaterThan 0
|
||||
displayBuffer.setSoftWrapped(true)
|
||||
expect(displayBuffer.getScrollLeft()).toBe 0
|
||||
displayBuffer.setScrollLeft(10)
|
||||
expect(displayBuffer.getScrollLeft()).toBe 0
|
||||
|
||||
describe "primitive folding", ->
|
||||
beforeEach ->
|
||||
displayBuffer.destroy()
|
||||
buffer.release()
|
||||
buffer = atom.project.bufferForPathSync('two-hundred.txt')
|
||||
displayBuffer = new DisplayBuffer({buffer, tabLength})
|
||||
displayBuffer.onDidChange changeHandler
|
||||
displayBuffer.on 'changed', changeHandler
|
||||
|
||||
describe "when folds are created and destroyed", ->
|
||||
describe "when a fold spans multiple lines", ->
|
||||
@@ -242,7 +220,7 @@ describe "DisplayBuffer", ->
|
||||
fold = displayBuffer.createFold(4, 7)
|
||||
expect(fold).toBeDefined()
|
||||
|
||||
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
expect(line4.fold).toBe fold
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line5.text).toBe '8'
|
||||
@@ -251,7 +229,7 @@ describe "DisplayBuffer", ->
|
||||
changeHandler.reset()
|
||||
|
||||
fold.destroy()
|
||||
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
expect(line4.fold).toBeUndefined()
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line5.text).toBe '5'
|
||||
@@ -262,7 +240,7 @@ describe "DisplayBuffer", ->
|
||||
it "renders a fold placeholder for the folded line but does not skip any lines", ->
|
||||
fold = displayBuffer.createFold(4, 4)
|
||||
|
||||
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
expect(line4.fold).toBe fold
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line5.text).toBe '5'
|
||||
@@ -275,7 +253,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
fold.destroy()
|
||||
|
||||
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
expect(line4.fold).toBeUndefined()
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line5.text).toBe '5'
|
||||
@@ -287,13 +265,13 @@ describe "DisplayBuffer", ->
|
||||
innerFold = displayBuffer.createFold(6, 7)
|
||||
outerFold = displayBuffer.createFold(4, 8)
|
||||
|
||||
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
expect(line4.fold).toBe outerFold
|
||||
expect(line4.text).toMatch /4-+/
|
||||
expect(line5.text).toMatch /9-+/
|
||||
|
||||
outerFold.destroy()
|
||||
[line4, line5, line6, line7] = displayBuffer.tokenizedLinesForScreenRows(4, 7)
|
||||
[line4, line5, line6, line7] = displayBuffer.linesForRows(4, 7)
|
||||
expect(line4.fold).toBeUndefined()
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line5.text).toBe '5'
|
||||
@@ -305,7 +283,7 @@ describe "DisplayBuffer", ->
|
||||
innerFold = displayBuffer.createFold(4, 6)
|
||||
outerFold = displayBuffer.createFold(4, 8)
|
||||
|
||||
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
expect(line4.fold).toBe outerFold
|
||||
expect(line4.text).toMatch /4-+/
|
||||
expect(line5.text).toMatch /9-+/
|
||||
@@ -326,25 +304,17 @@ describe "DisplayBuffer", ->
|
||||
|
||||
innerFold = displayBuffer.createFold(2, 5)
|
||||
expect(changeHandler).not.toHaveBeenCalled()
|
||||
[line0, line1] = displayBuffer.tokenizedLinesForScreenRows(0, 1)
|
||||
[line0, line1] = displayBuffer.linesForRows(0, 1)
|
||||
expect(line0.fold).toBe outerFold
|
||||
expect(line1.fold).toBeUndefined()
|
||||
|
||||
changeHandler.reset()
|
||||
innerFold.destroy()
|
||||
expect(changeHandler).not.toHaveBeenCalled()
|
||||
[line0, line1] = displayBuffer.tokenizedLinesForScreenRows(0, 1)
|
||||
[line0, line1] = displayBuffer.linesForRows(0, 1)
|
||||
expect(line0.fold).toBe outerFold
|
||||
expect(line1.fold).toBeUndefined()
|
||||
|
||||
describe "when a fold ends where another fold begins", ->
|
||||
it "continues to hide the lines inside the second fold", ->
|
||||
fold2 = displayBuffer.createFold(4, 9)
|
||||
fold1 = displayBuffer.createFold(0, 4)
|
||||
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toMatch /^0/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toMatch /^10/
|
||||
|
||||
describe "when there is another display buffer pointing to the same buffer", ->
|
||||
it "does not create folds in the other display buffer", ->
|
||||
otherDisplayBuffer = new DisplayBuffer({buffer, tabLength})
|
||||
@@ -363,19 +333,19 @@ describe "DisplayBuffer", ->
|
||||
buffer.setTextInRange([[1, 0], [5, 1]], 'party!')
|
||||
|
||||
it "removes the fold and replaces the selection with the new text", ->
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "0"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "party!"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch /^9-+/
|
||||
expect(displayBuffer.lineForRow(0).text).toBe "0"
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "party!"
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(3).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 1, end: 3, screenDelta: -2, bufferDelta: -4)
|
||||
|
||||
describe "when the changes is subsequently undone", ->
|
||||
xit "restores destroyed folds", ->
|
||||
buffer.undo()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe '2'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe '5'
|
||||
expect(displayBuffer.lineForRow(2).text).toBe '2'
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(3).text).toBe '5'
|
||||
|
||||
describe "when the old range surrounds two nested folds", ->
|
||||
it "removes both folds and replaces the selection with the new text", ->
|
||||
@@ -384,9 +354,9 @@ describe "DisplayBuffer", ->
|
||||
|
||||
buffer.setTextInRange([[1, 0], [10, 0]], 'goodbye')
|
||||
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "0"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "goodbye10"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe "11"
|
||||
expect(displayBuffer.lineForRow(0).text).toBe "0"
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "goodbye10"
|
||||
expect(displayBuffer.lineForRow(2).text).toBe "11"
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 1, end: 3, screenDelta: -2, bufferDelta: -9)
|
||||
|
||||
@@ -403,42 +373,42 @@ describe "DisplayBuffer", ->
|
||||
it "updates the buffer and re-positions subsequent folds", ->
|
||||
buffer.setTextInRange([[0, 0], [1, 1]], 'abc')
|
||||
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "abc"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).fold).toBe fold1
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe "5"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toMatch /^9-+/
|
||||
expect(displayBuffer.lineForRow(0).text).toBe "abc"
|
||||
expect(displayBuffer.lineForRow(1).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(2).text).toBe "5"
|
||||
expect(displayBuffer.lineForRow(3).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(4).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 0, end: 1, screenDelta: -1, bufferDelta: -1)
|
||||
changeHandler.reset()
|
||||
|
||||
fold1.destroy()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "abc"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "2"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch /^4-+/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe "5"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(5).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(6).text).toMatch /^9-+/
|
||||
expect(displayBuffer.lineForRow(0).text).toBe "abc"
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "2"
|
||||
expect(displayBuffer.lineForRow(3).text).toMatch /^4-+/
|
||||
expect(displayBuffer.lineForRow(4).text).toBe "5"
|
||||
expect(displayBuffer.lineForRow(5).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(6).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 1, end: 1, screenDelta: 2, bufferDelta: 0)
|
||||
|
||||
describe "when the old range straddles the beginning of a fold", ->
|
||||
it "destroys the fold", ->
|
||||
buffer.setTextInRange([[1, 1], [3, 0]], "a\nb\nc\nd\n")
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe '1a'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe 'b'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBeUndefined()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe 'c'
|
||||
expect(displayBuffer.lineForRow(1).text).toBe '1a'
|
||||
expect(displayBuffer.lineForRow(2).text).toBe 'b'
|
||||
expect(displayBuffer.lineForRow(2).fold).toBeUndefined()
|
||||
expect(displayBuffer.lineForRow(3).text).toBe 'c'
|
||||
|
||||
describe "when the old range follows a fold", ->
|
||||
it "re-positions the screen ranges for the change event based on the preceding fold", ->
|
||||
buffer.setTextInRange([[10, 0], [11, 0]], 'abc')
|
||||
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "1"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe "5"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(5).text).toMatch /^9-+/
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "1"
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(3).text).toBe "5"
|
||||
expect(displayBuffer.lineForRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 6, end: 7, screenDelta: -1, bufferDelta: -1)
|
||||
|
||||
@@ -449,12 +419,12 @@ describe "DisplayBuffer", ->
|
||||
expect(fold1.getStartRow()).toBe 2
|
||||
expect(fold1.getEndRow()).toBe 5
|
||||
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "1"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe "2"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch "5"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(5).text).toMatch /^9-+/
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "1"
|
||||
expect(displayBuffer.lineForRow(2).text).toBe "2"
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(3).text).toMatch "5"
|
||||
expect(displayBuffer.lineForRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 2, end: 2, screenDelta: 0, bufferDelta: 1)
|
||||
|
||||
@@ -464,12 +434,12 @@ describe "DisplayBuffer", ->
|
||||
expect(fold1.getStartRow()).toBe 2
|
||||
expect(fold1.getEndRow()).toBe 7
|
||||
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "1"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe "2"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch "5"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(5).text).toMatch /^9-+/
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "1"
|
||||
expect(displayBuffer.lineForRow(2).text).toBe "2"
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(3).text).toMatch "5"
|
||||
expect(displayBuffer.lineForRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 2, end: 2, screenDelta: 0, bufferDelta: 3)
|
||||
|
||||
@@ -478,21 +448,21 @@ describe "DisplayBuffer", ->
|
||||
it "destroys the fold", ->
|
||||
fold2.destroy()
|
||||
buffer.setTextInRange([[3, 0], [6, 0]], 'a\n')
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe '2'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBeUndefined()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe 'a'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe '6'
|
||||
expect(displayBuffer.lineForRow(2).text).toBe '2'
|
||||
expect(displayBuffer.lineForRow(2).fold).toBeUndefined()
|
||||
expect(displayBuffer.lineForRow(3).text).toBe 'a'
|
||||
expect(displayBuffer.lineForRow(4).text).toBe '6'
|
||||
|
||||
describe "when the old range is contained to a single line in-between two folds", ->
|
||||
it "re-renders the line with the placeholder and re-positions the second fold", ->
|
||||
buffer.insert([5, 0], 'abc\n')
|
||||
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "1"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch "abc"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe "5"
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(5).fold).toBe fold2
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(6).text).toMatch /^9-+/
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "1"
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(3).text).toMatch "abc"
|
||||
expect(displayBuffer.lineForRow(4).text).toBe "5"
|
||||
expect(displayBuffer.lineForRow(5).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(6).text).toMatch /^9-+/
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 3, end: 3, screenDelta: 1, bufferDelta: 1)
|
||||
|
||||
@@ -545,15 +515,15 @@ describe "DisplayBuffer", ->
|
||||
displayBuffer.createFold(1, 9)
|
||||
displayBuffer.createFold(11, 12)
|
||||
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe '1'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe '10'
|
||||
expect(displayBuffer.lineForRow(1).text).toBe '1'
|
||||
expect(displayBuffer.lineForRow(2).text).toBe '10'
|
||||
|
||||
displayBuffer.unfoldBufferRow(2)
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe '1'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe '2'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(7).fold).toBeDefined()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(8).text).toMatch /^9-+/
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).fold).toBeDefined()
|
||||
expect(displayBuffer.lineForRow(1).text).toBe '1'
|
||||
expect(displayBuffer.lineForRow(2).text).toBe '2'
|
||||
expect(displayBuffer.lineForRow(7).fold).toBeDefined()
|
||||
expect(displayBuffer.lineForRow(8).text).toMatch /^9-+/
|
||||
expect(displayBuffer.lineForRow(10).fold).toBeDefined()
|
||||
|
||||
describe ".outermostFoldsInBufferRowRange(startRow, endRow)", ->
|
||||
it "returns the outermost folds entirely contained in the given row range, exclusive of end row", ->
|
||||
@@ -568,7 +538,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "::clipScreenPosition(screenPosition, wrapBeyondNewlines: false, wrapAtSoftNewlines: false, skipAtomicTokens: false)", ->
|
||||
beforeEach ->
|
||||
displayBuffer.setSoftWrapped(true)
|
||||
displayBuffer.setSoftWrap(true)
|
||||
displayBuffer.setEditorWidthInChars(50)
|
||||
|
||||
it "allows valid positions", ->
|
||||
@@ -643,7 +613,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
it "correctly translates positions on soft wrapped lines containing tabs", ->
|
||||
buffer.setText('\t\taa bb cc dd ee ff gg')
|
||||
displayBuffer.setSoftWrapped(true)
|
||||
displayBuffer.setSoftWrap(true)
|
||||
displayBuffer.setEditorWidthInChars(10)
|
||||
expect(displayBuffer.screenPositionForBufferPosition([0, 10], wrapAtSoftNewlines: true)).toEqual [1, 0]
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([1, 0])).toEqual [0, 10]
|
||||
@@ -654,19 +624,6 @@ describe "DisplayBuffer", ->
|
||||
buffer.delete([[6, 0], [6, 65]])
|
||||
expect(displayBuffer.getMaxLineLength()).toBe 62
|
||||
|
||||
it "correctly updates the location of the longest screen line when changes occur", ->
|
||||
expect(displayBuffer.getLongestScreenRow()).toBe 6
|
||||
buffer.delete([[0, 0], [2, 0]])
|
||||
expect(displayBuffer.getLongestScreenRow()).toBe 4
|
||||
buffer.delete([[4, 0], [5, 0]])
|
||||
|
||||
expect(displayBuffer.getLongestScreenRow()).toBe 1
|
||||
expect(displayBuffer.getMaxLineLength()).toBe 62
|
||||
|
||||
buffer.delete([[2, 0], [4, 0]])
|
||||
expect(displayBuffer.getLongestScreenRow()).toBe 1
|
||||
expect(displayBuffer.getMaxLineLength()).toBe 62
|
||||
|
||||
describe "::destroy()", ->
|
||||
it "unsubscribes all display buffer markers from their underlying buffer marker (regression)", ->
|
||||
marker = displayBuffer.markBufferPosition([12, 2])
|
||||
@@ -686,7 +643,7 @@ describe "DisplayBuffer", ->
|
||||
expect(marker2.getScreenRange()).toEqual [[5, 4], [5, 10]]
|
||||
|
||||
it "emits a 'marker-created' event on the DisplayBuffer whenever a marker is created", ->
|
||||
displayBuffer.onDidCreateMarker markerCreatedHandler = jasmine.createSpy("markerCreatedHandler")
|
||||
displayBuffer.on 'marker-created', markerCreatedHandler = jasmine.createSpy("markerCreatedHandler")
|
||||
|
||||
marker1 = displayBuffer.markScreenRange([[5, 4], [5, 10]])
|
||||
expect(markerCreatedHandler).toHaveBeenCalledWith(marker1)
|
||||
@@ -722,7 +679,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
beforeEach ->
|
||||
marker = displayBuffer.markScreenRange([[5, 4], [5, 10]])
|
||||
marker.onDidChange markerChangedHandler = jasmine.createSpy("markerChangedHandler")
|
||||
marker.on 'changed', markerChangedHandler = jasmine.createSpy("markerChangedHandler")
|
||||
|
||||
it "triggers the 'changed' event whenever the markers head's screen position changes in the buffer or on screen", ->
|
||||
marker.setHeadScreenPosition([8, 20])
|
||||
@@ -859,8 +816,8 @@ describe "DisplayBuffer", ->
|
||||
|
||||
it "updates markers before emitting buffer change events, but does not notify their observers until the change event", ->
|
||||
marker2 = displayBuffer.markBufferRange([[8, 1], [8, 1]])
|
||||
marker2.onDidChange marker2ChangedHandler = jasmine.createSpy("marker2ChangedHandler")
|
||||
displayBuffer.onDidChange changeHandler = jasmine.createSpy("changeHandler").andCallFake -> onDisplayBufferChange()
|
||||
marker2.on 'changed', marker2ChangedHandler = jasmine.createSpy("marker2ChangedHandler")
|
||||
displayBuffer.on 'changed', changeHandler = jasmine.createSpy("changeHandler").andCallFake -> onDisplayBufferChange()
|
||||
|
||||
# New change ----
|
||||
|
||||
@@ -886,7 +843,7 @@ describe "DisplayBuffer", ->
|
||||
marker2ChangedHandler.reset()
|
||||
|
||||
marker3 = displayBuffer.markBufferRange([[8, 1], [8, 2]])
|
||||
marker3.onDidChange marker3ChangedHandler = jasmine.createSpy("marker3ChangedHandler")
|
||||
marker3.on 'changed', marker3ChangedHandler = jasmine.createSpy("marker3ChangedHandler")
|
||||
|
||||
onDisplayBufferChange = ->
|
||||
# calls change handler first
|
||||
@@ -932,7 +889,7 @@ describe "DisplayBuffer", ->
|
||||
expect(marker3ChangedHandler).toHaveBeenCalled()
|
||||
|
||||
it "updates the position of markers before emitting change events that aren't caused by a buffer change", ->
|
||||
displayBuffer.onDidChange changeHandler = jasmine.createSpy("changeHandler").andCallFake ->
|
||||
displayBuffer.on 'changed', changeHandler = jasmine.createSpy("changeHandler").andCallFake ->
|
||||
# calls change handler first
|
||||
expect(markerChangedHandler).not.toHaveBeenCalled()
|
||||
# but still updates the markers
|
||||
@@ -998,20 +955,20 @@ describe "DisplayBuffer", ->
|
||||
expect(marker.isValid()).toBeFalsy()
|
||||
expect(displayBuffer.getMarker(marker.id)).toBeUndefined()
|
||||
|
||||
it "notifies ::onDidDestroy observers when markers are destroyed", ->
|
||||
it "emits 'destroyed' events when markers are destroyed", ->
|
||||
destroyedHandler = jasmine.createSpy("destroyedHandler")
|
||||
marker = displayBuffer.markScreenRange([[5, 4], [5, 10]])
|
||||
marker.onDidDestroy destroyedHandler
|
||||
marker.on 'destroyed', destroyedHandler
|
||||
marker.destroy()
|
||||
expect(destroyedHandler).toHaveBeenCalled()
|
||||
destroyedHandler.reset()
|
||||
|
||||
marker2 = displayBuffer.markScreenRange([[5, 4], [5, 10]])
|
||||
marker2.onDidDestroy destroyedHandler
|
||||
marker2.on 'destroyed', destroyedHandler
|
||||
buffer.getMarker(marker2.id).destroy()
|
||||
expect(destroyedHandler).toHaveBeenCalled()
|
||||
|
||||
describe "Marker::copy(attributes)", ->
|
||||
describe "DisplayBufferMarker::copy(attributes)", ->
|
||||
it "creates a copy of the marker with the given attributes merged in", ->
|
||||
initialMarkerCount = displayBuffer.getMarkerCount()
|
||||
marker1 = displayBuffer.markScreenRange([[5, 4], [5, 10]], a: 1, b: 2)
|
||||
@@ -1020,65 +977,31 @@ describe "DisplayBuffer", ->
|
||||
marker2 = marker1.copy(b: 3)
|
||||
expect(marker2.getBufferRange()).toEqual marker1.getBufferRange()
|
||||
expect(displayBuffer.getMarkerCount()).toBe initialMarkerCount + 2
|
||||
expect(marker1.getProperties()).toEqual a: 1, b: 2
|
||||
expect(marker2.getProperties()).toEqual a: 1, b: 3
|
||||
expect(marker1.getAttributes()).toEqual a: 1, b: 2
|
||||
expect(marker2.getAttributes()).toEqual a: 1, b: 3
|
||||
|
||||
describe "Marker::getPixelRange()", ->
|
||||
describe "DisplayBufferMarker::getPixelRange()", ->
|
||||
it "returns the start and end positions of the marker based on the line height and character widths assigned to the DisplayBuffer", ->
|
||||
marker = displayBuffer.markScreenRange([[5, 10], [6, 4]])
|
||||
|
||||
displayBuffer.setLineHeightInPixels(20)
|
||||
displayBuffer.setDefaultCharWidth(10)
|
||||
|
||||
for char in ['r', 'e', 't', 'u', 'r', 'n']
|
||||
displayBuffer.setScopedCharWidth(["source.js", "keyword.control.js"], char, 11)
|
||||
displayBuffer.setScopedCharWidths(["source.js", "keyword.control.js"], r: 11, e: 11, t: 11, u: 11, n: 11)
|
||||
|
||||
{start, end} = marker.getPixelRange()
|
||||
expect(start.top).toBe 5 * 20
|
||||
expect(start.left).toBe (4 * 10) + (6 * 11)
|
||||
|
||||
describe 'when there are multiple DisplayBuffers for a buffer', ->
|
||||
describe 'when a marker is created', ->
|
||||
it 'the second display buffer will not emit a marker-created event when the marker has been deleted in the first marker-created event', ->
|
||||
displayBuffer2 = new DisplayBuffer({buffer, tabLength})
|
||||
displayBuffer.onDidCreateMarker markerCreated1 = jasmine.createSpy().andCallFake (marker) -> marker.destroy()
|
||||
displayBuffer2.onDidCreateMarker markerCreated2 = jasmine.createSpy()
|
||||
|
||||
displayBuffer.markBufferRange([[0, 0], [1, 5]], {})
|
||||
|
||||
expect(markerCreated1).toHaveBeenCalled()
|
||||
expect(markerCreated2).not.toHaveBeenCalled()
|
||||
|
||||
describe "decorations", ->
|
||||
[marker, decoration, decorationProperties] = []
|
||||
beforeEach ->
|
||||
marker = displayBuffer.markBufferRange([[2, 13], [3, 15]])
|
||||
decorationProperties = {type: 'gutter', class: 'one'}
|
||||
decoration = displayBuffer.decorateMarker(marker, decorationProperties)
|
||||
|
||||
it "can add decorations associated with markers and remove them", ->
|
||||
expect(decoration).toBeDefined()
|
||||
expect(decoration.getProperties()).toBe decorationProperties
|
||||
expect(displayBuffer.decorationForId(decoration.id)).toBe decoration
|
||||
decoration = {type: 'gutter', class: 'one'}
|
||||
marker = displayBuffer.markBufferRange([[2, 13], [3, 15]])
|
||||
|
||||
displayBuffer.addDecorationForMarker(marker, decoration)
|
||||
expect(displayBuffer.decorationsForScreenRowRange(2, 3)[marker.id][0]).toBe decoration
|
||||
|
||||
decoration.destroy()
|
||||
displayBuffer.removeDecorationForMarker(marker, decoration)
|
||||
expect(displayBuffer.decorationsForScreenRowRange(2, 3)[marker.id]).not.toBeDefined()
|
||||
expect(displayBuffer.decorationForId(decoration.id)).not.toBeDefined()
|
||||
|
||||
it "will not fail if the decoration is removed twice", ->
|
||||
decoration.destroy()
|
||||
decoration.destroy()
|
||||
expect(displayBuffer.decorationForId(decoration.id)).not.toBeDefined()
|
||||
|
||||
describe "when a decoration is updated via Decoration::update()", ->
|
||||
it "emits an 'updated' event containing the new and old params", ->
|
||||
decoration.onDidChangeProperties updatedSpy = jasmine.createSpy()
|
||||
decoration.setProperties type: 'gutter', class: 'two'
|
||||
|
||||
{oldProperties, newProperties} = updatedSpy.mostRecentCall.args[0]
|
||||
expect(oldProperties).toEqual decorationProperties
|
||||
expect(newProperties).toEqual type: 'gutter', class: 'two', id: decoration.id
|
||||
|
||||
describe "::setScrollTop", ->
|
||||
beforeEach ->
|
||||
@@ -1100,33 +1023,6 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.setScrollTop(maxScrollTop + 50)).toBe maxScrollTop
|
||||
expect(displayBuffer.getScrollTop()).toBe maxScrollTop
|
||||
|
||||
describe "editor.scrollPastEnd", ->
|
||||
describe "when editor.scrollPastEnd is false", ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.scrollPastEnd", false)
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setLineHeightInPixels(10)
|
||||
|
||||
it "does not add the height of the view to the scroll height", ->
|
||||
lineHeight = displayBuffer.getLineHeightInPixels()
|
||||
originalScrollHeight = displayBuffer.getScrollHeight()
|
||||
displayBuffer.setHeight(50)
|
||||
|
||||
expect(displayBuffer.getScrollHeight()).toBe originalScrollHeight
|
||||
|
||||
describe "when editor.scrollPastEnd is true", ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.scrollPastEnd", true)
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setLineHeightInPixels(10)
|
||||
|
||||
it "adds the height of the view to the scroll height", ->
|
||||
lineHeight = displayBuffer.getLineHeightInPixels()
|
||||
originalScrollHeight = displayBuffer.getScrollHeight()
|
||||
displayBuffer.setHeight(50)
|
||||
|
||||
expect(displayBuffer.getScrollHeight()).toEqual(originalScrollHeight + displayBuffer.height - (lineHeight * 3))
|
||||
|
||||
describe "::setScrollLeft", ->
|
||||
beforeEach ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
@@ -1171,38 +1067,3 @@ describe "DisplayBuffer", ->
|
||||
it "does not scroll vertically if the position is already in view", ->
|
||||
displayBuffer.scrollToScreenPosition([4, 20], center: true)
|
||||
expect(displayBuffer.getScrollTop()).toBe 0
|
||||
|
||||
describe "scroll width", ->
|
||||
cursorWidth = 1
|
||||
beforeEach ->
|
||||
displayBuffer.setDefaultCharWidth(10)
|
||||
|
||||
it "recomputes the scroll width when the default character width changes", ->
|
||||
expect(displayBuffer.getScrollWidth()).toBe 10 * 65 + cursorWidth
|
||||
|
||||
displayBuffer.setDefaultCharWidth(12)
|
||||
expect(displayBuffer.getScrollWidth()).toBe 12 * 65 + cursorWidth
|
||||
|
||||
it "recomputes the scroll width when the max line length changes", ->
|
||||
buffer.insert([6, 12], ' ')
|
||||
expect(displayBuffer.getScrollWidth()).toBe 10 * 66 + cursorWidth
|
||||
|
||||
buffer.delete([[6, 10], [6, 12]], ' ')
|
||||
expect(displayBuffer.getScrollWidth()).toBe 10 * 64 + cursorWidth
|
||||
|
||||
it "recomputes the scroll width when the scoped character widths change", ->
|
||||
operatorWidth = 20
|
||||
displayBuffer.setScopedCharWidth(['source.js', 'keyword.operator.js'], '<', operatorWidth)
|
||||
expect(displayBuffer.getScrollWidth()).toBe 10 * 64 + operatorWidth + cursorWidth
|
||||
|
||||
it "recomputes the scroll width when the scoped character widths change in a batch", ->
|
||||
operatorWidth = 20
|
||||
|
||||
displayBuffer.onDidChangeCharacterWidths changedSpy = jasmine.createSpy()
|
||||
|
||||
displayBuffer.batchCharacterMeasurement ->
|
||||
displayBuffer.setScopedCharWidth(['source.js', 'keyword.operator.js'], '<', operatorWidth)
|
||||
displayBuffer.setScopedCharWidth(['source.js', 'keyword.operator.js'], '?', operatorWidth)
|
||||
|
||||
expect(displayBuffer.getScrollWidth()).toBe 10 * 63 + operatorWidth * 2 + cursorWidth
|
||||
expect(changedSpy.callCount).toBe 1
|
||||
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
BIN
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 392 B |
externo
+1
@@ -0,0 +1 @@
|
||||
this tests files with no extensions
|
||||
@@ -1,4 +0,0 @@
|
||||
module.exports =
|
||||
activate: ->
|
||||
deactivate: -> throw new Error('Top that')
|
||||
serialize: ->
|
||||
@@ -1,13 +0,0 @@
|
||||
module.exports =
|
||||
activateCallCount: 0
|
||||
activationCommandCallCount: 0
|
||||
legacyActivationCommandCallCount: 0
|
||||
|
||||
activate: ->
|
||||
@activateCallCount++
|
||||
|
||||
atom.commands.add '.workspace', 'activation-command', =>
|
||||
@activationCommandCallCount++
|
||||
|
||||
atom.workspaceView.getActiveView()?.command 'activation-command', =>
|
||||
@legacyActivationCommandCallCount++
|
||||
@@ -1,2 +0,0 @@
|
||||
'activationCommands':
|
||||
'.workspace': 'activation-command'
|
||||
@@ -0,0 +1,13 @@
|
||||
class Foo
|
||||
atom.deserializers.add(this)
|
||||
@deserialize: ({data}) -> new Foo(data)
|
||||
constructor: (@data) ->
|
||||
|
||||
module.exports =
|
||||
activateCallCount: 0
|
||||
activationEventCallCount: 0
|
||||
|
||||
activate: ->
|
||||
@activateCallCount++
|
||||
atom.workspaceView.getActiveView()?.command 'activation-event', =>
|
||||
@activationEventCallCount++
|
||||
@@ -0,0 +1 @@
|
||||
'activationEvents': ['activation-event']
|
||||
@@ -1,13 +0,0 @@
|
||||
module.exports =
|
||||
config:
|
||||
numbers:
|
||||
type: 'object'
|
||||
properties:
|
||||
one:
|
||||
type: 'integer'
|
||||
default: 1
|
||||
two:
|
||||
type: 'integer'
|
||||
default: 2
|
||||
|
||||
activate: -> # no-op
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "no events",
|
||||
"version": "0.1.0",
|
||||
"activationCommands": {".workspace": []}
|
||||
"activationEvents": []
|
||||
}
|
||||
gerado
externo
gerado
externo
-1
@@ -1 +0,0 @@
|
||||
throw new Error("this simulates a native module's failure to load")
|
||||
gerado
externo
-4
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"name": "native-module",
|
||||
"main": "./main.js"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"name": "package-with-incompatible-native-module",
|
||||
"version": "1.0",
|
||||
"main": "./main.js"
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
'fileTypes': ['package-with-infinite-loop-grammar']
|
||||
'name': 'package-with-infinite-loop-grammar'
|
||||
'scopeName': 'source.package-with-infinite-loop-grammar'
|
||||
|
||||
# This grammar should loop forever if the line contains an `a`
|
||||
'patterns': [
|
||||
{
|
||||
'name': 'start'
|
||||
'begin': '^'
|
||||
'end': '$'
|
||||
'patterns': [
|
||||
{
|
||||
name: 'negative-look-ahead'
|
||||
match: "(?!a)"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,8 +1,7 @@
|
||||
'menu': [
|
||||
{'label': 'Second to Last'}
|
||||
{ 'label': 'Second to Last' }
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.test-1': [
|
||||
{label: 'Menu item 1', command: 'command-1'}
|
||||
]
|
||||
'.test-1':
|
||||
'Menu item 1': 'command-1'
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.test-1': [
|
||||
{label: 'Menu item 2', command: 'command-2'}
|
||||
]
|
||||
'.test-1':
|
||||
'Menu item 2': 'command-2'
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.test-1': [
|
||||
{label: 'Menu item 3', command: 'command-3'}
|
||||
]
|
||||
'.test-1':
|
||||
'Menu item 3': 'command-3'
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
This is a hidden file. Don't even try to load it as a snippet
|
||||
@@ -0,0 +1 @@
|
||||
This file isn't CSON, but shouldn't be a big deal
|
||||
@@ -0,0 +1,4 @@
|
||||
".test":
|
||||
"Test Snippet":
|
||||
prefix: "test"
|
||||
body: "testing 123"
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"theme": "ui",
|
||||
"stylesheets": ["editor.less"]
|
||||
}
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
@import "ui-variables";
|
||||
|
||||
.editor {
|
||||
padding-top: @component-padding;
|
||||
padding-right: @component-padding;
|
||||
padding-bottom: @component-padding;
|
||||
|
||||
color: @input-background-color;
|
||||
background-color: @background-color-info; // From the fallback variables, not overridden
|
||||
}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
// This does not contain all of the ui-variables available.
|
||||
@app-background-color: #00f; // Changed
|
||||
@input-background-color: #f00; // Changed
|
||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário