mirror of
https://github.com/atom/atom.git
synced 2026-01-23 13:58:08 -05:00
Merge branch 'master' into batch-updates
This commit is contained in:
12
package.json
12
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.183.0",
|
||||
"version": "0.185.0",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
@@ -93,9 +93,9 @@
|
||||
"dev-live-reload": "0.41.0",
|
||||
"encoding-selector": "0.18.0",
|
||||
"exception-reporting": "0.24.0",
|
||||
"find-and-replace": "0.157.0",
|
||||
"find-and-replace": "0.158.0",
|
||||
"fuzzy-finder": "0.68.0",
|
||||
"git-diff": "0.53.0",
|
||||
"git-diff": "0.54.0",
|
||||
"go-to-line": "0.30.0",
|
||||
"grammar-selector": "0.45.0",
|
||||
"image-view": "0.49.0",
|
||||
@@ -116,7 +116,7 @@
|
||||
"symbols-view": "0.84.0",
|
||||
"tabs": "0.67.0",
|
||||
"timecop": "0.31.0",
|
||||
"tree-view": "0.161.0",
|
||||
"tree-view": "0.162.0",
|
||||
"update-package-dependencies": "0.8.0",
|
||||
"welcome": "0.24.0",
|
||||
"whitespace": "0.29.0",
|
||||
@@ -132,14 +132,14 @@
|
||||
"language-html": "0.29.0",
|
||||
"language-hyperlink": "0.12.2",
|
||||
"language-java": "0.14.0",
|
||||
"language-javascript": "0.58.0",
|
||||
"language-javascript": "0.59.0",
|
||||
"language-json": "0.12.0",
|
||||
"language-less": "0.25.0",
|
||||
"language-make": "0.13.0",
|
||||
"language-mustache": "0.11.0",
|
||||
"language-objective-c": "0.15.0",
|
||||
"language-perl": "0.10.0",
|
||||
"language-php": "0.20.0",
|
||||
"language-php": "0.21.0",
|
||||
"language-property-list": "0.8.0",
|
||||
"language-python": "0.32.0",
|
||||
"language-ruby": "0.48.0",
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
babel = require '../src/babel'
|
||||
crypto = require 'crypto'
|
||||
grim = require 'grim'
|
||||
|
||||
describe "Babel transpiler support", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
describe "::createBabelVersionAndOptionsDigest", ->
|
||||
it "returns a digest for the library version and specified options", ->
|
||||
defaultOptions =
|
||||
@@ -30,21 +37,27 @@ describe "Babel transpiler support", ->
|
||||
it "transpiles it using babel", ->
|
||||
transpiled = require('./fixtures/babel/babel-single-quotes.js')
|
||||
expect(transpiled(3)).toBe 4
|
||||
expect(grim.getDeprecationsLength()).toBe 0
|
||||
|
||||
describe "when a .js file starts with 'use 6to5';", ->
|
||||
it "transpiles it using 6to5", ->
|
||||
it "transpiles it using babel and adds a pragma deprecation", ->
|
||||
expect(grim.getDeprecationsLength()).toBe 0
|
||||
transpiled = require('./fixtures/babel/6to5-single-quotes.js')
|
||||
expect(transpiled(3)).toBe 4
|
||||
expect(grim.getDeprecationsLength()).toBe 1
|
||||
|
||||
describe 'when a .js file starts with "use babel";', ->
|
||||
it "transpiles it using babel", ->
|
||||
transpiled = require('./fixtures/babel/babel-double-quotes.js')
|
||||
expect(transpiled(3)).toBe 4
|
||||
expect(grim.getDeprecationsLength()).toBe 0
|
||||
|
||||
describe 'when a .js file starts with "use 6to5";', ->
|
||||
it "transpiles it using babel", ->
|
||||
it "transpiles it using babel and adds a pragma deprecation", ->
|
||||
expect(grim.getDeprecationsLength()).toBe 0
|
||||
transpiled = require('./fixtures/babel/6to5-double-quotes.js')
|
||||
expect(transpiled(3)).toBe 4
|
||||
expect(grim.getDeprecationsLength()).toBe 1
|
||||
|
||||
describe "when a .js file does not start with 'use 6to6';", ->
|
||||
it "does not transpile it using babel", ->
|
||||
|
||||
@@ -75,7 +75,7 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' return '
|
||||
|
||||
atom.config.set('editor.preferredLineLength', 5)
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe 'funct'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' fun'
|
||||
|
||||
atom.config.set('editor.softWrapAtPreferredLineLength', false)
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' return '
|
||||
@@ -92,7 +92,7 @@ describe "DisplayBuffer", ->
|
||||
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.tokenizedLineForScreenRow(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", ->
|
||||
@@ -105,7 +105,7 @@ describe "DisplayBuffer", ->
|
||||
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.tokenizedLineForScreenRow(4).text).toBe ' right = [];'
|
||||
|
||||
describe "when there are hard tabs", ->
|
||||
beforeEach ->
|
||||
@@ -115,6 +115,11 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).tokens[0].isHardTab).toBeTruthy()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(3).tokens[1].isHardTab).toBeTruthy()
|
||||
|
||||
describe "when a line is wrapped", ->
|
||||
it "correctly tokenizes soft wrap indentation tokens", ->
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).tokens[0].isSoftWrapIndentation).toBeTruthy()
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(4).tokens[1].isSoftWrapIndentation).toBeTruthy()
|
||||
|
||||
describe "when the buffer changes", ->
|
||||
describe "when buffer lines are updated", ->
|
||||
describe "when whitespace is added after the max line length", ->
|
||||
@@ -138,8 +143,8 @@ describe "DisplayBuffer", ->
|
||||
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(8).text).toBe ' left1234567890.push(current) : '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(9).text).toBe ' right.push(current);'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' }'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 7, end: 8, screenDelta: 1, bufferDelta: 0)
|
||||
@@ -148,7 +153,7 @@ describe "DisplayBuffer", ->
|
||||
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(8).text).toBe ' 1234567890'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(9).text).toBe 'abcdefghij ? left.push(current) : '
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe 'right.push(current);'
|
||||
|
||||
@@ -159,7 +164,7 @@ describe "DisplayBuffer", ->
|
||||
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(5).text).toBe ' sort(left).concat(pivot).concat(sort(right));'
|
||||
expect(displayBuffer.tokenizedLineForScreenRow(6).text).toBe ' };'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 3, end: 9, screenDelta: -6, bufferDelta: -4)
|
||||
@@ -191,10 +196,10 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([3, 5])).toEqual([3, 5])
|
||||
expect(displayBuffer.screenPositionForBufferPosition([3, 50])).toEqual([3, 50])
|
||||
expect(displayBuffer.screenPositionForBufferPosition([3, 51])).toEqual([3, 50])
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([4, 0])).toEqual([3, 51])
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([4, 0])).toEqual([3, 50])
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([3, 50])).toEqual([3, 50])
|
||||
expect(displayBuffer.screenPositionForBufferPosition([3, 62])).toEqual([4, 11])
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([4, 11])).toEqual([3, 62])
|
||||
expect(displayBuffer.screenPositionForBufferPosition([3, 62])).toEqual([4, 15])
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([4, 11])).toEqual([3, 58])
|
||||
|
||||
# following a wrapped line
|
||||
expect(displayBuffer.screenPositionForBufferPosition([4, 5])).toEqual([5, 5])
|
||||
@@ -209,9 +214,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(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.tokenizedLineForScreenRow(12).tokens).toBe ' sort(left).concat(pivot).concat(sort'
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 0, end: 15, screenDelta: 3, bufferDelta: 0)
|
||||
|
||||
it "only allows positive widths to be assigned", ->
|
||||
@@ -222,7 +227,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
it "sets ::scrollLeft to 0 and keeps it there when soft wrapping is enabled", ->
|
||||
displayBuffer.setDefaultCharWidth(10)
|
||||
displayBuffer.setWidth(50)
|
||||
displayBuffer.setWidth(85)
|
||||
displayBuffer.manageScrollPosition = true
|
||||
|
||||
displayBuffer.setSoftWrapped(false)
|
||||
@@ -597,8 +602,8 @@ describe "DisplayBuffer", ->
|
||||
describe "when wrapBeyondNewlines is false (the default)", ->
|
||||
it "wraps positions beyond the end of hard newlines to the end of the line", ->
|
||||
expect(displayBuffer.clipScreenPosition([1, 10000])).toEqual [1, 30]
|
||||
expect(displayBuffer.clipScreenPosition([4, 30])).toEqual [4, 11]
|
||||
expect(displayBuffer.clipScreenPosition([4, 1000])).toEqual [4, 11]
|
||||
expect(displayBuffer.clipScreenPosition([4, 30])).toEqual [4, 15]
|
||||
expect(displayBuffer.clipScreenPosition([4, 1000])).toEqual [4, 15]
|
||||
|
||||
describe "when wrapBeyondNewlines is true", ->
|
||||
it "wraps positions past the end of hard newlines to the next line", ->
|
||||
@@ -610,6 +615,18 @@ describe "DisplayBuffer", ->
|
||||
displayBuffer.createFold(3, 5)
|
||||
expect(displayBuffer.clipScreenPosition([3, 5], wrapBeyondNewlines: true)).toEqual [4, 0]
|
||||
|
||||
describe "when skipSoftWrapIndentation is false (the default)", ->
|
||||
it "wraps positions at the end of previous soft-wrapped line", ->
|
||||
expect(displayBuffer.clipScreenPosition([4, 0])).toEqual [3, 50]
|
||||
expect(displayBuffer.clipScreenPosition([4, 1])).toEqual [3, 50]
|
||||
expect(displayBuffer.clipScreenPosition([4, 3])).toEqual [3, 50]
|
||||
|
||||
describe "when skipSoftWrapIndentation is true", ->
|
||||
it "clips positions to the beginning of the line", ->
|
||||
expect(displayBuffer.clipScreenPosition([4, 0], skipSoftWrapIndentation: true)).toEqual [4, 4]
|
||||
expect(displayBuffer.clipScreenPosition([4, 1], skipSoftWrapIndentation: true)).toEqual [4, 4]
|
||||
expect(displayBuffer.clipScreenPosition([4, 3], skipSoftWrapIndentation: true)).toEqual [4, 4]
|
||||
|
||||
describe "when wrapAtSoftNewlines is false (the default)", ->
|
||||
it "clips positions at the end of soft-wrapped lines to the character preceding the end of the line", ->
|
||||
expect(displayBuffer.clipScreenPosition([3, 50])).toEqual [3, 50]
|
||||
@@ -620,9 +637,9 @@ describe "DisplayBuffer", ->
|
||||
describe "when wrapAtSoftNewlines is true", ->
|
||||
it "wraps positions at the end of soft-wrapped lines to the next screen line", ->
|
||||
expect(displayBuffer.clipScreenPosition([3, 50], wrapAtSoftNewlines: true)).toEqual [3, 50]
|
||||
expect(displayBuffer.clipScreenPosition([3, 51], wrapAtSoftNewlines: true)).toEqual [4, 0]
|
||||
expect(displayBuffer.clipScreenPosition([3, 58], wrapAtSoftNewlines: true)).toEqual [4, 0]
|
||||
expect(displayBuffer.clipScreenPosition([3, 1000], wrapAtSoftNewlines: true)).toEqual [4, 0]
|
||||
expect(displayBuffer.clipScreenPosition([3, 51], wrapAtSoftNewlines: true)).toEqual [4, 4]
|
||||
expect(displayBuffer.clipScreenPosition([3, 58], wrapAtSoftNewlines: true)).toEqual [4, 4]
|
||||
expect(displayBuffer.clipScreenPosition([3, 1000], wrapAtSoftNewlines: true)).toEqual [4, 4]
|
||||
|
||||
describe "when skipAtomicTokens is false (the default)", ->
|
||||
it "clips screen positions in the middle of atomic tab characters to the beginning of the character", ->
|
||||
@@ -655,8 +672,8 @@ describe "DisplayBuffer", ->
|
||||
buffer.setText('\t\taa bb cc dd ee ff gg')
|
||||
displayBuffer.setSoftWrapped(true)
|
||||
displayBuffer.setEditorWidthInChars(10)
|
||||
expect(displayBuffer.screenPositionForBufferPosition([0, 10], wrapAtSoftNewlines: true)).toEqual [1, 0]
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([1, 0])).toEqual [0, 10]
|
||||
expect(displayBuffer.screenPositionForBufferPosition([0, 10], wrapAtSoftNewlines: true)).toEqual [1, 4]
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([1, 0])).toEqual [0, 9]
|
||||
|
||||
describe "::getMaxLineLength()", ->
|
||||
it "returns the length of the longest screen line", ->
|
||||
|
||||
1
spec/fixtures/packages/package-with-no-activate/index.js
vendored
Normal file
1
spec/fixtures/packages/package-with-no-activate/index.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = {}
|
||||
4
spec/fixtures/packages/package-with-no-activate/package.json
vendored
Normal file
4
spec/fixtures/packages/package-with-no-activate/package.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "package-with-no-activate",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
@@ -220,6 +220,17 @@ describe "PackageManager", ->
|
||||
expect(console.error).not.toHaveBeenCalled()
|
||||
expect(console.warn).not.toHaveBeenCalled()
|
||||
|
||||
describe "when the package does not export an activate function", ->
|
||||
it "activates the package and does not throw an exception or log a warning", ->
|
||||
spyOn(console, "warn")
|
||||
expect(-> atom.packages.activatePackage('package-with-no-activate')).not.toThrow()
|
||||
|
||||
waitsFor ->
|
||||
atom.packages.isPackageActive('package-with-no-activate')
|
||||
|
||||
runs ->
|
||||
expect(console.warn).not.toHaveBeenCalled()
|
||||
|
||||
it "passes the activate method the package's previously serialized state if it exists", ->
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
|
||||
@@ -1171,6 +1171,14 @@ describe "TextEditorComponent", ->
|
||||
regions = componentNode.querySelectorAll('.test-highlight .region')
|
||||
expect(regions.length).toBe 2
|
||||
|
||||
it "allows multiple space-delimited decoration classes", ->
|
||||
decoration.setProperties(type: 'highlight', class: 'foo bar')
|
||||
nextAnimationFrame()
|
||||
expect(componentNode.querySelectorAll('.foo.bar').length).toBe 1
|
||||
decoration.setProperties(type: 'highlight', class: 'bar baz')
|
||||
nextAnimationFrame()
|
||||
expect(componentNode.querySelectorAll('.bar.baz').length).toBe 1
|
||||
|
||||
it "renders classes on the regions directly if 'deprecatedRegionClass' option is defined", ->
|
||||
decoration = editor.decorateMarker(marker, type: 'highlight', class: 'test-highlight', deprecatedRegionClass: 'test-highlight-region')
|
||||
nextAnimationFrame()
|
||||
|
||||
@@ -287,7 +287,7 @@ describe "TextEditor", ->
|
||||
|
||||
it "positions the cursor at the buffer position that corresponds to the given screen position", ->
|
||||
editor.setCursorScreenPosition([9, 0])
|
||||
expect(editor.getCursorBufferPosition()).toEqual [8, 11]
|
||||
expect(editor.getCursorBufferPosition()).toEqual [8, 10]
|
||||
|
||||
describe ".moveUp()", ->
|
||||
it "moves the cursor up", ->
|
||||
@@ -334,6 +334,17 @@ describe "TextEditor", ->
|
||||
expect(editor.getCursors()).toEqual [cursor1]
|
||||
expect(cursor1.getBufferPosition()).toEqual [0,0]
|
||||
|
||||
describe "when the cursor was moved down from the beginning of an indented soft-wrapped line", ->
|
||||
it "moves to the beginning of the previous line", ->
|
||||
editor.setSoftWrapped(true)
|
||||
editor.setEditorWidthInChars(50)
|
||||
|
||||
editor.setCursorScreenPosition([3, 0])
|
||||
editor.moveDown()
|
||||
editor.moveDown()
|
||||
editor.moveUp()
|
||||
expect(editor.getCursorScreenPosition()).toEqual [4, 4]
|
||||
|
||||
describe ".moveDown()", ->
|
||||
it "moves the cursor down", ->
|
||||
editor.setCursorScreenPosition([2, 2])
|
||||
@@ -375,6 +386,16 @@ describe "TextEditor", ->
|
||||
editor.moveUp()
|
||||
expect(editor.getCursorScreenPosition().column).toBe 0
|
||||
|
||||
describe "when the cursor is at the beginning of an indented soft-wrapped line", ->
|
||||
it "moves to the beginning of the line's continuation on the next screen row", ->
|
||||
editor.setSoftWrapped(true)
|
||||
editor.setEditorWidthInChars(50)
|
||||
|
||||
editor.setCursorScreenPosition([3, 0])
|
||||
editor.moveDown()
|
||||
expect(editor.getCursorScreenPosition()).toEqual [4, 4]
|
||||
|
||||
|
||||
describe "when there is a selection", ->
|
||||
beforeEach ->
|
||||
editor.setSelectedBufferRange([[4, 9],[5, 10]])
|
||||
@@ -432,6 +453,16 @@ describe "TextEditor", ->
|
||||
editor.moveLeft()
|
||||
expect(editor.getCursorScreenPosition()).toEqual [10, 0]
|
||||
|
||||
describe "when line is wrapped and follow previous line indentation", ->
|
||||
beforeEach ->
|
||||
editor.setSoftWrapped(true)
|
||||
editor.setEditorWidthInChars(50)
|
||||
|
||||
it "wraps to the end of the previous line", ->
|
||||
editor.setCursorScreenPosition([4, 4])
|
||||
editor.moveLeft()
|
||||
expect(editor.getCursorScreenPosition()).toEqual [3, 50]
|
||||
|
||||
describe "when the cursor is on the first line", ->
|
||||
it "remains in the same position (0,0)", ->
|
||||
editor.setCursorScreenPosition(row: 0, column: 0)
|
||||
@@ -628,11 +659,11 @@ describe "TextEditor", ->
|
||||
editor.moveToFirstCharacterOfLine()
|
||||
[cursor1, cursor2] = editor.getCursors()
|
||||
expect(cursor1.getScreenPosition()).toEqual [2,0]
|
||||
expect(cursor2.getScreenPosition()).toEqual [8,4]
|
||||
expect(cursor2.getScreenPosition()).toEqual [8,2]
|
||||
|
||||
editor.moveToFirstCharacterOfLine()
|
||||
expect(cursor1.getScreenPosition()).toEqual [2,0]
|
||||
expect(cursor2.getScreenPosition()).toEqual [8,0]
|
||||
expect(cursor2.getScreenPosition()).toEqual [8,2]
|
||||
|
||||
describe "when soft wrap is off", ->
|
||||
it "moves to the first character of the current line or the beginning of the line if it's already on the first character", ->
|
||||
|
||||
@@ -8,6 +8,7 @@ crypto = require 'crypto'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
babel = null # Defer until used
|
||||
Grim = null # Defer until used
|
||||
|
||||
stats =
|
||||
hits: 0
|
||||
@@ -132,10 +133,30 @@ transpile = (sourceCode, filePath, cachePath) ->
|
||||
# either generated on the fly or pulled from cache.
|
||||
loadFile = (module, filePath) ->
|
||||
sourceCode = fs.readFileSync(filePath, 'utf8')
|
||||
return module._compile(sourceCode, filePath) unless sourceCode.startsWith('"use 6to5"') or
|
||||
sourceCode.startsWith("'use 6to5'") or
|
||||
sourceCode.startsWith('"use babel"') or
|
||||
sourceCode.startsWith("'use babel'")
|
||||
if sourceCode.startsWith('"use babel"') or sourceCode.startsWith("'use babel'")
|
||||
# Continue.
|
||||
else if sourceCode.startsWith('"use 6to5"') or sourceCode.startsWith("'use 6to5'")
|
||||
# Create a manual deprecation since the stack is too deep to use Grim
|
||||
# which limits the depth to 3
|
||||
Grim ?= require 'grim'
|
||||
stack = [
|
||||
{
|
||||
fileName: __filename
|
||||
functionName: 'loadFile'
|
||||
location: "#{__filename}:161:5"
|
||||
}
|
||||
{
|
||||
fileName: filePath
|
||||
functionName: '<unknown>'
|
||||
location: "#{filePath}:1:1"
|
||||
}
|
||||
]
|
||||
deprecation =
|
||||
message: "Use the 'use babel' pragma instead of 'use 6to5'"
|
||||
stacks: [stack]
|
||||
Grim.addSerializedDeprecation(deprecation)
|
||||
else
|
||||
return module._compile(sourceCode, filePath)
|
||||
|
||||
cachePath = getCachePath(sourceCode)
|
||||
js = getCachedJavaScript(cachePath) ? transpile(sourceCode, filePath, cachePath)
|
||||
|
||||
@@ -271,7 +271,7 @@ class Cursor extends Model
|
||||
{ row, column } = @getScreenPosition()
|
||||
|
||||
column = @goalColumn if @goalColumn?
|
||||
@setScreenPosition({row: row - rowCount, column: column})
|
||||
@setScreenPosition({row: row - rowCount, column: column}, skipSoftWrapIndentation: true)
|
||||
@goalColumn = column
|
||||
|
||||
# Public: Moves the cursor down one screen row.
|
||||
@@ -288,7 +288,7 @@ class Cursor extends Model
|
||||
{ row, column } = @getScreenPosition()
|
||||
|
||||
column = @goalColumn if @goalColumn?
|
||||
@setScreenPosition({row: row + rowCount, column: column})
|
||||
@setScreenPosition({row: row + rowCount, column: column}, skipSoftWrapIndentation: true)
|
||||
@goalColumn = column
|
||||
|
||||
# Public: Moves the cursor left one screen column.
|
||||
@@ -359,19 +359,21 @@ class Cursor extends Model
|
||||
# line.
|
||||
moveToFirstCharacterOfLine: ->
|
||||
screenRow = @getScreenRow()
|
||||
lineBufferRange = @editor.bufferRangeForScreenRange([[screenRow, 0], [screenRow, Infinity]])
|
||||
screenLineStart = @editor.clipScreenPosition([screenRow, 0], skipSoftWrapIndentation: true)
|
||||
screenLineEnd = [screenRow, Infinity]
|
||||
screenLineBufferRange = @editor.bufferRangeForScreenRange([screenLineStart, screenLineEnd])
|
||||
|
||||
firstCharacterColumn = null
|
||||
@editor.scanInBufferRange /\S/, lineBufferRange, ({range, stop}) ->
|
||||
@editor.scanInBufferRange /\S/, screenLineBufferRange, ({range, stop}) ->
|
||||
firstCharacterColumn = range.start.column
|
||||
stop()
|
||||
|
||||
if firstCharacterColumn? and firstCharacterColumn isnt @getBufferColumn()
|
||||
targetBufferColumn = firstCharacterColumn
|
||||
else
|
||||
targetBufferColumn = lineBufferRange.start.column
|
||||
targetBufferColumn = screenLineBufferRange.start.column
|
||||
|
||||
@setBufferPosition([lineBufferRange.start.row, targetBufferColumn])
|
||||
@setBufferPosition([screenLineBufferRange.start.row, targetBufferColumn])
|
||||
|
||||
# Public: Moves the cursor to the end of the line.
|
||||
moveToEndOfScreenLine: ->
|
||||
|
||||
@@ -819,11 +819,12 @@ class DisplayBuffer extends Model
|
||||
# options - A hash with the following values:
|
||||
# wrapBeyondNewlines: if `true`, continues wrapping past newlines
|
||||
# wrapAtSoftNewlines: if `true`, continues wrapping past soft newlines
|
||||
# skipSoftWrapIndentation: if `true`, skips soft wrap indentation without wrapping to the previous line
|
||||
# screenLine: if `true`, indicates that you're using a line number, not a row number
|
||||
#
|
||||
# Returns the new, clipped {Point}. Note that this could be the same as `position` if no clipping was performed.
|
||||
clipScreenPosition: (screenPosition, options={}) ->
|
||||
{ wrapBeyondNewlines, wrapAtSoftNewlines } = options
|
||||
{ wrapBeyondNewlines, wrapAtSoftNewlines, skipSoftWrapIndentation } = options
|
||||
{ row, column } = Point.fromObject(screenPosition)
|
||||
|
||||
if row < 0
|
||||
@@ -841,9 +842,15 @@ class DisplayBuffer extends Model
|
||||
if screenLine.isSoftWrapped() and column >= maxScreenColumn
|
||||
if wrapAtSoftNewlines
|
||||
row++
|
||||
column = 0
|
||||
column = @screenLines[row].clipScreenColumn(0)
|
||||
else
|
||||
column = screenLine.clipScreenColumn(maxScreenColumn - 1)
|
||||
else if screenLine.isColumnInsideSoftWrapIndentation(column)
|
||||
if skipSoftWrapIndentation
|
||||
column = screenLine.clipScreenColumn(0)
|
||||
else
|
||||
row--
|
||||
column = @screenLines[row].getMaxScreenColumn() - 1
|
||||
else if wrapBeyondNewlines and column > maxScreenColumn and row < @getLastRow()
|
||||
row++
|
||||
column = 0
|
||||
@@ -851,28 +858,6 @@ class DisplayBuffer extends Model
|
||||
column = screenLine.clipScreenColumn(column, options)
|
||||
new Point(row, column)
|
||||
|
||||
# Given a line, finds the point where it would wrap.
|
||||
#
|
||||
# line - The {String} to check
|
||||
# softWrapColumn - The {Number} where you want soft wrapping to occur
|
||||
#
|
||||
# Returns a {Number} representing the `line` position where the wrap would take place.
|
||||
# Returns `null` if a wrap wouldn't occur.
|
||||
findWrapColumn: (line, softWrapColumn=@getSoftWrapColumn()) ->
|
||||
return unless @isSoftWrapped()
|
||||
return unless line.length > softWrapColumn
|
||||
|
||||
if /\s/.test(line[softWrapColumn])
|
||||
# search forward for the start of a word past the boundary
|
||||
for column in [softWrapColumn..line.length]
|
||||
return column if /\S/.test(line[column])
|
||||
return line.length
|
||||
else
|
||||
# search backward for the start of the word on the boundary
|
||||
for column in [softWrapColumn..0]
|
||||
return column + 1 if /\s/.test(line[column])
|
||||
return softWrapColumn
|
||||
|
||||
# Calculates a {Range} representing the start of the {TextBuffer} until the end.
|
||||
#
|
||||
# Returns a {Range}.
|
||||
@@ -1157,10 +1142,12 @@ class DisplayBuffer extends Model
|
||||
bufferRow += foldedRowCount
|
||||
else
|
||||
softWraps = 0
|
||||
while wrapScreenColumn = @findWrapColumn(tokenizedLine.text)
|
||||
[wrappedLine, tokenizedLine] = tokenizedLine.softWrapAt(wrapScreenColumn)
|
||||
screenLines.push(wrappedLine)
|
||||
softWraps++
|
||||
if @isSoftWrapped()
|
||||
while wrapScreenColumn = tokenizedLine.findWrapColumn(@getSoftWrapColumn())
|
||||
[wrappedLine, tokenizedLine] = tokenizedLine.softWrapAt(wrapScreenColumn)
|
||||
break if wrappedLine.hasOnlySoftWrapIndentation()
|
||||
screenLines.push(wrappedLine)
|
||||
softWraps++
|
||||
screenLines.push(tokenizedLine)
|
||||
|
||||
if softWraps > 0
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
RegionStyleProperties = ['top', 'left', 'right', 'width', 'height']
|
||||
SpaceRegex = /\s+/
|
||||
|
||||
module.exports =
|
||||
class HighlightsComponent
|
||||
@@ -44,8 +45,17 @@ class HighlightsComponent
|
||||
|
||||
# update class
|
||||
if newHighlightState.class isnt oldHighlightState.class
|
||||
highlightNode.classList.remove(oldHighlightState.class) if oldHighlightState.class?
|
||||
highlightNode.classList.add(newHighlightState.class)
|
||||
if oldHighlightState.class?
|
||||
if SpaceRegex.test(oldHighlightState.class)
|
||||
highlightNode.classList.remove(oldHighlightState.class.split(SpaceRegex)...)
|
||||
else
|
||||
highlightNode.classList.remove(oldHighlightState.class)
|
||||
|
||||
if SpaceRegex.test(newHighlightState.class)
|
||||
highlightNode.classList.add(newHighlightState.class.split(SpaceRegex)...)
|
||||
else
|
||||
highlightNode.classList.add(newHighlightState.class)
|
||||
|
||||
oldHighlightState.class = newHighlightState.class
|
||||
|
||||
@updateHighlightRegions(id, newHighlightState)
|
||||
|
||||
@@ -157,7 +157,7 @@ class Package
|
||||
@activateConfig()
|
||||
@activateStylesheets()
|
||||
if @requireMainModule()
|
||||
@mainModule.activate(atom.packages.getPackageState(@name) ? {})
|
||||
@mainModule.activate?(atom.packages.getPackageState(@name) ? {})
|
||||
@mainActivated = true
|
||||
@activateServices()
|
||||
catch e
|
||||
|
||||
@@ -1817,13 +1817,13 @@ class TextEditor extends Model
|
||||
|
||||
# Merge cursors that have the same screen position
|
||||
mergeCursors: ->
|
||||
positions = []
|
||||
positions = {}
|
||||
for cursor in @getCursors()
|
||||
position = cursor.getBufferPosition().toString()
|
||||
if position in positions
|
||||
if positions.hasOwnProperty(position)
|
||||
cursor.destroy()
|
||||
else
|
||||
positions.push(position)
|
||||
positions[position] = true
|
||||
|
||||
preserveCursorPositionOnBufferReload: ->
|
||||
cursorPosition = null
|
||||
|
||||
@@ -21,7 +21,7 @@ class Token
|
||||
firstTrailingWhitespaceIndex: null
|
||||
hasInvisibleCharacters: false
|
||||
|
||||
constructor: ({@value, @scopes, @isAtomic, @bufferDelta, @isHardTab, @hasPairedCharacter}) ->
|
||||
constructor: ({@value, @scopes, @isAtomic, @bufferDelta, @isHardTab, @hasPairedCharacter, @isSoftWrapIndentation}) ->
|
||||
@screenDelta = @value.length
|
||||
@bufferDelta ?= @screenDelta
|
||||
@hasPairedCharacter ?= textUtils.hasPairedCharacter(@value)
|
||||
@@ -144,6 +144,15 @@ class Token
|
||||
isHardTab: isHardTab
|
||||
)
|
||||
|
||||
buildSoftWrapIndentationToken: (length) ->
|
||||
new Token(
|
||||
value: _.multiplyString(" ", length),
|
||||
scopes: @scopes,
|
||||
bufferDelta: 0,
|
||||
isAtomic: true,
|
||||
isSoftWrapIndentation: true
|
||||
)
|
||||
|
||||
isOnlyWhitespace: ->
|
||||
not WhitespaceRegex.test(@value)
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ class TokenizedLine
|
||||
@tokens = @breakOutAtomicTokens(tokens)
|
||||
@text = @buildText()
|
||||
@bufferDelta = @buildBufferDelta()
|
||||
@softWrapIndentationTokens = @getSoftWrapIndentationTokens()
|
||||
@softWrapIndentationDelta = @buildSoftWrapIndentationDelta()
|
||||
|
||||
@id = idCounter++
|
||||
@markLeadingAndTrailingWhitespaceTokens()
|
||||
@@ -49,7 +51,9 @@ class TokenizedLine
|
||||
break if tokenStartColumn + token.screenDelta > column
|
||||
tokenStartColumn += token.screenDelta
|
||||
|
||||
if token.isAtomic and tokenStartColumn < column
|
||||
if @isColumnInsideSoftWrapIndentation(tokenStartColumn)
|
||||
@softWrapIndentationDelta
|
||||
else if token.isAtomic and tokenStartColumn < column
|
||||
if skipAtomicTokens
|
||||
tokenStartColumn + token.screenDelta
|
||||
else
|
||||
@@ -85,6 +89,46 @@ class TokenizedLine
|
||||
getMaxBufferColumn: ->
|
||||
@startBufferColumn + @bufferDelta
|
||||
|
||||
# Given a boundary column, finds the point where this line would wrap.
|
||||
#
|
||||
# maxColumn - The {Number} where you want soft wrapping to occur
|
||||
#
|
||||
# Returns a {Number} representing the `line` position where the wrap would take place.
|
||||
# Returns `null` if a wrap wouldn't occur.
|
||||
findWrapColumn: (maxColumn) ->
|
||||
return unless @text.length > maxColumn
|
||||
|
||||
if /\s/.test(@text[maxColumn])
|
||||
# search forward for the start of a word past the boundary
|
||||
for column in [maxColumn..@text.length]
|
||||
return column if /\S/.test(@text[column])
|
||||
|
||||
return @text.length
|
||||
else
|
||||
# search backward for the start of the word on the boundary
|
||||
for column in [maxColumn..0] when @isColumnOutsideSoftWrapIndentation(column)
|
||||
return column + 1 if /\s/.test(@text[column])
|
||||
|
||||
return maxColumn
|
||||
|
||||
# Calculates how many trailing spaces in this line's indentation cannot fit in a single tab.
|
||||
#
|
||||
# Returns a {Number} representing the odd indentation spaces in this line.
|
||||
getOddIndentationSpaces: ->
|
||||
oddIndentLevel = @indentLevel - Math.floor(@indentLevel)
|
||||
Math.round(@tabLength * oddIndentLevel)
|
||||
|
||||
buildSoftWrapIndentationTokens: (token) ->
|
||||
indentTokens = [0...Math.floor(@indentLevel)].map =>
|
||||
token.buildSoftWrapIndentationToken(@tabLength)
|
||||
|
||||
if @getOddIndentationSpaces()
|
||||
indentTokens.concat(
|
||||
token.buildSoftWrapIndentationToken @getOddIndentationSpaces()
|
||||
)
|
||||
else
|
||||
indentTokens
|
||||
|
||||
softWrapAt: (column) ->
|
||||
return [new TokenizedLine([], '', [0, 0], [0, 0]), this] if column == 0
|
||||
|
||||
@@ -98,25 +142,50 @@ class TokenizedLine
|
||||
leftTextLength += nextToken.value.length
|
||||
leftTokens.push nextToken
|
||||
|
||||
indentationTokens = @buildSoftWrapIndentationTokens(leftTokens[0])
|
||||
|
||||
leftFragment = new TokenizedLine(
|
||||
tokens: leftTokens
|
||||
startBufferColumn: @startBufferColumn
|
||||
ruleStack: @ruleStack
|
||||
invisibles: @invisibles
|
||||
lineEnding: null
|
||||
lineEnding: null,
|
||||
indentLevel: @indentLevel,
|
||||
tabLength: @tabLength
|
||||
)
|
||||
rightFragment = new TokenizedLine(
|
||||
tokens: rightTokens
|
||||
tokens: indentationTokens.concat(rightTokens)
|
||||
startBufferColumn: @bufferColumnForScreenColumn(column)
|
||||
ruleStack: @ruleStack
|
||||
invisibles: @invisibles
|
||||
lineEnding: @lineEnding
|
||||
lineEnding: @lineEnding,
|
||||
indentLevel: @indentLevel,
|
||||
tabLength: @tabLength
|
||||
)
|
||||
[leftFragment, rightFragment]
|
||||
|
||||
isSoftWrapped: ->
|
||||
@lineEnding is null
|
||||
|
||||
isColumnOutsideSoftWrapIndentation: (column) ->
|
||||
return true if @softWrapIndentationTokens.length == 0
|
||||
|
||||
column > @softWrapIndentationDelta
|
||||
|
||||
isColumnInsideSoftWrapIndentation: (column) ->
|
||||
return false if @softWrapIndentationTokens.length == 0
|
||||
|
||||
column < @softWrapIndentationDelta
|
||||
|
||||
getSoftWrapIndentationTokens: ->
|
||||
_.select(@tokens, (token) -> token.isSoftWrapIndentation)
|
||||
|
||||
buildSoftWrapIndentationDelta: ->
|
||||
_.reduce @softWrapIndentationTokens, ((acc, token) -> acc + token.screenDelta), 0
|
||||
|
||||
hasOnlySoftWrapIndentation: ->
|
||||
@tokens.length == @softWrapIndentationTokens.length
|
||||
|
||||
tokenAtBufferColumn: (bufferColumn) ->
|
||||
@tokens[@tokenIndexAtBufferColumn(bufferColumn)]
|
||||
|
||||
@@ -173,7 +242,7 @@ class TokenizedLine
|
||||
changedText = true
|
||||
else
|
||||
if invisibles.space
|
||||
if token.hasLeadingWhitespace()
|
||||
if token.hasLeadingWhitespace() and not token.isSoftWrapIndentation
|
||||
token.value = token.value.replace LeadingWhitespaceRegex, (leadingWhitespace) ->
|
||||
leadingWhitespace.replace RepeatedSpaceRegex, invisibles.space
|
||||
token.hasInvisibleCharacters = true
|
||||
|
||||
Reference in New Issue
Block a user