diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index 831f18a15..7833ac0ac 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -210,7 +210,7 @@ module.exports = (grunt) -> grunt.registerTask('compile', ['coffee', 'prebuild-less', 'cson']) grunt.registerTask('lint', ['coffeelint', 'csslint', 'lesslint']) grunt.registerTask('test', ['shell:kill-atom', 'run-specs']) - grunt.registerTask('ci', ['download-atom-shell', 'build', 'set-development-version', 'lint', 'test', 'publish-build']) + grunt.registerTask('ci', ['output-disk-space', 'download-atom-shell', 'build', 'set-development-version', 'lint', 'test', 'publish-build']) grunt.registerTask('deploy', ['partial-clean', 'download-atom-shell', 'build', 'codesign']) grunt.registerTask('docs', ['markdown:guides', 'build-docs']) grunt.registerTask('default', ['download-atom-shell', 'build', 'set-development-version', 'install']) diff --git a/build/tasks/output-disk-space.coffee b/build/tasks/output-disk-space.coffee new file mode 100644 index 000000000..372ead672 --- /dev/null +++ b/build/tasks/output-disk-space.coffee @@ -0,0 +1,25 @@ +module.exports = (grunt) -> + {spawn} = require('./task-helpers')(grunt) + + grunt.registerTask 'output-disk-space', 'Print diskspace available', -> + return unless process.platform is 'darwin' + + done = @async() + + cmd = 'df' + args = ['-Hl'] + spawn {cmd, args}, (error, result, code) -> + return done(error) if error? + + lines = result.stdout.split("\n") + + for line in lines[1..] + [filesystem, size, used, avail, capacity, extra] = line.split(/\s+/) + capacity = parseInt(capacity) + + if capacity > 90 + grunt.log.error("#{filesystem} is at #{capacity}% capacity!") + else if capacity > 80 + grunt.log.ok("#{filesystem} is at #{capacity}% capacity.") + + done() diff --git a/build/tasks/task-helpers.coffee b/build/tasks/task-helpers.coffee index 4362393d0..f83430884 100644 --- a/build/tasks/task-helpers.coffee +++ b/build/tasks/task-helpers.coffee @@ -39,7 +39,7 @@ module.exports = (grunt) -> proc = childProcess.spawn(options.cmd, options.args, options.opts) proc.stdout.on 'data', (data) -> stdout.push(data.toString()) proc.stderr.on 'data', (data) -> stderr.push(data.toString()) - proc.on 'exit', (exitCode, signal) -> + proc.on 'close', (exitCode, signal) -> error = new Error(signal) if exitCode != 0 results = {stderr: stderr.join(''), stdout: stdout.join(''), code: exitCode} grunt.log.error results.stderr if exitCode != 0 diff --git a/keymaps/darwin.cson b/keymaps/darwin.cson index adf8bb64b..facd6cc8e 100644 --- a/keymaps/darwin.cson +++ b/keymaps/darwin.cson @@ -111,6 +111,7 @@ 'cmd-alt-p': 'editor:log-cursor-scope' 'cmd-k cmd-u': 'editor:upper-case' 'cmd-k cmd-l': 'editor:lower-case' + 'cmd-l': 'editor:select-line' 'body.platform-darwin .editor:not(.mini)': # Atom specific @@ -129,6 +130,7 @@ 'cmd-/': 'editor:toggle-line-comments' 'cmd-j': 'editor:join-line' 'cmd-D': 'editor:duplicate-line' + 'cmd-L': 'editor:split-selections-into-lines' 'cmd-alt-[': 'editor:fold-current-row' 'cmd-alt-]': 'editor:unfold-current-row' diff --git a/menus/darwin.cson b/menus/darwin.cson index 8cd314c1e..8d7c8b754 100644 --- a/menus/darwin.cson +++ b/menus/darwin.cson @@ -99,6 +99,7 @@ submenu: [ { label: 'Add Selection Above', command: 'editor:add-selection-above' } { label: 'Add Selection Below', command: 'editor:add-selection-below' } + { label: 'Split into Lines', command: 'editor:split-selections-into-lines'} { type: 'separator' } { label: 'Select to Top', command: 'core:select-to-top' } { label: 'Select to Bottom', command: 'core:select-to-bottom' } diff --git a/menus/win32.cson b/menus/win32.cson index e4017fc42..339da35a5 100644 --- a/menus/win32.cson +++ b/menus/win32.cson @@ -106,6 +106,7 @@ submenu: [ { label: 'Add Selection &Above', command: 'editor:add-selection-above' } { label: 'Add Selection &Below', command: 'editor:add-selection-below' } + { label: 'S&plit into Lines', command: 'editor:split-selections-into-lines'} { type: 'separator' } { label: 'Select to &Top', command: 'core:select-to-top' } { label: 'Select to Botto&m', command: 'core:select-to-bottom' } diff --git a/package.json b/package.json index f440ad28a..d3b8ef04e 100644 --- a/package.json +++ b/package.json @@ -24,10 +24,10 @@ "coffee-script": "1.6.3", "coffeestack": "0.6.0", "emissary": "0.19.0", - "first-mate": "0.11.0", + "first-mate": "0.14.0", "fs-plus": "0.14.0", "fstream": "0.1.24", - "fuzzaldrin": "0.1.0", + "fuzzaldrin": "0.5.0", "git-utils": "0.29.0", "guid": "0.0.10", "jasmine-focused": "~0.15.0", @@ -73,22 +73,22 @@ "command-palette": "0.14.0", "dev-live-reload": "0.22.0", "editor-stats": "0.12.0", - "exception-reporting": "0.9.0", + "exception-reporting": "0.10.0", "feedback": "0.22.0", - "find-and-replace": "0.68.0", - "fuzzy-finder": "0.28.0", + "find-and-replace": "0.70.0", + "fuzzy-finder": "0.30.0", "gists": "0.13.0", "git-diff": "0.21.0", "github-sign-in": "0.15.0", - "go-to-line": "0.12.0", - "grammar-selector": "0.15.0", + "go-to-line": "0.14.0", + "grammar-selector": "0.16.0", "image-view": "0.14.0", "keybinding-resolver": "0.8.0", - "markdown-preview": "0.22.0", + "markdown-preview": "0.23.0", "metrics": "0.20.0", "package-generator": "0.23.0", "release-notes": "0.15.0", - "settings-view": "0.54.0", + "settings-view": "0.55.0", "snippets": "0.17.0", "spell-check": "0.18.0", "status-bar": "0.30.0", @@ -97,7 +97,7 @@ "tabs": "0.16.0", "terminal": "0.23.0", "timecop": "0.12.0", - "to-the-hubs": "0.16.0", + "to-the-hubs": "0.17.0", "tree-view": "0.58.0", "visual-bell": "0.6.0", "welcome": "0.4.0", diff --git a/spec/editor-spec.coffee b/spec/editor-spec.coffee index 821c9becb..96bca8bf3 100644 --- a/spec/editor-spec.coffee +++ b/spec/editor-spec.coffee @@ -819,6 +819,11 @@ describe "Editor", -> editor.selectLine() expect(editor.getSelectedBufferRange()).toEqual [[12,0], [12,2]] + editor.setCursorBufferPosition([0, 2]) + editor.selectLine() + editor.selectLine() + expect(editor.getSelectedBufferRange()).toEqual [[0,0], [2,0]] + describe ".selectToBeginningOfWord()", -> it "selects text from cusor position to beginning of word", -> editor.setCursorScreenPosition [0,13] @@ -1181,6 +1186,27 @@ describe "Editor", -> [[10, 0], [10, 0]] ] + describe ".splitSelectionsIntoLines()", -> + it "splits all multi-line selections into one selection per line", -> + editor.setSelectedBufferRange([[0, 3], [2, 4]]) + editor.splitSelectionsIntoLines() + expect(editor.getSelectedBufferRanges()).toEqual [ + [[0, 3], [0, 29]] + [[1, 0], [1, 30]] + [[2, 0], [2, 4]] + ] + + editor.setSelectedBufferRange([[0, 3], [1, 10]]) + editor.splitSelectionsIntoLines() + expect(editor.getSelectedBufferRanges()).toEqual [ + [[0, 3], [0, 29]] + [[1, 0], [1, 10]] + ] + + editor.setSelectedBufferRange([[0, 0], [0, 3]]) + editor.splitSelectionsIntoLines() + expect(editor.getSelectedBufferRanges()).toEqual [[[0, 0], [0, 3]]] + describe ".consolidateSelections()", -> it "destroys all selections but the most recent, returning true if any selections were destroyed", -> editor.setSelectedBufferRange([[3, 16], [3, 21]]) diff --git a/src/atom-package.coffee b/src/atom-package.coffee index aa62359e9..6546945bb 100644 --- a/src/atom-package.coffee +++ b/src/atom-package.coffee @@ -52,12 +52,6 @@ class AtomPackage extends Package console.warn "Failed to load package named '#{@name}'", e.stack ? e this - enable: -> - atom.config.removeAtKeyPath('core.disabledPackages', @metadata.name) - - disable: -> - atom.config.pushAtKeyPath('core.disabledPackages', @metadata.name) - reset: -> @stylesheets = [] @keymaps = [] diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 3e9aacc18..fa18a59c1 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -52,6 +52,8 @@ class AtomApplication resourcePath: null version: null + exit: (status) -> app.exit(status) + constructor: (options) -> {@resourcePath, @version, @devMode} = options global.atomApplication = this diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 9a15c251b..0f09bfaa4 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -18,7 +18,7 @@ class AtomWindow isSpec: null constructor: (settings={}) -> - {@resourcePath, pathToOpen, initialLine, @isSpec} = settings + {@resourcePath, pathToOpen, initialLine, @isSpec, @exitWhenDone} = settings global.atomApplication.addWindow(this) @setupNodePath(@resourcePath) @@ -82,7 +82,7 @@ class AtomWindow @browserWindow.destroy() if chosen is 0 @browserWindow.on 'crashed', => - atom.exit(100) if @isSpec + global.atomApplication.exit(100) if @exitWhenDone chosen = dialog.showMessageBox @browserWindow, type: 'warning' diff --git a/src/directory.coffee b/src/directory.coffee index 8a17435b6..1719e93cb 100644 --- a/src/directory.coffee +++ b/src/directory.coffee @@ -73,11 +73,11 @@ class Directory if fullPath is @getPath() '' - else if fullPath.indexOf(path.join(@getPath(), path.sep)) is 0 + else if @isPathPrefixOf(@getPath(), fullPath) fullPath.substring(@getPath().length + 1) else if fullPath is @getRealPathSync() '' - else if fullPath.indexOf(path.join(@getRealPathSync(), path.sep)) is 0 + else if @isPathPrefixOf(@getRealPathSync(), fullPath) fullPath.substring(@getRealPathSync().length + 1) else fullPath @@ -139,3 +139,7 @@ class Directory if @watchSubscription? @watchSubscription.close() @watchSubscription = null + + # Private: Does given full path start with the given prefix? + isPathPrefixOf: (prefix, fullPath) -> + fullPath.indexOf(prefix) is 0 and fullPath[prefix.length] is path.sep diff --git a/src/display-buffer-marker.coffee b/src/display-buffer-marker.coffee index 1bbd6633e..8c08b3c9e 100644 --- a/src/display-buffer-marker.coffee +++ b/src/display-buffer-marker.coffee @@ -168,7 +168,7 @@ class DisplayBufferMarker # Returns a {String} representation of the marker inspect: -> - "DisplayBufferMarker(id: #{@id}, bufferRange: #{@getBufferRange().inspect()})" + "DisplayBufferMarker(id: #{@id}, bufferRange: #{@getBufferRange()})" ### Internal ### diff --git a/src/editor-view.coffee b/src/editor-view.coffee index 9c51a5554..eb8d2cfbc 100644 --- a/src/editor-view.coffee +++ b/src/editor-view.coffee @@ -183,6 +183,7 @@ class EditorView extends View 'editor:newline-above': @insertNewlineAbove 'editor:add-selection-below': @addSelectionBelow 'editor:add-selection-above': @addSelectionAbove + 'editor:split-selections-into-lines': => @editor.splitSelectionsIntoLines() 'editor:toggle-soft-tabs': @toggleSoftTabs 'editor:toggle-soft-wrap': @toggleSoftWrap 'editor:fold-all': @foldAll diff --git a/src/editor.coffee b/src/editor.coffee index c144aa10d..291024c7b 100644 --- a/src/editor.coffee +++ b/src/editor.coffee @@ -1191,6 +1191,23 @@ class Editor extends Model addSelectionAbove: -> @expandSelectionsBackward (selection) => selection.addSelectionAbove() + # Public: Split any multi-line selections into one selection per line. + # + # This methods break apart all multi-line selections to create multiple + # single-line selections that cumulatively cover the same original area. + splitSelectionsIntoLines: -> + for selection in @getSelections() + range = selection.getBufferRange() + continue if range.isSingleLine() + + selection.destroy() + {start, end} = range + @addSelectionForBufferRange([start, [start.row, Infinity]]) + {row} = start + while ++row < end.row + @addSelectionForBufferRange([[row, 0], [row, Infinity]]) + @addSelectionForBufferRange([[end.row, 0], [end.row, end.column]]) + # Public: Transposes the current text selections. # # The text in each selection is reversed so `abcd` would become `dcba`. The diff --git a/src/package.coffee b/src/package.coffee index 4d8112466..f7dac9ffe 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -47,6 +47,12 @@ class Package isActive: -> atom.packages.isPackageActive(@name) + enable: -> + atom.config.removeAtKeyPath('core.disabledPackages', @metadata.name) + + disable: -> + atom.config.pushAtKeyPath('core.disabledPackages', @metadata.name) + isTheme: -> !!@metadata?.theme diff --git a/src/pane-container.coffee b/src/pane-container.coffee index 0ce46ed38..7602057b6 100644 --- a/src/pane-container.coffee +++ b/src/pane-container.coffee @@ -39,7 +39,7 @@ class PaneContainer extends View ### Public ### itemDestroyed: (item) -> - @trigger 'item-destroyed', item + @trigger 'item-destroyed', [item] getRoot: -> @children().first().view() diff --git a/src/project.coffee b/src/project.coffee index 7a32a933e..333f5c7bc 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -300,7 +300,7 @@ class Project extends Model promise = deferred.promise promise.cancel = -> task.terminate() - deferred.reject('cancelled') + deferred.resolve('cancelled') promise # Public: Performs a replace across all the specified files in the project. diff --git a/src/selection.coffee b/src/selection.coffee index fa5078b67..915f3fb0b 100644 --- a/src/selection.coffee +++ b/src/selection.coffee @@ -132,7 +132,7 @@ class Selection # The line Number to select (default: the row of the cursor) selectLine: (row=@cursor.getBufferPosition().row) -> range = @editor.bufferRangeForBufferRow(row, includeNewline: true) - @setBufferRange(range) + @setBufferRange(@getBufferRange().union(range)) @linewise = true @wordwise = false @initialScreenRange = @getScreenRange()