mirror of
https://github.com/atom/atom.git
synced 2026-04-06 03:02:13 -04:00
Merge branch 'master' into mb-custom-extension-grammar-map
Conflicts: package.json
This commit is contained in:
@@ -7,8 +7,8 @@ which are hosted in the [Atom Organization](https://github.com/atom) on GitHub.
|
||||
These are just guidelines, not rules, use your best judgment and feel free to
|
||||
propose changes to this document in a pull request.
|
||||
|
||||
This project adheres to the [Open Code of Conduct][code-of-conduct]. By participating, you are expected to uphold this code.
|
||||
[code-of-conduct]: http://todogroup.org/opencodeofconduct/#Atom/opensource@github.com
|
||||
This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable behavior to atom@github.com.
|
||||
|
||||
## Submitting Issues
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ Visit [atom.io](https://atom.io) to learn more or visit the [Atom forum](https:/
|
||||
Follow [@AtomEditor](https://twitter.com/atomeditor) on Twitter for important
|
||||
announcements.
|
||||
|
||||
This project adheres to the [Open Code of Conduct][code-of-conduct]. By participating, you are expected to uphold this code.
|
||||
[code-of-conduct]: http://todogroup.org/opencodeofconduct/#Atom/opensource@github.com
|
||||
This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable behavior to atom@github.com.
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
@@ -237,9 +237,11 @@ module.exports = (grunt) ->
|
||||
ciTasks.push('dump-symbols') if process.platform isnt 'win32'
|
||||
ciTasks.push('set-version', 'check-licenses', 'lint', 'generate-asar')
|
||||
ciTasks.push('mkdeb') if process.platform is 'linux'
|
||||
ciTasks.push('codesign:exe') if process.platform is 'win32' and not process.env.TRAVIS
|
||||
ciTasks.push('create-windows-installer:installer') if process.platform is 'win32'
|
||||
ciTasks.push('test') if process.platform is 'darwin'
|
||||
ciTasks.push('codesign') unless process.env.TRAVIS
|
||||
ciTasks.push('codesign:installer') if process.platform is 'win32' and not process.env.TRAVIS
|
||||
ciTasks.push('codesign:app') if process.platform is 'darwin' and not process.env.TRAVIS
|
||||
ciTasks.push('publish-build') unless process.env.TRAVIS
|
||||
grunt.registerTask('ci', ciTasks)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"fs-plus": "2.x",
|
||||
"github-releases": "~0.2.0",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-electron-installer": "^0.36.0",
|
||||
"grunt-electron-installer": "^0.37.0",
|
||||
"grunt-cli": "~0.1.9",
|
||||
"grunt-coffeelint": "git+https://github.com/atom/grunt-coffeelint.git#cfb99aa99811d52687969532bd5a98011ed95bfe",
|
||||
"grunt-contrib-coffee": "~0.12.0",
|
||||
@@ -27,7 +27,7 @@
|
||||
"harmony-collections": "~0.3.8",
|
||||
"legal-eagle": "~0.10.0",
|
||||
"minidump": "~0.9",
|
||||
"npm": "2.5.1",
|
||||
"npm": "2.13.3",
|
||||
"rcedit": "~0.3.0",
|
||||
"request": "~2.27.0",
|
||||
"rimraf": "~2.2.2",
|
||||
|
||||
@@ -1,46 +1,39 @@
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{spawn} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'codesign', 'Codesign the app', ->
|
||||
grunt.registerTask 'codesign:exe', 'Codesign atom.exe and Update.exe', ->
|
||||
done = @async()
|
||||
spawn {cmd: 'taskkill', args: ['/F', '/IM', 'atom.exe']}, ->
|
||||
cmd = process.env.JANKY_SIGNTOOL ? 'signtool'
|
||||
atomExePath = path.join(grunt.config.get('atom.shellAppDir'), 'atom.exe')
|
||||
spawn {cmd, args: [atomExePath]}, (error) ->
|
||||
return done(error) if error?
|
||||
|
||||
updateExePath = path.resolve(__dirname, '..', 'node_modules', 'grunt-electron-installer', 'vendor', 'Update.exe')
|
||||
spawn {cmd, args: [updateExePath]}, (error) -> done(error)
|
||||
|
||||
grunt.registerTask 'codesign:installer', 'Codesign AtomSetup.exe', ->
|
||||
done = @async()
|
||||
cmd = process.env.JANKY_SIGNTOOL ? 'signtool'
|
||||
atomSetupExePath = path.resolve(grunt.config.get('atom.buildDir'), 'installer', 'AtomSetup.exe')
|
||||
spawn {cmd, args: [atomSetupExePath]}, (error) -> done(error)
|
||||
|
||||
grunt.registerTask 'codesign:app', 'Codesign Atom.app', ->
|
||||
done = @async()
|
||||
|
||||
if process.platform is 'darwin' and process.env.XCODE_KEYCHAIN
|
||||
unlockKeychain (error) ->
|
||||
if error?
|
||||
done(error)
|
||||
else
|
||||
signApp(done)
|
||||
else
|
||||
signApp(done)
|
||||
unlockKeychain (error) ->
|
||||
return done(error) if error?
|
||||
|
||||
cmd = 'codesign'
|
||||
args = ['--deep', '--force', '--verbose', '--sign', 'Developer ID Application: GitHub', grunt.config.get('atom.shellAppDir')]
|
||||
spawn {cmd, args}, (error) -> done(error)
|
||||
|
||||
unlockKeychain = (callback) ->
|
||||
return callback() unless process.env.XCODE_KEYCHAIN
|
||||
|
||||
cmd = 'security'
|
||||
{XCODE_KEYCHAIN_PASSWORD, XCODE_KEYCHAIN} = process.env
|
||||
args = ['unlock-keychain', '-p', XCODE_KEYCHAIN_PASSWORD, XCODE_KEYCHAIN]
|
||||
spawn {cmd, args}, (error) -> callback(error)
|
||||
|
||||
signApp = (callback) ->
|
||||
switch process.platform
|
||||
when 'darwin'
|
||||
cmd = 'codesign'
|
||||
args = ['--deep', '--force', '--verbose', '--sign', 'Developer ID Application: GitHub', grunt.config.get('atom.shellAppDir')]
|
||||
spawn {cmd, args}, (error) -> callback(error)
|
||||
when 'win32'
|
||||
spawn {cmd: 'taskkill', args: ['/F', '/IM', 'atom.exe']}, ->
|
||||
cmd = process.env.JANKY_SIGNTOOL ? 'signtool'
|
||||
args = [path.join(grunt.config.get('atom.shellAppDir'), 'atom.exe')]
|
||||
|
||||
spawn {cmd, args}, (error) ->
|
||||
return callback(error) if error?
|
||||
|
||||
setupExePath = path.resolve(grunt.config.get('atom.buildDir'), 'installer', 'AtomSetup.exe')
|
||||
if fs.isFileSync(setupExePath)
|
||||
args = [setupExePath]
|
||||
spawn {cmd, args}, (error) -> callback(error)
|
||||
else
|
||||
callback()
|
||||
else
|
||||
callback()
|
||||
|
||||
54
package.json
54
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.8",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
@@ -15,9 +15,9 @@
|
||||
"atomShellVersion": "0.22.3",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^5.1.8",
|
||||
"atom-space-pen-views": "^2.0.4",
|
||||
"babel-core": "^5.8.3",
|
||||
"atom-keymap": "^5.1.10",
|
||||
"atom-space-pen-views": "^2.1.0",
|
||||
"babel-core": "^5.8.21",
|
||||
"bootstrap": "^3.3.4",
|
||||
"clear-cut": "^2.0.1",
|
||||
"coffee-cash": "0.8.0",
|
||||
@@ -27,7 +27,7 @@
|
||||
"delegato": "^1",
|
||||
"emissary": "^1.3.3",
|
||||
"event-kit": "^1.2.0",
|
||||
"first-mate": "^4.1.8",
|
||||
"first-mate": "^4.2",
|
||||
"fs-plus": "^2.8.0",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "^2.1",
|
||||
@@ -47,7 +47,7 @@
|
||||
"q": "^1.1.2",
|
||||
"random-words": "0.0.1",
|
||||
"runas": "2.0.0",
|
||||
"scandal": "2.1.1",
|
||||
"scandal": "2.1.2",
|
||||
"scoped-property-store": "^0.17.0",
|
||||
"scrollbar-style": "^3.1",
|
||||
"season": "^5.3",
|
||||
@@ -57,7 +57,7 @@
|
||||
"space-pen": "3.8.2",
|
||||
"stacktrace-parser": "0.1.1",
|
||||
"temp": "0.8.1",
|
||||
"text-buffer": "6.5.0",
|
||||
"text-buffer": "6.5.2",
|
||||
"theorist": "^1.0.2",
|
||||
"typescript-simple": "1.0.0",
|
||||
"underscore-plus": "^1.6.6",
|
||||
@@ -65,15 +65,15 @@
|
||||
},
|
||||
"packageDependencies": {
|
||||
"atom-dark-syntax": "0.27.0",
|
||||
"atom-dark-ui": "0.49.0",
|
||||
"atom-dark-ui": "0.50.0",
|
||||
"atom-light-syntax": "0.28.0",
|
||||
"atom-light-ui": "0.41.0",
|
||||
"atom-light-ui": "0.43.0",
|
||||
"base16-tomorrow-dark-theme": "0.26.0",
|
||||
"base16-tomorrow-light-theme": "0.9.0",
|
||||
"one-dark-ui": "1.0.2",
|
||||
"one-dark-ui": "1.0.3",
|
||||
"one-dark-syntax": "1.1.0",
|
||||
"one-light-syntax": "1.1.0",
|
||||
"one-light-ui": "1.0.2",
|
||||
"one-light-ui": "1.0.3",
|
||||
"solarized-dark-syntax": "0.38.1",
|
||||
"solarized-light-syntax": "0.22.1",
|
||||
"about": "1.0.1",
|
||||
@@ -85,7 +85,7 @@
|
||||
"autocomplete-snippets": "1.7.1",
|
||||
"autoflow": "0.25.0",
|
||||
"autosave": "0.22.0",
|
||||
"background-tips": "0.25.0",
|
||||
"background-tips": "0.26.0",
|
||||
"bookmarks": "0.36.0",
|
||||
"bracket-matcher": "0.76.0",
|
||||
"command-palette": "0.36.0",
|
||||
@@ -93,7 +93,7 @@
|
||||
"dev-live-reload": "0.46.0",
|
||||
"encoding-selector": "0.21.0",
|
||||
"exception-reporting": "0.36.0",
|
||||
"find-and-replace": "0.175.0",
|
||||
"find-and-replace": "0.180.0",
|
||||
"fuzzy-finder": "0.87.0",
|
||||
"git-diff": "0.55.0",
|
||||
"go-to-line": "0.30.0",
|
||||
@@ -105,7 +105,7 @@
|
||||
"markdown-preview": "0.150.0",
|
||||
"metrics": "0.51.0",
|
||||
"notifications": "0.57.0",
|
||||
"open-on-github": "0.37.0",
|
||||
"open-on-github": "0.38.0",
|
||||
"package-generator": "0.40.0",
|
||||
"release-notes": "0.53.0",
|
||||
"settings-view": "0.213.1",
|
||||
@@ -116,30 +116,30 @@
|
||||
"symbols-view": "0.100.0",
|
||||
"tabs": "0.82.0",
|
||||
"timecop": "0.31.0",
|
||||
"tree-view": "0.181.0",
|
||||
"tree-view": "0.183.0",
|
||||
"update-package-dependencies": "0.10.0",
|
||||
"welcome": "0.29.0",
|
||||
"welcome": "0.30.0",
|
||||
"whitespace": "0.30.0",
|
||||
"wrap-guide": "0.35.0",
|
||||
"language-c": "0.46.0",
|
||||
"language-c": "0.47.0",
|
||||
"language-clojure": "0.16.0",
|
||||
"language-coffee-script": "0.41.0",
|
||||
"language-csharp": "0.6.0",
|
||||
"language-css": "0.32.2",
|
||||
"language-csharp": "0.7.0",
|
||||
"language-css": "0.33.0",
|
||||
"language-gfm": "0.80.0",
|
||||
"language-git": "0.10.0",
|
||||
"language-go": "0.32.0",
|
||||
"language-go": "0.37.0",
|
||||
"language-html": "0.40.1",
|
||||
"language-hyperlink": "0.14.0",
|
||||
"language-java": "0.15.0",
|
||||
"language-javascript": "0.85.0",
|
||||
"language-java": "0.16.0",
|
||||
"language-javascript": "0.87.1",
|
||||
"language-json": "0.16.0",
|
||||
"language-less": "0.28.2",
|
||||
"language-make": "0.14.0",
|
||||
"language-make": "0.16.0",
|
||||
"language-mustache": "0.12.0",
|
||||
"language-objective-c": "0.15.0",
|
||||
"language-perl": "0.28.0",
|
||||
"language-php": "0.28.0",
|
||||
"language-php": "0.29.0",
|
||||
"language-property-list": "0.8.0",
|
||||
"language-python": "0.38.0",
|
||||
"language-ruby": "0.57.0",
|
||||
@@ -149,10 +149,10 @@
|
||||
"language-source": "0.9.0",
|
||||
"language-sql": "0.17.0",
|
||||
"language-text": "0.7.0",
|
||||
"language-todo": "0.25.0",
|
||||
"language-todo": "0.26.0",
|
||||
"language-toml": "0.16.0",
|
||||
"language-xml": "0.31.0",
|
||||
"language-yaml": "0.23.0"
|
||||
"language-xml": "0.32.0",
|
||||
"language-yaml": "0.24.0"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -112,6 +112,13 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe 'uvwxyz'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(2).bufferDelta).toBe 'uvwxyz'.length
|
||||
|
||||
it "closes all scopes at the wrap boundary", ->
|
||||
displayBuffer.setEditorWidthInChars(10)
|
||||
buffer.setText("`aaa${1+2}aaa`")
|
||||
iterator = displayBuffer.tokenizedLineForScreenRow(1).getTokenIterator()
|
||||
scopes = iterator.getScopes()
|
||||
expect(scopes[scopes.length - 1]).not.toBe 'punctuation.section.embedded.js'
|
||||
|
||||
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 = [], '
|
||||
|
||||
@@ -444,7 +444,7 @@ describe "PackageManager", ->
|
||||
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes: 'ctrl-z', target: element1[0])).toHaveLength 0
|
||||
|
||||
atom.config.set("core.disabledKeymaps", ["package-with-keymaps-manifest"])
|
||||
atom.config.set("core.packagesWithKeymapsDisabled", ["package-with-keymaps-manifest"])
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-keymaps-manifest")
|
||||
@@ -455,16 +455,16 @@ describe "PackageManager", ->
|
||||
describe "when the package's keymaps are disabled and re-enabled after it is activated", ->
|
||||
it "removes and re-adds the keymaps", ->
|
||||
element1 = $$ -> @div class: 'test-1'
|
||||
atom.packages.observeDisabledKeymaps()
|
||||
atom.packages.observePackagesWithKeymapsDisabled()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-keymaps-manifest")
|
||||
|
||||
runs ->
|
||||
atom.config.set("core.disabledKeymaps", ['package-with-keymaps-manifest'])
|
||||
atom.config.set("core.packagesWithKeymapsDisabled", ['package-with-keymaps-manifest'])
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes: 'ctrl-z', target: element1[0])).toHaveLength 0
|
||||
|
||||
atom.config.set("core.disabledKeymaps", [])
|
||||
atom.config.set("core.packagesWithKeymapsDisabled", [])
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes: 'ctrl-z', target: element1[0])[0].command).toBe 'keymap-1'
|
||||
|
||||
describe "menu loading", ->
|
||||
|
||||
@@ -824,7 +824,8 @@ describe "TextEditorComponent", ->
|
||||
|
||||
describe "when the component is destroyed", ->
|
||||
it "stops listening for folding events", ->
|
||||
nextAnimationFrame()
|
||||
nextAnimationFrame() unless nextAnimationFrame is noAnimationFrame # clear pending frame request if needed
|
||||
|
||||
component.destroy()
|
||||
|
||||
lineNumber = component.lineNumberNodeForScreenRow(1)
|
||||
@@ -1791,6 +1792,22 @@ describe "TextEditorComponent", ->
|
||||
expect(nextAnimationFrame).toBe noAnimationFrame
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[2, 4], [6, 8]]
|
||||
|
||||
describe "when the command key is held down", ->
|
||||
it "adds a new selection and selects to the nearest screen position, then merges intersecting selections when the mouse button is released", ->
|
||||
editor.setSelectedScreenRange([[4, 4], [4, 9]])
|
||||
|
||||
linesNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([2, 4]), which: 1, metaKey: true))
|
||||
linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([6, 8]), which: 1))
|
||||
nextAnimationFrame()
|
||||
expect(editor.getSelectedScreenRanges()).toEqual [[[4, 4], [4, 9]], [[2, 4], [6, 8]]]
|
||||
|
||||
linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([4, 6]), which: 1))
|
||||
nextAnimationFrame()
|
||||
expect(editor.getSelectedScreenRanges()).toEqual [[[4, 4], [4, 9]], [[2, 4], [4, 6]]]
|
||||
|
||||
linesNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenPosition([4, 6]), which: 1))
|
||||
expect(editor.getSelectedScreenRanges()).toEqual [[[2, 4], [4, 9]]]
|
||||
|
||||
describe "when the editor is destroyed while dragging", ->
|
||||
it "cleans up the handlers for window.mouseup and window.mousemove", ->
|
||||
linesNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([2, 4]), which: 1))
|
||||
@@ -1936,6 +1953,32 @@ describe "TextEditorComponent", ->
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenRowInGutter(2)))
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[2, 0], [7, 0]]
|
||||
|
||||
it "orients the selection appropriately when the mouse moves above or below the initially-clicked row", ->
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(4)))
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(2)))
|
||||
nextAnimationFrame()
|
||||
expect(editor.getLastSelection().isReversed()).toBe true
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(6)))
|
||||
nextAnimationFrame()
|
||||
expect(editor.getLastSelection().isReversed()).toBe false
|
||||
|
||||
it "autoscrolls to the cursor position, but not the entire selected range", ->
|
||||
wrapperNode.style.height = 6 * lineHeightInPixels + 'px'
|
||||
component.measureDimensions()
|
||||
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(2)))
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(6)))
|
||||
nextAnimationFrame()
|
||||
|
||||
expect(editor.getScrollTop()).toBeGreaterThan 0
|
||||
maxScrollTop = editor.getScrollTop()
|
||||
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(5)))
|
||||
nextAnimationFrame()
|
||||
expect(editor.getScrollTop()).toBe maxScrollTop
|
||||
|
||||
describe "when the gutter is meta-clicked and dragged", ->
|
||||
beforeEach ->
|
||||
editor.setSelectedScreenRange([[3, 0], [3, 2]])
|
||||
@@ -1948,10 +1991,12 @@ describe "TextEditorComponent", ->
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenRowInGutter(6), metaKey: true))
|
||||
expect(editor.getSelectedScreenRanges()).toEqual [[[3, 0], [3, 2]], [[4, 0], [7, 0]]]
|
||||
|
||||
it "merges overlapping selections", ->
|
||||
it "merges overlapping selections when the mouse button is released", ->
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(2), metaKey: true))
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(6), metaKey: true))
|
||||
nextAnimationFrame()
|
||||
expect(editor.getSelectedScreenRanges()).toEqual [[[3, 0], [3, 2]], [[2, 0], [7, 0]]]
|
||||
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenRowInGutter(6), metaKey: true))
|
||||
expect(editor.getSelectedScreenRanges()).toEqual [[[2, 0], [7, 0]]]
|
||||
|
||||
|
||||
@@ -85,80 +85,6 @@ describe "TextEditor", ->
|
||||
expect(editor.tokenizedLineForScreenRow(0).tokens.length).toBe 1
|
||||
expect(editor.tokenizedLineForScreenRow(1).tokens.length).toBe 2 # sof tab
|
||||
|
||||
describe "when the editor is constructed with an initialLine option", ->
|
||||
it "positions the cursor on the specified line", ->
|
||||
editor = null
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.less', initialLine: 5).then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.getLastCursor().getBufferPosition().row).toEqual 5
|
||||
expect(editor.getLastCursor().getBufferPosition().column).toEqual 0
|
||||
|
||||
describe "when the editor is constructed with an initialColumn option", ->
|
||||
it "positions the cursor on the specified column", ->
|
||||
editor = null
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.less', initialColumn: 8).then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.getLastCursor().getBufferPosition().row).toEqual 0
|
||||
expect(editor.getLastCursor().getBufferPosition().column).toEqual 8
|
||||
|
||||
describe "when the editor is reopened with an initialLine option", ->
|
||||
it "positions the cursor on the specified line", ->
|
||||
editor = null
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.less', initialLine: 5).then (o) -> editor = o
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.less', initialLine: 4).then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.getLastCursor().getBufferPosition().row).toEqual 4
|
||||
expect(editor.getLastCursor().getBufferPosition().column).toEqual 0
|
||||
|
||||
describe "when the editor is reopened with an initialColumn option", ->
|
||||
it "positions the cursor on the specified column", ->
|
||||
editor = null
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.less', initialColumn: 8).then (o) -> editor = o
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.less', initialColumn: 7).then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.getLastCursor().getBufferPosition().row).toEqual 0
|
||||
expect(editor.getLastCursor().getBufferPosition().column).toEqual 7
|
||||
|
||||
it "ignores non-numeric initialLine and initialColumn options", ->
|
||||
[editor1, editor2, editor3] = []
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.less', initialColumn: 8, initialLine: NaN).then (o) -> editor1 = o
|
||||
|
||||
runs ->
|
||||
expect(editor1.getLastCursor().getBufferPosition().row).toEqual 0
|
||||
expect(editor1.getLastCursor().getBufferPosition().column).toEqual 8
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.less', initialColumn: NaN, initialLine: 3).then (o) -> editor2 = o
|
||||
|
||||
runs ->
|
||||
expect(editor2.getLastCursor().getBufferPosition().row).toEqual 3
|
||||
expect(editor2.getLastCursor().getBufferPosition().column).toEqual 0
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.less', initialColumn: NaN, initialLine: NaN).then (o) -> editor3 = o
|
||||
|
||||
runs ->
|
||||
expect(editor3.getLastCursor().getBufferPosition().row).toEqual 3
|
||||
expect(editor3.getLastCursor().getBufferPosition().column).toEqual 0
|
||||
|
||||
describe ".copy()", ->
|
||||
it "returns a different edit session with the same initial state", ->
|
||||
editor.setSelectedBufferRange([[1, 2], [3, 4]])
|
||||
|
||||
@@ -585,6 +585,7 @@ describe "TokenizedBuffer", ->
|
||||
describe "when the selector matches a single token at the position", ->
|
||||
it "returns the range covered by the token", ->
|
||||
expect(tokenizedBuffer.bufferRangeForScopeAtPosition('.storage.modifier.js', [0, 1])).toEqual [[0, 0], [0, 3]]
|
||||
expect(tokenizedBuffer.bufferRangeForScopeAtPosition('.storage.modifier.js', [0, 3])).toEqual [[0, 0], [0, 3]]
|
||||
|
||||
describe "when the selector matches a run of multiple tokens at the position", ->
|
||||
it "returns the range covered by all contigous tokens (within a single line)", ->
|
||||
|
||||
@@ -225,6 +225,44 @@ describe "Workspace", ->
|
||||
expect(workspace.paneContainer.root.children[0]).toBe pane1
|
||||
expect(workspace.paneContainer.root.children[1]).toBe pane4
|
||||
|
||||
describe "when an initialLine and initialColumn are specified", ->
|
||||
it "moves the cursor to the indicated location", ->
|
||||
waitsForPromise ->
|
||||
workspace.open('a', initialLine: 1, initialColumn: 5)
|
||||
|
||||
runs ->
|
||||
expect(workspace.getActiveTextEditor().getCursorBufferPosition()).toEqual [1, 5]
|
||||
|
||||
waitsForPromise ->
|
||||
workspace.open('a', initialLine: 2, initialColumn: 4)
|
||||
|
||||
runs ->
|
||||
expect(workspace.getActiveTextEditor().getCursorBufferPosition()).toEqual [2, 4]
|
||||
|
||||
waitsForPromise ->
|
||||
workspace.open('a', initialLine: 0, initialColumn: 0)
|
||||
|
||||
runs ->
|
||||
expect(workspace.getActiveTextEditor().getCursorBufferPosition()).toEqual [0, 0]
|
||||
|
||||
waitsForPromise ->
|
||||
workspace.open('a', initialLine: NaN, initialColumn: 4)
|
||||
|
||||
runs ->
|
||||
expect(workspace.getActiveTextEditor().getCursorBufferPosition()).toEqual [0, 4]
|
||||
|
||||
waitsForPromise ->
|
||||
workspace.open('a', initialLine: 2, initialColumn: NaN)
|
||||
|
||||
runs ->
|
||||
expect(workspace.getActiveTextEditor().getCursorBufferPosition()).toEqual [2, 0]
|
||||
|
||||
waitsForPromise ->
|
||||
workspace.open('a', initialLine: Infinity, initialColumn: Infinity)
|
||||
|
||||
runs ->
|
||||
expect(workspace.getActiveTextEditor().getCursorBufferPosition()).toEqual [2, 11]
|
||||
|
||||
describe "when the file is over 2MB", ->
|
||||
it "opens the editor with largeFileMode: true", ->
|
||||
spyOn(fs, 'getSizeSync').andReturn 2 * 1048577 # 2MB
|
||||
|
||||
@@ -15,6 +15,18 @@ stats =
|
||||
misses: 0
|
||||
|
||||
defaultOptions =
|
||||
# Currently, the cache key is a function of:
|
||||
# * The version of Babel used to transpile the .js file.
|
||||
# * The contents of this defaultOptions object.
|
||||
# * The contents of the .js file.
|
||||
# That means that we cannot allow information from an unknown source
|
||||
# to affect the cache key for the output of transpilation, which means
|
||||
# we cannot allow users to override these default options via a .babelrc
|
||||
# file, because the contents of that .babelrc file will not make it into
|
||||
# the cache key. It would be great to support .babelrc files once we
|
||||
# have a way to do so that is safe with respect to caching.
|
||||
breakConfig: true
|
||||
|
||||
# The Chrome dev tools will show the original version of the file
|
||||
# when the source map is inlined.
|
||||
sourceMap: 'inline'
|
||||
|
||||
@@ -67,10 +67,20 @@ class Marker
|
||||
@bufferMarker.destroy()
|
||||
@disposables.dispose()
|
||||
|
||||
# Essential: Creates and returns a new {Marker} with the same properties as this
|
||||
# marker.
|
||||
# Essential: Creates and returns a new {Marker} with the same properties as
|
||||
# this marker.
|
||||
#
|
||||
# * `properties` {Object}
|
||||
# {Selection} markers (markers with a custom property `type: "selection"`)
|
||||
# should be copied with a different `type` value, for example with
|
||||
# `marker.copy({type: null})`. Otherwise, the new marker's selection will
|
||||
# be merged with this marker's selection, and a `null` value will be
|
||||
# returned.
|
||||
#
|
||||
# * `properties` (optional) {Object} properties to associate with the new
|
||||
# marker. The new marker's properties are computed by extending this marker's
|
||||
# properties with `properties`.
|
||||
#
|
||||
# Returns a {Marker}.
|
||||
copy: (properties) ->
|
||||
@displayBuffer.getMarker(@bufferMarker.copy(properties).id)
|
||||
|
||||
|
||||
@@ -310,12 +310,12 @@ class PackageManager
|
||||
@activatePackage(packageName) for packageName in packagesToEnable
|
||||
null
|
||||
|
||||
unobserveDisabledKeymaps: ->
|
||||
@disabledKeymapsSubscription?.dispose()
|
||||
@disabledKeymapsSubscription = null
|
||||
unobservePackagesWithKeymapsDisabled: ->
|
||||
@packagesWithKeymapsDisabledSubscription?.dispose()
|
||||
@packagesWithKeymapsDisabledSubscription = null
|
||||
|
||||
observeDisabledKeymaps: ->
|
||||
@disabledKeymapsSubscription ?= atom.config.onDidChange 'core.disabledKeymaps', ({newValue, oldValue}) =>
|
||||
observePackagesWithKeymapsDisabled: ->
|
||||
@packagesWithKeymapsDisabledSubscription ?= atom.config.onDidChange 'core.packagesWithKeymapsDisabled', ({newValue, oldValue}) =>
|
||||
keymapsToEnable = _.difference(oldValue, newValue)
|
||||
keymapsToDisable = _.difference(newValue, oldValue)
|
||||
|
||||
@@ -409,7 +409,7 @@ class PackageManager
|
||||
promises.push(promise) unless pack.hasActivationCommands()
|
||||
return
|
||||
@observeDisabledPackages()
|
||||
@observeDisabledKeymaps()
|
||||
@observePackagesWithKeymapsDisabled()
|
||||
promises
|
||||
|
||||
# Activate a single package by name
|
||||
@@ -438,7 +438,7 @@ class PackageManager
|
||||
@deactivatePackage(pack.name) for pack in @getLoadedPackages()
|
||||
return
|
||||
@unobserveDisabledPackages()
|
||||
@unobserveDisabledKeymaps()
|
||||
@unobservePackagesWithKeymapsDisabled()
|
||||
|
||||
# Deactivate the package with the given name
|
||||
deactivatePackage: (name) ->
|
||||
|
||||
@@ -201,7 +201,7 @@ class Package
|
||||
activateResources: ->
|
||||
@activationDisposables = new CompositeDisposable
|
||||
|
||||
keymapIsDisabled = _.include(atom.config.get("core.disabledKeymaps") ? [], @name)
|
||||
keymapIsDisabled = _.include(atom.config.get("core.packagesWithKeymapsDisabled") ? [], @name)
|
||||
if keymapIsDisabled
|
||||
@deactivateKeymaps()
|
||||
else
|
||||
|
||||
@@ -135,21 +135,23 @@ class PaneElement extends HTMLElement
|
||||
hasFocus: ->
|
||||
this is document.activeElement or @contains(document.activeElement)
|
||||
|
||||
atom.commands.add 'atom-workspace',
|
||||
'pane:show-next-item': -> @getModel().getActivePane().activateNextItem()
|
||||
'pane:show-previous-item': -> @getModel().getActivePane().activatePreviousItem()
|
||||
'pane:show-item-1': -> @getModel().getActivePane().activateItemAtIndex(0)
|
||||
'pane:show-item-2': -> @getModel().getActivePane().activateItemAtIndex(1)
|
||||
'pane:show-item-3': -> @getModel().getActivePane().activateItemAtIndex(2)
|
||||
'pane:show-item-4': -> @getModel().getActivePane().activateItemAtIndex(3)
|
||||
'pane:show-item-5': -> @getModel().getActivePane().activateItemAtIndex(4)
|
||||
'pane:show-item-6': -> @getModel().getActivePane().activateItemAtIndex(5)
|
||||
'pane:show-item-7': -> @getModel().getActivePane().activateItemAtIndex(6)
|
||||
'pane:show-item-8': -> @getModel().getActivePane().activateItemAtIndex(7)
|
||||
'pane:show-item-9': -> @getModel().getActivePane().activateItemAtIndex(8)
|
||||
'pane:move-item-right': -> @getModel().getActivePane().moveItemRight()
|
||||
'pane:move-item-left': -> @getModel().getActivePane().moveItemLeft()
|
||||
|
||||
atom.commands.add 'atom-pane',
|
||||
'pane:save-items': -> @getModel().saveItems()
|
||||
'pane:show-next-item': -> @getModel().activateNextItem()
|
||||
'pane:show-previous-item': -> @getModel().activatePreviousItem()
|
||||
'pane:show-item-1': -> @getModel().activateItemAtIndex(0)
|
||||
'pane:show-item-2': -> @getModel().activateItemAtIndex(1)
|
||||
'pane:show-item-3': -> @getModel().activateItemAtIndex(2)
|
||||
'pane:show-item-4': -> @getModel().activateItemAtIndex(3)
|
||||
'pane:show-item-5': -> @getModel().activateItemAtIndex(4)
|
||||
'pane:show-item-6': -> @getModel().activateItemAtIndex(5)
|
||||
'pane:show-item-7': -> @getModel().activateItemAtIndex(6)
|
||||
'pane:show-item-8': -> @getModel().activateItemAtIndex(7)
|
||||
'pane:show-item-9': -> @getModel().activateItemAtIndex(8)
|
||||
'pane:move-item-right': -> @getModel().moveItemRight()
|
||||
'pane:move-item-left': -> @getModel().moveItemLeft()
|
||||
'pane:split-left': -> @getModel().splitLeft(copyActiveItem: true)
|
||||
'pane:split-right': -> @getModel().splitRight(copyActiveItem: true)
|
||||
'pane:split-up': -> @getModel().splitUp(copyActiveItem: true)
|
||||
|
||||
@@ -404,7 +404,7 @@ class TextEditorComponent
|
||||
@editor.getLastSelection().selectLine()
|
||||
|
||||
@handleDragUntilMouseUp event, (screenPosition) =>
|
||||
@editor.selectToScreenPosition(screenPosition)
|
||||
@editor.selectToScreenPosition(screenPosition, true)
|
||||
|
||||
onLineNumberGutterMouseDown: (event) =>
|
||||
return unless event.button is 0 # only handle the left mouse button
|
||||
@@ -428,9 +428,10 @@ class TextEditorComponent
|
||||
dragRow = screenPosition.row
|
||||
dragBufferRow = @editor.bufferRowForScreenRow(dragRow)
|
||||
if dragBufferRow < clickedBufferRow # dragging up
|
||||
@editor.setSelectedBufferRange([[dragBufferRow, 0], [clickedBufferRow + 1, 0]], preserveFolds: true)
|
||||
@editor.setSelectedBufferRange([[dragBufferRow, 0], [clickedBufferRow + 1, 0]], reversed: true, preserveFolds: true, autoscroll: false)
|
||||
else
|
||||
@editor.setSelectedBufferRange([[clickedBufferRow, 0], [dragBufferRow + 1, 0]], preserveFolds: true)
|
||||
@editor.setSelectedBufferRange([[clickedBufferRow, 0], [dragBufferRow + 1, 0]], reversed: false, preserveFolds: true, autoscroll: false)
|
||||
@editor.getLastCursor().autoscroll()
|
||||
|
||||
onGutterMetaClick: (event) =>
|
||||
clickedRow = @screenPositionForMouseEvent(event).row
|
||||
@@ -448,9 +449,6 @@ class TextEditorComponent
|
||||
else
|
||||
rowSelection.setBufferRange([[clickedBufferRow, 0], [dragBufferRow + 1, 0]], preserveFolds: true)
|
||||
|
||||
# After updating the selected screen range, merge overlapping selections
|
||||
@editor.mergeIntersectingSelections(preserveFolds: true)
|
||||
|
||||
# The merge process will possibly destroy the current selection because
|
||||
# it will be merged into another one. Therefore, we need to obtain a
|
||||
# reference to the new selection that contains the originally selected row
|
||||
@@ -552,6 +550,7 @@ class TextEditorComponent
|
||||
onMouseUp = (event) =>
|
||||
stopDragging()
|
||||
@editor.finalizeSelections()
|
||||
@editor.mergeIntersectingSelections()
|
||||
pasteSelectionClipboard(event)
|
||||
|
||||
stopDragging = ->
|
||||
|
||||
@@ -1948,10 +1948,11 @@ class TextEditor extends Model
|
||||
# This method may merge selections that end up intesecting.
|
||||
#
|
||||
# * `position` An instance of {Point}, with a given `row` and `column`.
|
||||
selectToScreenPosition: (position) ->
|
||||
selectToScreenPosition: (position, suppressMerge) ->
|
||||
lastSelection = @getLastSelection()
|
||||
lastSelection.selectToScreenPosition(position)
|
||||
@mergeIntersectingSelections(reversed: lastSelection.isReversed())
|
||||
unless suppressMerge
|
||||
@mergeIntersectingSelections(reversed: lastSelection.isReversed())
|
||||
|
||||
# Essential: Move the cursor of each selection one character upward while
|
||||
# preserving the selection's tail position.
|
||||
|
||||
@@ -490,7 +490,7 @@ class TokenizedBuffer extends Model
|
||||
scopes.pop()
|
||||
else
|
||||
endColumn = startColumn + tag
|
||||
if endColumn > position.column
|
||||
if endColumn >= position.column
|
||||
break
|
||||
else
|
||||
startColumn = endColumn
|
||||
|
||||
@@ -387,15 +387,17 @@ class TokenizedLine
|
||||
rightSpecialTokens[rightTags.length] = specialToken
|
||||
rightTags.push(tag)
|
||||
|
||||
# tag represents the start or end of a scop
|
||||
# tag represents the start of a scope
|
||||
else if (tag % 2) is -1
|
||||
if screenColumn < column
|
||||
leftTags.push(tag)
|
||||
rightOpenScopes.push(tag)
|
||||
else
|
||||
rightTags.push(tag)
|
||||
|
||||
# tag represents the end of a scope
|
||||
else
|
||||
if screenColumn < column
|
||||
if screenColumn <= column
|
||||
leftTags.push(tag)
|
||||
rightOpenScopes.pop()
|
||||
else
|
||||
|
||||
@@ -70,24 +70,15 @@ class ViewRegistry
|
||||
# workspace what view constructor it should use to represent them:
|
||||
#
|
||||
# ```coffee
|
||||
# atom.views.addViewProvider
|
||||
# modelConstructor: TextEditor
|
||||
# viewConstructor: TextEditorElement
|
||||
# atom.views.addViewProvider TextEditor, (textEditor) ->
|
||||
# textEditorElement = new TextEditorElement
|
||||
# textEditorElement.initialize(textEditor)
|
||||
# textEditorElement
|
||||
# ```
|
||||
#
|
||||
# * `providerSpec` {Object} containing the following keys:
|
||||
# * `modelConstructor` Constructor {Function} for your model.
|
||||
# * `viewConstructor` (Optional) Constructor {Function} for your view. It
|
||||
# should be a subclass of `HTMLElement` (that is, your view should be a
|
||||
# DOM node) and have a `::setModel()` method which will be called
|
||||
# immediately after construction. If you don't supply this property, you
|
||||
# must supply the `createView` property with a function that never returns
|
||||
# `undefined`.
|
||||
# * `createView` (Optional) Factory {Function} that must return a subclass
|
||||
# of `HTMLElement` or `undefined`. If this property is not present or the
|
||||
# function returns `undefined`, the view provider will fall back to the
|
||||
# `viewConstructor` property. If you don't provide this property, you must
|
||||
# provider a `viewConstructor` property.
|
||||
# * `modelConstructor` Constructor {Function} for your model.
|
||||
# * `createView` Factory {Function} that is passed an instance of your model
|
||||
# and must return a subclass of `HTMLElement` or `undefined`.
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to remove the
|
||||
# added provider.
|
||||
|
||||
@@ -468,11 +468,11 @@ class Workspace extends Model
|
||||
pane.activate() if activatePane
|
||||
|
||||
initialLine = initialColumn = 0
|
||||
if Number.isFinite(options.initialLine)
|
||||
unless Number.isNaN(options.initialLine)
|
||||
initialLine = options.initialLine
|
||||
if Number.isFinite(options.initialColumn)
|
||||
unless Number.isNaN(options.initialColumn)
|
||||
initialColumn = options.initialColumn
|
||||
if initialLine > 0 or initialColumn > 0
|
||||
if initialLine >= 0 or initialColumn >= 0
|
||||
item.setCursorBufferPosition?([initialLine, initialColumn])
|
||||
|
||||
index = pane.getActiveItemIndex()
|
||||
|
||||
@@ -20,6 +20,7 @@ atom-workspace {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
color: @text-color;
|
||||
background-color: @app-background-color;
|
||||
font-family: @font-family;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user