Merge branch 'master' into mb-custom-extension-grammar-map

Conflicts:
	package.json
This commit is contained in:
Max Brunsfeld
2015-08-12 17:31:15 -07:00
24 changed files with 231 additions and 201 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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",

View File

@@ -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()

View File

@@ -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": {

View File

@@ -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 = [], '

View File

@@ -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", ->

View File

@@ -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]]]

View File

@@ -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]])

View File

@@ -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)", ->

View File

@@ -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

View File

@@ -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'

View File

@@ -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)

View File

@@ -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) ->

View File

@@ -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

View File

@@ -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)

View File

@@ -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 = ->

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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()

View File

@@ -20,6 +20,7 @@ atom-workspace {
height: 100%;
overflow: hidden;
position: relative;
color: @text-color;
background-color: @app-background-color;
font-family: @font-family;