mirror of
https://github.com/atom/atom.git
synced 2026-01-24 06:18:03 -05:00
Merge branch 'master' into jl-bump-mdpv
This commit is contained in:
10
Dockerfile
10
Dockerfile
@@ -2,7 +2,7 @@
|
||||
# DESCRIPTION: Image to build Atom and create a .rpm file
|
||||
|
||||
# Base docker image
|
||||
FROM fedora:20
|
||||
FROM fedora:21
|
||||
|
||||
# Install dependencies
|
||||
RUN yum install -y \
|
||||
@@ -12,11 +12,11 @@ RUN yum install -y \
|
||||
glibc-devel \
|
||||
git-core \
|
||||
libgnome-keyring-devel \
|
||||
rpmdevtools
|
||||
rpmdevtools \
|
||||
nodejs \
|
||||
npm
|
||||
|
||||
# Install node
|
||||
RUN curl -sL https://rpm.nodesource.com/setup | bash -
|
||||
RUN yum install -y nodejs
|
||||
RUN npm install -g npm@1.4.28 --loglevel error
|
||||
|
||||
ADD . /atom
|
||||
WORKDIR /atom
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2014 GitHub Inc.
|
||||
Copyright (c) 2015 GitHub Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "0.149.0"
|
||||
"atom-package-manager": "0.152.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ module.exports = (grunt) ->
|
||||
strings =
|
||||
CompanyName: 'GitHub, Inc.'
|
||||
FileDescription: 'Atom'
|
||||
LegalCopyright: 'Copyright (C) 2014 GitHub, Inc. All rights reserved'
|
||||
LegalCopyright: 'Copyright (C) 2015 GitHub, Inc. All rights reserved'
|
||||
ProductName: 'Atom'
|
||||
ProductVersion: version
|
||||
|
||||
|
||||
17
package.json
17
package.json
@@ -17,7 +17,7 @@
|
||||
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
|
||||
}
|
||||
],
|
||||
"atomShellVersion": "0.21.3",
|
||||
"atomShellVersion": "0.22.2",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^4",
|
||||
@@ -64,8 +64,9 @@
|
||||
"space-pen": "3.8.2",
|
||||
"stacktrace-parser": "0.1.1",
|
||||
"temp": "0.8.1",
|
||||
"text-buffer": "^5.0.2",
|
||||
"text-buffer": "^5.1.0",
|
||||
"theorist": "^1.0.2",
|
||||
"typescript-simple": "^1.0.0",
|
||||
"underscore-plus": "^1.6.6"
|
||||
},
|
||||
"packageDependencies": {
|
||||
@@ -110,19 +111,19 @@
|
||||
"package-generator": "0.38.0",
|
||||
"release-notes": "0.52.0",
|
||||
"settings-view": "0.185.0",
|
||||
"snippets": "0.85.0",
|
||||
"snippets": "0.86.0",
|
||||
"spell-check": "0.55.0",
|
||||
"status-bar": "0.64.0",
|
||||
"styleguide": "0.44.0",
|
||||
"symbols-view": "0.92.0",
|
||||
"symbols-view": "0.93.0",
|
||||
"tabs": "0.67.0",
|
||||
"timecop": "0.31.0",
|
||||
"tree-view": "0.168.0",
|
||||
"update-package-dependencies": "0.9.0",
|
||||
"welcome": "0.25.0",
|
||||
"welcome": "0.26.0",
|
||||
"whitespace": "0.29.0",
|
||||
"wrap-guide": "0.31.0",
|
||||
"language-c": "0.41.0",
|
||||
"language-c": "0.42.0",
|
||||
"language-clojure": "0.13.0",
|
||||
"language-coffee-script": "0.39.0",
|
||||
"language-csharp": "0.5.0",
|
||||
@@ -143,12 +144,12 @@
|
||||
"language-php": "0.21.0",
|
||||
"language-property-list": "0.8.0",
|
||||
"language-python": "0.32.0",
|
||||
"language-ruby": "0.49.0",
|
||||
"language-ruby": "0.50.0",
|
||||
"language-ruby-on-rails": "0.21.0",
|
||||
"language-sass": "0.36.0",
|
||||
"language-shellscript": "0.13.0",
|
||||
"language-source": "0.9.0",
|
||||
"language-sql": "0.14.0",
|
||||
"language-sql": "0.15.0",
|
||||
"language-text": "0.6.0",
|
||||
"language-todo": "0.17.0",
|
||||
"language-toml": "0.15.0",
|
||||
|
||||
@@ -48,7 +48,7 @@ function removeNodeModules() {
|
||||
|
||||
readEnvironmentVariables();
|
||||
removeNodeModules();
|
||||
cp.safeExec.bind(global, 'npm install npm', {cwd: path.resolve(__dirname, '..', 'build')}, function() {
|
||||
cp.safeExec.bind(global, 'npm install npm --loglevel error', {cwd: path.resolve(__dirname, '..', 'build')}, function() {
|
||||
cp.safeExec.bind(global, 'node script/bootstrap', function(error) {
|
||||
if (error)
|
||||
process.exit(1);
|
||||
|
||||
@@ -57,7 +57,7 @@ function verifyNpm(cb) {
|
||||
var npmMajorVersion = +versionArray[0] || 0;
|
||||
var npmMinorVersion = +versionArray[1] || 0;
|
||||
if (npmMajorVersion === 1 && npmMinorVersion < 4)
|
||||
cb("npm v1.4+ is required to build Atom.");
|
||||
cb("npm v1.4+ is required to build Atom. Version " + npmVersion + " was detected.");
|
||||
else
|
||||
cb(null, "npm: v" + npmVersion);
|
||||
});
|
||||
|
||||
@@ -3,26 +3,37 @@ CSON = require 'season'
|
||||
CoffeeCache = require 'coffee-cash'
|
||||
|
||||
babel = require '../src/babel'
|
||||
typescript = require '../src/typescript'
|
||||
CompileCache = require '../src/compile-cache'
|
||||
|
||||
describe "Compile Cache", ->
|
||||
describe ".addPathToCache(filePath)", ->
|
||||
it "adds the path to the correct CSON, CoffeeScript, or babel cache", ->
|
||||
it "adds the path to the correct CSON, CoffeeScript, babel or typescript cache", ->
|
||||
spyOn(CSON, 'readFileSync').andCallThrough()
|
||||
spyOn(CoffeeCache, 'addPathToCache').andCallThrough()
|
||||
spyOn(babel, 'addPathToCache').andCallThrough()
|
||||
spyOn(typescript, 'addPathToCache').andCallThrough()
|
||||
|
||||
CompileCache.addPathToCache(path.join(__dirname, 'fixtures', 'cson.cson'))
|
||||
expect(CSON.readFileSync.callCount).toBe 1
|
||||
expect(CoffeeCache.addPathToCache.callCount).toBe 0
|
||||
expect(babel.addPathToCache.callCount).toBe 0
|
||||
expect(typescript.addPathToCache.callCount).toBe 0
|
||||
|
||||
CompileCache.addPathToCache(path.join(__dirname, 'fixtures', 'coffee.coffee'))
|
||||
expect(CSON.readFileSync.callCount).toBe 1
|
||||
expect(CoffeeCache.addPathToCache.callCount).toBe 1
|
||||
expect(babel.addPathToCache.callCount).toBe 0
|
||||
expect(typescript.addPathToCache.callCount).toBe 0
|
||||
|
||||
CompileCache.addPathToCache(path.join(__dirname, 'fixtures', 'babel', 'babel-double-quotes.js'))
|
||||
expect(CSON.readFileSync.callCount).toBe 1
|
||||
expect(CoffeeCache.addPathToCache.callCount).toBe 1
|
||||
expect(babel.addPathToCache.callCount).toBe 1
|
||||
expect(typescript.addPathToCache.callCount).toBe 0
|
||||
|
||||
CompileCache.addPathToCache(path.join(__dirname, 'fixtures', 'typescript', 'valid.ts'))
|
||||
expect(CSON.readFileSync.callCount).toBe 1
|
||||
expect(CoffeeCache.addPathToCache.callCount).toBe 1
|
||||
expect(babel.addPathToCache.callCount).toBe 1
|
||||
expect(typescript.addPathToCache.callCount).toBe 1
|
||||
|
||||
@@ -15,8 +15,8 @@ describe "DefaultDirectoryProvider", ->
|
||||
provider = new DefaultDirectoryProvider()
|
||||
tmp = temp.mkdirSync()
|
||||
nonNormalizedPath = tmp + path.sep + ".." + path.sep + path.basename(tmp)
|
||||
expect(tmp.contains("..")).toBe false
|
||||
expect(nonNormalizedPath.contains("..")).toBe true
|
||||
expect(tmp.includes("..")).toBe false
|
||||
expect(nonNormalizedPath.includes("..")).toBe true
|
||||
|
||||
directory = provider.directoryForURISync(nonNormalizedPath)
|
||||
expect(directory.getPath()).toEqual tmp
|
||||
|
||||
@@ -48,7 +48,6 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.getLineCount()).toBe 100 + originalLineCount
|
||||
|
||||
it "reassigns the scrollTop if it exceeds the max possible value after lines are removed", ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setHeight(50)
|
||||
displayBuffer.setLineHeightInPixels(10)
|
||||
displayBuffer.setScrollTop(80)
|
||||
@@ -287,7 +286,6 @@ describe "DisplayBuffer", ->
|
||||
it "sets ::scrollLeft to 0 and keeps it there when soft wrapping is enabled", ->
|
||||
displayBuffer.setDefaultCharWidth(10)
|
||||
displayBuffer.setWidth(85)
|
||||
displayBuffer.manageScrollPosition = true
|
||||
|
||||
displayBuffer.setSoftWrapped(false)
|
||||
displayBuffer.setScrollLeft(Infinity)
|
||||
@@ -1174,7 +1172,6 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "::setScrollTop", ->
|
||||
beforeEach ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setLineHeightInPixels(10)
|
||||
|
||||
it "disallows negative values", ->
|
||||
@@ -1196,7 +1193,6 @@ describe "DisplayBuffer", ->
|
||||
describe "when editor.scrollPastEnd is false", ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.scrollPastEnd", false)
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setLineHeightInPixels(10)
|
||||
|
||||
it "does not add the height of the view to the scroll height", ->
|
||||
@@ -1209,7 +1205,6 @@ describe "DisplayBuffer", ->
|
||||
describe "when editor.scrollPastEnd is true", ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.scrollPastEnd", true)
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setLineHeightInPixels(10)
|
||||
|
||||
it "adds the height of the view to the scroll height", ->
|
||||
@@ -1221,7 +1216,6 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "::setScrollLeft", ->
|
||||
beforeEach ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setLineHeightInPixels(10)
|
||||
displayBuffer.setDefaultCharWidth(10)
|
||||
|
||||
@@ -1242,18 +1236,21 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "::scrollToScreenPosition(position, [options])", ->
|
||||
beforeEach ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
displayBuffer.setLineHeightInPixels(10)
|
||||
displayBuffer.setDefaultCharWidth(10)
|
||||
displayBuffer.setHorizontalScrollbarHeight(0)
|
||||
displayBuffer.setHeight(50)
|
||||
displayBuffer.setWidth(50)
|
||||
displayBuffer.setWidth(150)
|
||||
|
||||
it "sets the scroll top and scroll left so the given screen position is in view", ->
|
||||
displayBuffer.scrollToScreenPosition([8, 20])
|
||||
expect(displayBuffer.getScrollBottom()).toBe (9 + displayBuffer.getVerticalScrollMargin()) * 10
|
||||
expect(displayBuffer.getScrollRight()).toBe (20 + displayBuffer.getHorizontalScrollMargin()) * 10
|
||||
|
||||
displayBuffer.scrollToScreenPosition([8, 20])
|
||||
expect(displayBuffer.getScrollBottom()).toBe (9 + displayBuffer.getVerticalScrollMargin()) * 10
|
||||
expect(displayBuffer.getScrollRight()).toBe (20 + displayBuffer.getHorizontalScrollMargin()) * 10
|
||||
|
||||
describe "when the 'center' option is true", ->
|
||||
it "vertically scrolls to center the given position vertically", ->
|
||||
displayBuffer.scrollToScreenPosition([8, 20], center: true)
|
||||
@@ -1320,6 +1317,7 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.getVisibleRowRange()).toEqual [0, 0]
|
||||
|
||||
it "ends at last buffer row even if there's more space available", ->
|
||||
displayBuffer.setHeight(150)
|
||||
displayBuffer.setScrollTop(60)
|
||||
|
||||
expect(displayBuffer.getVisibleRowRange()).toEqual [6, 13]
|
||||
expect(displayBuffer.getVisibleRowRange()).toEqual [0, 13]
|
||||
|
||||
1
spec/fixtures/typescript/invalid.ts
vendored
Normal file
1
spec/fixtures/typescript/invalid.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
var foo = 123 123; // Syntax error
|
||||
2
spec/fixtures/typescript/valid.ts
vendored
Normal file
2
spec/fixtures/typescript/valid.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
var inc = v => v + 1
|
||||
export = inc
|
||||
@@ -693,7 +693,7 @@ describe "TextEditorComponent", ->
|
||||
describe "cursor rendering", ->
|
||||
it "renders the currently visible cursors", ->
|
||||
cursor1 = editor.getLastCursor()
|
||||
cursor1.setScreenPosition([0, 5])
|
||||
cursor1.setScreenPosition([0, 5], autoscroll: false)
|
||||
|
||||
wrapperNode.style.height = 4.5 * lineHeightInPixels + 'px'
|
||||
wrapperNode.style.width = 20 * lineHeightInPixels + 'px'
|
||||
@@ -706,8 +706,8 @@ describe "TextEditorComponent", ->
|
||||
expect(cursorNodes[0].offsetWidth).toBe charWidth
|
||||
expect(cursorNodes[0].style['-webkit-transform']).toBe "translate(#{5 * charWidth}px, #{0 * lineHeightInPixels}px)"
|
||||
|
||||
cursor2 = editor.addCursorAtScreenPosition([8, 11])
|
||||
cursor3 = editor.addCursorAtScreenPosition([4, 10])
|
||||
cursor2 = editor.addCursorAtScreenPosition([8, 11], autoscroll: false)
|
||||
cursor3 = editor.addCursorAtScreenPosition([4, 10], autoscroll: false)
|
||||
nextAnimationFrame()
|
||||
|
||||
cursorNodes = componentNode.querySelectorAll('.cursor')
|
||||
@@ -1524,7 +1524,7 @@ describe "TextEditorComponent", ->
|
||||
expect(inputNode.offsetLeft).toBe 0
|
||||
|
||||
# In bounds, not focused
|
||||
editor.setCursorBufferPosition([5, 4])
|
||||
editor.setCursorBufferPosition([5, 4], autoscroll: false)
|
||||
nextAnimationFrame()
|
||||
expect(inputNode.offsetTop).toBe 0
|
||||
expect(inputNode.offsetLeft).toBe 0
|
||||
@@ -1542,7 +1542,7 @@ describe "TextEditorComponent", ->
|
||||
expect(inputNode.offsetLeft).toBe 0
|
||||
|
||||
# Out of bounds, not focused
|
||||
editor.setCursorBufferPosition([1, 2])
|
||||
editor.setCursorBufferPosition([1, 2], autoscroll: false)
|
||||
nextAnimationFrame()
|
||||
expect(inputNode.offsetTop).toBe 0
|
||||
expect(inputNode.offsetLeft).toBe 0
|
||||
|
||||
@@ -351,11 +351,11 @@ describe "TextEditorPresenter", ->
|
||||
expectValues presenter.getState().hiddenInput, {top: 0, left: 0}
|
||||
|
||||
expectStateUpdate presenter, -> editor.setCursorBufferPosition([11, 43])
|
||||
expectValues presenter.getState().hiddenInput, {top: 50 - 10, left: 300 - 10}
|
||||
expectValues presenter.getState().hiddenInput, {top: 11 * 10 - editor.getScrollTop(), left: 43 * 10 - editor.getScrollLeft()}
|
||||
|
||||
newCursor = null
|
||||
expectStateUpdate presenter, -> newCursor = editor.addCursorAtBufferPosition([6, 10])
|
||||
expectValues presenter.getState().hiddenInput, {top: (6 * 10) - 40, left: (10 * 10) - 70}
|
||||
expectValues presenter.getState().hiddenInput, {top: (6 * 10) - editor.getScrollTop(), left: (10 * 10) - editor.getScrollLeft()}
|
||||
|
||||
expectStateUpdate presenter, -> newCursor.destroy()
|
||||
expectValues presenter.getState().hiddenInput, {top: 50 - 10, left: 300 - 10}
|
||||
@@ -1417,33 +1417,33 @@ describe "TextEditorPresenter", ->
|
||||
expect(stateForSelection(presenter, 1)).toBeUndefined()
|
||||
|
||||
# moving into view
|
||||
expectStateUpdate presenter, -> editor.getSelections()[1].setBufferRange([[2, 4], [2, 6]])
|
||||
expectStateUpdate presenter, -> editor.getSelections()[1].setBufferRange([[2, 4], [2, 6]], autoscroll: false)
|
||||
expectValues stateForSelection(presenter, 1), {
|
||||
regions: [{top: 2 * 10, left: 4 * 10, width: 2 * 10, height: 10}]
|
||||
}
|
||||
|
||||
# becoming empty
|
||||
expectStateUpdate presenter, -> editor.getSelections()[1].clear()
|
||||
expectStateUpdate presenter, -> editor.getSelections()[1].clear(autoscroll: false)
|
||||
expect(stateForSelection(presenter, 1)).toBeUndefined()
|
||||
|
||||
# becoming non-empty
|
||||
expectStateUpdate presenter, -> editor.getSelections()[1].setBufferRange([[2, 4], [2, 6]])
|
||||
expectStateUpdate presenter, -> editor.getSelections()[1].setBufferRange([[2, 4], [2, 6]], autoscroll: false)
|
||||
expectValues stateForSelection(presenter, 1), {
|
||||
regions: [{top: 2 * 10, left: 4 * 10, width: 2 * 10, height: 10}]
|
||||
}
|
||||
|
||||
# moving out of view
|
||||
expectStateUpdate presenter, -> editor.getSelections()[1].setBufferRange([[3, 4], [3, 6]])
|
||||
expectStateUpdate presenter, -> editor.getSelections()[1].setBufferRange([[3, 4], [3, 6]], autoscroll: false)
|
||||
expect(stateForSelection(presenter, 1)).toBeUndefined()
|
||||
|
||||
# adding
|
||||
expectStateUpdate presenter, -> editor.addSelectionForBufferRange([[1, 4], [1, 6]])
|
||||
expectStateUpdate presenter, -> editor.addSelectionForBufferRange([[1, 4], [1, 6]], autoscroll: false)
|
||||
expectValues stateForSelection(presenter, 2), {
|
||||
regions: [{top: 1 * 10, left: 4 * 10, width: 2 * 10, height: 10}]
|
||||
}
|
||||
|
||||
# moving added selection
|
||||
expectStateUpdate presenter, -> editor.getSelections()[2].setBufferRange([[1, 4], [1, 8]])
|
||||
expectStateUpdate presenter, -> editor.getSelections()[2].setBufferRange([[1, 4], [1, 8]], autoscroll: false)
|
||||
expectValues stateForSelection(presenter, 2), {
|
||||
regions: [{top: 1 * 10, left: 4 * 10, width: 4 * 10, height: 10}]
|
||||
}
|
||||
|
||||
@@ -921,7 +921,6 @@ describe "TextEditor", ->
|
||||
|
||||
describe "autoscroll", ->
|
||||
beforeEach ->
|
||||
editor.manageScrollPosition = true
|
||||
editor.setVerticalScrollMargin(2)
|
||||
editor.setHorizontalScrollMargin(2)
|
||||
editor.setLineHeightInPixels(10)
|
||||
@@ -971,9 +970,8 @@ describe "TextEditor", ->
|
||||
|
||||
it "scrolls left when the last cursor gets closer than ::horizontalScrollMargin to the left of the editor", ->
|
||||
editor.setScrollRight(editor.getScrollWidth())
|
||||
editor.setCursorScreenPosition([6, 62])
|
||||
|
||||
expect(editor.getScrollRight()).toBe editor.getScrollWidth()
|
||||
editor.setCursorScreenPosition([6, 62], autoscroll: false)
|
||||
|
||||
editor.moveLeft()
|
||||
expect(editor.getScrollLeft()).toBe 59 * 10
|
||||
@@ -994,6 +992,38 @@ describe "TextEditor", ->
|
||||
editor.undo()
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
|
||||
it "honors the autoscroll option on cursor and selection manipulation methods", ->
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
editor.addCursorAtScreenPosition([11, 11], autoscroll: false)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
editor.addCursorAtBufferPosition([11, 11], autoscroll: false)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
editor.setCursorScreenPosition([11, 11], autoscroll: false)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
editor.setCursorBufferPosition([11, 11], autoscroll: false)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
editor.addSelectionForBufferRange([[11, 11], [11, 11]], autoscroll: false)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
editor.addSelectionForScreenRange([[11, 11], [11, 12]], autoscroll: false)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
editor.setSelectedBufferRange([[11, 0], [11, 1]], autoscroll: false)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
editor.setSelectedScreenRange([[11, 0], [11, 6]], autoscroll: false)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
editor.clearSelections(autoscroll: false)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
|
||||
editor.addSelectionForScreenRange([[0, 0], [0, 4]])
|
||||
|
||||
editor.getCursors()[0].setScreenPosition([11, 11], autoscroll: true)
|
||||
expect(editor.getScrollTop()).toBeGreaterThan 0
|
||||
editor.getCursors()[0].setBufferPosition([0, 0], autoscroll: true)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
editor.getSelections()[0].setScreenRange([[11, 0], [11, 4]], autoscroll: true)
|
||||
expect(editor.getScrollTop()).toBeGreaterThan 0
|
||||
editor.getSelections()[0].setBufferRange([[0, 0], [0, 4]], autoscroll: true)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
|
||||
describe '.logCursorScope()', ->
|
||||
beforeEach ->
|
||||
spyOn(atom.notifications, 'addInfo')
|
||||
@@ -1254,7 +1284,6 @@ describe "TextEditor", ->
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[0,0], [2,0]]
|
||||
|
||||
it "autoscrolls to the selection", ->
|
||||
editor.manageScrollPosition = true
|
||||
editor.setLineHeightInPixels(10)
|
||||
editor.setDefaultCharWidth(10)
|
||||
editor.setHeight(50)
|
||||
@@ -1521,24 +1550,28 @@ describe "TextEditor", ->
|
||||
expect(selection1.getScreenRange()).toEqual [[2, 2], [3, 4]]
|
||||
|
||||
describe ".setSelectedBufferRange(range)", ->
|
||||
describe "when the 'autoscroll' option is true", ->
|
||||
it "autoscrolls to the selection", ->
|
||||
editor.manageScrollPosition = true
|
||||
editor.setLineHeightInPixels(10)
|
||||
editor.setDefaultCharWidth(10)
|
||||
editor.setHeight(50)
|
||||
editor.setWidth(50)
|
||||
editor.setHorizontalScrollbarHeight(0)
|
||||
it "autoscrolls the selection if it is last unless the 'autoscroll' option is false", ->
|
||||
editor.setVerticalScrollMargin(2)
|
||||
editor.setHorizontalScrollMargin(2)
|
||||
editor.setLineHeightInPixels(10)
|
||||
editor.setDefaultCharWidth(10)
|
||||
editor.setHeight(70)
|
||||
editor.setWidth(100)
|
||||
editor.setHorizontalScrollbarHeight(0)
|
||||
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
|
||||
editor.setSelectedBufferRange([[5, 6], [6, 8]], autoscroll: true)
|
||||
expect(editor.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10
|
||||
expect(editor.getScrollRight()).toBe 50
|
||||
editor.setSelectedBufferRange([[5, 6], [6, 8]])
|
||||
expect(editor.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10
|
||||
expect(editor.getScrollRight()).toBe (8 + editor.getHorizontalScrollMargin()) * 10
|
||||
|
||||
editor.setSelectedBufferRange([[6, 6], [6, 8]], autoscroll: true)
|
||||
expect(editor.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10
|
||||
expect(editor.getScrollRight()).toBe (8 + editor.getHorizontalScrollMargin()) * 10
|
||||
editor.setSelectedBufferRange([[0, 0], [0, 0]])
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
expect(editor.getScrollLeft()).toBe 0
|
||||
|
||||
editor.setSelectedBufferRange([[6, 6], [6, 8]])
|
||||
expect(editor.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10
|
||||
expect(editor.getScrollRight()).toBe (8 + editor.getHorizontalScrollMargin()) * 10
|
||||
|
||||
describe ".selectMarker(marker)", ->
|
||||
describe "if the marker is valid", ->
|
||||
@@ -1560,16 +1593,15 @@ describe "TextEditor", ->
|
||||
expect(editor.getSelectedBufferRanges()).toEqual [[[0, 0], [0, 0]], [[3, 4], [5, 6]]]
|
||||
|
||||
it "autoscrolls to the added selection if needed", ->
|
||||
editor.manageScrollPosition = true
|
||||
|
||||
editor.setVerticalScrollMargin(2)
|
||||
editor.setHorizontalScrollMargin(2)
|
||||
editor.setLineHeightInPixels(10)
|
||||
editor.setDefaultCharWidth(10)
|
||||
editor.setHeight(50)
|
||||
editor.setWidth(50)
|
||||
|
||||
editor.setHeight(80)
|
||||
editor.setWidth(100)
|
||||
editor.addSelectionForBufferRange([[8, 10], [8, 15]])
|
||||
expect(editor.getScrollTop()).toBe 75
|
||||
expect(editor.getScrollLeft()).toBe 160
|
||||
expect(editor.getScrollBottom()).toBe (9 * 10) + (2 * 10)
|
||||
expect(editor.getScrollRight()).toBe (15 * 10) + (2 * 10)
|
||||
|
||||
describe ".addSelectionBelow()", ->
|
||||
describe "when the selection is non-empty", ->
|
||||
@@ -1922,7 +1954,6 @@ describe "TextEditor", ->
|
||||
expect(cursor2.getBufferPosition()).toEqual [2, 7]
|
||||
|
||||
it "autoscrolls to the last cursor", ->
|
||||
editor.manageScrollPosition = true
|
||||
editor.setCursorScreenPosition([1, 2])
|
||||
editor.addCursorAtScreenPosition([10, 4])
|
||||
editor.setLineHeightInPixels(10)
|
||||
@@ -4056,7 +4087,7 @@ describe "TextEditor", ->
|
||||
editor.setLineHeightInPixels(10)
|
||||
editor.setDefaultCharWidth(10)
|
||||
editor.setHeight(60)
|
||||
editor.setWidth(50)
|
||||
editor.setWidth(130)
|
||||
editor.setHorizontalScrollbarHeight(0)
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
expect(editor.getScrollLeft()).toBe 0
|
||||
@@ -4072,8 +4103,6 @@ describe "TextEditor", ->
|
||||
|
||||
describe ".pageUp/Down()", ->
|
||||
it "scrolls one screen height up or down and moves the cursor one page length", ->
|
||||
editor.manageScrollPosition = true
|
||||
|
||||
editor.setLineHeightInPixels(10)
|
||||
editor.setHeight(50)
|
||||
expect(editor.getScrollHeight()).toBe 130
|
||||
@@ -4097,8 +4126,6 @@ describe "TextEditor", ->
|
||||
|
||||
describe ".selectPageUp/Down()", ->
|
||||
it "selects one screen height of text up or down", ->
|
||||
editor.manageScrollPosition = true
|
||||
|
||||
editor.setLineHeightInPixels(10)
|
||||
editor.setHeight(50)
|
||||
expect(editor.getScrollHeight()).toBe 130
|
||||
|
||||
30
spec/typescript-spec.coffee
Normal file
30
spec/typescript-spec.coffee
Normal file
@@ -0,0 +1,30 @@
|
||||
typescript = require '../src/typescript'
|
||||
crypto = require 'crypto'
|
||||
|
||||
describe "TypeScript transpiler support", ->
|
||||
describe "::createTypeScriptVersionAndOptionsDigest", ->
|
||||
it "returns a digest for the library version and specified options", ->
|
||||
defaultOptions =
|
||||
target: 1 # ES5
|
||||
module: 'commonjs'
|
||||
sourceMap: true
|
||||
version = '1.4.1'
|
||||
shasum = crypto.createHash('sha1')
|
||||
shasum.update('typescript', 'utf8')
|
||||
shasum.update('\0', 'utf8')
|
||||
shasum.update(version, 'utf8')
|
||||
shasum.update('\0', 'utf8')
|
||||
shasum.update(JSON.stringify(defaultOptions))
|
||||
expectedDigest = shasum.digest('hex')
|
||||
|
||||
observedDigest = typescript.createTypeScriptVersionAndOptionsDigest(version, defaultOptions)
|
||||
expect(observedDigest).toEqual expectedDigest
|
||||
|
||||
describe "when there is a .ts file", ->
|
||||
it "transpiles it using typescript", ->
|
||||
transpiled = require('./fixtures/typescript/valid.ts')
|
||||
expect(transpiled(3)).toBe 4
|
||||
|
||||
describe "when the .ts file is invalid", ->
|
||||
it "does not transpile", ->
|
||||
expect(-> require('./fixtures/typescript/invalid.ts')).toThrow()
|
||||
@@ -2,6 +2,7 @@ path = require 'path'
|
||||
CSON = require 'season'
|
||||
CoffeeCache = require 'coffee-cash'
|
||||
babel = require './babel'
|
||||
typescript = require './typescript'
|
||||
|
||||
# This file is required directly by apm so that files can be cached during
|
||||
# package install so that the first package load in Atom doesn't have to
|
||||
@@ -16,6 +17,7 @@ exports.addPathToCache = (filePath, atomHome) ->
|
||||
CoffeeCache.setCacheDirectory(path.join(cacheDir, 'coffee'))
|
||||
CSON.setCacheDir(path.join(cacheDir, 'cson'))
|
||||
babel.setCacheDirectory(path.join(cacheDir, 'js', 'babel'))
|
||||
typescript.setCacheDirectory(path.join(cacheDir, 'ts'))
|
||||
|
||||
switch path.extname(filePath)
|
||||
when '.coffee'
|
||||
@@ -24,3 +26,5 @@ exports.addPathToCache = (filePath, atomHome) ->
|
||||
CSON.readFileSync(filePath)
|
||||
when '.js'
|
||||
babel.addPathToCache(filePath)
|
||||
when '.ts'
|
||||
typescript.addPathToCache(filePath)
|
||||
|
||||
@@ -15,7 +15,6 @@ class Cursor extends Model
|
||||
bufferPosition: null
|
||||
goalColumn: null
|
||||
visible: true
|
||||
needsAutoscroll: null
|
||||
|
||||
# Instantiated by a {TextEditor}
|
||||
constructor: ({@editor, @marker, id}) ->
|
||||
@@ -30,10 +29,6 @@ class Cursor extends Model
|
||||
{textChanged} = e
|
||||
return if oldHeadScreenPosition.isEqual(newHeadScreenPosition)
|
||||
|
||||
# Supports old editor view
|
||||
@needsAutoscroll ?= @isLastCursor() and !textChanged
|
||||
@autoscroll() if @editor.manageScrollPosition and @isLastCursor() and textChanged
|
||||
|
||||
@goalColumn = null
|
||||
|
||||
movedEvent =
|
||||
@@ -53,7 +48,6 @@ class Cursor extends Model
|
||||
@emit 'destroyed'
|
||||
@emitter.emit 'did-destroy'
|
||||
@emitter.dispose()
|
||||
@needsAutoscroll = true
|
||||
|
||||
destroy: ->
|
||||
@marker.destroy()
|
||||
@@ -128,8 +122,9 @@ class Cursor extends Model
|
||||
#
|
||||
# * `bufferPosition` {Array} of two numbers: the buffer row, and the buffer column.
|
||||
# * `options` (optional) {Object} with the following keys:
|
||||
# * `autoscroll` A Boolean which, if `true`, scrolls the {TextEditor} to wherever
|
||||
# the cursor moves to.
|
||||
# * `autoscroll` {Boolean} indicating whether to autoscroll to the new
|
||||
# position. Defaults to `true` if this is the most recently added cursor,
|
||||
# `false` otherwise.
|
||||
setBufferPosition: (bufferPosition, options={}) ->
|
||||
@changePosition options, =>
|
||||
@marker.setHeadBufferPosition(bufferPosition, options)
|
||||
@@ -600,7 +595,6 @@ class Cursor extends Model
|
||||
setVisible: (visible) ->
|
||||
if @visible != visible
|
||||
@visible = visible
|
||||
@needsAutoscroll ?= true if @visible and @isLastCursor()
|
||||
@emit 'visibility-changed', @visible
|
||||
@emitter.emit 'did-change-visibility', @visible
|
||||
|
||||
@@ -628,11 +622,10 @@ class Cursor extends Model
|
||||
|
||||
# Public: Prevents this cursor from causing scrolling.
|
||||
clearAutoscroll: ->
|
||||
@needsAutoscroll = null
|
||||
|
||||
# Public: Deselects the current selection.
|
||||
clearSelection: ->
|
||||
@selection?.clear()
|
||||
clearSelection: (options) ->
|
||||
@selection?.clear(options)
|
||||
|
||||
# Public: Get the RegExp used by the cursor to determine what a "word" is.
|
||||
#
|
||||
@@ -655,12 +648,9 @@ class Cursor extends Model
|
||||
###
|
||||
|
||||
changePosition: (options, fn) ->
|
||||
@clearSelection()
|
||||
@needsAutoscroll = options.autoscroll ? @isLastCursor()
|
||||
@clearSelection(options)
|
||||
fn()
|
||||
if @needsAutoscroll
|
||||
@emit 'autoscrolled' # Support legacy editor
|
||||
@autoscroll() if @needsAutoscroll and @editor.manageScrollPosition # Support react editor view
|
||||
@autoscroll() if options.autoscroll ? @isLastCursor()
|
||||
|
||||
getPixelRect: ->
|
||||
@editor.pixelRectForScreenRange(@getScreenRange())
|
||||
|
||||
@@ -22,7 +22,6 @@ class DisplayBuffer extends Model
|
||||
Serializable.includeInto(this)
|
||||
|
||||
@properties
|
||||
manageScrollPosition: false
|
||||
softWrapped: null
|
||||
editorWidthInChars: null
|
||||
lineHeightInPixels: null
|
||||
@@ -200,12 +199,22 @@ class DisplayBuffer extends Model
|
||||
# visible - A {Boolean} indicating of the tokenized buffer is shown
|
||||
setVisible: (visible) -> @tokenizedBuffer.setVisible(visible)
|
||||
|
||||
getVerticalScrollMargin: -> @verticalScrollMargin
|
||||
getVerticalScrollMargin: -> Math.min(@verticalScrollMargin, (@getHeight() - @getLineHeightInPixels()) / 2)
|
||||
setVerticalScrollMargin: (@verticalScrollMargin) -> @verticalScrollMargin
|
||||
|
||||
getHorizontalScrollMargin: -> @horizontalScrollMargin
|
||||
getVerticalScrollMarginInPixels: ->
|
||||
scrollMarginInPixels = @getVerticalScrollMargin() * @getLineHeightInPixels()
|
||||
maxScrollMarginInPixels = (@getHeight() - @getLineHeightInPixels()) / 2
|
||||
Math.min(scrollMarginInPixels, maxScrollMarginInPixels)
|
||||
|
||||
getHorizontalScrollMargin: -> Math.min(@horizontalScrollMargin, (@getWidth() - @getDefaultCharWidth()) / 2)
|
||||
setHorizontalScrollMargin: (@horizontalScrollMargin) -> @horizontalScrollMargin
|
||||
|
||||
getHorizontalScrollMarginInPixels: ->
|
||||
scrollMarginInPixels = @getHorizontalScrollMargin() * @getDefaultCharWidth()
|
||||
maxScrollMarginInPixels = (@getWidth() - @getDefaultCharWidth()) / 2
|
||||
Math.min(scrollMarginInPixels, maxScrollMarginInPixels)
|
||||
|
||||
getHorizontalScrollbarHeight: -> @horizontalScrollbarHeight
|
||||
setHorizontalScrollbarHeight: (@horizontalScrollbarHeight) -> @horizontalScrollbarHeight
|
||||
|
||||
@@ -268,26 +277,19 @@ class DisplayBuffer extends Model
|
||||
|
||||
getScrollTop: -> @scrollTop
|
||||
setScrollTop: (scrollTop) ->
|
||||
if @manageScrollPosition
|
||||
@scrollTop = Math.round(Math.max(0, Math.min(@getMaxScrollTop(), scrollTop)))
|
||||
else
|
||||
@scrollTop = Math.round(scrollTop)
|
||||
@scrollTop = Math.round(Math.max(0, Math.min(@getMaxScrollTop(), scrollTop)))
|
||||
|
||||
getMaxScrollTop: ->
|
||||
@getScrollHeight() - @getClientHeight()
|
||||
|
||||
getScrollBottom: -> @scrollTop + @height
|
||||
getScrollBottom: -> @scrollTop + @getClientHeight()
|
||||
setScrollBottom: (scrollBottom) ->
|
||||
@setScrollTop(scrollBottom - @getClientHeight())
|
||||
@getScrollBottom()
|
||||
|
||||
getScrollLeft: -> @scrollLeft
|
||||
setScrollLeft: (scrollLeft) ->
|
||||
if @manageScrollPosition
|
||||
@scrollLeft = Math.round(Math.max(0, Math.min(@getScrollWidth() - @getClientWidth(), scrollLeft)))
|
||||
@scrollLeft
|
||||
else
|
||||
@scrollLeft = Math.round(scrollLeft)
|
||||
@scrollLeft = Math.round(Math.max(0, Math.min(@getScrollWidth() - @getClientWidth(), scrollLeft)))
|
||||
|
||||
getMaxScrollLeft: ->
|
||||
@getScrollWidth() - @getClientWidth()
|
||||
@@ -372,15 +374,16 @@ class DisplayBuffer extends Model
|
||||
@intersectsVisibleRowRange(start.row, end.row + 1)
|
||||
|
||||
scrollToScreenRange: (screenRange, options) ->
|
||||
verticalScrollMarginInPixels = @getVerticalScrollMargin() * @getLineHeightInPixels()
|
||||
horizontalScrollMarginInPixels = @getHorizontalScrollMargin() * @getDefaultCharWidth()
|
||||
verticalScrollMarginInPixels = @getVerticalScrollMarginInPixels()
|
||||
horizontalScrollMarginInPixels = @getHorizontalScrollMarginInPixels()
|
||||
|
||||
{top, left, height, width} = @pixelRectForScreenRange(screenRange)
|
||||
bottom = top + height
|
||||
right = left + width
|
||||
{top, left} = @pixelRectForScreenRange(new Range(screenRange.start, screenRange.start))
|
||||
{top: endTop, left: endLeft, height: endHeight} = @pixelRectForScreenRange(new Range(screenRange.end, screenRange.end))
|
||||
bottom = endTop + endHeight
|
||||
right = endLeft
|
||||
|
||||
if options?.center
|
||||
desiredScrollCenter = top + height / 2
|
||||
desiredScrollCenter = (top + bottom) / 2
|
||||
unless @getScrollTop() < desiredScrollCenter < @getScrollBottom()
|
||||
desiredScrollTop = desiredScrollCenter - @getHeight() / 2
|
||||
desiredScrollBottom = desiredScrollCenter + @getHeight() / 2
|
||||
@@ -391,15 +394,26 @@ class DisplayBuffer extends Model
|
||||
desiredScrollLeft = left - horizontalScrollMarginInPixels
|
||||
desiredScrollRight = right + horizontalScrollMarginInPixels
|
||||
|
||||
if desiredScrollTop < @getScrollTop()
|
||||
@setScrollTop(desiredScrollTop)
|
||||
else if desiredScrollBottom > @getScrollBottom()
|
||||
@setScrollBottom(desiredScrollBottom)
|
||||
if options?.reversed ? true
|
||||
if desiredScrollBottom > @getScrollBottom()
|
||||
@setScrollBottom(desiredScrollBottom)
|
||||
if desiredScrollTop < @getScrollTop()
|
||||
@setScrollTop(desiredScrollTop)
|
||||
|
||||
if desiredScrollLeft < @getScrollLeft()
|
||||
@setScrollLeft(desiredScrollLeft)
|
||||
else if desiredScrollRight > @getScrollRight()
|
||||
@setScrollRight(desiredScrollRight)
|
||||
if desiredScrollRight > @getScrollRight()
|
||||
@setScrollRight(desiredScrollRight)
|
||||
if desiredScrollLeft < @getScrollLeft()
|
||||
@setScrollLeft(desiredScrollLeft)
|
||||
else
|
||||
if desiredScrollTop < @getScrollTop()
|
||||
@setScrollTop(desiredScrollTop)
|
||||
if desiredScrollBottom > @getScrollBottom()
|
||||
@setScrollBottom(desiredScrollBottom)
|
||||
|
||||
if desiredScrollLeft < @getScrollLeft()
|
||||
@setScrollLeft(desiredScrollLeft)
|
||||
if desiredScrollRight > @getScrollRight()
|
||||
@setScrollRight(desiredScrollRight)
|
||||
|
||||
scrollToScreenPosition: (screenPosition, options) ->
|
||||
@scrollToScreenRange(new Range(screenPosition, screenPosition), options)
|
||||
@@ -1113,7 +1127,7 @@ class DisplayBuffer extends Model
|
||||
handleTokenizedBufferChange: (tokenizedBufferChange) =>
|
||||
{start, end, delta, bufferChange} = tokenizedBufferChange
|
||||
@updateScreenLines(start, end + 1, delta, delayChangeEvent: bufferChange?)
|
||||
@setScrollTop(Math.min(@getScrollTop(), @getMaxScrollTop())) if @manageScrollPosition and delta < 0
|
||||
@setScrollTop(Math.min(@getScrollTop(), @getMaxScrollTop())) if delta < 0
|
||||
|
||||
updateScreenLines: (startBufferRow, endBufferRow, bufferDelta=0, options={}) ->
|
||||
startBufferRow = @rowMap.bufferRowRangeForBufferRow(startBufferRow)[0]
|
||||
|
||||
@@ -686,7 +686,7 @@ class Pane extends Model
|
||||
true
|
||||
|
||||
handleSaveError: (error) ->
|
||||
if error.message.endsWith('is a directory')
|
||||
if error.code is 'EISDIR' or error.message.endsWith('is a directory')
|
||||
atom.notifications.addWarning("Unable to save file: #{error.message}")
|
||||
else if error.code is 'EACCES' and error.path?
|
||||
atom.notifications.addWarning("Unable to save file: Permission denied '#{error.path}'")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{Point, Range} = require 'text-buffer'
|
||||
{Model} = require 'theorist'
|
||||
{pick} = require 'underscore-plus'
|
||||
{pick} = _ = require 'underscore-plus'
|
||||
{Emitter} = require 'event-kit'
|
||||
Grim = require 'grim'
|
||||
|
||||
@@ -14,7 +14,6 @@ class Selection extends Model
|
||||
editor: null
|
||||
initialScreenRange: null
|
||||
wordwise: false
|
||||
needsAutoscroll: null
|
||||
|
||||
constructor: ({@cursor, @marker, @editor, id}) ->
|
||||
@emitter = new Emitter
|
||||
@@ -35,6 +34,9 @@ class Selection extends Model
|
||||
destroy: ->
|
||||
@marker.destroy()
|
||||
|
||||
isLastSelection: ->
|
||||
this is @editor.getLastSelection()
|
||||
|
||||
###
|
||||
Section: Event Subscription
|
||||
###
|
||||
@@ -96,19 +98,20 @@ class Selection extends Model
|
||||
#
|
||||
# * `screenRange` The new {Range} to select.
|
||||
# * `options` (optional) {Object} with the keys:
|
||||
# * `preserveFolds` if `true`, the fold settings are preserved after the selection moves.
|
||||
# * `autoscroll` if `true`, the {TextEditor} scrolls to the new selection.
|
||||
# * `preserveFolds` if `true`, the fold settings are preserved after the
|
||||
# selection moves.
|
||||
# * `autoscroll` {Boolean} indicating whether to autoscroll to the new
|
||||
# range. Defaults to `true` if this is the most recently added selection,
|
||||
# `false` otherwise.
|
||||
setBufferRange: (bufferRange, options={}) ->
|
||||
bufferRange = Range.fromObject(bufferRange)
|
||||
@needsAutoscroll = options.autoscroll
|
||||
options.reversed ?= @isReversed()
|
||||
@editor.destroyFoldsContainingBufferRange(bufferRange) unless options.preserveFolds
|
||||
@modifySelection =>
|
||||
needsFlash = options.flash
|
||||
delete options.flash if options.flash?
|
||||
@cursor.needsAutoscroll = false if @needsAutoscroll?
|
||||
@marker.setBufferRange(bufferRange, options)
|
||||
@autoscroll() if @needsAutoscroll and @editor.manageScrollPosition
|
||||
@autoscroll() if options?.autoscroll ? @isLastSelection()
|
||||
@decoration.flash('flash', @editor.selectionFlashDuration) if needsFlash
|
||||
|
||||
# Public: Returns the starting and ending buffer rows the selection is
|
||||
@@ -184,9 +187,15 @@ class Selection extends Model
|
||||
###
|
||||
|
||||
# Public: Clears the selection, moving the marker to the head.
|
||||
clear: ->
|
||||
#
|
||||
# * `options` (optional) {Object} with the following keys:
|
||||
# * `autoscroll` {Boolean} indicating whether to autoscroll to the new
|
||||
# range. Defaults to `true` if this is the most recently added selection,
|
||||
# `false` otherwise.
|
||||
clear: (options) ->
|
||||
@marker.setProperties(goalScreenRange: null)
|
||||
@marker.clearTail() unless @retainSelection
|
||||
@autoscroll() if options?.autoscroll ? @isLastSelection()
|
||||
@finalize()
|
||||
|
||||
# Public: Selects the text from the current cursor position to a given screen
|
||||
@@ -359,7 +368,6 @@ class Selection extends Model
|
||||
@editor.unfoldBufferRow(oldBufferRange.end.row)
|
||||
wasReversed = @isReversed()
|
||||
@clear()
|
||||
@cursor.needsAutoscroll = @cursor.isLastCursor()
|
||||
|
||||
autoIndentFirstLine = false
|
||||
precedingText = @editor.getTextInRange([[oldBufferRange.start.row, 0], oldBufferRange.start])
|
||||
@@ -398,6 +406,8 @@ class Selection extends Model
|
||||
else if options.autoDecreaseIndent and NonWhitespaceRegExp.test(text)
|
||||
@editor.autoDecreaseIndentForBufferRow(newBufferRange.start.row)
|
||||
|
||||
@autoscroll() if @isLastSelection()
|
||||
|
||||
newBufferRange
|
||||
|
||||
# Public: Removes the first character before the selection if the selection
|
||||
@@ -713,7 +723,7 @@ class Selection extends Model
|
||||
else
|
||||
options.goalScreenRange = myGoalScreenRange ? otherGoalScreenRange
|
||||
|
||||
@setBufferRange(@getBufferRange().union(otherSelection.getBufferRange()), options)
|
||||
@setBufferRange(@getBufferRange().union(otherSelection.getBufferRange()), _.extend(autoscroll: false, options))
|
||||
otherSelection.destroy()
|
||||
|
||||
###
|
||||
@@ -755,10 +765,12 @@ class Selection extends Model
|
||||
@linewise = false
|
||||
|
||||
autoscroll: ->
|
||||
@editor.scrollToScreenRange(@getScreenRange())
|
||||
if @marker.hasTail()
|
||||
@editor.scrollToScreenRange(@getScreenRange(), reversed: @isReversed())
|
||||
else
|
||||
@cursor.autoscroll()
|
||||
|
||||
clearAutoscroll: ->
|
||||
@needsAutoscroll = null
|
||||
|
||||
modifySelection: (fn) ->
|
||||
@retainSelection = true
|
||||
|
||||
@@ -39,7 +39,6 @@ class TextEditorComponent
|
||||
@lineOverdrawMargin = lineOverdrawMargin if lineOverdrawMargin?
|
||||
@disposables = new CompositeDisposable
|
||||
|
||||
@editor.manageScrollPosition = true
|
||||
@observeConfig()
|
||||
@setScrollSensitivity(atom.config.get('editor.scrollSensitivity'))
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ class TextEditor extends Model
|
||||
|
||||
@delegatesProperties '$lineHeightInPixels', '$defaultCharWidth', '$height', '$width',
|
||||
'$verticalScrollbarWidth', '$horizontalScrollbarHeight', '$scrollTop', '$scrollLeft',
|
||||
'manageScrollPosition', toProperty: 'displayBuffer'
|
||||
toProperty: 'displayBuffer'
|
||||
|
||||
constructor: ({@softTabs, initialLine, initialColumn, tabLength, softWrapped, @displayBuffer, buffer, registerEditor, suppressCursorCreation, @mini, @placeholderText, @gutterVisible}) ->
|
||||
super
|
||||
@@ -1132,13 +1132,13 @@ class TextEditor extends Model
|
||||
|
||||
# Essential: Undo the last change.
|
||||
undo: ->
|
||||
@getLastCursor().needsAutoscroll = true
|
||||
@buffer.undo(this)
|
||||
@buffer.undo()
|
||||
@getLastSelection().autoscroll()
|
||||
|
||||
# Essential: Redo the last change.
|
||||
redo: ->
|
||||
@getLastCursor().needsAutoscroll = true
|
||||
@buffer.redo(this)
|
||||
@getLastSelection().autoscroll()
|
||||
|
||||
# Extended: Batch multiple operations as a single undo/redo step.
|
||||
#
|
||||
@@ -1608,8 +1608,9 @@ class TextEditor extends Model
|
||||
# * `bufferPosition` A {Point} or {Array} of `[row, column]`
|
||||
#
|
||||
# Returns a {Cursor}.
|
||||
addCursorAtBufferPosition: (bufferPosition) ->
|
||||
addCursorAtBufferPosition: (bufferPosition, options) ->
|
||||
@markBufferPosition(bufferPosition, @getSelectionMarkerAttributes())
|
||||
@getLastSelection().cursor.autoscroll() unless options?.autoscroll is false
|
||||
@getLastSelection().cursor
|
||||
|
||||
# Essential: Add a cursor at the position in screen coordinates.
|
||||
@@ -1617,8 +1618,9 @@ class TextEditor extends Model
|
||||
# * `screenPosition` A {Point} or {Array} of `[row, column]`
|
||||
#
|
||||
# Returns a {Cursor}.
|
||||
addCursorAtScreenPosition: (screenPosition) ->
|
||||
addCursorAtScreenPosition: (screenPosition, options) ->
|
||||
@markScreenPosition(screenPosition, @getSelectionMarkerAttributes())
|
||||
@getLastSelection().cursor.autoscroll() unless options?.autoscroll is false
|
||||
@getLastSelection().cursor
|
||||
|
||||
# Essential: Returns {Boolean} indicating whether or not there are multiple cursors.
|
||||
@@ -1949,9 +1951,8 @@ class TextEditor extends Model
|
||||
# Returns the added {Selection}.
|
||||
addSelectionForBufferRange: (bufferRange, options={}) ->
|
||||
@markBufferRange(bufferRange, _.defaults(@getSelectionMarkerAttributes(), options))
|
||||
selection = @getLastSelection()
|
||||
selection.autoscroll() if @manageScrollPosition
|
||||
selection
|
||||
@getLastSelection().autoscroll() unless options.autoscroll is false
|
||||
@getLastSelection()
|
||||
|
||||
# Essential: Add a selection for the given range in screen coordinates.
|
||||
#
|
||||
@@ -1963,9 +1964,8 @@ class TextEditor extends Model
|
||||
# Returns the added {Selection}.
|
||||
addSelectionForScreenRange: (screenRange, options={}) ->
|
||||
@markScreenRange(screenRange, _.defaults(@getSelectionMarkerAttributes(), options))
|
||||
selection = @getLastSelection()
|
||||
selection.autoscroll() if @manageScrollPosition
|
||||
selection
|
||||
@getLastSelection().autoscroll() unless options.autoscroll is false
|
||||
@getLastSelection()
|
||||
|
||||
# Essential: Select from the current cursor position to the given position in
|
||||
# buffer coordinates.
|
||||
@@ -2271,6 +2271,7 @@ class TextEditor extends Model
|
||||
@selections.push(selection)
|
||||
selectionBufferRange = selection.getBufferRange()
|
||||
@mergeIntersectingSelections(preserveFolds: marker.getProperties().preserveFolds)
|
||||
|
||||
if selection.destroyed
|
||||
for selection in @getSelections()
|
||||
if selection.intersectsBufferRange(selectionBufferRange)
|
||||
@@ -2288,9 +2289,9 @@ class TextEditor extends Model
|
||||
|
||||
# Reduce one or more selections to a single empty selection based on the most
|
||||
# recently added cursor.
|
||||
clearSelections: ->
|
||||
clearSelections: (options) ->
|
||||
@consolidateSelections()
|
||||
@getLastSelection().clear()
|
||||
@getLastSelection().clear(options)
|
||||
|
||||
# Reduce multiple selections to the most recently added selection.
|
||||
consolidateSelections: ->
|
||||
|
||||
106
src/typescript.coffee
Normal file
106
src/typescript.coffee
Normal file
@@ -0,0 +1,106 @@
|
||||
###
|
||||
Cache for source code transpiled by TypeScript.
|
||||
|
||||
Inspired by https://github.com/atom/atom/blob/7a719d585db96ff7d2977db9067e1d9d4d0adf1a/src/babel.coffee
|
||||
###
|
||||
|
||||
crypto = require 'crypto'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
tss = null # Defer until used
|
||||
|
||||
stats =
|
||||
hits: 0
|
||||
misses: 0
|
||||
|
||||
defaultOptions =
|
||||
target: 1 # ES5
|
||||
module: 'commonjs'
|
||||
sourceMap: true
|
||||
|
||||
createTypeScriptVersionAndOptionsDigest = (version, options) ->
|
||||
shasum = crypto.createHash('sha1')
|
||||
# Include the version of typescript in the hash.
|
||||
shasum.update('typescript', 'utf8')
|
||||
shasum.update('\0', 'utf8')
|
||||
shasum.update(version, 'utf8')
|
||||
shasum.update('\0', 'utf8')
|
||||
shasum.update(JSON.stringify(options))
|
||||
shasum.digest('hex')
|
||||
|
||||
cacheDir = null
|
||||
jsCacheDir = null
|
||||
|
||||
getCachePath = (sourceCode) ->
|
||||
digest = crypto.createHash('sha1').update(sourceCode, 'utf8').digest('hex')
|
||||
|
||||
unless jsCacheDir?
|
||||
tssVersion = require('typescript-simple/package.json').version
|
||||
jsCacheDir = path.join(cacheDir, createTypeScriptVersionAndOptionsDigest(tssVersion, defaultOptions))
|
||||
|
||||
path.join(jsCacheDir, "#{digest}.js")
|
||||
|
||||
getCachedJavaScript = (cachePath) ->
|
||||
if fs.isFileSync(cachePath)
|
||||
try
|
||||
cachedJavaScript = fs.readFileSync(cachePath, 'utf8')
|
||||
stats.hits++
|
||||
return cachedJavaScript
|
||||
null
|
||||
|
||||
# Returns the TypeScript options that should be used to transpile filePath.
|
||||
createOptions = (filePath) ->
|
||||
options = filename: filePath
|
||||
for key, value of defaultOptions
|
||||
options[key] = value
|
||||
options
|
||||
|
||||
transpile = (sourceCode, filePath, cachePath) ->
|
||||
options = createOptions(filePath)
|
||||
unless tss?
|
||||
{TypeScriptSimple} = require 'typescript-simple'
|
||||
tss = new TypeScriptSimple(options, false)
|
||||
js = tss.compile(sourceCode, filePath)
|
||||
stats.misses++
|
||||
|
||||
try
|
||||
fs.writeFileSync(cachePath, js)
|
||||
|
||||
js
|
||||
|
||||
# Function that obeys the contract of an entry in the require.extensions map.
|
||||
# Returns the transpiled version of the JavaScript code at filePath, which is
|
||||
# either generated on the fly or pulled from cache.
|
||||
loadFile = (module, filePath) ->
|
||||
sourceCode = fs.readFileSync(filePath, 'utf8')
|
||||
cachePath = getCachePath(sourceCode)
|
||||
js = getCachedJavaScript(cachePath) ? transpile(sourceCode, filePath, cachePath)
|
||||
module._compile(js, filePath)
|
||||
|
||||
register = ->
|
||||
Object.defineProperty(require.extensions, '.ts', {
|
||||
enumerable: true
|
||||
writable: false
|
||||
value: loadFile
|
||||
})
|
||||
|
||||
setCacheDirectory = (newCacheDir) ->
|
||||
if cacheDir isnt newCacheDir
|
||||
cacheDir = newCacheDir
|
||||
jsCacheDir = null
|
||||
|
||||
module.exports =
|
||||
register: register
|
||||
setCacheDirectory: setCacheDirectory
|
||||
getCacheMisses: -> stats.misses
|
||||
getCacheHits: -> stats.hits
|
||||
|
||||
# Visible for testing.
|
||||
createTypeScriptVersionAndOptionsDigest: createTypeScriptVersionAndOptionsDigest
|
||||
|
||||
addPathToCache: (filePath) ->
|
||||
return if path.extname(filePath) isnt '.ts'
|
||||
|
||||
sourceCode = fs.readFileSync(filePath, 'utf8')
|
||||
cachePath = getCachePath(sourceCode)
|
||||
transpile(sourceCode, filePath, cachePath)
|
||||
@@ -47,6 +47,7 @@ window.onload = function() {
|
||||
setupCsonCache(cacheDir);
|
||||
setupSourceMapCache(cacheDir);
|
||||
setupBabel(cacheDir);
|
||||
setupTypeScript(cacheDir);
|
||||
|
||||
require(loadSettings.bootstrapScript);
|
||||
require('ipc').sendChannel('window-command', 'window:loaded');
|
||||
@@ -95,6 +96,12 @@ var setupBabel = function(cacheDir) {
|
||||
babel.register();
|
||||
}
|
||||
|
||||
var setupTypeScript = function(cacheDir) {
|
||||
var typescript = require('../src/typescript');
|
||||
typescript.setCacheDirectory(path.join(cacheDir, 'typescript'));
|
||||
typescript.register();
|
||||
}
|
||||
|
||||
var setupCsonCache = function(cacheDir) {
|
||||
require('season').setCacheDir(path.join(cacheDir, 'cson'));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user