Comparar commits
7 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 0eb44e06d4 | |||
| 94b7fc8a75 | |||
| 0fde4382d2 | |||
| 4e1434eafa | |||
| 7cffe77efa | |||
| f9e94e9779 | |||
| 59a4cbafcf |
@@ -6,9 +6,3 @@ spec/fixtures/**/*.less text eol=lf
|
||||
spec/fixtures/**/*.css text eol=lf
|
||||
spec/fixtures/**/*.txt text eol=lf
|
||||
spec/fixtures/dir/**/* text eol=lf
|
||||
|
||||
# Git 1.7 does not support **/* patterns
|
||||
spec/fixtures/css.css text eol=lf
|
||||
spec/fixtures/sample.js text eol=lf
|
||||
spec/fixtures/sample.less text eol=lf
|
||||
spec/fixtures/sample.txt text eol=lf
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
v0.10.21
|
||||
@@ -1 +1,2 @@
|
||||
ca =
|
||||
cache = ~/.atom/.npm
|
||||
|
||||
@@ -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
|
||||
|
||||
+6
-15
@@ -1,28 +1,20 @@
|
||||
# Contributing to Atom
|
||||
|
||||
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
|
||||
# :tada: Contributing to Atom :tada:
|
||||
|
||||
The following is a set of guidelines for contributing to Atom and its packages,
|
||||
which are hosted in the [Atom Organization](https://github.com/atom) on GitHub.
|
||||
If you're unsure which package is causing your problem or if you're having an
|
||||
issue with Atom core, please open an issue on the [main atom repository](https://github.com/atom/atom/issues).
|
||||
These are just guidelines, not rules, use your best judgement and feel free to
|
||||
propose changes to this document in a pull request.
|
||||
issue with Atom core, please use the feedback form in the application or email
|
||||
[atom@github.com](mailto:atom@github.com). These are just guidelines, not rules,
|
||||
use your best judgement and feel free to propose changes to this document in a
|
||||
pull request.
|
||||
|
||||
## Submitting Issues
|
||||
|
||||
* Check the [debugging guide](https://atom.io/docs/latest/debugging) for tips
|
||||
on debugging. You might be able to find the cause of the problem and fix
|
||||
things yourself.
|
||||
* Include the version of Atom you are using and the OS.
|
||||
* Include screenshots and animated GIFs whenever possible; they are immensely
|
||||
helpful.
|
||||
* Include the behavior you expected and other places you've seen that behavior
|
||||
such as Emacs, vi, Xcode, etc.
|
||||
* Check the dev tools (`alt-cmd-i`) for errors to include. If the dev tools
|
||||
are open _before_ the error is triggered, a full stack trace for the error
|
||||
will be logged. If you can reproduce the error, use this approach to get the
|
||||
full stack trace and include it in the issue.
|
||||
* Check the dev tools (`alt-cmd-i`) for errors and stack traces to include.
|
||||
* On Mac, check Console.app for stack traces to include if reporting a crash.
|
||||
* Perform a cursory search to see if a similar issue has already been submitted.
|
||||
|
||||
@@ -76,7 +68,6 @@ For more information on how to work with Atom's official packages, see
|
||||
* :memo: `:memo:` when writing docs
|
||||
* :penguin: `:penguin:` when fixing something on Linux
|
||||
* :apple: `:apple:` when fixing something on Mac OS
|
||||
* :checkered_flag: `:checkered_flag:` when fixing something on Windows
|
||||
* :bug: `:bug:` when fixing a bug
|
||||
* :fire: `:fire:` when removing code or files
|
||||
* :green_heart: `:green_heart:` when fixing the CI build
|
||||
|
||||
-16
@@ -6,25 +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.
|
||||
|
||||
## Building
|
||||
|
||||
* [Linux](docs/build-instructions/linux.md)
|
||||
@@ -33,5 +18,4 @@ manually upgrade to future releases by re-downloading the `.zip` file.
|
||||
* [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).
|
||||
|
||||
+1
-1
@@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "0.93.2"
|
||||
"atom-package-manager": "0.57.0"
|
||||
}
|
||||
}
|
||||
|
||||
+2
-7
@@ -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)
|
||||
|
||||
@@ -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
-25
@@ -39,28 +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')
|
||||
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 = process.env.INSTALL_PREFIX ? '/usr/local'
|
||||
|
||||
coffeeConfig =
|
||||
glob_to_multiple:
|
||||
@@ -96,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: [
|
||||
@@ -130,8 +121,6 @@ module.exports = (grunt) ->
|
||||
|
||||
atom: {appDir, appName, symbolsDir, buildDir, contentsDir, installDir, shellAppDir}
|
||||
|
||||
docsOutputDir: 'docs/output'
|
||||
|
||||
coffee: coffeeConfig
|
||||
|
||||
less: lessConfig
|
||||
@@ -144,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'
|
||||
@@ -216,7 +210,7 @@ module.exports = (grunt) ->
|
||||
|
||||
shell:
|
||||
'kill-atom':
|
||||
command: killCommand
|
||||
command: 'pkill -9 Atom'
|
||||
options:
|
||||
stdout: false
|
||||
stderr: false
|
||||
@@ -225,16 +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('mkdeb') if process.platform is 'linux'
|
||||
ciTasks.push('set-version', 'check-licenses', 'lint')
|
||||
ciTasks.push('test') if process.platform isnt 'linux'
|
||||
ciTasks.push('codesign', '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)
|
||||
|
||||
+11
-12
@@ -7,19 +7,18 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "~0.2.9",
|
||||
"donna": "1.0.1",
|
||||
"tello": "1.0.3",
|
||||
"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-download-atom-shell": "~0.8.0",
|
||||
"grunt-cson": "0.8.0",
|
||||
"grunt-download-atom-shell": "~0.7.2",
|
||||
"grunt-lesslint": "0.13.0",
|
||||
"grunt-markdown": "~0.4.0",
|
||||
"grunt-peg": "~1.1.0",
|
||||
@@ -27,16 +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.5.x",
|
||||
"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",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{cp, isAtomPackage, mkdir, rm} = require('./task-helpers')(grunt)
|
||||
@@ -14,9 +13,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,114 +44,41 @@ 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')
|
||||
# Add .* to avoid matching hunspell_dictionaries.
|
||||
path.join('spellchecker', 'vendor', 'hunspell', '.*')
|
||||
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)
|
||||
|
||||
# Add .* to avoid matching hunspell_dictionaries.
|
||||
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) ->
|
||||
unless /.+\.plist/.test(sourcePath)
|
||||
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'), ''
|
||||
|
||||
dependencies = ['compile', "generate-license:save"]
|
||||
dependencies.push('copy-info-plist') if process.platform is 'darwin'
|
||||
dependencies.push('set-exe-icon') if process.platform is 'win32'
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
path = require 'path'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{spawn} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'codesign', 'Codesign the app', ->
|
||||
done = @async()
|
||||
|
||||
if process.platform is 'darwin' and process.env.XCODE_KEYCHAIN
|
||||
if process.env.XCODE_KEYCHAIN
|
||||
unlockKeychain (error) ->
|
||||
if error?
|
||||
done(error)
|
||||
@@ -22,15 +20,6 @@ module.exports = (grunt) ->
|
||||
spawn {cmd, args}, (error) -> callback(error)
|
||||
|
||||
signApp = (callback) ->
|
||||
switch process.platform
|
||||
when 'darwin'
|
||||
cmd = 'codesign'
|
||||
args = ['-f', '-v', '-s', '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) -> callback(error)
|
||||
else
|
||||
callback()
|
||||
cmd = 'codesign'
|
||||
args = ['-f', '-v', '-s', 'Developer ID Application: GitHub', grunt.config.get('atom.shellAppDir')]
|
||||
spawn {cmd, args}, (error) -> callback(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)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
runas = null
|
||||
|
||||
@@ -10,7 +9,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'
|
||||
@@ -27,28 +25,12 @@ module.exports = (grunt) ->
|
||||
binDir = path.join(installDir, 'bin')
|
||||
shareDir = path.join(installDir, 'share', 'atom')
|
||||
|
||||
iconName = path.join(shareDir,'resources','app','resources','atom.png')
|
||||
|
||||
mkdir binDir
|
||||
cp 'atom.sh', path.join(binDir, 'atom')
|
||||
rm shareDir
|
||||
mkdir path.dirname(shareDir)
|
||||
cp shellAppDir, shareDir
|
||||
|
||||
# Create Atom.desktop if installation not in temporary folder
|
||||
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')
|
||||
|
||||
{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)
|
||||
|
||||
# Create relative symbol link for apm.
|
||||
process.chdir(binDir)
|
||||
rm('apm')
|
||||
|
||||
@@ -2,51 +2,30 @@ 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'
|
||||
else if process.arch is 'x64'
|
||||
arch = 'amd64'
|
||||
else
|
||||
return done("Unsupported arch #{process.arch}")
|
||||
|
||||
{name, version, description} = grunt.file.readJSON('package.json')
|
||||
section = 'devel'
|
||||
arch = 'amd64'
|
||||
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}
|
||||
|
||||
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, 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')
|
||||
|
||||
@@ -8,7 +8,11 @@ GitHub = require 'github-releases'
|
||||
request = require 'request'
|
||||
|
||||
grunt = null
|
||||
|
||||
maxReleases = 10
|
||||
assets = [
|
||||
{assetName: 'atom-mac.zip', sourceName: 'Atom.app'}
|
||||
{assetName: 'atom-mac-symbols.zip', sourceName: 'Atom.breakpad.syms'}
|
||||
]
|
||||
commitSha = process.env.JANKY_SHA1
|
||||
token = process.env.ATOM_ACCESS_TOKEN
|
||||
defaultHeaders =
|
||||
@@ -17,25 +21,15 @@ defaultHeaders =
|
||||
|
||||
module.exports = (gruntObject) ->
|
||||
grunt = gruntObject
|
||||
{cp} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'publish-build', 'Publish the built app', ->
|
||||
return unless process.platform is 'darwin'
|
||||
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,54 +38,23 @@ 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')
|
||||
sourcePath = fs.listSync(buildDir, ['.deb'])[0]
|
||||
if process.arch is 'ia32g'
|
||||
arch = 'i386'
|
||||
else
|
||||
arch = 'amd64'
|
||||
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) ->
|
||||
if process.platform is 'win32'
|
||||
zipCommand = "C:/psmodules/7z.exe a -r #{assetName} #{sourcePath}"
|
||||
else
|
||||
zipCommand = "zip -r --symlinks #{assetName} #{sourcePath}"
|
||||
zipApps = (buildDir, assets, callback) ->
|
||||
zip = (directory, sourceName, assetName, callback) ->
|
||||
options = {cwd: directory, maxBuffer: Infinity}
|
||||
child_process.exec zipCommand, options, (error, stdout, stderr) ->
|
||||
logError("Zipping #{sourcePath} failed", error, stderr) if error?
|
||||
child_process.exec "zip -r --symlinks #{assetName} #{sourceName}", options, (error, stdout, stderr) ->
|
||||
if error?
|
||||
logError("Zipping #{sourceName} failed", error, stderr)
|
||||
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) ->
|
||||
@@ -156,7 +119,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')}"]
|
||||
@@ -47,8 +39,7 @@ module.exports = (grunt) ->
|
||||
grunt.verbose.writeln "Launching #{path.basename(packagePath)} specs."
|
||||
spawn options, (error, results, code) ->
|
||||
if process.platform is 'win32'
|
||||
if error
|
||||
process.stderr.write(fs.readFileSync(path.join(packagePath, 'ci.log')))
|
||||
process.stderr.write(fs.readFileSync(path.join(packagePath, 'ci.log')))
|
||||
fs.unlinkSync(path.join(packagePath, 'ci.log'))
|
||||
|
||||
failedPackages.push path.basename(packagePath) if error
|
||||
@@ -61,15 +52,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}"]
|
||||
@@ -80,7 +77,7 @@ module.exports = (grunt) ->
|
||||
|
||||
spawn options, (error, results, code) ->
|
||||
if process.platform is 'win32'
|
||||
process.stderr.write(fs.readFileSync('ci.log')) if error
|
||||
process.stderr.write(fs.readFileSync('ci.log'))
|
||||
fs.unlinkSync('ci.log')
|
||||
else
|
||||
# TODO: Restore concurrency on Windows
|
||||
@@ -94,7 +91,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
|
||||
@@ -108,8 +105,8 @@ module.exports = (grunt) ->
|
||||
|
||||
grunt.log.error("[Error]".red + " #{failures.join(', ')} spec(s) failed") if failures.length > 0
|
||||
|
||||
if process.platform is 'win32' and process.env.JANKY_SHA1
|
||||
# Package specs are still flaky on Windows CI
|
||||
done(!coreSpecFailed)
|
||||
else
|
||||
# TODO: Mark the build as green on Windows until specs pass.
|
||||
if process.platform is 'darwin'
|
||||
done(!coreSpecFailed and failedPackages.length == 0)
|
||||
else if process.platform is 'win32'
|
||||
done(true)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"max_line_length": {
|
||||
"level": "ignore"
|
||||
},
|
||||
"no_empty_param_list": {
|
||||
"level": "error"
|
||||
},
|
||||
"arrow_spacing": {
|
||||
"level": "error"
|
||||
},
|
||||
"no_interpolation_in_single_quotes": {
|
||||
"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
|
||||
|
||||
@@ -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`
|
||||
@@ -91,16 +91,6 @@ the current keystroke sequence and continue searching from its parent. If you
|
||||
want to remove a binding from a keymap you don't control, such as keymaps in
|
||||
Atom core or in packages, use the `unset!` directive.
|
||||
|
||||
For example, the following code removes the keybinding for `a` in the Tree View,
|
||||
which is normally used to trigger the `tree-view:add-file` command:
|
||||
|
||||
```coffee
|
||||
'.tree-view':
|
||||
'a': 'unset!'
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Forcing Chromium's Native Keystroke Handling
|
||||
|
||||
If you want to force the native browser behavior for a given keystroke, use the
|
||||
|
||||
@@ -1,271 +0,0 @@
|
||||
# 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,
|
||||
which does other useful things like incrementing your version in `package.json`
|
||||
and making sure you have pushed your git tag. In fact, Atom itself shells out to
|
||||
`apm` rather than hitting the API directly. If you're curious about how Atom
|
||||
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
|
||||
[Atom.io account page](https://atom.io/account) in the `Authorization` header.
|
||||
|
||||
### Media type
|
||||
|
||||
All requests that take parameters require `application/json`.
|
||||
|
||||
# API Resources
|
||||
|
||||
## Packages
|
||||
|
||||
### Listing packages
|
||||
|
||||
#### GET /api/packages
|
||||
|
||||
Parameters:
|
||||
|
||||
- **page** (optional)
|
||||
|
||||
Returns a list of all packages in the following format:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"releases": {
|
||||
"latest": "0.6.0"
|
||||
},
|
||||
"name": "thedaniel-test-package",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thedaniel/test-package"
|
||||
}
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
Parameters:
|
||||
|
||||
- **engine** (optional) - Only show packages with versions compatible with this
|
||||
Atom version. Must be valid [SemVer](http://semver.org).
|
||||
|
||||
Returns:
|
||||
|
||||
```json
|
||||
{
|
||||
"releases": {
|
||||
"latest": "0.6.0"
|
||||
},
|
||||
"name": "thedaniel-test-package",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thedaniel/test-package"
|
||||
},
|
||||
"versions": [
|
||||
(see single version output below)
|
||||
...,
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Creating a package
|
||||
|
||||
#### POST /api/packages
|
||||
|
||||
Create a new package; requires authentication.
|
||||
|
||||
The name and version will be fetched from the `package.json`
|
||||
file in the specified repository. The authenticating user *must* have access
|
||||
to the indicated repository.
|
||||
|
||||
When a package is created, a release hook is registered with GitHub for package
|
||||
version creation.
|
||||
|
||||
Parameters:
|
||||
|
||||
- **repository** - String. The repository containing the plugin, in the form "owner/repo"
|
||||
|
||||
Returns:
|
||||
|
||||
- **201** - Successfully created, returns created package.
|
||||
- **400** - Repository is inaccessible, nonexistent, not an atom package. Possible
|
||||
error messages include:
|
||||
- That repo does not exist, isn't an atom package, or atombot does not have access
|
||||
- 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
|
||||
|
||||
Delete a package; requires authentication.
|
||||
|
||||
Returns:
|
||||
|
||||
- **204** - Success
|
||||
- **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
|
||||
|
||||
Returns `package.json` with `dist` key added for e.g. tarball download:
|
||||
|
||||
```json
|
||||
{
|
||||
"bugs": {
|
||||
"url": "https://github.com/thedaniel/test-package/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "~0.2.6",
|
||||
"pegjs": "~0.7.0",
|
||||
"season": "~0.13.0"
|
||||
},
|
||||
"description": "Expand snippets matching the current prefix with `tab`.",
|
||||
"dist": {
|
||||
"tarball": "https://codeload.github.com/..."
|
||||
},
|
||||
"engines": {
|
||||
"atom": "*"
|
||||
},
|
||||
"main": "./lib/snippets",
|
||||
"name": "thedaniel-test-package",
|
||||
"publishConfig": {
|
||||
"registry": "https://...",
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thedaniel/test-package.git"
|
||||
},
|
||||
"version": "0.6.0"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Creating a new package version
|
||||
|
||||
#### 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.
|
||||
|
||||
#### Parameters
|
||||
|
||||
- **tag** - A git tag for the version you'd like to create. It's important to note
|
||||
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
|
||||
- **409** - Version exists
|
||||
|
||||
### Deleting a version
|
||||
|
||||
#### DELETE /api/packages/:package_name/versions/:version_name
|
||||
|
||||
Deletes a package version; requires authentication.
|
||||
|
||||
Note that a version cannot be republished with a different tag if it is deleted.
|
||||
If you need to delete the latest version of a package for e.g. security reasons,
|
||||
you'll need to increment the version when republishing.
|
||||
|
||||
Returns 204 No Content
|
||||
|
||||
|
||||
## Stars
|
||||
|
||||
### Listing user stars
|
||||
|
||||
#### GET /api/users/:login/stars
|
||||
|
||||
List a user's starred packages.
|
||||
|
||||
Return value is similar to **GET /api/packages**
|
||||
|
||||
#### GET /api/stars
|
||||
|
||||
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
|
||||
|
||||
#### GET /api/updates
|
||||
|
||||
Atom update feed, following the format expected by [Squirrel](https://github.com/Squirrel/).
|
||||
|
||||
Returns:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "0.96.0",
|
||||
"notes": "[HTML release notes]",
|
||||
"pub_date": "2014-05-19T15:52:06.000Z",
|
||||
"url": "https://www.atom.io/api/updates/download"
|
||||
}
|
||||
```
|
||||
@@ -4,87 +4,27 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
|
||||
|
||||
## Requirements
|
||||
|
||||
* 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)
|
||||
* OS with 64-bit architecture
|
||||
* [node.js](http://nodejs.org/download/) v0.10.x
|
||||
* [npm](http://www.npmjs.org/) v1.4.x
|
||||
* libgnome-keyring-dev `sudo apt-get install libgnome-keyring-dev` (refer to your distribution's manual on how to install packages if you are not on Debian or Ubuntu-based systems)
|
||||
* `npm config set python /usr/bin/python2 -g` to ensure that gyp uses Python 2
|
||||
|
||||
### 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.
|
||||
|
||||
## 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 +43,7 @@ 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.
|
||||
|
||||
@@ -9,12 +9,9 @@
|
||||
## Instructions
|
||||
|
||||
```sh
|
||||
git clone https://github.com/atom/atom.git
|
||||
git clone https://github.com/atom/atom
|
||||
cd atom
|
||||
script/build # Creates application at /Applications/Atom.app
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### OSX build error reports in atom/atom
|
||||
* Use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Aos-x&type=Issues) to get a list of reports about build errors on OSX.
|
||||
|
||||
@@ -2,24 +2,10 @@
|
||||
|
||||
## Requirements
|
||||
|
||||
### On Windows 7
|
||||
* [Visual C++ 2010 Express](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs#DownloadFamilies_4)
|
||||
* [Visual Studio 2010 Service Pack 1](http://www.microsoft.com/en-us/download/details.aspx?id=23691)
|
||||
* Windows 7 or later
|
||||
* [Visual C++ 2010 Express](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs#DownloadFamilies_4) with [SP1](http://www.microsoft.com/en-us/download/details.aspx?id=23691)
|
||||
* [node.js](http://nodejs.org/download/) v0.10.x
|
||||
* For 64-bit builds of node and native modules you **must** have the
|
||||
[Windows 7 64-bit SDK](http://www.microsoft.com/en-us/download/details.aspx?id=8279).
|
||||
You may also need the [compiler update for the Windows SDK 7.1](http://www.microsoft.com/en-us/download/details.aspx?id=4422)
|
||||
* [Python](http://www.python.org/download/) v2.7.
|
||||
* The python.exe must be available at `%SystemDrive%\Python27\python.exe`.
|
||||
If it is installed elsewhere, you can create a symbolic link to the
|
||||
directory containing the python.exe using:
|
||||
`mklink /d %SystemDrive%\Python27 D:\elsewhere\Python27`
|
||||
* [GitHub for Windows](http://windows.github.com/)
|
||||
|
||||
### On Windows 8
|
||||
* [Visual Studio Express 2013 for Windows Desktop](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs#DownloadFamilies_2)
|
||||
* [node.js](http://nodejs.org/download/) v0.10.x
|
||||
* [Python](http://www.python.org/download/) v2.7.x (required by [node-gyp](https://github.com/TooTallNate/node-gyp))
|
||||
* [Python](http://www.python.org/download/) v2.7.x
|
||||
* [GitHub for Windows](http://windows.github.com/)
|
||||
|
||||
## Instructions
|
||||
@@ -30,19 +16,15 @@
|
||||
cd C:\
|
||||
git clone https://github.com/atom/atom/
|
||||
cd atom
|
||||
script/build # Creates application in the `Program Files` directory
|
||||
script\build
|
||||
```
|
||||
|
||||
## 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
|
||||
|
||||
@@ -51,39 +33,3 @@ If none of this works, do install Github for Windows and use its Git shell. Make
|
||||
|
||||
* If you just installed node you need to restart your computer before node is
|
||||
available on your Path.
|
||||
|
||||
|
||||
* `script/build` outputs only the Node and Python versions before returning
|
||||
|
||||
* Try moving the repository to `C:\atom`. Most likely, the path is too long.
|
||||
See [issue #2200](https://github.com/atom/atom/issues/2200).
|
||||
|
||||
* `error MSB4025: The project file could not be loaded. Invalid character in the given encoding.`
|
||||
|
||||
* These can occur because your home directory (`%USERPROFILE%`) has non-ASCII
|
||||
characters in it. This is a bug in [gyp](https://code.google.com/p/gyp/)
|
||||
which is used to build native node modules and there is no known workaround.
|
||||
* 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.
|
||||
|
||||
@@ -225,21 +225,6 @@ 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, pass in another object instead of a command. To add a separator, use
|
||||
`-` for the command of the item.
|
||||
|
||||
```coffeescript
|
||||
'context-menu':
|
||||
'.workspace':
|
||||
'Inspect Element': 'core:inspect'
|
||||
'Separator': '-'
|
||||
'Text':
|
||||
'Select All': 'core:select-all'
|
||||
'Another Separator': '-'
|
||||
'Deleted Selected Text': 'core:delete'
|
||||
```
|
||||
|
||||
## Snippets
|
||||
|
||||
An extension can supply language snippets in the _snippets_ directory which
|
||||
|
||||
@@ -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,107 +0,0 @@
|
||||
# Debugging
|
||||
|
||||
Atom provides several tools to help you understand unexpected behavior and debug problems. This guide describes some of those tools and a few approaches to help you debug and provide more helpful information when [submitting issues]:
|
||||
|
||||
* [Update to the latest version](#update-to-the-latest-version)
|
||||
* [Check Atom and package settings](#check-atom-and-package-settings)
|
||||
* [Check the keybindings](#check-the-keybindings)
|
||||
* [Check if the problem shows up in safe mode](#check-if-the-problem-shows-up-in-safe-mode)
|
||||
* [Check your config files](#check-your-config-files)
|
||||
* [Check for errors in the developer tools](#check-for-errors-in-the-developer-tools)
|
||||
|
||||
## Update to the latest version
|
||||
|
||||
You might be running into an issue which was already fixed in a more recent version of Atom than the one you're using.
|
||||
|
||||
If you're building Atom from source, pull down the latest version of master and [re-build][building atom].
|
||||
|
||||
If you're using released version, check which version of Atom you're using:
|
||||
|
||||
```shell
|
||||
$ atom --version
|
||||
0.99.0
|
||||
```
|
||||
|
||||
Head on over to the [list of releases][atom releases] and see if there's a more recent release. You can update to the most recent release by downloading Atom from the releases page, or with the in-app auto-updater. The in-app auto-updater checks for and downloads a new version after you restart Atom, or if you use the Atom > Check for Update menu option.
|
||||
|
||||
## Check Atom and package settings
|
||||
|
||||
In some cases, unexpected behavior might be caused by misconfigured or unconfigured settings in Atom or in one of the packages.
|
||||
|
||||
Open Atom's Settings View with `cmd-,` or the Atom > Preferences menu option.
|
||||
|
||||
![Settings View]
|
||||
|
||||
Check Atom's settings in the Settings pane, there's a description of each configuration option [here][customizing guide]. For example, if you want Atom to use hard tabs (real tabs) and not soft tabs (spaces), disable the "Soft Tabs" option.
|
||||
|
||||
Since Atom ships with a set of packages and you can install additional packages yourself, check the list of packages and their settings. For example, if you'd like to get rid of the vertical line in the middle of the editor, disable the [Wrap Guide package]. And if you don't like it when Atom strips trailing whitespace or ensures that there's a single trailing newline in the file, you can configure that in the [Whitespace packages'][whitespace package] settings.
|
||||
|
||||
![Package Settings]
|
||||
|
||||
## Check the keybindings
|
||||
|
||||
If a command is not executing when you hit a keystroke or the wrong command is executing, there might be an issue with the keybindings for that keystroke. Atom ships with the [Keybinding resolver][keybinding resolver package], a neat package which helps you understand which keybindings are executed.
|
||||
|
||||
Show the keybinding resolver with <code>cmd-.</code> or with "Key Binding Resolver: Show" from the Command palette. With the keybinding resolver shown, hit a keystroke:
|
||||
|
||||
![Keybinding Resolver]
|
||||
|
||||
The keybinding resolver shows you a list of keybindings that exist for the keystroke, where each item in the list has the following:
|
||||
* the command for the keybinding,
|
||||
* the CSS selector used to define the context in which the keybinding is valid, and
|
||||
* the file in which the keybinding is defined.
|
||||
|
||||
Of all the keybinding that are listed (grey color), at most one keybinding is matched and executed (green color). If the command you wanted to trigger isn't listed, then a keybinding for that command hasn't been defined. More keybindings are provided by [packages] and you can [define your own keybindings][customizing keybindings].
|
||||
|
||||
If multiple keybindings are matched, Atom determines which keybinding will be executed based on the [specificity of the selectors and the order in which they were loaded][specificity and order]. If the command you wanted to trigger is listed in the Keybinding resolver, but wasn't the one that was executed, this is normally explained by one of two causes:
|
||||
* the keystroke was not used in the context defined by the keybinding's selector. For example, you can't trigger the "Tree View: Add File" command if the Tree View is not focused, or
|
||||
* there is another keybinding that took precedence. This often happens when you install a package which defines keybinding that conflict with existing keybindings. If the package's keybindings have selectors with higher specificity or were loaded later, they'll have priority over existing ones.
|
||||
|
||||
Atom loads core Atom keybindings and package keybindings first, and user-defined keybindings after last. Since user-defined keybindings are loaded last, you can use your `keymap.cson` file to tweak the keybindings and sort out problems like these. For example, you can remove keybindings with [the `unset!` directive][unset directive].
|
||||
|
||||
If you notice that a package's keybindings are taking precedence over core Atom keybindings, it might be a good idea to report the issue on the package's GitHub repository.
|
||||
|
||||
## Check if the problem shows up in safe mode
|
||||
|
||||
A large part of Atom's functionality comes from packages you can install. In some cases, these packages might be causing unexpected behavior, problems, or performance issues.
|
||||
|
||||
To determine if a package you installed is causing problems, start Atom from the terminal in safe mode:
|
||||
|
||||
```
|
||||
$ atom --safe
|
||||
```
|
||||
|
||||
This starts Atom, but does not load packages from `~/.atom/packages` or `~/.atom/dev/packages`. If you can no longer reproduce the problem in safe mode, it's likely it was caused by one of the packages.
|
||||
|
||||
To figure out which package is causing trouble, start Atom normally again and open Settings (`cmd-,`). Since Settings allow you to disable each installed package, you can disable packages one by one until you can no longer reproduce the issue. Restart (`cmd-q`) or reload (`cmd-ctrl-alt-l`) Atom after you disable each package to make sure it's completely gone.
|
||||
|
||||
When you find the problematic package, you can disable or uninstall the package, and consider creating an issue on the package's GitHub repository.
|
||||
|
||||
## Check your config files
|
||||
|
||||
You might have defined some custom functionality or styles in Atom's [Init script or Stylesheet]. In some situations, these personal hacks might be causing problems so try clearing those files and restarting Atom.
|
||||
|
||||
## Check for errors in the developer tools
|
||||
|
||||
When an error is thrown in Atom, the developer tools are automatically shown with the error logged in the Console tab. However, if the dev tools are open before the error is triggered, a full stack trace for the error will be logged:
|
||||
|
||||
![devtools error]
|
||||
|
||||
If you can reproduce the error, use this approach to get the full stack trace. The stack trace might point to a problem in your [Init script][init script or stylesheet] or a specific package you installed, which you can then disable and report an issue on its GitHub repository.
|
||||
|
||||
[submitting issues]: https://github.com/atom/atom/blob/master/CONTRIBUTING.md#submitting-issues
|
||||
[building atom]: https://github.com/atom/atom#building
|
||||
[atom releases]: https://github.com/atom/atom/releases
|
||||
[customizing guide]: https://atom.io/docs/latest/customizing-atom#configuration-key-reference
|
||||
[settings view]: https://f.cloud.github.com/assets/671378/2241795/ba4827d8-9ce4-11e3-93a8-6666ee100917.png
|
||||
[package settings]: https://cloud.githubusercontent.com/assets/38924/3173588/7e5f6b0c-ebe8-11e3-9ec3-e8d140967e79.png
|
||||
[wrap guide package]: https://atom.io/packages/wrap-guide
|
||||
[whitespace package]: https://atom.io/packages/whitespace
|
||||
[keybinding resolver package]: https://atom.io/packages/keybinding-resolver
|
||||
[keybinding resolver]: https://f.cloud.github.com/assets/671378/2241702/5dd5a102-9cde-11e3-9e3f-1d999930492f.png
|
||||
[customizing keybindings]: https://atom.io/docs/latest/customizing-atom#customizing-key-bindings
|
||||
[packages]: https://atom.io/packages
|
||||
[specificity and order]: https://atom.io/docs/latest/advanced/keymaps#specificity-and-cascade-order
|
||||
[unset directive]: https://atom.io/docs/latest/advanced/keymaps#removing-bindings
|
||||
[init script or stylesheet]: https://atom.io/docs/latest/customizing-atom#quick-personal-hacks
|
||||
[devtools error]: https://cloud.githubusercontent.com/assets/38924/3177710/11b4e510-ec13-11e3-96db-a2e8a7891773.png
|
||||
@@ -9,7 +9,6 @@
|
||||
* [Converting a TextMate Bundle](converting-a-text-mate-bundle.md)
|
||||
* [Converting a TextMate Theme](converting-a-text-mate-theme.md)
|
||||
* [Contributing](contributing.md)
|
||||
* [Debugging](debugging.md)
|
||||
|
||||
### Advanced Topics
|
||||
|
||||
|
||||
@@ -75,34 +75,18 @@ credentials are stored securely in your [keychain][keychain] once you login.
|
||||
:tada: Your package is now published and available on atom.io. Head on over to
|
||||
`http://atom.io/packages/my-package` to see your package's page.
|
||||
|
||||
With `apm publish`, you can bump the version and publish by using
|
||||
```sh
|
||||
apm publish <version-type>
|
||||
```
|
||||
where `<version-type>` can be `major`, `minor` and `patch`.
|
||||
|
||||
The `major` option to the publish command tells apm to increment the first
|
||||
digit of the version before publishing so the published version will be `1.0.0`
|
||||
and the Git tag created will be `v1.0.0`.
|
||||
|
||||
The `minor` option to the publish command tells apm to increment the second
|
||||
digit of the version before publishing so the published version will be `0.1.0`
|
||||
and the Git tag created will be `v0.1.0`.
|
||||
|
||||
The `patch` option to the publish command tells apm to increment the third
|
||||
digit of the version before publishing so the published version will be `0.0.1`
|
||||
and the Git tag created will be `v0.0.1`.
|
||||
|
||||
Use `major` when you make a huge change, like a rewrite, or a large change to the functionality or interface.
|
||||
Use `minor` when adding or removing a feature.
|
||||
Use `patch` when you make a small change like a bug fix that does not add or remove features.
|
||||
In the future you can run `apm publish major` to publish the `1.0.0` version but
|
||||
since this was the first version being published it is a good idea to start
|
||||
with a minor release.
|
||||
|
||||
### Further Reading
|
||||
|
||||
* Check out [semantic versioning][semver] to learn more about versioning your
|
||||
package releases.
|
||||
* Consult the [Atom.io package API docs][apm-rest-api] to learn more about how
|
||||
`apm` works.
|
||||
|
||||
[atomio]: https://atom.io
|
||||
[github]: https://github.com
|
||||
@@ -111,4 +95,3 @@ Use `patch` when you make a small change like a bug fix that does not add or rem
|
||||
[repo-guide]: http://guides.github.com/overviews/desktop
|
||||
[semver]: http://semver.org
|
||||
[your-first-package]: your-first-package.html
|
||||
[apm-rest-api]: apm-rest-api.md
|
||||
|
||||
+5
-73
@@ -1,4 +1,4 @@
|
||||
# Writing specs
|
||||
# Writting specs
|
||||
|
||||
Atom uses [Jasmine](http://jasmine.github.io/2.0/introduction.html) as its spec framework. Any new functionality should have specs to guard against regressions.
|
||||
|
||||
@@ -10,7 +10,7 @@ Atom uses [Jasmine](http://jasmine.github.io/2.0/introduction.html) as its spec
|
||||
|
||||
Spec files **must** end with `-spec` so add `sample-spec.coffee` to `atom/spec`.
|
||||
|
||||
0. Add one or more `describe` methods
|
||||
0. Add one or more `describe` method
|
||||
|
||||
The `describe` method takes two arguments, a description and a function. If the description explains a behavior it typically begins with `when` if it is more like a unit test it begins with the method name.
|
||||
|
||||
@@ -28,7 +28,7 @@ Atom uses [Jasmine](http://jasmine.github.io/2.0/introduction.html) as its spec
|
||||
|
||||
0. Add one or more `it` method
|
||||
|
||||
The `it` method also takes two arguments, a description and a function. Try and make the description flow with the `it` method. For example, a description of `this should work` doesn't read well as `it this should work`. But a description of `should work` sounds great as `it should work`.
|
||||
The `it` method also takes two arugments, a description and a function. Try and make the description flow with the `it` method. For example, a description of `this should work` doesn't read well as `it this should work`. But a description of `should work` sounds great as `it should work`.
|
||||
|
||||
```coffee
|
||||
describe "when a test is written", ->
|
||||
@@ -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 [jamsine 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,75 +47,7 @@ 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
|
||||
## Runnings 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
|
||||
|
||||
@@ -22,5 +22,3 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
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'
|
||||
|
||||
@@ -52,10 +52,7 @@
|
||||
'shift-down': 'core:select-down'
|
||||
'shift-left': 'core:select-left'
|
||||
'shift-right': 'core:select-right'
|
||||
'shift-pageup': 'core:select-page-up'
|
||||
'shift-pagedown': 'core:select-page-down'
|
||||
'delete': 'core:delete'
|
||||
'shift-delete': 'core:delete'
|
||||
'pageup': 'core:page-up'
|
||||
'pagedown': 'core:page-down'
|
||||
'backspace': 'core:backspace'
|
||||
@@ -68,8 +65,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 +114,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'
|
||||
|
||||
|
||||
+3
-24
@@ -7,15 +7,13 @@
|
||||
'left': 'core:move-left'
|
||||
'right': 'core:move-right'
|
||||
'ctrl-alt-r': 'window:reload'
|
||||
'ctrl-shift-i': 'window:toggle-dev-tools'
|
||||
'ctrl-alt-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,28 +25,19 @@
|
||||
'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'
|
||||
'ctrl-insert': 'core:copy'
|
||||
'shift-insert': 'core:paste'
|
||||
'shift-up': 'core:select-up'
|
||||
'shift-down': 'core:select-down'
|
||||
'shift-left': 'core:select-left'
|
||||
'shift-right': 'core:select-right'
|
||||
'shift-pageup': 'core:select-page-up'
|
||||
'shift-pagedown': 'core:select-page-down'
|
||||
'delete': 'core:delete'
|
||||
'shift-delete': 'core:cut'
|
||||
'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'
|
||||
@@ -69,15 +58,6 @@
|
||||
'ctrl-k ctrl-down': 'window:focus-pane-below'
|
||||
'ctrl-k ctrl-left': 'window:focus-pane-on-left'
|
||||
'ctrl-k ctrl-right': 'window:focus-pane-on-right'
|
||||
'alt-1': 'pane:show-item-1'
|
||||
'alt-2': 'pane:show-item-2'
|
||||
'alt-3': 'pane:show-item-3'
|
||||
'alt-4': 'pane:show-item-4'
|
||||
'alt-5': 'pane:show-item-5'
|
||||
'alt-6': 'pane:show-item-6'
|
||||
'alt-7': 'pane:show-item-7'
|
||||
'alt-8': 'pane:show-item-8'
|
||||
'alt-9': 'pane:show-item-9'
|
||||
|
||||
'.workspace .editor':
|
||||
# Platform Bindings
|
||||
@@ -94,10 +74,9 @@
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-a': 'core:select-all'
|
||||
'ctrl-alt-shift-p': 'editor:log-cursor-scope'
|
||||
'ctrl-alt-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
-16
@@ -17,7 +17,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,36 +24,25 @@
|
||||
'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'
|
||||
'ctrl-v': 'core:paste'
|
||||
'ctrl-insert': 'core:copy'
|
||||
'shift-insert': 'core:paste'
|
||||
'shift-up': 'core:select-up'
|
||||
'shift-down': 'core:select-down'
|
||||
'shift-left': 'core:select-left'
|
||||
'shift-right': 'core:select-right'
|
||||
'shift-pageup': 'core:select-page-up'
|
||||
'shift-pagedown': 'core:select-page-down'
|
||||
'delete': 'core:delete'
|
||||
'shift-delete': 'core:cut'
|
||||
'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'
|
||||
'ctrl-alt-down': 'editor:add-selection-below'
|
||||
'ctrl-=': 'window:increase-font-size'
|
||||
'ctrl-+': 'window:increase-font-size'
|
||||
'ctrl--': 'window:decrease-font-size'
|
||||
@@ -84,15 +72,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-alt-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
-14
@@ -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' }
|
||||
]
|
||||
@@ -111,7 +109,6 @@
|
||||
submenu: [
|
||||
{ label: 'Add Selection Above', command: 'editor:add-selection-above' }
|
||||
{ label: 'Add Selection Below', command: 'editor:add-selection-below' }
|
||||
{ label: 'Single Selection', command: 'editor:consolidate-selections'}
|
||||
{ label: 'Split into Lines', command: 'editor:split-selections-into-lines'}
|
||||
{ type: 'separator' }
|
||||
{ label: 'Select to Top', command: 'core:select-to-top' }
|
||||
@@ -194,13 +191,3 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer':
|
||||
'Undo': 'core:undo'
|
||||
'Redo': 'core:redo'
|
||||
'Cut': 'core:cut'
|
||||
'Copy': 'core:copy'
|
||||
'Paste': 'core:paste'
|
||||
'Delete': 'core:delete'
|
||||
'Select All': 'core:select-all'
|
||||
|
||||
+14
-21
@@ -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' }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -114,7 +108,6 @@
|
||||
{ label: 'Add Selection &Above', command: 'editor:add-selection-above' }
|
||||
{ label: 'Add Selection &Below', command: 'editor:add-selection-below' }
|
||||
{ label: 'S&plit into Lines', command: 'editor:split-selections-into-lines'}
|
||||
{ label: 'Single Selection', command: 'editor:consolidate-selections'}
|
||||
{ type: 'separator' }
|
||||
{ label: 'Select to &Top', command: 'core:select-to-top' }
|
||||
{ label: 'Select to Botto&m', command: 'core:select-to-bottom' }
|
||||
@@ -139,6 +132,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,13 +154,3 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer':
|
||||
'Undo': 'core:undo'
|
||||
'Redo': 'core:redo'
|
||||
'Cut': 'core:cut'
|
||||
'Copy': 'core:copy'
|
||||
'Paste': 'core:paste'
|
||||
'Delete': 'core:delete'
|
||||
'Select All': 'core:select-all'
|
||||
|
||||
+15
-19
@@ -8,19 +8,14 @@
|
||||
{ label: 'Open Folder...', command: 'application:open-folder' }
|
||||
{ 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' }
|
||||
{ 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: 'E&xit', command: 'application:quit' }
|
||||
@@ -132,7 +127,6 @@
|
||||
{ label: 'Add Selection &Above', command: 'editor:add-selection-above' }
|
||||
{ label: 'Add Selection &Below', command: 'editor:add-selection-below' }
|
||||
{ label: 'S&plit into Lines', command: 'editor:split-selections-into-lines'}
|
||||
{ label: 'Single Selection', command: 'editor:consolidate-selections'}
|
||||
{ type: 'separator' }
|
||||
{ label: 'Select to &Top', command: 'core:select-to-top' }
|
||||
{ label: 'Select to Botto&m', command: 'core:select-to-bottom' }
|
||||
@@ -157,25 +151,27 @@
|
||||
submenu: []
|
||||
}
|
||||
|
||||
{
|
||||
label: '&Window'
|
||||
submenu: [
|
||||
{ label: 'Mi&nimize', command: 'application:minimize' }
|
||||
{ label: 'Ma&ximize', command: 'application:zoom' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Bring &All to Front', command: 'application:bring-all-windows-to-front' }
|
||||
]
|
||||
}
|
||||
|
||||
{
|
||||
label: '&Help'
|
||||
submenu: [
|
||||
{ label: '&About Atom...', command: 'application:about' }
|
||||
{ label: 'View &Terms of Use', command: 'application:open-terms-of-use' }
|
||||
{ label: 'View &License', command: 'application:open-license' }
|
||||
{ label: "VERSION", enabled: false }
|
||||
{ label: "Install &update", command: 'application:install-update', visible: false }
|
||||
{ type: 'separator' }
|
||||
{ label: '&Documentation', command: 'application:open-documentation' }
|
||||
{ type: 'separator' }
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.overlayer':
|
||||
'Undo': 'core:undo'
|
||||
'Redo': 'core:redo'
|
||||
'Cut': 'core:cut'
|
||||
'Copy': 'core:copy'
|
||||
'Paste': 'core:paste'
|
||||
'Delete': 'core:delete'
|
||||
'Select All': 'core:select-all'
|
||||
|
||||
+89
-93
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.128.0",
|
||||
"version": "0.98.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.16.2",
|
||||
"atomShellVersion": "0.12.5",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^2.1.1",
|
||||
"atom-keymap": "^0.22.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.1.1",
|
||||
"fs-plus": "^2.2.6",
|
||||
"emissary": "^1.2.1",
|
||||
"first-mate": "^1.5.3",
|
||||
"fs-plus": "^2.2.3",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "^2.1",
|
||||
"git-utils": "^2.1.4",
|
||||
"grim": "0.12.0",
|
||||
"fuzzaldrin": "^1.1",
|
||||
"git-utils": "^1.3",
|
||||
"grim": "0.10.0",
|
||||
"guid": "0.0.10",
|
||||
"jasmine-tagged": "^1.1.2",
|
||||
"less-cache": "0.14.0",
|
||||
"jasmine-tagged": "^1.1.1",
|
||||
"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.2",
|
||||
"pathwatcher": "^1.3.1",
|
||||
"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.0",
|
||||
"react-atom-fork": "^0.10.0",
|
||||
"reactionary-atom-fork": "^0.9.0",
|
||||
"runas": "^0.5",
|
||||
"scandal": "0.15.2",
|
||||
"scoped-property-store": "^0.9.0",
|
||||
"scrollbar-style": "^1.0.2",
|
||||
"scrollbar-style": "^0.4.0",
|
||||
"season": "^1.0.2",
|
||||
"semver": "1.1.4",
|
||||
"serializable": "^1",
|
||||
"space-pen": "3.4.7",
|
||||
"temp": "0.7.0",
|
||||
"text-buffer": "^3.2.4",
|
||||
"theorist": "^1.0.2",
|
||||
"underscore-plus": "^1.5.1",
|
||||
"space-pen": "3.2.0",
|
||||
"temp": "0.5.0",
|
||||
"text-buffer": "^2.2.2",
|
||||
"theorist": "^1",
|
||||
"underscore-plus": "^1.3.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.17.0",
|
||||
"background-tips": "0.16.0",
|
||||
"bookmarks": "0.28.0",
|
||||
"bracket-matcher": "0.55.0",
|
||||
"command-palette": "0.24.0",
|
||||
"deprecation-cop": "0.10.0",
|
||||
"dev-live-reload": "0.34.0",
|
||||
"exception-reporting": "0.20.0",
|
||||
"atom-dark-syntax": "0.15.0",
|
||||
"atom-dark-ui": "0.26.0",
|
||||
"atom-light-syntax": "0.17.0",
|
||||
"atom-light-ui": "0.24.0",
|
||||
"base16-tomorrow-dark-theme": "0.15.0",
|
||||
"solarized-dark-syntax": "0.14.0",
|
||||
"solarized-light-syntax": "0.7.0",
|
||||
"archive-view": "0.31.0",
|
||||
"autocomplete": "0.28.0",
|
||||
"autoflow": "0.17.0",
|
||||
"autosave": "0.13.0",
|
||||
"background-tips": "0.13.0",
|
||||
"bookmarks": "0.22.0",
|
||||
"bracket-matcher": "0.38.0",
|
||||
"command-palette": "0.21.0",
|
||||
"deprecation-cop": "0.5.0",
|
||||
"dev-live-reload": "0.30.0",
|
||||
"exception-reporting": "0.17.0",
|
||||
"feedback": "0.33.0",
|
||||
"find-and-replace": "0.138.0",
|
||||
"fuzzy-finder": "0.58.0",
|
||||
"git-diff": "0.39.0",
|
||||
"go-to-line": "0.25.0",
|
||||
"grammar-selector": "0.29.0",
|
||||
"image-view": "0.36.0",
|
||||
"incompatible-packages": "0.9.0",
|
||||
"keybinding-resolver": "0.20.0",
|
||||
"link": "0.25.0",
|
||||
"markdown-preview": "0.102.0",
|
||||
"metrics": "0.34.0",
|
||||
"open-on-github": "0.30.0",
|
||||
"package-generator": "0.31.0",
|
||||
"release-notes": "0.36.0",
|
||||
"settings-view": "0.142.0",
|
||||
"snippets": "0.52.0",
|
||||
"spell-check": "0.42.0",
|
||||
"status-bar": "0.44.0",
|
||||
"styleguide": "0.30.0",
|
||||
"symbols-view": "0.63.0",
|
||||
"tabs": "0.50.0",
|
||||
"timecop": "0.22.0",
|
||||
"tree-view": "0.124.0",
|
||||
"find-and-replace": "0.106.0",
|
||||
"fuzzy-finder": "0.51.0",
|
||||
"git-diff": "0.28.0",
|
||||
"go-to-line": "0.21.0",
|
||||
"grammar-selector": "0.27.0",
|
||||
"image-view": "0.33.0",
|
||||
"keybinding-resolver": "0.17.0",
|
||||
"link": "0.22.0",
|
||||
"markdown-preview": "0.72.0",
|
||||
"metrics": "0.32.0",
|
||||
"open-on-github": "0.28.0",
|
||||
"package-generator": "0.30.0",
|
||||
"release-notes": "0.31.0",
|
||||
"settings-view": "0.116.0",
|
||||
"snippets": "0.43.0",
|
||||
"spell-check": "0.35.0",
|
||||
"status-bar": "0.40.0",
|
||||
"styleguide": "0.29.0",
|
||||
"symbols-view": "0.53.0",
|
||||
"tabs": "0.40.0",
|
||||
"timecop": "0.18.0",
|
||||
"tree-view": "0.93.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.30.0",
|
||||
"language-css": "0.17.0",
|
||||
"language-gfm": "0.50.0",
|
||||
"welcome": "0.14.0",
|
||||
"whitespace": "0.22.0",
|
||||
"wrap-guide": "0.18.0",
|
||||
"language-c": "0.15.0",
|
||||
"language-coffee-script": "0.22.0",
|
||||
"language-css": "0.16.0",
|
||||
"language-gfm": "0.38.0",
|
||||
"language-git": "0.9.0",
|
||||
"language-go": "0.17.0",
|
||||
"language-html": "0.26.0",
|
||||
"language-hyperlink": "0.12.0",
|
||||
"language-java": "0.11.0",
|
||||
"language-javascript": "0.39.0",
|
||||
"language-go": "0.12.0",
|
||||
"language-html": "0.22.0",
|
||||
"language-hyperlink": "0.9.0",
|
||||
"language-java": "0.10.0",
|
||||
"language-javascript": "0.26.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-perl": "0.8.0",
|
||||
"language-php": "0.14.0",
|
||||
"language-property-list": "0.7.0",
|
||||
"language-python": "0.19.0",
|
||||
"language-ruby": "0.37.0",
|
||||
"language-ruby-on-rails": "0.18.0",
|
||||
"language-sass": "0.21.0",
|
||||
"language-python": "0.17.0",
|
||||
"language-ruby": "0.25.0",
|
||||
"language-ruby-on-rails": "0.14.0",
|
||||
"language-sass": "0.11.0",
|
||||
"language-shellscript": "0.8.0",
|
||||
"language-source": "0.8.0",
|
||||
"language-sql": "0.10.0",
|
||||
"language-source": "0.7.0",
|
||||
"language-sql": "0.8.0",
|
||||
"language-text": "0.6.0",
|
||||
"language-todo": "0.11.0",
|
||||
"language-todo": "0.10.0",
|
||||
"language-toml": "0.12.0",
|
||||
"language-xml": "0.20.0",
|
||||
"language-yaml": "0.17.0"
|
||||
"language-xml": "0.13.0",
|
||||
"language-yaml": "0.6.0"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
[Desktop Entry]
|
||||
Name=Atom
|
||||
Comment=<%= description %>
|
||||
Exec=<%= installDir %>/share/atom/atom %U
|
||||
Icon=<%= iconName %>
|
||||
Exec=/usr/share/atom/atom %U
|
||||
Icon=atom
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Utility;TextEditor;Development;
|
||||
MimeType=text/plain;
|
||||
Categories=GNOME;GTK;Utility;TextEditor;
|
||||
|
||||
@@ -3,6 +3,6 @@ Version: <%= version %>
|
||||
Section: <%= section %>
|
||||
Priority: optional
|
||||
Architecture: <%= arch %>
|
||||
Installed-Size: <%= installedSize %>
|
||||
Installed-Size: `du -ks usr|cut -f 1`
|
||||
Maintainer: <%= maintainer %>
|
||||
Description: <%= description %>
|
||||
|
||||
+38
-74
@@ -1,8 +1,23 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var fs = require('fs');
|
||||
var verifyRequirements = require('./utils/verify-requirements');
|
||||
|
||||
var nodeVersion = process.versions.node.split('.')
|
||||
var nodeMajorVersion = +nodeVersion[0]
|
||||
var nodeMinorVersion = +nodeVersion[1]
|
||||
if (nodeMajorVersion === 0 && nodeMinorVersion < 10) {
|
||||
console.warn("You must run script/bootstrap and script/build with node v0.10 or above");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Make sure python2.7 is installed
|
||||
if (process.platform == 'win32' && !fs.existsSync('C:\\Python27\\')) {
|
||||
console.warn("You must have Python 2.7 installed at 'C:\\Python27\\'");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var safeExec = require('./utils/child-process-wrapper.js').safeExec;
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
// Executes an array of commands one by one.
|
||||
@@ -10,90 +25,39 @@ function executeCommands(commands, done, index) {
|
||||
index = (index == undefined ? 0 : index);
|
||||
if (index < commands.length) {
|
||||
var command = commands[index];
|
||||
if (command.message)
|
||||
console.log(command.message);
|
||||
var options = null;
|
||||
if (typeof command !== 'string') {
|
||||
options = command.options;
|
||||
command = command.command;
|
||||
}
|
||||
safeExec(command, options, executeCommands.bind(this, commands, done, index + 1));
|
||||
}
|
||||
else
|
||||
} else
|
||||
done(null);
|
||||
}
|
||||
|
||||
function bootstrap() {
|
||||
var apmInstallPath = path.resolve(__dirname, '..', 'apm');
|
||||
if (!fs.existsSync(apmInstallPath))
|
||||
fs.mkdirSync(apmInstallPath);
|
||||
if (!fs.existsSync(path.join(apmInstallPath, 'node_modules')))
|
||||
fs.mkdirSync(path.join(apmInstallPath, 'node_modules'));
|
||||
var apmInstallPath = path.resolve(__dirname, '..', 'apm');
|
||||
if (!fs.existsSync(apmInstallPath))
|
||||
fs.mkdirSync(apmInstallPath);
|
||||
if (!fs.existsSync(path.join(apmInstallPath, 'node_modules')))
|
||||
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 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 npmPath = path.resolve(__dirname, '..', 'build', 'node_modules', '.bin', 'npm');
|
||||
var initialNpmCommand = fs.existsSync(npmPath) ? npmPath : 'npm';
|
||||
var npmFlags = ' --userconfig=' + path.resolve('.npmrc') + ' ';
|
||||
var npmPath = path.resolve(__dirname, '..', 'build', 'node_modules', '.bin', 'npm');
|
||||
var npmFlags = ' --userconfig=' + path.resolve('.npmrc') + ' ';
|
||||
|
||||
var packagesToDedupe = ['fs-plus', 'humanize-plus', 'oniguruma', 'roaster', 'season', 'grim'];
|
||||
var packagesToDedupe = ['fs-plus', 'humanize-plus', 'oniguruma', 'roaster', 'season'];
|
||||
var echoNewLine = process.platform == 'win32' ? 'echo.' : 'echo';
|
||||
|
||||
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';
|
||||
var commands = [
|
||||
{command: 'npm' + npmFlags + 'install --quiet', options: {cwd: path.resolve(__dirname, '..', 'build'), ignoreStdout: true}},
|
||||
{command: npmPath + npmFlags + 'install --quiet', options: {cwd: apmInstallPath, ignoreStdout: true}},
|
||||
echoNewLine,
|
||||
apmPath + ' clean ' + apmFlags,
|
||||
apmPath + ' install --quiet ' + apmFlags,
|
||||
apmPath + ' dedupe --quiet ' + apmFlags + ' ' + packagesToDedupe.join(' '),
|
||||
];
|
||||
|
||||
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')
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
process.chdir(path.dirname(__dirname));
|
||||
executeCommands(commands, process.exit);
|
||||
}
|
||||
|
||||
verifyRequirements(function(error, successMessage) {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(successMessage);
|
||||
bootstrap();
|
||||
});
|
||||
process.chdir(path.dirname(__dirname));
|
||||
executeCommands(commands, process.exit);
|
||||
|
||||
+19
-24
@@ -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) {
|
||||
@@ -16,34 +19,26 @@ function loadEnvironmentVariables(filePath) {
|
||||
var value = parts[1].trim().substr(1, parts[1].length - 2);
|
||||
process.env[key] = value;
|
||||
}
|
||||
} catch(error) {
|
||||
console.error("Failed to load environment variables: " + filePath, error.code);
|
||||
}
|
||||
} catch(error) { }
|
||||
}
|
||||
|
||||
function readEnvironmentVariables() {
|
||||
if (process.platform === 'win32')
|
||||
loadEnvironmentVariables(path.resolve('/jenkins/config/atomcredentials'));
|
||||
else if (process.platform === 'darwin') {
|
||||
loadEnvironmentVariables('/var/lib/jenkins/config/atomcredentials');
|
||||
loadEnvironmentVariables('/var/lib/jenkins/config/xcodekeychain');
|
||||
}
|
||||
loadEnvironmentVariables('/var/lib/jenkins/config/atomcredentials')
|
||||
loadEnvironmentVariables('/var/lib/jenkins/config/xcodekeychain')
|
||||
}
|
||||
|
||||
readEnvironmentVariables();
|
||||
cp.safeExec.bind(global, 'npm install npm', {cwd: path.resolve(__dirname, '..', 'build')}, function() {
|
||||
cp.safeExec.bind(global, 'node script/bootstrap', function(error) {
|
||||
if (error)
|
||||
process.exit(1);
|
||||
require('fs-plus').removeSync.bind(global, path.join(homeDir, '.atom'))
|
||||
var async = require('async');
|
||||
var gruntPath = path.join('build', 'node_modules', '.bin', 'grunt') + (process.platform === 'win32' ? '.cmd' : '');
|
||||
var tasks = [
|
||||
cp.safeExec.bind(global, 'git clean -dff'),
|
||||
cp.safeExec.bind(global, gruntPath + ' ci --gruntfile build/Gruntfile.coffee --stack --no-color'),
|
||||
]
|
||||
async.series(tasks, function(error) {
|
||||
process.exit(error ? 1 : 0);
|
||||
});
|
||||
})();
|
||||
cp.safeExec.bind(global, 'node script/bootstrap', function(error) {
|
||||
if (error)
|
||||
process.exit(1);
|
||||
require('fs-plus').removeSync.bind(global, path.join(homeDir, '.atom'))
|
||||
var async = require('async');
|
||||
var gruntPath = path.join('build', 'node_modules', '.bin', 'grunt') + (process.platform === 'win32' ? '.cmd' : '');
|
||||
var tasks = [
|
||||
cp.safeExec.bind(global, 'git clean -dff'),
|
||||
cp.safeExec.bind(global, gruntPath + ' ci --gruntfile build/Gruntfile.coffee --stack --no-color'),
|
||||
]
|
||||
async.series(tasks, function(error) {
|
||||
process.exit(error ? 1 : 0);
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -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
|
||||
+3
-12
@@ -1,10 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
var cp = require('./utils/child-process-wrapper.js');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var os = require('os');
|
||||
|
||||
var removeCommand = process.platform === 'win32' ? 'rmdir /S /Q ' : 'rm -rf ';
|
||||
var removeCommand = process.platform === 'win32' ? 'del /F /Q /S ' : 'rm -rf ';
|
||||
var productName = require('../package.json').productName;
|
||||
|
||||
process.chdir(path.dirname(__dirname));
|
||||
@@ -24,7 +23,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'],
|
||||
];
|
||||
@@ -32,15 +30,8 @@ var run = function() {
|
||||
var next = commands.shift();
|
||||
if (!next)
|
||||
process.exit(0);
|
||||
|
||||
if (Array.isArray(next)) {
|
||||
var pathToRemove = path.resolve.apply(path.resolve, next);
|
||||
if (fs.existsSync(pathToRemove))
|
||||
next = removeCommand + pathToRemove;
|
||||
else
|
||||
return run();
|
||||
}
|
||||
|
||||
if (Array.isArray(next))
|
||||
next = removeCommand + path.resolve.apply(path.resolve, next);
|
||||
cp.safeExec(next, run);
|
||||
};
|
||||
run();
|
||||
|
||||
@@ -1,17 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
var cp = require('./utils/child-process-wrapper.js');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
// node build/node_modules/.bin/grunt "$@"
|
||||
var gruntPath = path.resolve(__dirname, '..', 'build', 'node_modules', '.bin', 'grunt') + (process.platform === 'win32' ? '.cmd' : '');
|
||||
|
||||
if (!fs.existsSync(gruntPath)) {
|
||||
console.error('Grunt command does not exist at: ' + gruntPath);
|
||||
console.error('Run script/bootstrap to install Grunt');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var args = ['--gruntfile', path.resolve('build', 'Gruntfile.coffee')];
|
||||
args = args.concat(process.argv.slice(2));
|
||||
cp.safeSpawn(gruntPath, args, process.exit);
|
||||
|
||||
Arquivo executável
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env coffee
|
||||
|
||||
path = require 'path'
|
||||
CommandInstaller = require '../src/command-installer'
|
||||
|
||||
callback = (error) ->
|
||||
console.warn error.message if error?
|
||||
|
||||
CommandInstaller.installAtomCommand(path.resolve(__dirname, '..'), callback)
|
||||
CommandInstaller.installApmCommand(path.resolve(__dirname, '..'), callback)
|
||||
+12
-14
@@ -8,29 +8,27 @@ ROOT=`readlink -f $(dirname $SCRIPT)/..`
|
||||
cd $ROOT
|
||||
|
||||
VERSION="$1"
|
||||
ARCH="$2"
|
||||
CONTROL_FILE="$3"
|
||||
DESKTOP_FILE="$4"
|
||||
ICON_FILE="$5"
|
||||
DEB_PATH="$6"
|
||||
FILE_MODE=755
|
||||
CONTROL_FILE="$2"
|
||||
DESKTOP_FILE="$3"
|
||||
ICON_FILE="$4"
|
||||
DEB_PATH="$5"
|
||||
|
||||
TARGET_ROOT="`mktemp -d`"
|
||||
chmod 755 "$TARGET_ROOT"
|
||||
TARGET="$TARGET_ROOT/atom-$VERSION-$ARCH"
|
||||
TARGET="$TARGET_ROOT/atom-$VERSION-amd64"
|
||||
|
||||
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"
|
||||
cp "$CONTROL_FILE" "$TARGET/DEBIAN/control"
|
||||
mkdir -p "$TARGET/DEBIAN"
|
||||
mv "$CONTROL_FILE" "$TARGET/DEBIAN/control"
|
||||
|
||||
mkdir -m $FILE_MODE -p "$TARGET/usr/share/applications"
|
||||
cp "$DESKTOP_FILE" "$TARGET/usr/share/applications"
|
||||
mkdir -p "$TARGET/usr/share/applications"
|
||||
mv "$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"
|
||||
|
||||
dpkg-deb -b "$TARGET"
|
||||
mv "$TARGET_ROOT/atom-$VERSION-$ARCH.deb" "$DEB_PATH"
|
||||
mv "$TARGET_ROOT/atom-$VERSION-amd64.deb" "$DEB_PATH"
|
||||
rm -rf $TARGET_ROOT
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var childProcess = require('child_process');
|
||||
|
||||
var pythonExecutable = process.env.PYTHON;
|
||||
|
||||
module.exports = function(cb) {
|
||||
verifyNode(function(error, nodeSuccessMessage) {
|
||||
if (error) {
|
||||
cb(error);
|
||||
return;
|
||||
}
|
||||
|
||||
verifyNpm(function(error, npmSuccessMessage) {
|
||||
if (error) {
|
||||
cb(error);
|
||||
return;
|
||||
}
|
||||
|
||||
verifyPython27(function(error, pythonSuccessMessage) {
|
||||
cb(error, (nodeSuccessMessage + "\n" + npmSuccessMessage + "\n" + pythonSuccessMessage).trim());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
function verifyNode(cb) {
|
||||
var nodeVersion = process.versions.node;
|
||||
var versionArray = nodeVersion.split('.');
|
||||
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.";
|
||||
cb(error);
|
||||
}
|
||||
else {
|
||||
cb(null, "Node: v" + nodeVersion);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyNpm(cb) {
|
||||
var localNpmPath = path.resolve(__dirname, '..', '..', 'build', 'node_modules', '.bin', 'npm');
|
||||
if (process.platform === 'win32')
|
||||
localNpmPath += ".cmd";
|
||||
|
||||
var npmCommand = fs.existsSync(localNpmPath) ? localNpmPath : 'npm';
|
||||
if (npmCommand === 'npm' && process.platform === 'win32')
|
||||
npmCommand += ".cmd";
|
||||
|
||||
childProcess.execFile(npmCommand, ['-v'], { env: process.env }, function(err, stdout) {
|
||||
if (err)
|
||||
return cb("npm 1.4 is required to build Atom. An error (" + err + ") occured when checking the version.");
|
||||
|
||||
var npmVersion = stdout ? stdout.trim() : '';
|
||||
var versionArray = npmVersion.split('.');
|
||||
var npmMajorVersion = +versionArray[0] || 0;
|
||||
var npmMinorVersion = +versionArray[1] || 0;
|
||||
if (npmMajorVersion === 1 && npmMinorVersion < 4)
|
||||
cb("npm v1.4+ is required to build Atom.");
|
||||
else
|
||||
cb(null, "npm: v" + npmVersion);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function verifyPython27(cb) {
|
||||
if (process.platform == 'win32') {
|
||||
if (!pythonExecutable) {
|
||||
var systemDrive = process.env.SystemDrive || 'C:\\';
|
||||
pythonExecutable = path.join(systemDrive, 'Python27', 'python.exe');
|
||||
|
||||
if (!fs.existsSync(pythonExecutable)) {
|
||||
pythonExecutable = 'python';
|
||||
}
|
||||
}
|
||||
|
||||
checkPythonVersion(pythonExecutable, cb);
|
||||
}
|
||||
else {
|
||||
cb(null, '');
|
||||
}
|
||||
}
|
||||
|
||||
function checkPythonVersion (python, cb) {
|
||||
var pythonHelpMessage = "Set the PYTHON env var to '/path/to/Python27/python.exe' if your python is installed in a non-default location.";
|
||||
|
||||
childProcess.execFile(python, ['-c', 'import platform; print(platform.python_version());'], { env: process.env }, function (err, stdout) {
|
||||
if (err) {
|
||||
error = "Python 2.7 is required to build Atom. An error (" + err + ") occured when checking the version of '" + python + "'. ";
|
||||
error += pythonHelpMessage;
|
||||
cb(error);
|
||||
return;
|
||||
}
|
||||
|
||||
var version = stdout.trim();
|
||||
if (~version.indexOf('+')) {
|
||||
version = version.replace(/\+/g, '');
|
||||
}
|
||||
if (~version.indexOf('rc')) {
|
||||
version = version.replace(/rc(.*)$/ig, '');
|
||||
}
|
||||
|
||||
// Atom requires python 2.7 or higher (but not python 3) for node-gyp
|
||||
var versionArray = version.split('.').map(function(num) { return +num; });
|
||||
var goodPythonVersion = (versionArray[0] === 2 && versionArray[1] >= 7);
|
||||
if (!goodPythonVersion) {
|
||||
error = "Python 2.7 is required to build Atom. '" + python + "' returns version " + version + ". ";
|
||||
error += pythonHelpMessage;
|
||||
cb(error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Finally, if we've gotten this far, callback to resume the install process.
|
||||
cb(null, "Python: v" + version);
|
||||
});
|
||||
}
|
||||
@@ -2,14 +2,13 @@ path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
{convertStackTrace} = require 'coffeestack'
|
||||
{View, $, $$} = require '../src/space-pen-extensions'
|
||||
grim = require 'grim'
|
||||
|
||||
sourceMaps = {}
|
||||
formatStackTrace = (spec, message='', stackTrace) ->
|
||||
return stackTrace unless stackTrace
|
||||
|
||||
jasminePattern = /^\s*at\s+.*\(?.*[/\\]jasmine(-[^/\\]*)?\.js:\d+:\d+\)?\s*$/
|
||||
firstJasmineLinePattern = /^\s*at [/\\].*[/\\]jasmine(-[^/\\]*)?\.js:\d+:\d+\)?\s*$/
|
||||
jasminePattern = /^\s*at\s+.*\(?.*\/jasmine(-[^\/]*)?\.js:\d+:\d+\)?\s*$/
|
||||
firstJasmineLinePattern = /^\s*at \/.*\/jasmine(-[^\/]*)?\.js:\d+:\d+\)?\s*$/
|
||||
convertedLines = []
|
||||
for line in stackTrace.split('\n')
|
||||
convertedLines.push(line) unless jasminePattern.test(line)
|
||||
@@ -24,7 +23,7 @@ formatStackTrace = (spec, message='', stackTrace) ->
|
||||
|
||||
for line, index in lines
|
||||
# Remove prefix of lines matching: at [object Object].<anonymous> (path:1:2)
|
||||
prefixMatch = line.match(/at \[object Object\]\.<anonymous> \(([^)]+)\)/)
|
||||
prefixMatch = line.match(/at \[object Object\]\.<anonymous> \(([^\)]+)\)/)
|
||||
line = "at #{prefixMatch[1]}" if prefixMatch
|
||||
|
||||
# Relativize locations to spec directory
|
||||
@@ -53,11 +52,6 @@ class AtomReporter extends View
|
||||
@div outlet: "message", class: 'message'
|
||||
@div outlet: "results", class: 'results'
|
||||
|
||||
@div outlet: "deprecations", class: 'status alert alert-warning', style: 'display: none', =>
|
||||
@span outlet: 'deprecationStatus', '0 deprecations'
|
||||
@div class: 'deprecation-toggle'
|
||||
@div outlet: 'deprecationList', class: 'deprecation-list'
|
||||
|
||||
startedAt: null
|
||||
runningSpecCount: 0
|
||||
completeSpecCount: 0
|
||||
@@ -65,7 +59,6 @@ class AtomReporter extends View
|
||||
failedCount: 0
|
||||
skippedCount: 0
|
||||
totalSpecCount: 0
|
||||
deprecationCount: 0
|
||||
@timeoutId: 0
|
||||
|
||||
reportRunnerStarting: (runner) ->
|
||||
@@ -95,44 +88,14 @@ class AtomReporter extends View
|
||||
reportSpecStarting: (spec) ->
|
||||
@specStarted(spec)
|
||||
|
||||
addDeprecations: (spec) ->
|
||||
deprecations = grim.getDeprecations()
|
||||
@deprecationCount += deprecations.length
|
||||
@deprecations.show() if @deprecationCount > 0
|
||||
if @deprecationCount is 1
|
||||
@deprecationStatus.text("1 deprecation")
|
||||
else
|
||||
@deprecationStatus.text("#{@deprecationCount} deprecations")
|
||||
|
||||
for deprecation in deprecations
|
||||
@deprecationList.append $$ ->
|
||||
@div class: 'padded', =>
|
||||
@div class: 'result-message fail deprecation-message', deprecation.message
|
||||
|
||||
for stack in deprecation.stacks
|
||||
fullStack = stack.map ({functionName, location}) ->
|
||||
if functionName is '<unknown>'
|
||||
" at #{location}"
|
||||
else
|
||||
" at #{functionName} (#{location})"
|
||||
@pre class: 'stack-trace padded', formatStackTrace(spec, deprecation.message, fullStack.join('\n'))
|
||||
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}) ->
|
||||
element = $(currentTarget)
|
||||
deprecationList = $(document).find('.deprecation-list')
|
||||
deprecationList.toggle()
|
||||
element.toggleClass('folded')
|
||||
false
|
||||
|
||||
updateSpecCounts: ->
|
||||
if @skippedCount
|
||||
specCount = "#{@completeSpecCount - @skippedCount}/#{@totalSpecCount - @skippedCount} (#{@skippedCount} skipped)"
|
||||
@@ -212,7 +175,6 @@ class AtomReporter extends View
|
||||
specView = new SpecResultView(spec)
|
||||
specView.attach()
|
||||
@failedCount++
|
||||
@addDeprecations(spec)
|
||||
|
||||
class SuiteResultView extends View
|
||||
@content: ->
|
||||
|
||||
+19
-49
@@ -241,15 +241,15 @@ describe "the `atom` global", ->
|
||||
two = atom.themes.stringToId(two)
|
||||
three = atom.themes.stringToId(three)
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
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)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
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", ->
|
||||
@@ -263,14 +263,14 @@ describe "the `atom` global", ->
|
||||
two = atom.themes.stringToId(two)
|
||||
three = atom.themes.stringToId(three)
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
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)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toBeNull()
|
||||
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", ->
|
||||
@@ -350,7 +350,7 @@ describe "the `atom` global", ->
|
||||
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 method", ->
|
||||
it "absorbs exceptions that are thrown by the package module's serialize methods", ->
|
||||
spyOn(console, 'error')
|
||||
|
||||
waitsForPromise ->
|
||||
@@ -365,16 +365,6 @@ describe "the `atom` global", ->
|
||||
expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
|
||||
it "absorbs exceptions that are thrown by the package module's deactivate method", ->
|
||||
spyOn(console, 'error')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-that-throws-on-deactivate")
|
||||
|
||||
runs ->
|
||||
expect(-> atom.packages.deactivatePackage("package-that-throws-on-deactivate")).not.toThrow()
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
|
||||
it "removes the package's grammars", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-grammars')
|
||||
@@ -390,8 +380,8 @@ describe "the `atom` global", ->
|
||||
|
||||
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
|
||||
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 ->
|
||||
@@ -503,14 +493,13 @@ describe "the `atom` global", ->
|
||||
expect(atom.config.get('core.disabledPackages')).toContain packageName
|
||||
|
||||
describe "with themes", ->
|
||||
reloadedHandler = null
|
||||
|
||||
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'
|
||||
@@ -528,17 +517,13 @@ describe "the `atom` global", ->
|
||||
expect(atom.config.get('core.themes')).toContain packageName
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
reloadedHandler = jasmine.createSpy('reloadedHandler')
|
||||
reloadedHandler.reset()
|
||||
atom.themes.onDidReloadAll reloadedHandler
|
||||
|
||||
# disabling of theme
|
||||
pack = atom.packages.disablePackage(packageName)
|
||||
|
||||
waitsFor ->
|
||||
reloadedHandler.callCount is 1
|
||||
not (pack in atom.packages.getActivePackages())
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.getActivePackages()).not.toContain pack
|
||||
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
|
||||
@@ -546,22 +531,7 @@ describe "the `atom` global", ->
|
||||
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'
|
||||
|
||||
@@ -23,18 +23,6 @@ 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 42
|
||||
|
||||
@@ -6,8 +6,7 @@ describe "ContextMenuManager", ->
|
||||
[contextMenu] = []
|
||||
|
||||
beforeEach ->
|
||||
{resourcePath} = atom.getLoadSettings()
|
||||
contextMenu = new ContextMenuManager({resourcePath})
|
||||
contextMenu = new ContextMenuManager
|
||||
|
||||
describe "adding definitions", ->
|
||||
it 'loads', ->
|
||||
@@ -18,59 +17,6 @@ describe "ContextMenuManager", ->
|
||||
expect(contextMenu.definitions['.selector'][0].label).toEqual 'label'
|
||||
expect(contextMenu.definitions['.selector'][0].command).toEqual 'command'
|
||||
|
||||
it 'does not add duplicate menu items', ->
|
||||
contextMenu.add 'file-path',
|
||||
'.selector':
|
||||
'label': 'command'
|
||||
|
||||
contextMenu.add 'file-path',
|
||||
'.selector':
|
||||
'label': 'command'
|
||||
|
||||
expect(contextMenu.definitions['.selector'][0].label).toEqual 'label'
|
||||
expect(contextMenu.definitions['.selector'][0].command).toEqual 'command'
|
||||
expect(contextMenu.definitions['.selector'].length).toBe 1
|
||||
|
||||
it 'allows multiple separators', ->
|
||||
contextMenu.add 'file-path',
|
||||
'.selector':
|
||||
'separator1': '-'
|
||||
'separator2': '-'
|
||||
|
||||
expect(contextMenu.definitions['.selector'].length).toBe 2
|
||||
expect(contextMenu.definitions['.selector'][0].type).toEqual 'separator'
|
||||
expect(contextMenu.definitions['.selector'][1].type).toEqual 'separator'
|
||||
|
||||
it 'allows duplicate commands with different labels', ->
|
||||
contextMenu.add 'file-path',
|
||||
'.selector':
|
||||
'label': 'command'
|
||||
|
||||
contextMenu.add 'file-path',
|
||||
'.selector':
|
||||
'another label': 'command'
|
||||
|
||||
expect(contextMenu.definitions['.selector'][0].label).toEqual 'label'
|
||||
expect(contextMenu.definitions['.selector'][0].command).toEqual 'command'
|
||||
expect(contextMenu.definitions['.selector'][1].label).toEqual 'another label'
|
||||
expect(contextMenu.definitions['.selector'][1].command).toEqual 'command'
|
||||
|
||||
it "loads submenus", ->
|
||||
contextMenu.add 'file-path',
|
||||
'.selector':
|
||||
'parent':
|
||||
'child-1': 'child-1:trigger'
|
||||
'child-2': 'child-2:trigger'
|
||||
'parent-2': 'parent-2:trigger'
|
||||
|
||||
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'
|
||||
|
||||
describe 'dev mode', ->
|
||||
it 'loads', ->
|
||||
contextMenu.add 'file-path',
|
||||
@@ -159,7 +105,7 @@ describe "ContextMenuManager", ->
|
||||
expect(menu[2].command).toEqual 'dev-command'
|
||||
expect(menu[3]).toBeUndefined()
|
||||
|
||||
describe "executeBuildHandlers", ->
|
||||
describe "#executeBuildHandlers", ->
|
||||
menuTemplate = [
|
||||
label: 'label'
|
||||
executeAtBuild: ->
|
||||
@@ -173,3 +119,4 @@ describe "ContextMenuManager", ->
|
||||
|
||||
expect(buildFn).toHaveBeenCalled()
|
||||
expect(buildFn.mostRecentCall.args[0]).toBe event
|
||||
|
||||
|
||||
+123
-291
@@ -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
|
||||
@@ -955,42 +912,6 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.findMarkers(class: 'a', startBufferRow: 0, endBufferRow: 3)).toEqual [marker1]
|
||||
expect(displayBuffer.findMarkers(endBufferRow: 10)).toEqual [marker3]
|
||||
|
||||
it "allows the startScreenRow and endScreenRow to be specified", ->
|
||||
marker1 = displayBuffer.markBufferRange([[6, 0], [7, 0]], class: 'a')
|
||||
marker2 = displayBuffer.markBufferRange([[9, 0], [10, 0]], class: 'a')
|
||||
displayBuffer.createFold(4, 7)
|
||||
expect(displayBuffer.findMarkers(class: 'a', startScreenRow: 6, endScreenRow: 7)).toEqual [marker2]
|
||||
|
||||
it "allows intersectsBufferRowRange to be specified", ->
|
||||
marker1 = displayBuffer.markBufferRange([[5, 0], [5, 0]], class: 'a')
|
||||
marker2 = displayBuffer.markBufferRange([[8, 0], [8, 0]], class: 'a')
|
||||
displayBuffer.createFold(4, 7)
|
||||
expect(displayBuffer.findMarkers(class: 'a', intersectsBufferRowRange: [5, 6])).toEqual [marker1]
|
||||
|
||||
it "allows intersectsScreenRowRange to be specified", ->
|
||||
marker1 = displayBuffer.markBufferRange([[5, 0], [5, 0]], class: 'a')
|
||||
marker2 = displayBuffer.markBufferRange([[8, 0], [8, 0]], class: 'a')
|
||||
displayBuffer.createFold(4, 7)
|
||||
expect(displayBuffer.findMarkers(class: 'a', intersectsScreenRowRange: [5, 10])).toEqual [marker2]
|
||||
|
||||
it "allows containedInScreenRange to be specified", ->
|
||||
marker1 = displayBuffer.markBufferRange([[5, 0], [5, 0]], class: 'a')
|
||||
marker2 = displayBuffer.markBufferRange([[8, 0], [8, 0]], class: 'a')
|
||||
displayBuffer.createFold(4, 7)
|
||||
expect(displayBuffer.findMarkers(class: 'a', containedInScreenRange: [[5, 0], [7, 0]])).toEqual [marker2]
|
||||
|
||||
it "allows intersectsBufferRange to be specified", ->
|
||||
marker1 = displayBuffer.markBufferRange([[5, 0], [5, 0]], class: 'a')
|
||||
marker2 = displayBuffer.markBufferRange([[8, 0], [8, 0]], class: 'a')
|
||||
displayBuffer.createFold(4, 7)
|
||||
expect(displayBuffer.findMarkers(class: 'a', intersectsBufferRange: [[5, 0], [6, 0]])).toEqual [marker1]
|
||||
|
||||
it "allows intersectsScreenRange to be specified", ->
|
||||
marker1 = displayBuffer.markBufferRange([[5, 0], [5, 0]], class: 'a')
|
||||
marker2 = displayBuffer.markBufferRange([[8, 0], [8, 0]], class: 'a')
|
||||
displayBuffer.createFold(4, 7)
|
||||
expect(displayBuffer.findMarkers(class: 'a', intersectsScreenRange: [[5, 0], [10, 0]])).toEqual [marker2]
|
||||
|
||||
describe "marker destruction", ->
|
||||
it "allows markers to be destroyed", ->
|
||||
marker = displayBuffer.markScreenRange([[5, 4], [5, 10]])
|
||||
@@ -998,16 +919,16 @@ 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()
|
||||
|
||||
@@ -1029,57 +950,12 @@ describe "DisplayBuffer", ->
|
||||
|
||||
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
|
||||
expect(displayBuffer.decorationsForScreenRowRange(2, 3)[marker.id][0]).toBe decoration
|
||||
|
||||
decoration.destroy()
|
||||
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 ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
@@ -1121,61 +997,17 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.setScrollLeft(maxScrollLeft + 50)).toBe maxScrollLeft
|
||||
expect(displayBuffer.getScrollLeft()).toBe maxScrollLeft
|
||||
|
||||
describe "::scrollToScreenPosition(position, [options])", ->
|
||||
beforeEach ->
|
||||
describe "::scrollToScreenPosition(position)", ->
|
||||
it "sets the scroll top and scroll left so the given screen position is in view", ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setLineHeightInPixels(10)
|
||||
displayBuffer.setDefaultCharWidth(10)
|
||||
displayBuffer.setHorizontalScrollbarHeight(0)
|
||||
|
||||
displayBuffer.setHeight(50)
|
||||
displayBuffer.setWidth(50)
|
||||
maxScrollTop = displayBuffer.getScrollHeight() - displayBuffer.getHeight()
|
||||
|
||||
it "sets the scroll top and scroll left so the given screen position is in view", ->
|
||||
displayBuffer.scrollToScreenPosition([8, 20])
|
||||
expect(displayBuffer.getScrollBottom()).toBe (9 + displayBuffer.getVerticalScrollMargin()) * 10
|
||||
expect(displayBuffer.getScrollRight()).toBe (20 + displayBuffer.getHorizontalScrollMargin()) * 10
|
||||
|
||||
describe "when the 'center' option is true", ->
|
||||
it "vertically scrolls to center the given position vertically", ->
|
||||
displayBuffer.scrollToScreenPosition([8, 20], center: true)
|
||||
expect(displayBuffer.getScrollTop()).toBe (8 * 10) + 5 - (50 / 2)
|
||||
expect(displayBuffer.getScrollRight()).toBe (20 + displayBuffer.getHorizontalScrollMargin()) * 10
|
||||
|
||||
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
|
||||
|
||||
+224
-1653
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+336
-759
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 |
@@ -0,0 +1 @@
|
||||
undefined
|
||||
Arquivo binário não exibido.
BIN
Arquivo binário não exibido.
BIN
Arquivo binário não exibido.
BIN
Arquivo binário não exibido.
BIN
Arquivo binário não exibido.
BIN
Arquivo binário não exibido.
-1
@@ -1 +0,0 @@
|
||||
x�ŽInB1³ö)úσ„¢°fÉ Úîvb�ù‘c†ãóQn�e=©žª,½· ÚÄ·9˜¡r&V!ªÆq¢êuH¢.Éâ)i6Ί|™àtuÞº�}-(+lUΉŒf_pUµQIcx�ßË€ßÚŽxoåÔ`wzáï}~ulçmYú(+•�QJ¤ëºvNþÿƒØµñž·ó1ÅiHL¢
|
||||
BIN
Arquivo binário não exibido.
BIN
Arquivo binário não exibido.
BIN
Arquivo binário não exibido.
@@ -1 +1 @@
|
||||
8a9c86f1cb1f14b8f436eb91f4b052c8802ca99e
|
||||
ef046e9eecaa5255ea5e9817132d4001724d6ae1
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Full of text
|
||||
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: ->
|
||||
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)"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
@import "stylesheets/first";
|
||||
@import "stylesheets/second";
|
||||
@import "stylesheets/last";
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"theme": "ui"
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
.editor {
|
||||
padding-top: 101px;
|
||||
padding-right: 101px;
|
||||
padding-bottom: 101px;
|
||||
|
||||
color: red;
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
.editor {
|
||||
/* padding-top: 103px;
|
||||
padding-right: 103px;*/
|
||||
padding-bottom: 103px;
|
||||
}
|
||||
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