diff --git a/apm/package.json b/apm/package.json
index 46f42f23f..79b3eeed1 100644
--- a/apm/package.json
+++ b/apm/package.json
@@ -6,6 +6,6 @@
"url": "https://github.com/atom/atom.git"
},
"dependencies": {
- "atom-package-manager": "1.1.0"
+ "atom-package-manager": "1.2.0"
}
}
diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee
index 62672b1e4..f61ae7261 100644
--- a/build/Gruntfile.coffee
+++ b/build/Gruntfile.coffee
@@ -41,7 +41,7 @@ module.exports = (grunt) ->
buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'atom-build')
installDir = grunt.option('install-dir')
- home = if process.env is 'win32' then process.env.USERPROFILE else process.env.HOME
+ home = if process.platform is 'win32' then process.env.USERPROFILE else process.env.HOME
atomShellDownloadDir = path.join(home, '.atom', 'atom-shell')
symbolsDir = path.join(buildDir, 'Atom.breakpad.syms')
diff --git a/build/tasks/build-task.coffee b/build/tasks/build-task.coffee
index 21f59c4c0..c9964b474 100644
--- a/build/tasks/build-task.coffee
+++ b/build/tasks/build-task.coffee
@@ -14,9 +14,9 @@ module.exports = (grunt) ->
mkdir path.dirname(buildDir)
if process.platform is 'darwin'
- cp 'atom-shell/Atom.app', shellAppDir
+ cp 'atom-shell/Atom.app', shellAppDir, filter: /default_app/
else
- cp 'atom-shell', shellAppDir
+ cp 'atom-shell', shellAppDir, filter: /default_app/
mkdir appDir
@@ -45,29 +45,45 @@ module.exports = (grunt) ->
path.join('git-utils', 'deps')
path.join('oniguruma', 'deps')
path.join('less', 'dist')
- path.join('less', 'test')
path.join('bootstrap', 'docs')
- path.join('bootstrap', 'examples')
+ path.join('bootstrap', '_config.yml')
+ path.join('bootstrap', '_includes')
+ path.join('bootstrap', '_layouts')
+ path.join('npm', 'doc')
+ path.join('npm', 'html')
+ path.join('npm', 'man')
+ path.join('npm', 'node_modules', '.bin', 'beep')
+ path.join('npm', 'node_modules', '.bin', 'clear')
+ path.join('npm', 'node_modules', '.bin', 'starwars')
path.join('pegjs', 'examples')
- path.join('plist', 'tests')
- path.join('xmldom', 'test')
- path.join('combined-stream', 'test')
- path.join('delayed-stream', 'test')
- path.join('domhandler', 'test')
- path.join('fstream-ignore', 'test')
- path.join('harmony-collections', 'test')
- path.join('lru-cache', 'test')
- path.join('minimatch', 'test')
- path.join('normalize-package-data', 'test')
- path.join('npm', 'test')
path.join('jasmine-reporters', 'ext')
path.join('jasmine-node', 'node_modules', 'gaze')
+ path.join('jasmine-node', 'spec')
+ path.join('node_modules', 'nan')
+ path.join('build', 'binding.Makefile')
+ path.join('build', 'config.gypi')
+ path.join('build', 'gyp-mac-tool')
+ path.join('build', 'Makefile')
path.join('build', 'Release', 'obj.target')
path.join('build', 'Release', 'obj')
path.join('build', 'Release', '.deps')
path.join('vendor', 'apm')
path.join('resources', 'mac')
path.join('resources', 'win')
+
+ # These are only require in dev mode when the grammar isn't precompiled
+ path.join('atom-keymap', 'node_modules', 'loophole')
+ path.join('atom-keymap', 'node_modules', 'pegjs')
+ path.join('atom-keymap', 'node_modules', '.bin', 'pegjs')
+ path.join('snippets', 'node_modules', 'loophole')
+ path.join('snippets', 'node_modules', 'pegjs')
+ path.join('snippets', 'node_modules', '.bin', 'pegjs')
+
+ '.DS_Store'
+ '.jshintrc'
+ '.npmignore'
+ '.pairs'
+ '.travis.yml'
]
ignoredPaths = ignoredPaths.map (ignoredPath) -> _.escapeRegExp(ignoredPath)
@@ -75,21 +91,56 @@ module.exports = (grunt) ->
ignoredPaths.push "#{_.escapeRegExp(path.join('spellchecker', 'vendor', 'hunspell') + path.sep)}.*"
ignoredPaths.push "#{_.escapeRegExp(path.join('build', 'Release') + path.sep)}.*\\.pdb"
+ # Ignore *.cc and *.h files from native modules
+ ignoredPaths.push "#{_.escapeRegExp(path.join('ctags', 'src') + path.sep)}.*\\.(cc|h)*"
+ ignoredPaths.push "#{_.escapeRegExp(path.join('git-utils', 'src') + path.sep)}.*\\.(cc|h)*"
+ ignoredPaths.push "#{_.escapeRegExp(path.join('keytar', 'src') + path.sep)}.*\\.(cc|h)*"
+ ignoredPaths.push "#{_.escapeRegExp(path.join('nslog', 'src') + path.sep)}.*\\.(cc|h)*"
+ ignoredPaths.push "#{_.escapeRegExp(path.join('oniguruma', 'src') + path.sep)}.*\\.(cc|h)*"
+ ignoredPaths.push "#{_.escapeRegExp(path.join('pathwatcher', 'src') + path.sep)}.*\\.(cc|h)*"
+ ignoredPaths.push "#{_.escapeRegExp(path.join('runas', 'src') + path.sep)}.*\\.(cc|h)*"
+ ignoredPaths.push "#{_.escapeRegExp(path.join('scrollbar-style', 'src') + path.sep)}.*\\.(cc|h)*"
+ ignoredPaths.push "#{_.escapeRegExp(path.join('spellchecker', 'src') + path.sep)}.*\\.(cc|h)*"
+
+ # Ignore build files
+ ignoredPaths.push "#{_.escapeRegExp(path.sep)}binding\\.gyp$"
+ ignoredPaths.push "#{_.escapeRegExp(path.sep)}.+\\.target.mk$"
+ ignoredPaths.push "#{_.escapeRegExp(path.sep)}linker\\.lock$"
+ ignoredPaths.push "#{_.escapeRegExp(path.join('build', 'Release') + path.sep)}.+\\.node\\.dSYM"
+
# Hunspell dictionaries are only not needed on OS X.
if process.platform is 'darwin'
ignoredPaths.push path.join('spellchecker', 'vendor', 'hunspell_dictionaries')
ignoredPaths = ignoredPaths.map (ignoredPath) -> "(#{ignoredPath})"
+
+ testFolderPattern = new RegExp("#{_.escapeRegExp(path.sep)}te?sts?#{_.escapeRegExp(path.sep)}")
+ exampleFolderPattern = new RegExp("#{_.escapeRegExp(path.sep)}examples?#{_.escapeRegExp(path.sep)}")
+ benchmarkFolderPattern = new RegExp("#{_.escapeRegExp(path.sep)}benchmarks?#{_.escapeRegExp(path.sep)}")
+
nodeModulesFilter = new RegExp(ignoredPaths.join('|'))
+ filterNodeModule = (pathToCopy) ->
+ return true if benchmarkFolderPattern.test(pathToCopy)
+
+ pathToCopy = path.resolve(pathToCopy)
+ nodeModulesFilter.test(pathToCopy) or testFolderPattern.test(pathToCopy) or exampleFolderPattern.test(pathToCopy)
+
packageFilter = new RegExp("(#{ignoredPaths.join('|')})|(.+\\.(cson|coffee)$)")
+ filterPackage = (pathToCopy) ->
+ return true if benchmarkFolderPattern.test(pathToCopy)
+
+ pathToCopy = path.resolve(pathToCopy)
+ packageFilter.test(pathToCopy) or testFolderPattern.test(pathToCopy) or exampleFolderPattern.test(pathToCopy)
+
for directory in nonPackageDirectories
- cp directory, path.join(appDir, directory), filter: nodeModulesFilter
+ cp directory, path.join(appDir, directory), filter: filterNodeModule
+
for directory in packageDirectories
- cp directory, path.join(appDir, directory), filter: packageFilter
+ cp directory, path.join(appDir, directory), filter: filterPackage
cp 'spec', path.join(appDir, 'spec')
cp 'src', path.join(appDir, 'src'), filter: /.+\.(cson|coffee)$/
cp 'static', path.join(appDir, 'static')
- cp 'apm', path.join(appDir, 'apm'), filter: nodeModulesFilter
+ cp 'apm', path.join(appDir, 'apm'), filter: filterNodeModule
if process.platform is 'darwin'
grunt.file.recurse path.join('resources', 'mac'), (sourcePath, rootDirectory, subDirectory='', filename) ->
diff --git a/build/tasks/output-build-filetypes.coffee b/build/tasks/output-build-filetypes.coffee
new file mode 100644
index 000000000..64b952bbe
--- /dev/null
+++ b/build/tasks/output-build-filetypes.coffee
@@ -0,0 +1,21 @@
+path = require 'path'
+
+module.exports = (grunt) ->
+ grunt.registerTask 'output-build-filetypes', 'Log counts for each filetype in the built application', ->
+ shellAppDir = grunt.config.get('atom.shellAppDir')
+
+ types = {}
+ grunt.file.recurse shellAppDir, (absolutePath, rootPath, relativePath, fileName) ->
+ extension = path.extname(fileName) or fileName
+ types[extension] ?= 0
+ types[extension]++
+
+ extensions = Object.keys(types).sort (extension1, extension2) ->
+ diff = types[extension2] - types[extension1]
+ if diff is 0
+ extension1.toLowerCase().localeCompare(extension2.toLowerCase())
+ else
+ diff
+
+ extensions.forEach (extension) ->
+ grunt.log.error "#{extension}: #{types[extension]}"
diff --git a/build/tasks/task-helpers.coffee b/build/tasks/task-helpers.coffee
index 4b388ce63..a25f9ea31 100644
--- a/build/tasks/task-helpers.coffee
+++ b/build/tasks/task-helpers.coffee
@@ -7,7 +7,7 @@ module.exports = (grunt) ->
grunt.fatal("Cannot copy non-existent #{source.cyan} to #{destination.cyan}")
copyFile = (sourcePath, destinationPath) ->
- return if filter?.test(sourcePath)
+ return if filter?(sourcePath) or filter?.test?(sourcePath)
stats = fs.lstatSync(sourcePath)
if stats.isSymbolicLink()
diff --git a/keymaps/linux.cson b/keymaps/linux.cson
index a092ff962..d643ff0bb 100644
--- a/keymaps/linux.cson
+++ b/keymaps/linux.cson
@@ -96,6 +96,7 @@
'ctrl-alt-shift-p': 'editor:log-cursor-scope'
'ctrl-k ctrl-u': 'editor:upper-case'
'ctrl-k ctrl-l': 'editor:lower-case'
+ 'ctrl-l': 'editor:select-line'
'.workspace .editor:not(.mini)':
# Atom specific
diff --git a/keymaps/win32.cson b/keymaps/win32.cson
index 01408fb38..a97d29c2c 100644
--- a/keymaps/win32.cson
+++ b/keymaps/win32.cson
@@ -93,6 +93,7 @@
'ctrl-alt-shift-p': 'editor:log-cursor-scope'
'ctrl-k ctrl-u': 'editor:upper-case'
'ctrl-k ctrl-l': 'editor:lower-case'
+ 'ctrl-l': 'editor:select-line'
'.workspace .editor:not(.mini)':
# Atom specific
diff --git a/menus/darwin.cson b/menus/darwin.cson
index 647f20d6a..ae32b353e 100644
--- a/menus/darwin.cson
+++ b/menus/darwin.cson
@@ -37,7 +37,7 @@
{ label: 'Save As...', command: 'core:save-as' }
{ label: 'Save All', command: 'window:save-all' }
{ type: 'separator' }
- { label: 'Close Buffer', command: 'core:close' }
+ { label: 'Close Tab', command: 'core:close' }
{ label: 'Close Pane', command: 'pane:close' }
{ label: 'Close Window', command: 'window:close' }
]
diff --git a/menus/linux.cson b/menus/linux.cson
index 850b25d91..f12c46406 100644
--- a/menus/linux.cson
+++ b/menus/linux.cson
@@ -14,8 +14,8 @@
{ label: 'Save &As...', command: 'core:save-as' }
{ label: 'Save A&ll', command: 'window:save-all' }
{ type: 'separator' }
- { label: '&Close Buffer', command: 'core:close' }
- { label: 'Close All &Buffers', command: 'pane:close' }
+ { label: '&Close Tab', command: 'core:close' }
+ { label: 'Close &Pane', command: 'pane:close' }
{ label: 'Clos&e Window', command: 'window:close' }
{ type: 'separator' }
{ label: 'Quit', command: 'application:quit' }
diff --git a/menus/win32.cson b/menus/win32.cson
index 6f43528bf..4654d8841 100644
--- a/menus/win32.cson
+++ b/menus/win32.cson
@@ -9,13 +9,18 @@
{ label: 'Reopen Last &Item', command: 'pane:reopen-closed-item' }
{ type: 'separator' }
{ label: 'Se&ttings', command: 'application:show-settings' }
+ { label: 'Open Your Config', command: 'application:open-your-config' }
+ { label: 'Open Your Init Script', command: 'application:open-your-init-script' }
+ { label: 'Open Your Keymap', command: 'application:open-your-keymap' }
+ { label: 'Open Your Snippets', command: 'application:open-your-snippets' }
+ { label: 'Open Your Stylesheet', command: 'application:open-your-stylesheet' }
{ type: 'separator' }
{ label: '&Save', command: 'core:save' }
{ label: 'Save &As...', command: 'core:save-as' }
{ label: 'Save A&ll', command: 'window:save-all' }
{ type: 'separator' }
- { label: '&Close Buffer', command: 'core:close' }
- { label: 'Close All &Buffers', command: 'pane:close' }
+ { label: '&Close Tab', command: 'core:close' }
+ { label: 'Close &Pane', command: 'pane:close' }
{ label: 'Clos&e Window', command: 'window:close' }
{ type: 'separator' }
{ label: 'E&xit', command: 'application:quit' }
diff --git a/package.json b/package.json
index 30302854f..73f639819 100644
--- a/package.json
+++ b/package.json
@@ -96,12 +96,12 @@
"package-generator": "0.31.0",
"release-notes": "0.35.0",
"settings-view": "0.134.0",
- "snippets": "1.0.0",
+ "snippets": "1.1.0",
"spell-check": "1.0.0",
"status-bar": "0.41.0",
"styleguide": "0.29.0",
"symbols-view": "1.0.0",
- "tabs": "0.45.0",
+ "tabs": "0.46.0",
"timecop": "0.21.0",
"tree-view": "1.1.0",
"update-package-dependencies": "0.6.0",
@@ -109,16 +109,16 @@
"whitespace": "0.25.0",
"wrap-guide": "0.21.0",
- "language-c": "0.22.0",
+ "language-c": "0.24.0",
"language-coffee-script": "0.27.0",
"language-css": "0.17.0",
"language-gfm": "0.43.0",
"language-git": "0.9.0",
- "language-go": "0.14.0",
+ "language-go": "0.15.0",
"language-html": "0.22.0",
"language-hyperlink": "0.10.0",
"language-java": "0.11.0",
- "language-javascript": "0.36.0",
+ "language-javascript": "0.37.0",
"language-json": "0.8.0",
"language-less": "0.13.0",
"language-make": "0.10.0",
diff --git a/script/bootstrap b/script/bootstrap
index f286096a6..c802a45cd 100755
--- a/script/bootstrap
+++ b/script/bootstrap
@@ -77,7 +77,7 @@ function bootstrap() {
moduleInstallCommand,
dedupeApmCommand + ' ' + packagesToDedupe.join(' '),
{
- command: dedupeNpmCommand + ' request',
+ command: dedupeNpmCommand + ' request semver',
options: {
cwd: path.resolve(__dirname, '..', 'apm', 'node_modules', 'atom-package-manager')
}
diff --git a/spec/editor-component-spec.coffee b/spec/editor-component-spec.coffee
index 3d8af165f..113a05620 100644
--- a/spec/editor-component-spec.coffee
+++ b/spec/editor-component-spec.coffee
@@ -7,7 +7,7 @@ nbsp = String.fromCharCode(160)
describe "EditorComponent", ->
[contentNode, editor, wrapperView, wrapperNode, component, componentNode, verticalScrollbarNode, horizontalScrollbarNode] = []
- [lineHeightInPixels, charWidth, delayAnimationFrames, nextAnimationFrame, runSetImmediateCallbacks, lineOverdrawMargin] = []
+ [lineHeightInPixels, charWidth, delayAnimationFrames, nextAnimationFrame, runSetImmediateCallbacks, hasSetImmediateCallbacks, lineOverdrawMargin] = []
beforeEach ->
lineOverdrawMargin = 2
@@ -41,6 +41,9 @@ describe "EditorComponent", ->
setImmediateFns.length = 0
fn() for fn in fns
+ hasSetImmediateCallbacks = ->
+ setImmediateFns.length isnt 0
+
spyOn(window, 'setImmediate').andCallFake (fn) -> setImmediateFns.push(fn)
contentNode = document.querySelector('#jasmine-content')
@@ -192,6 +195,10 @@ describe "EditorComponent", ->
for lineNode in lineNodes
expect(lineNode.style.width).toBe scrollViewWidth + 'px'
+ it "renders an nbsp on empty lines when no line-ending character is defined", ->
+ atom.config.set("editor.showInvisibles", false)
+ expect(component.lineNodeForScreenRow(10).textContent).toBe nbsp
+
describe "when showInvisibles is enabled", ->
invisibles = null
@@ -232,7 +239,15 @@ describe "EditorComponent", ->
expect(component.lineNodeForScreenRow(0).textContent).toBe "a line that ends with a carriage return#{invisibles.cr}#{invisibles.eol}"
it "renders invisible line-ending characters on empty lines", ->
- expect(component.lineNodeForScreenRow(10).textContent).toBe nbsp + invisibles.eol
+ expect(component.lineNodeForScreenRow(10).textContent).toBe invisibles.eol
+
+ it "renders an nbsp on empty lines when the line-ending character is an empty string", ->
+ atom.config.set("editor.invisibles", eol: '')
+ expect(component.lineNodeForScreenRow(10).textContent).toBe nbsp
+
+ it "renders an nbsp on empty lines when no line-ending character is defined", ->
+ atom.config.set("editor.invisibles", eol: null)
+ expect(component.lineNodeForScreenRow(10).textContent).toBe nbsp
it "interleaves invisible line-ending characters with indent guides on empty lines", ->
component.setShowIndentGuide(true)
@@ -269,7 +284,6 @@ describe "EditorComponent", ->
describe "when indent guides are enabled", ->
beforeEach ->
component.setShowIndentGuide(true)
- runSetImmediateCallbacks()
it "adds an 'indent-guide' class to spans comprising the leading whitespace", ->
line1LeafNodes = getLeafNodes(component.lineNodeForScreenRow(1))
@@ -346,7 +360,6 @@ describe "EditorComponent", ->
describe "when indent guides are disabled", ->
beforeEach ->
component.setShowIndentGuide(false)
- runSetImmediateCallbacks()
it "does not render indent guides on lines containing only whitespace", ->
editor.getBuffer().insert([1, Infinity], '\n ')
@@ -563,7 +576,7 @@ describe "EditorComponent", ->
it "does not fold when the line number componentNode is clicked", ->
lineNumber = component.lineNumberNodeForScreenRow(1)
lineNumber.dispatchEvent(buildClickEvent(lineNumber))
- runSetImmediateCallbacks()
+ expect(hasSetImmediateCallbacks()).toBe false
expect(lineNumberHasClass(1, 'folded')).toBe false
describe "cursor rendering", ->
@@ -1404,7 +1417,6 @@ describe "EditorComponent", ->
beforeEach ->
cursor = editor.getCursor()
cursor.setScreenPosition([0, 0])
- runSetImmediateCallbacks()
it "adds the 'has-selection' class to the editor when there is a selection", ->
expect(componentNode.classList.contains('has-selection')).toBe false
@@ -1565,7 +1577,8 @@ describe "EditorComponent", ->
component.measureHeightAndWidth()
runSetImmediateCallbacks()
- expect(horizontalScrollbarNode.scrollWidth).toBe gutterNode.offsetWidth + editor.getScrollWidth()
+ expect(horizontalScrollbarNode.scrollWidth).toBe editor.getScrollWidth()
+ expect(horizontalScrollbarNode.style.left).toBe '0px'
describe "mousewheel events", ->
beforeEach ->
@@ -1651,7 +1664,7 @@ describe "EditorComponent", ->
wheelEvent = new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: 10)
Object.defineProperty(wheelEvent, 'target', get: -> lineNode)
componentNode.dispatchEvent(wheelEvent)
- runSetImmediateCallbacks()
+ expect(hasSetImmediateCallbacks()).toBe false
expect(editor.getScrollTop()).toBe 0
@@ -1668,7 +1681,7 @@ describe "EditorComponent", ->
wheelEvent = new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: 100) # goes nowhere, we're already at scrollTop 0
Object.defineProperty(wheelEvent, 'target', get: -> lineNode)
componentNode.dispatchEvent(wheelEvent)
- runSetImmediateCallbacks()
+ expect(hasSetImmediateCallbacks()).toBe false
expect(component.mouseWheelScreenRow).toBe 0
editor.insertText("hello")
@@ -1766,7 +1779,7 @@ describe "EditorComponent", ->
it "does not handle input events when input is disabled", ->
component.setInputEnabled(false)
componentNode.dispatchEvent(buildTextInputEvent(data: 'x', target: inputNode))
- runSetImmediateCallbacks()
+ expect(hasSetImmediateCallbacks()).toBe false
expect(editor.lineForBufferRow(0)).toBe 'var quicksort = function () {'
describe "when IME composition is used to insert international characters", ->
@@ -1884,7 +1897,6 @@ describe "EditorComponent", ->
hiddenParent.style.display = 'block'
advanceClock(component.domPollingInterval)
- runSetImmediateCallbacks()
expect(componentNode.querySelectorAll('.line').length).toBeGreaterThan 0
@@ -1894,7 +1906,6 @@ describe "EditorComponent", ->
initialLineHeightInPixels = editor.getLineHeightInPixels()
component.setLineHeight(2)
- runSetImmediateCallbacks()
expect(editor.getLineHeightInPixels()).toBe initialLineHeightInPixels
wrapperView.show()
@@ -1907,7 +1918,6 @@ describe "EditorComponent", ->
initialCharWidth = editor.getDefaultCharWidth()
component.setFontSize(22)
- runSetImmediateCallbacks()
expect(editor.getLineHeightInPixels()).toBe initialLineHeightInPixels
expect(editor.getDefaultCharWidth()).toBe initialCharWidth
@@ -1919,7 +1929,6 @@ describe "EditorComponent", ->
wrapperView.hide()
component.setFontSize(22)
- runSetImmediateCallbacks()
wrapperView.show()
editor.setCursorBufferPosition([0, Infinity])
@@ -1936,7 +1945,6 @@ describe "EditorComponent", ->
initialCharWidth = editor.getDefaultCharWidth()
component.setFontFamily('sans-serif')
- runSetImmediateCallbacks()
expect(editor.getDefaultCharWidth()).toBe initialCharWidth
wrapperView.show()
@@ -1946,7 +1954,6 @@ describe "EditorComponent", ->
wrapperView.hide()
component.setFontFamily('sans-serif')
- runSetImmediateCallbacks()
wrapperView.show()
editor.setCursorBufferPosition([0, Infinity])
diff --git a/spec/fixtures/binary-file.png b/spec/fixtures/binary-file.png
deleted file mode 100644
index b4d6eb7c3..000000000
Binary files a/spec/fixtures/binary-file.png and /dev/null differ
diff --git a/spec/fixtures/js b/spec/fixtures/js
deleted file mode 100644
index 2d7276030..000000000
--- a/spec/fixtures/js
+++ /dev/null
@@ -1 +0,0 @@
-this tests files with no extensions
diff --git a/spec/fixtures/packages/package-with-infinite-loop-grammar/grammars/grammar.cson b/spec/fixtures/packages/package-with-infinite-loop-grammar/grammars/grammar.cson
deleted file mode 100644
index 8ac183c23..000000000
--- a/spec/fixtures/packages/package-with-infinite-loop-grammar/grammars/grammar.cson
+++ /dev/null
@@ -1,18 +0,0 @@
-'fileTypes': ['package-with-infinite-loop-grammar']
-'name': 'package-with-infinite-loop-grammar'
-'scopeName': 'source.package-with-infinite-loop-grammar'
-
-# This grammar should loop forever if the line contains an `a`
-'patterns': [
- {
- 'name': 'start'
- 'begin': '^'
- 'end': '$'
- 'patterns': [
- {
- name: 'negative-look-ahead'
- match: "(?!a)"
- }
- ]
- }
-]
diff --git a/spec/fixtures/packages/package-with-snippets/snippets/.hidden-file b/spec/fixtures/packages/package-with-snippets/snippets/.hidden-file
deleted file mode 100644
index 7aa86d685..000000000
--- a/spec/fixtures/packages/package-with-snippets/snippets/.hidden-file
+++ /dev/null
@@ -1 +0,0 @@
-This is a hidden file. Don't even try to load it as a snippet
diff --git a/spec/fixtures/packages/package-with-snippets/snippets/junk-file b/spec/fixtures/packages/package-with-snippets/snippets/junk-file
deleted file mode 100644
index 5549cb956..000000000
--- a/spec/fixtures/packages/package-with-snippets/snippets/junk-file
+++ /dev/null
@@ -1 +0,0 @@
-This file isn't CSON, but shouldn't be a big deal
\ No newline at end of file
diff --git a/spec/fixtures/packages/package-with-snippets/snippets/test.cson b/spec/fixtures/packages/package-with-snippets/snippets/test.cson
deleted file mode 100644
index b936fea16..000000000
--- a/spec/fixtures/packages/package-with-snippets/snippets/test.cson
+++ /dev/null
@@ -1,4 +0,0 @@
-".test":
- "Test Snippet":
- prefix: "test"
- body: "testing 123"
diff --git a/spec/fixtures/packages/theme-with-multiple-imported-files/index.less b/spec/fixtures/packages/theme-with-multiple-imported-files/index.less
deleted file mode 100644
index 3cc8a95ae..000000000
--- a/spec/fixtures/packages/theme-with-multiple-imported-files/index.less
+++ /dev/null
@@ -1,3 +0,0 @@
-@import "stylesheets/first";
-@import "stylesheets/second";
-@import "stylesheets/last";
diff --git a/spec/fixtures/packages/theme-with-multiple-imported-files/package.json b/spec/fixtures/packages/theme-with-multiple-imported-files/package.json
deleted file mode 100644
index 16e770b05..000000000
--- a/spec/fixtures/packages/theme-with-multiple-imported-files/package.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "theme": "ui"
-}
diff --git a/spec/fixtures/packages/theme-with-multiple-imported-files/stylesheets/first.less b/spec/fixtures/packages/theme-with-multiple-imported-files/stylesheets/first.less
deleted file mode 100644
index f9af1a345..000000000
--- a/spec/fixtures/packages/theme-with-multiple-imported-files/stylesheets/first.less
+++ /dev/null
@@ -1,7 +0,0 @@
-.editor {
- padding-top: 101px;
- padding-right: 101px;
- padding-bottom: 101px;
-
- color: red;
-}
\ No newline at end of file
diff --git a/spec/fixtures/packages/theme-with-multiple-imported-files/stylesheets/last.less b/spec/fixtures/packages/theme-with-multiple-imported-files/stylesheets/last.less
deleted file mode 100644
index c0cface8c..000000000
--- a/spec/fixtures/packages/theme-with-multiple-imported-files/stylesheets/last.less
+++ /dev/null
@@ -1,5 +0,0 @@
-.editor {
-/* padding-top: 103px;
- padding-right: 103px;*/
- padding-bottom: 103px;
-}
\ No newline at end of file
diff --git a/spec/fixtures/packages/theme-with-multiple-imported-files/stylesheets/second.less b/spec/fixtures/packages/theme-with-multiple-imported-files/stylesheets/second.less
deleted file mode 100644
index a14760b4f..000000000
--- a/spec/fixtures/packages/theme-with-multiple-imported-files/stylesheets/second.less
+++ /dev/null
@@ -1,9 +0,0 @@
-@import "ui-variables";
-
-@number: 102px;
-
-.editor {
-/* padding-top: 102px;*/
- padding-right: @number;
- padding-bottom: @number;
-}
diff --git a/spec/fixtures/packages/theme-with-multiple-imported-files/stylesheets/ui-variables.less b/spec/fixtures/packages/theme-with-multiple-imported-files/stylesheets/ui-variables.less
deleted file mode 100644
index 9cefd6823..000000000
--- a/spec/fixtures/packages/theme-with-multiple-imported-files/stylesheets/ui-variables.less
+++ /dev/null
@@ -1,75 +0,0 @@
-// Variables different from the original are marked 'Changed'
-
-@text-color: #333;
-@text-color-subtle: #777;
-@text-color-highlight: #111;
-@text-color-selected: @text-color-highlight;
-
-@text-color-info: #5293d8;
-@text-color-success: #1fe977;
-@text-color-warning: #f78a46;
-@text-color-error: #c00;
-
-@background-color-info: #0098ff;
-@background-color-success: #17ca65;
-@background-color-warning: #ff4800;
-@background-color-error: #c00;
-@background-color-highlight: rgba(255, 255, 255, 0.10);
-@background-color-selected: @background-color-highlight;
-
-@app-background-color: #00f; // Changed
-
-@base-background-color: #fff;
-@base-border-color: #eee;
-
-@pane-item-background-color: @base-background-color;
-@pane-item-border-color: @base-border-color;
-
-@input-background-color: #f00; // Changed
-@input-border-color: @base-border-color;
-
-@tool-panel-background-color: #f4f4f4;
-@tool-panel-border-color: @base-border-color;
-
-@inset-panel-background-color: #eee;
-@inset-panel-border-color: @base-border-color;
-
-@panel-heading-background-color: #ddd;
-@panel-heading-border-color: transparent;
-
-@overlay-background-color: #f4f4f4;
-@overlay-border-color: @base-border-color;
-
-@button-background-color: #ccc;
-@button-background-color-hover: lighten(@button-background-color, 5%);
-@button-background-color-selected: @button-background-color-hover;
-@button-border-color: #aaa;
-
-@tab-bar-background-color: #fff;
-@tab-bar-border-color: darken(@tab-background-color-active, 10%);
-@tab-background-color: #f4f4f4;
-@tab-background-color-active: #fff;
-@tab-border-color: @base-border-color;
-
-@tree-view-background-color: @tool-panel-background-color;
-@tree-view-border-color: @tool-panel-border-color;
-
-@ui-site-color-1: @background-color-success; // green
-@ui-site-color-2: @background-color-info; // blue
-@ui-site-color-3: @background-color-warning; // orange
-@ui-site-color-4: #db2ff4; // purple
-@ui-site-color-5: #f5e11d; // yellow
-
-@font-size: 12px;
-
-@disclosure-arrow-size: 12px;
-
-@component-padding: 150px;
-@component-icon-padding: 5px;
-@component-icon-size: 16px;
-@component-line-height: 25px;
-@component-border-radius: 2px;
-
-@tab-height: 30px;
-
-@font-family: Arial;
diff --git a/spec/fixtures/replication/home-1/project/file-1.txt b/spec/fixtures/replication/home-1/project/file-1.txt
deleted file mode 100644
index 980a0d5f1..000000000
--- a/spec/fixtures/replication/home-1/project/file-1.txt
+++ /dev/null
@@ -1 +0,0 @@
-Hello World!
diff --git a/spec/fixtures/replication/home-1/project/file-2.txt b/spec/fixtures/replication/home-1/project/file-2.txt
deleted file mode 100644
index 1ce3f8113..000000000
--- a/spec/fixtures/replication/home-1/project/file-2.txt
+++ /dev/null
@@ -1 +0,0 @@
-Goodbye World!
diff --git a/spec/fixtures/replication/home-2/project/file-1.txt b/spec/fixtures/replication/home-2/project/file-1.txt
deleted file mode 100644
index 980a0d5f1..000000000
--- a/spec/fixtures/replication/home-2/project/file-1.txt
+++ /dev/null
@@ -1 +0,0 @@
-Hello World!
diff --git a/spec/fixtures/replication/home-2/project/file-2.txt b/spec/fixtures/replication/home-2/project/file-2.txt
deleted file mode 100644
index 1ce3f8113..000000000
--- a/spec/fixtures/replication/home-2/project/file-2.txt
+++ /dev/null
@@ -1 +0,0 @@
-Goodbye World!
diff --git a/spec/fixtures/sample-with-error.less b/spec/fixtures/sample-with-error.less
deleted file mode 100644
index 4396e25cf..000000000
--- a/spec/fixtures/sample-with-error.less
+++ /dev/null
@@ -1 +0,0 @@
-#header {
\ No newline at end of file
diff --git a/spec/fixtures/sample.plist b/spec/fixtures/sample.plist
deleted file mode 100644
index e5556c132..000000000
--- a/spec/fixtures/sample.plist
+++ /dev/null
@@ -1,71 +0,0 @@
-
-
-
-
- fileTypes
-
- txt
-
- keyEquivalent
- ^~P
- name
- Plain Text
- patterns
-
-
- captures
-
- 1
-
- name
- punctuation.definition.item.text
-
-
- match
- ^\s*(•).*$\n?
- name
- meta.bullet-point.strong.text
-
-
- captures
-
- 1
-
- name
- punctuation.definition.item.text
-
-
- match
- ^\s*(·).*$\n?
- name
- meta.bullet-point.light.text
-
-
- captures
-
- 1
-
- name
- punctuation.definition.item.text
-
-
- match
- ^\s*(\*).*$\n?
- name
- meta.bullet-point.star.text
-
-
- begin
- ^([ \t]*)(?=\S)
- contentName
- meta.paragraph.text
- end
- ^(?!\1(?=\S))
-
-
- scopeName
- text.plain
- uuid
- 3130E4FA-B10E-11D9-9F75-000D93589AF6
-
-
diff --git a/spec/fixtures/symlink-to-dir b/spec/fixtures/symlink-to-dir
deleted file mode 120000
index 872451932..000000000
--- a/spec/fixtures/symlink-to-dir
+++ /dev/null
@@ -1 +0,0 @@
-dir
\ No newline at end of file
diff --git a/spec/fixtures/symlink-to-file b/spec/fixtures/symlink-to-file
deleted file mode 120000
index cdd38b0e4..000000000
--- a/spec/fixtures/symlink-to-file
+++ /dev/null
@@ -1 +0,0 @@
-sample.js
\ No newline at end of file
diff --git a/spec/fixtures/zed/a b/spec/fixtures/zed/a
deleted file mode 100644
index 789819226..000000000
--- a/spec/fixtures/zed/a
+++ /dev/null
@@ -1 +0,0 @@
-a
diff --git a/src/editor-component.coffee b/src/editor-component.coffee
index 120616249..29029756e 100644
--- a/src/editor-component.coffee
+++ b/src/editor-component.coffee
@@ -34,7 +34,6 @@ EditorComponent = React.createClass
selectionChanged: false
selectionAdded: false
scrollingVertically: false
- gutterWidth: 0
refreshingScrollbars: false
measuringScrollbars: true
mouseWheelScreenRow: null
@@ -94,8 +93,8 @@ EditorComponent = React.createClass
div {className, style, tabIndex: -1},
if not mini and showLineNumbers
GutterComponent {
- ref: 'gutter', onMouseDown: @onGutterMouseDown, onWidthChanged: @onGutterWidthChanged,
- lineDecorations, defaultCharWidth, editor, renderedRowRange, maxLineNumberDigits, scrollViewHeight,
+ ref: 'gutter', onMouseDown: @onGutterMouseDown, lineDecorations,
+ defaultCharWidth, editor, renderedRowRange, maxLineNumberDigits, scrollViewHeight,
scrollTop, scrollHeight, lineHeightInPixels, @pendingChanges, mouseWheelScreenRow, @useHardwareAcceleration
}
@@ -121,6 +120,18 @@ EditorComponent = React.createClass
placeholderText, @performedInitialMeasurement
}
+ ScrollbarComponent
+ ref: 'horizontalScrollbar'
+ className: 'horizontal-scrollbar'
+ orientation: 'horizontal'
+ onScroll: @onHorizontalScroll
+ scrollLeft: scrollLeft
+ scrollWidth: scrollWidth
+ visible: horizontallyScrollable and not @refreshingScrollbars and not @measuringScrollbars
+ scrollableInOppositeDirection: verticallyScrollable
+ verticalScrollbarWidth: verticalScrollbarWidth
+ horizontalScrollbarHeight: horizontalScrollbarHeight
+
ScrollbarComponent
ref: 'verticalScrollbar'
className: 'vertical-scrollbar'
@@ -133,18 +144,6 @@ EditorComponent = React.createClass
verticalScrollbarWidth: verticalScrollbarWidth
horizontalScrollbarHeight: horizontalScrollbarHeight
- ScrollbarComponent
- ref: 'horizontalScrollbar'
- className: 'horizontal-scrollbar'
- orientation: 'horizontal'
- onScroll: @onHorizontalScroll
- scrollLeft: scrollLeft
- scrollWidth: scrollWidth + @gutterWidth
- visible: horizontallyScrollable and not @refreshingScrollbars and not @measuringScrollbars
- scrollableInOppositeDirection: verticallyScrollable
- verticalScrollbarWidth: verticalScrollbarWidth
- horizontalScrollbarHeight: horizontalScrollbarHeight
-
# Also used to measure the height/width of scrollbars after the initial render
ScrollbarCornerComponent
ref: 'scrollbarCorner'
@@ -834,9 +833,6 @@ EditorComponent = React.createClass
remeasureCharacterWidths: ->
@refs.lines.remeasureCharacterWidths()
- onGutterWidthChanged: (@gutterWidth) ->
- @requestUpdate()
-
measureScrollbars: ->
return unless @visible
@measuringScrollbars = false
diff --git a/src/editor.coffee b/src/editor.coffee
index 870c14b6c..4531d4dce 100644
--- a/src/editor.coffee
+++ b/src/editor.coffee
@@ -1067,9 +1067,11 @@ class Editor extends Model
# All the changes made inside the given {Function} can be reverted with a
# single call to {::undo}.
#
- # fn - A {Function} that will be called with each {Selection}.
+ # fn - A {Function} that will be called once for each {Selection}. The first
+ # argument will be a {Selection} and the second argument will be the
+ # {Number} index of that selection.
mutateSelectedText: (fn) ->
- @transact => fn(selection,index) for selection,index in @getSelections()
+ @transact => fn(selection, index) for selection, index in @getSelections()
replaceSelectedText: (options={}, fn) ->
{selectWordIfEmpty} = options
diff --git a/src/gutter-component.coffee b/src/gutter-component.coffee
index ae2e9f9f2..01106fa4c 100644
--- a/src/gutter-component.coffee
+++ b/src/gutter-component.coffee
@@ -63,9 +63,6 @@ GutterComponent = React.createClass
@updateDummyLineNumber()
@removeLineNumberNodes()
- unless isEqualForProperties(oldProps, @props, 'maxLineNumberDigits', 'defaultCharWidth')
- @measureWidth()
-
@clearScreenRowCaches() unless oldProps.lineHeightInPixels is @props.lineHeightInPixels
@updateLineNumbers()
@@ -223,9 +220,3 @@ GutterComponent = React.createClass
editor.unfoldBufferRow(bufferRow)
else
editor.foldBufferRow(bufferRow)
-
- measureWidth: ->
- width = @getDOMNode().offsetWidth
- unless width is @measuredWidth
- @measuredWidth = width
- @props.onWidthChanged?(width)
diff --git a/src/lines-component.coffee b/src/lines-component.coffee
index d1b1aba94..755e49429 100644
--- a/src/lines-component.coffee
+++ b/src/lines-component.coffee
@@ -181,7 +181,7 @@ LinesComponent = React.createClass
lineHTML
else
- ' ' + @buildEndOfLineHTML(line, @props.invisibles)
+ @buildEndOfLineHTML(line, @props.invisibles) or ' '
buildLineInnerHTML: (line) ->
{invisibles, mini, showIndentGuide, invisibles} = @props
@@ -204,9 +204,11 @@ LinesComponent = React.createClass
return '' if @props.mini or line.isSoftWrapped()
html = ''
- if invisibles.cr? and line.lineEnding is '\r\n'
+ # Note the lack of '?' in the character checks. A user can set the chars
+ # to an empty string which we will interpret as not-set
+ if invisibles.cr and line.lineEnding is '\r\n'
html += "#{invisibles.cr}"
- if invisibles.eol?
+ if invisibles.eol
html += "#{invisibles.eol}"
html
diff --git a/src/scrollbar-component.coffee b/src/scrollbar-component.coffee
index 88f1beec3..b8657b594 100644
--- a/src/scrollbar-component.coffee
+++ b/src/scrollbar-component.coffee
@@ -17,8 +17,9 @@ ScrollbarComponent = React.createClass
style.width = verticalScrollbarWidth
style.bottom = horizontalScrollbarHeight if scrollableInOppositeDirection
when 'horizontal'
- style.height = horizontalScrollbarHeight
+ style.left = 0
style.right = verticalScrollbarWidth if scrollableInOppositeDirection
+ style.height = horizontalScrollbarHeight
div {className, style, @onScroll},
switch orientation