From 2cda2b9fe25dc0d5494087de755ab85cde520ae3 Mon Sep 17 00:00:00 2001 From: Mutwin Kraus Date: Wed, 3 Apr 2013 16:32:30 +0200 Subject: [PATCH 01/15] Move cursor to beginning of next word --- src/app/editor.coffee | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index a9583b713..53f58e5e8 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -118,10 +118,12 @@ class Editor extends View 'editor:move-to-first-character-of-line': @moveCursorToFirstCharacterOfLine 'editor:move-to-beginning-of-word': @moveCursorToBeginningOfWord 'editor:move-to-end-of-word': @moveCursorToEndOfWord + 'editor:move-to-beginning-of-next-word': @moveCursorToBeginningOfNextWord 'editor:select-to-end-of-line': @selectToEndOfLine 'editor:select-to-beginning-of-line': @selectToBeginningOfLine 'editor:select-to-end-of-word': @selectToEndOfWord 'editor:select-to-beginning-of-word': @selectToBeginningOfWord + 'editor:select-to-beginning-of-next-word': @selectToBeginningOfNextWord 'editor:select-line': @selectLine 'editor:transpose': @transpose 'editor:upper-case': @upperCase @@ -174,6 +176,7 @@ class Editor extends View moveCursorRight: -> @activeEditSession.moveCursorRight() moveCursorToBeginningOfWord: -> @activeEditSession.moveCursorToBeginningOfWord() moveCursorToEndOfWord: -> @activeEditSession.moveCursorToEndOfWord() + moveCursorToBeginningOfNextWord: -> @activeEditSession.moveCursorToEndOfWord(); @activeEditSession.moveCursorRight() moveCursorToTop: -> @activeEditSession.moveCursorToTop() moveCursorToBottom: -> @activeEditSession.moveCursorToBottom() moveCursorToBeginningOfLine: -> @activeEditSession.moveCursorToBeginningOfLine() @@ -211,6 +214,7 @@ class Editor extends View selectToEndOfLine: -> @activeEditSession.selectToEndOfLine() selectToBeginningOfWord: -> @activeEditSession.selectToBeginningOfWord() selectToEndOfWord: -> @activeEditSession.selectToEndOfWord() + selectToBeginningOfNextWord: -> @activeEditSession.selectToEndOfWord(); @activeEditSession.selectRight() selectWord: -> @activeEditSession.selectWord() selectLine: -> @activeEditSession.selectLine() selectToScreenPosition: (position) -> @activeEditSession.selectToScreenPosition(position) From abce3d7f9b0137c7e244674ab3a206c1822a6894 Mon Sep 17 00:00:00 2001 From: Mutwin Kraus Date: Wed, 3 Apr 2013 18:57:01 +0200 Subject: [PATCH 02/15] Add autocomplete:next/previous events --- src/packages/autocomplete/lib/autocomplete-view.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/packages/autocomplete/lib/autocomplete-view.coffee b/src/packages/autocomplete/lib/autocomplete-view.coffee index 2123c442f..48948a4fc 100644 --- a/src/packages/autocomplete/lib/autocomplete-view.coffee +++ b/src/packages/autocomplete/lib/autocomplete-view.coffee @@ -27,6 +27,8 @@ class AutocompleteView extends SelectList handleEvents: -> @editor.on 'editor:path-changed', => @setCurrentBuffer(@editor.getBuffer()) @editor.command 'autocomplete:attach', => @attach() + @editor.command 'autocomplete:next', => @selectNextItem() + @editor.command 'autocomplete:previous', => @selectPreviousItem() @miniEditor.preempt 'textInput', (e) => text = e.originalEvent.data From 460c4a0b09bb5b87acc6448fa23a32462b824f8b Mon Sep 17 00:00:00 2001 From: Mutwin Kraus Date: Wed, 3 Apr 2013 19:03:33 +0200 Subject: [PATCH 03/15] Selection support for bracket matcher --- .../lib/bracket-matcher.coffee | 20 +++++++++++++++++++ .../spec/bracket-matcher-spec.coffee | 11 ++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/packages/bracket-matcher/lib/bracket-matcher.coffee b/src/packages/bracket-matcher/lib/bracket-matcher.coffee index 11398aad2..a08e49e43 100644 --- a/src/packages/bracket-matcher/lib/bracket-matcher.coffee +++ b/src/packages/bracket-matcher/lib/bracket-matcher.coffee @@ -30,6 +30,8 @@ module.exports = editor.on 'cursor:moved.bracket-matcher', => @updateMatch(editor) editor.command 'editor:go-to-matching-bracket.bracket-matcher', => @goToMatchingPair(editor) + editor.command 'editor:select-to-matching-bracket.bracket-matcher', => + @selectToMatchingPair(editor) editor.on 'editor:will-be-removed', => editor.off('.bracket-matcher') editor.startHighlightView = @addHighlightView(editor) editor.endHighlightView = @addHighlightView(editor) @@ -57,6 +59,24 @@ module.exports = else if previousPosition.isEqual(endPosition) editor.setCursorBufferPosition(startPosition) + selectToMatchingPair: (editor) -> + return unless @pairHighlighted + return unless underlayer = editor.getPane()?.find('.underlayer') + + position = editor.getCursorBufferPosition() + previousPosition = position.translate([0, -1]) + startPosition = underlayer.find('.bracket-matcher:first').data('bufferPosition') + endPosition = underlayer.find('.bracket-matcher:last').data('bufferPosition') + + if position.isEqual(startPosition) + editor.selectToScreenPosition(editor.screenPositionForBufferPosition(endPosition.translate([0, 1]))) + else if previousPosition.isEqual(startPosition) + editor.selectToScreenPosition(editor.screenPositionForBufferPosition(endPosition)) + else if position.isEqual(endPosition) + editor.selectToScreenPosition(editor.screenPositionForBufferPosition(startPosition.translate([0, 1]))) + else if previousPosition.isEqual(endPosition) + editor.selectToScreenPosition(editor.screenPositionForBufferPosition(startPosition)) + moveHighlightViews: (editor, bufferRange) -> { start, end } = Range.fromObject(bufferRange) startPixelPosition = editor.pixelPositionForBufferPosition(start) diff --git a/src/packages/bracket-matcher/spec/bracket-matcher-spec.coffee b/src/packages/bracket-matcher/spec/bracket-matcher-spec.coffee index 9a44ba3a7..58c971c6c 100644 --- a/src/packages/bracket-matcher/spec/bracket-matcher-spec.coffee +++ b/src/packages/bracket-matcher/spec/bracket-matcher-spec.coffee @@ -86,6 +86,17 @@ describe "bracket matching", -> editor.trigger "editor:go-to-matching-bracket" expect(editor.getCursorBufferPosition()).toEqual [0, 28] + describe "when editor:select-to-matching-bracket is triggered", -> + it " selects until the next matched bracket", -> + editor.moveCursorToEndOfLine() + editor.moveCursorLeft() + editor.trigger "editor:select-to-matching-bracket" + expect(editor.getCursorBufferPosition()).toEqual [12, 1] + selections = editor.getSelections() + expect(selections.length).toBe(1) + range = selections[0].getBufferRange() + expect(range).toEqual([[0,28], [12,1]]) + describe "matching bracket insertion", -> beforeEach -> editSession.buffer.setText("") From 08783f19e433f5b906e5d0dfed68ab32d5a33309 Mon Sep 17 00:00:00 2001 From: Mutwin Kraus Date: Wed, 3 Apr 2013 19:48:29 +0200 Subject: [PATCH 04/15] Skip save confirmation for pane --- src/app/pane.coffee | 8 ++++---- src/app/text-buffer.coffee | 8 +++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/app/pane.coffee b/src/app/pane.coffee index e9132cc11..683a5db72 100644 --- a/src/app/pane.coffee +++ b/src/app/pane.coffee @@ -135,11 +135,11 @@ class Pane extends View @trigger 'pane:item-added', [item, index] item - destroyActiveItem: => - @destroyItem(@activeItem) + destroyActiveItem: (promptToSave=true) => + @destroyItem(@activeItem, promptToSave) false - destroyItem: (item) -> + destroyItem: (item, promptToSave=true) -> container = @getContainer() reallyDestroyItem = => @removeItem(item) @@ -148,7 +148,7 @@ class Pane extends View @autosaveItem(item) - if item.isModified?() + if promptToSave && item.isModified?() @promptToSaveItem(item, reallyDestroyItem) else reallyDestroyItem() diff --git a/src/app/text-buffer.coffee b/src/app/text-buffer.coffee index 36f93724c..228aa73c5 100644 --- a/src/app/text-buffer.coffee +++ b/src/app/text-buffer.coffee @@ -37,8 +37,9 @@ class Buffer @lineEndings = [] if path - throw "Path '#{path}' does not exist" unless fs.exists(path) - @setPath(path) + # throw "Path '#{path}' does not exist" unless fs.exists(path) + if fs.exists(path) + @setPath(path) if initialText? @setText(initialText) @updateCachedDiskContents() @@ -96,7 +97,8 @@ class Buffer @trigger 'reloaded' updateCachedDiskContents: -> - @cachedDiskContents = @file.read() + if @file? + @cachedDiskContents = @file.read() getBaseName: -> @file?.getBaseName() From 26bcf7718b0aa80f8d7fc06331adcc50375e015d Mon Sep 17 00:00:00 2001 From: Mutwin Kraus Date: Thu, 4 Apr 2013 15:03:35 +0200 Subject: [PATCH 05/15] Revert "Selection support for bracket matcher" This reverts commit 460c4a0b09bb5b87acc6448fa23a32462b824f8b. --- .../lib/bracket-matcher.coffee | 20 ------------------- .../spec/bracket-matcher-spec.coffee | 11 ---------- 2 files changed, 31 deletions(-) diff --git a/src/packages/bracket-matcher/lib/bracket-matcher.coffee b/src/packages/bracket-matcher/lib/bracket-matcher.coffee index 18c4c6f55..4d80300fa 100644 --- a/src/packages/bracket-matcher/lib/bracket-matcher.coffee +++ b/src/packages/bracket-matcher/lib/bracket-matcher.coffee @@ -30,8 +30,6 @@ module.exports = editor.on 'cursor:moved.bracket-matcher', => @updateMatch(editor) editor.command 'editor:go-to-matching-bracket.bracket-matcher', => @goToMatchingPair(editor) - editor.command 'editor:select-to-matching-bracket.bracket-matcher', => - @selectToMatchingPair(editor) editor.on 'editor:will-be-removed', => editor.off('.bracket-matcher') editor.startHighlightView = @addHighlightView(editor) editor.endHighlightView = @addHighlightView(editor) @@ -59,24 +57,6 @@ module.exports = else if previousPosition.isEqual(endPosition) editor.setCursorBufferPosition(startPosition) - selectToMatchingPair: (editor) -> - return unless @pairHighlighted - return unless underlayer = editor.getPane()?.find('.underlayer') - - position = editor.getCursorBufferPosition() - previousPosition = position.translate([0, -1]) - startPosition = underlayer.find('.bracket-matcher:first').data('bufferPosition') - endPosition = underlayer.find('.bracket-matcher:last').data('bufferPosition') - - if position.isEqual(startPosition) - editor.selectToScreenPosition(editor.screenPositionForBufferPosition(endPosition.translate([0, 1]))) - else if previousPosition.isEqual(startPosition) - editor.selectToScreenPosition(editor.screenPositionForBufferPosition(endPosition)) - else if position.isEqual(endPosition) - editor.selectToScreenPosition(editor.screenPositionForBufferPosition(startPosition.translate([0, 1]))) - else if previousPosition.isEqual(endPosition) - editor.selectToScreenPosition(editor.screenPositionForBufferPosition(startPosition)) - moveHighlightViews: (editor, bufferRange) -> { start, end } = Range.fromObject(bufferRange) startPixelPosition = editor.pixelPositionForBufferPosition(start) diff --git a/src/packages/bracket-matcher/spec/bracket-matcher-spec.coffee b/src/packages/bracket-matcher/spec/bracket-matcher-spec.coffee index 58c971c6c..9a44ba3a7 100644 --- a/src/packages/bracket-matcher/spec/bracket-matcher-spec.coffee +++ b/src/packages/bracket-matcher/spec/bracket-matcher-spec.coffee @@ -86,17 +86,6 @@ describe "bracket matching", -> editor.trigger "editor:go-to-matching-bracket" expect(editor.getCursorBufferPosition()).toEqual [0, 28] - describe "when editor:select-to-matching-bracket is triggered", -> - it " selects until the next matched bracket", -> - editor.moveCursorToEndOfLine() - editor.moveCursorLeft() - editor.trigger "editor:select-to-matching-bracket" - expect(editor.getCursorBufferPosition()).toEqual [12, 1] - selections = editor.getSelections() - expect(selections.length).toBe(1) - range = selections[0].getBufferRange() - expect(range).toEqual([[0,28], [12,1]]) - describe "matching bracket insertion", -> beforeEach -> editSession.buffer.setText("") From 2445829f83557c1746c51cb18c706f0641f51df5 Mon Sep 17 00:00:00 2001 From: Mutwin Kraus Date: Mon, 8 Apr 2013 14:15:25 +0200 Subject: [PATCH 06/15] Specs for moveCursorToBeginningOfNextWord --- spec/app/edit-session-spec.coffee | 29 +++++++++++++++++++++++++++++ src/app/cursor.coffee | 16 ++++++++++++++++ src/app/edit-session.coffee | 6 ++++++ src/app/editor.coffee | 4 ++-- src/app/selection.coffee | 3 +++ 5 files changed, 56 insertions(+), 2 deletions(-) diff --git a/spec/app/edit-session-spec.coffee b/spec/app/edit-session-spec.coffee index 3327b9f06..5ed7bdabb 100644 --- a/spec/app/edit-session-spec.coffee +++ b/spec/app/edit-session-spec.coffee @@ -341,6 +341,35 @@ describe "EditSession", -> editSession.moveCursorToEndOfWord() expect(editSession.getCursorBufferPosition()).toEqual [11, 8] + describe ".moveCursorToBeginningOfNextWord()", -> + it "moves the cursor before the first character of the next word", -> + editSession.setCursorBufferPosition [0,6] + editSession.addCursorAtBufferPosition [1,11] + editSession.addCursorAtBufferPosition [2,0] + [cursor1, cursor2, cursor3] = editSession.getCursors() + + editSession.moveCursorToBeginningOfNextWord() + + expect(cursor1.getBufferPosition()).toEqual [0, 14] + expect(cursor2.getBufferPosition()).toEqual [1, 13] + expect(cursor3.getBufferPosition()).toEqual [2, 4] + + it "does not blow up when there is no next word", -> + editSession.setCursorBufferPosition [Infinity, Infinity] + endPosition = editSession.getCursorBufferPosition() + editSession.moveCursorToBeginningOfNextWord() + expect(editSession.getCursorBufferPosition()).toEqual endPosition + + it "treats lines with only whitespace as a word", -> + editSession.setCursorBufferPosition([9, 4]) + editSession.moveCursorToBeginningOfNextWord() + expect(editSession.getCursorBufferPosition()).toEqual [10, 0] + + it "works when the current line is blank", -> + editSession.setCursorBufferPosition([10, 0]) + editSession.moveCursorToBeginningOfNextWord() + expect(editSession.getCursorBufferPosition()).toEqual [11, 9] + describe ".getCurrentParagraphBufferRange()", -> it "returns the buffer range of the current paragraph, delimited by blank lines or the beginning / end of the file", -> buffer.setText """ diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 52760c63b..7f198145f 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -165,6 +165,10 @@ class Cursor if position = @getEndOfCurrentWordBufferPosition() @setBufferPosition(position) + moveToBeginningOfNextWord: -> + if position = @getBeginningOfNextWordBufferPosition() + @setBufferPosition(position) + getBeginningOfCurrentWordBufferPosition: (options = {}) -> allowPrevious = options.allowPrevious ? true currentBufferPosition = @getBufferPosition() @@ -194,6 +198,18 @@ class Cursor endOfWordPosition or currentBufferPosition + getBeginningOfNextWordBufferPosition: (options = {}) -> + currentBufferPosition = @getBufferPosition() + start = if @isSurroundedByWhitespace() then currentBufferPosition else @getEndOfCurrentWordBufferPosition() + scanRange = [start, @editSession.getEofBufferPosition()] + + beginningOfNextWordPosition = null + @editSession.scanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) => + beginningOfNextWordPosition = range.start + stop() + + beginningOfNextWordPosition or currentBufferPosition + getCurrentWordBufferRange: (options={}) -> startOptions = _.extend(_.clone(options), allowPrevious: false) endOptions = _.extend(_.clone(options), allowNext: false) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index e3365b9bf..7ae9304e2 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -728,6 +728,9 @@ class EditSession moveCursorToEndOfWord: -> @moveCursors (cursor) -> cursor.moveToEndOfWord() + moveCursorToBeginningOfNextWord: -> + @moveCursors (cursor) -> cursor.moveToBeginningOfNextWord() + moveCursors: (fn) -> fn(cursor) for cursor in @getCursors() @mergeCursors() @@ -802,6 +805,9 @@ class EditSession selectToEndOfWord: -> @expandSelectionsForward (selection) => selection.selectToEndOfWord() + selectToBeginningOfNextWord: -> + @expandSelectionsForward (selection) => selection.selectToBeginningOfNextWord() + selectWord: -> @expandSelectionsForward (selection) => selection.selectWord() diff --git a/src/app/editor.coffee b/src/app/editor.coffee index ff93dccf0..43fdd2a95 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -180,7 +180,7 @@ class Editor extends View moveCursorRight: -> @activeEditSession.moveCursorRight() moveCursorToBeginningOfWord: -> @activeEditSession.moveCursorToBeginningOfWord() moveCursorToEndOfWord: -> @activeEditSession.moveCursorToEndOfWord() - moveCursorToBeginningOfNextWord: -> @activeEditSession.moveCursorToEndOfWord(); @activeEditSession.moveCursorRight() + moveCursorToBeginningOfNextWord: -> @activeEditSession.moveCursorToBeginningOfNextWord() moveCursorToTop: -> @activeEditSession.moveCursorToTop() moveCursorToBottom: -> @activeEditSession.moveCursorToBottom() moveCursorToBeginningOfLine: -> @activeEditSession.moveCursorToBeginningOfLine() @@ -221,7 +221,7 @@ class Editor extends View addSelectionAbove: -> @activeEditSession.addSelectionAbove() selectToBeginningOfWord: -> @activeEditSession.selectToBeginningOfWord() selectToEndOfWord: -> @activeEditSession.selectToEndOfWord() - selectToBeginningOfNextWord: -> @activeEditSession.selectToEndOfWord(); @activeEditSession.selectRight() + selectToBeginningOfNextWord: -> @activeEditSession.selectBeginningOfNextWord() selectWord: -> @activeEditSession.selectWord() selectLine: -> @activeEditSession.selectLine() selectToScreenPosition: (position) -> @activeEditSession.selectToScreenPosition(position) diff --git a/src/app/selection.coffee b/src/app/selection.coffee index 03bf8aca4..c3f91eb69 100644 --- a/src/app/selection.coffee +++ b/src/app/selection.coffee @@ -152,6 +152,9 @@ class Selection selectToEndOfWord: -> @modifySelection => @cursor.moveToEndOfWord() + selectToBeginningOfNextWord: -> + @modifySelection => @cursor.moveToBeginningOfNextWord() + addSelectionBelow: -> range = (@goalBufferRange ? @getBufferRange()).copy() nextRow = range.end.row + 1 From 9041c56ef39859fd376542c99d5050d6ffaf5d8d Mon Sep 17 00:00:00 2001 From: Mutwin Kraus Date: Mon, 8 Apr 2013 14:19:28 +0200 Subject: [PATCH 07/15] Spec for selectToBeginningOfNextWord --- spec/app/edit-session-spec.coffee | 19 +++++++++++++++++++ src/app/editor.coffee | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/spec/app/edit-session-spec.coffee b/spec/app/edit-session-spec.coffee index 5ed7bdabb..4a19d59f1 100644 --- a/spec/app/edit-session-spec.coffee +++ b/spec/app/edit-session-spec.coffee @@ -648,6 +648,25 @@ describe "EditSession", -> expect(selection2.getBufferRange()).toEqual [[3,48], [3,50]] expect(selection2.isReversed()).toBeFalsy() + describe ".selectToBeginningOfNextWord()", -> + it "selects text from cusor position to beginning of next word", -> + editSession.setCursorScreenPosition [0,4] + editSession.addCursorAtScreenPosition [3,48] + + editSession.selectToBeginningOfNextWord() + + expect(editSession.getCursors().length).toBe 2 + [cursor1, cursor2] = editSession.getCursors() + expect(cursor1.getBufferPosition()).toEqual [0,14] + expect(cursor2.getBufferPosition()).toEqual [3,51] + + expect(editSession.getSelections().length).toBe 2 + [selection1, selection2] = editSession.getSelections() + expect(selection1.getBufferRange()).toEqual [[0,4], [0,14]] + expect(selection1.isReversed()).toBeFalsy() + expect(selection2.getBufferRange()).toEqual [[3,48], [3,51]] + expect(selection2.isReversed()).toBeFalsy() + describe ".selectWord()", -> describe "when the cursor is inside a word", -> it "selects the entire word", -> diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 43fdd2a95..c9b36abbf 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -221,7 +221,7 @@ class Editor extends View addSelectionAbove: -> @activeEditSession.addSelectionAbove() selectToBeginningOfWord: -> @activeEditSession.selectToBeginningOfWord() selectToEndOfWord: -> @activeEditSession.selectToEndOfWord() - selectToBeginningOfNextWord: -> @activeEditSession.selectBeginningOfNextWord() + selectToBeginningOfNextWord: -> @activeEditSession.selectToBeginningOfNextWord() selectWord: -> @activeEditSession.selectWord() selectLine: -> @activeEditSession.selectLine() selectToScreenPosition: (position) -> @activeEditSession.selectToScreenPosition(position) From a630f05ae4964fb6324517e31ee766c5a3f9cee4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 6 Apr 2013 15:05:33 +0800 Subject: [PATCH 08/15] The dragged tab should carry information of file. --- src/packages/tabs/lib/tab-bar-view.coffee | 5 +++++ src/packages/tabs/spec/tabs-spec.coffee | 12 ++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/packages/tabs/lib/tab-bar-view.coffee b/src/packages/tabs/lib/tab-bar-view.coffee index ea8abd24b..2865d084c 100644 --- a/src/packages/tabs/lib/tab-bar-view.coffee +++ b/src/packages/tabs/lib/tab-bar-view.coffee @@ -91,6 +91,11 @@ class TabBarView extends View paneIndex = @paneContainer.indexOfPane(pane) event.originalEvent.dataTransfer.setData 'from-pane-index', paneIndex + item = @pane.getItems()[el.index()] + if item.getPath? + event.originalEvent.dataTransfer.setData 'text/uri-list', 'file://' + item.getPath() + event.originalEvent.dataTransfer.setData 'text/plain', item.getPath() + onDragEnd: (event) => @find(".is-dragging").removeClass 'is-dragging' diff --git a/src/packages/tabs/spec/tabs-spec.coffee b/src/packages/tabs/spec/tabs-spec.coffee index b5b733c17..a8222d6be 100644 --- a/src/packages/tabs/spec/tabs-spec.coffee +++ b/src/packages/tabs/spec/tabs-spec.coffee @@ -279,8 +279,8 @@ describe "TabBarView", -> expect(pane2.activeItem).toBe item1 expect(pane2.focus).toHaveBeenCalled() - describe 'when a non-tab is dragged to pane', -> - it 'has no effect', -> + describe "when a non-tab is dragged to pane", -> + it "has no effect", -> expect(tabBar.getTabs().map (tab) -> tab.text()).toEqual ["Item 1", "sample.js", "Item 2"] expect(pane.getItems()).toEqual [item1, editSession1, item2] expect(pane.activeItem).toBe item2 @@ -294,3 +294,11 @@ describe "TabBarView", -> expect(pane.activeItem).toBe item2 expect(pane.focus).not.toHaveBeenCalled() + describe "when a tab is dragged out of application", -> + it "should carry file's information", -> + [dragStartEvent, dropEvent] = buildDragEvents(tabBar.tabAtIndex(1), tabBar.tabAtIndex(1)) + tabBar.onDragStart(dragStartEvent) + + expect(dragStartEvent.originalEvent.dataTransfer.getData("text/plain")).toEqual editSession1.getPath() + expect(dragStartEvent.originalEvent.dataTransfer.getData("text/uri-list")).toEqual 'file://' + editSession1.getPath() + From fdcbf611aabdcc03290db053cb3073a394e2b646 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 6 Apr 2013 16:08:10 +0800 Subject: [PATCH 09/15] The drop marker should disappear when drag is done. Previously we make drop marker disappear when drop is done, it would case the marker to live forever if the drop is not done in Atom. --- src/packages/tabs/lib/tab-bar-view.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/packages/tabs/lib/tab-bar-view.coffee b/src/packages/tabs/lib/tab-bar-view.coffee index 2865d084c..bcd088183 100644 --- a/src/packages/tabs/lib/tab-bar-view.coffee +++ b/src/packages/tabs/lib/tab-bar-view.coffee @@ -98,6 +98,8 @@ class TabBarView extends View onDragEnd: (event) => @find(".is-dragging").removeClass 'is-dragging' + @children('.is-drop-target').removeClass 'is-drop-target' + @children('.drop-target-is-after').removeClass 'drop-target-is-after' onDragOver: (event) => unless event.originalEvent.dataTransfer.getData('atom-event') is 'true' @@ -125,8 +127,6 @@ class TabBarView extends View return event.stopPropagation() - @children('.is-drop-target').removeClass 'is-drop-target' - @children('.drop-target-is-after').removeClass 'drop-target-is-after' dataTransfer = event.originalEvent.dataTransfer fromIndex = parseInt(dataTransfer.getData('sortable-index')) From 3c4966f6a35154131e857157932177ce1a3bf1b9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 8 Apr 2013 20:17:40 +0800 Subject: [PATCH 10/15] Open the file dragged to window. --- spec/app/window-spec.coffee | 28 ++++++++++++++++++++++++++++ src/app/window.coffee | 19 +++++++++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/spec/app/window-spec.coffee b/spec/app/window-spec.coffee index c27a7a31e..b93d7abbf 100644 --- a/spec/app/window-spec.coffee +++ b/spec/app/window-spec.coffee @@ -198,3 +198,31 @@ describe "Window", -> expect(deserialize({ deserializer: 'Foo', version: 3, name: 'Bar' })).toBeUndefined() expect(deserialize({ deserializer: 'Foo', version: 1, name: 'Bar' })).toBeUndefined() expect(deserialize({ deserializer: 'Foo', name: 'Bar' })).toBeUndefined() + + describe "drag and drop", -> + buildDragEvent = (type, files) -> + dataTransfer = + files: files + data: {} + setData: (key, value) -> @data[key] = value + getData: (key) -> @data[key] + + event = $.Event(type) + event.originalEvent = { dataTransfer } + event.preventDefault = -> + event.stopPropagation = -> + event + + describe "when a file is dragged to window", -> + it "opens it", -> + spyOn(atom, "open") + event = buildDragEvent("drop", [ {path: "/fake1"}, {path: "/fake2"} ]) + window.onDrop(event) + expect(atom.open.callCount).toBe 2 + + describe "when a non-file is dragged to window", -> + it "does nothing", -> + spyOn(atom, "open") + event = buildDragEvent("drop", []) + window.onDrop(event) + expect(atom.open).not.toHaveBeenCalled() diff --git a/src/app/window.coffee b/src/app/window.coffee index d78f54caa..490351c70 100644 --- a/src/app/window.coffee +++ b/src/app/window.coffee @@ -25,12 +25,6 @@ window.setUpEnvironment = -> $(document).on 'keydown', keymap.handleKeyEvent keymap.bindDefaultKeys() - ignoreEvents = (e) -> - e.preventDefault() - e.stopPropagation() - $(document).on 'dragover', ignoreEvents - $(document).on 'drop', ignoreEvents - requireStylesheet 'reset' requireStylesheet 'atom' requireStylesheet 'overlay' @@ -50,6 +44,7 @@ window.startup = -> console.warn "Failed to install `atom` binary" handleWindowEvents() + handleDragDrop() config.load() keymap.loadBundledKeymaps() atom.loadThemes() @@ -93,6 +88,18 @@ window.handleWindowEvents = -> $(window).command 'window:close', => confirmClose() $(window).command 'window:reload', => reload() +window.handleDragDrop = -> + $(document).on 'dragover', (e) -> + e.preventDefault() + e.stopPropagation() + $(document).on 'drop', onDrop + +window.onDrop = (e) -> + e.preventDefault() + e.stopPropagation() + for file in e.originalEvent.dataTransfer.files + atom.open(file.path) + window.deserializeWindowState = -> RootView = require 'root-view' Project = require 'project' From a5b8478060d133aa3ddfa51272e85c564595323d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 9 Apr 2013 15:33:41 +0800 Subject: [PATCH 11/15] Allow dragging of tab when there is only one tab. The tabs should be able to be draggale out of the application at any time, and if there is only one tab it should not be able to be dropped in the same window. --- src/packages/tabs/lib/tab-bar-view.coffee | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/packages/tabs/lib/tab-bar-view.coffee b/src/packages/tabs/lib/tab-bar-view.coffee index bcd088183..be0a0c0af 100644 --- a/src/packages/tabs/lib/tab-bar-view.coffee +++ b/src/packages/tabs/lib/tab-bar-view.coffee @@ -77,11 +77,8 @@ class TabBarView extends View (@paneContainer.getPanes().length > 1) or (@pane.getItems().length > 1) onDragStart: (event) => - unless @shouldAllowDrag(event) - event.preventDefault() - return - - event.originalEvent.dataTransfer.setData 'atom-event', 'true' + if @shouldAllowDrag() + event.originalEvent.dataTransfer.setData 'atom-event', 'true' el = $(event.target).closest('.sortable') el.addClass 'is-dragging' From b2cb527f0380cc88ff79cf0e1123f2e816d44f4a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 9 Apr 2013 08:47:38 -0700 Subject: [PATCH 12/15] Look in all panes for existing preview to show Previously only the next pane was checked for an existing preview which would fail to locate any existing previews that were moved to different panes or were no longer in the next pane for the edit session. --- .../lib/markdown-preview.coffee | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/packages/markdown-preview/lib/markdown-preview.coffee b/src/packages/markdown-preview/lib/markdown-preview.coffee index 1b46eccb5..8011339b9 100644 --- a/src/packages/markdown-preview/lib/markdown-preview.coffee +++ b/src/packages/markdown-preview/lib/markdown-preview.coffee @@ -15,12 +15,19 @@ module.exports = console.warn("Can not render markdown for '#{editSession.getUri() ? 'untitled'}'") return - if nextPane = activePane.getNextPane() - if preview = nextPane.itemForUri("markdown-preview:#{editSession.getPath()}") - nextPane.showItem(preview) - preview.fetchRenderedMarkdown() - else - nextPane.showItem(new MarkdownPreviewView(editSession.buffer)) + {previewPane, previewItem} = @getExistingPreview(editSession) + if previewItem? + previewPane.showItem(previewItem) + previewItem.fetchRenderedMarkdown() + else if nextPane = activePane.getNextPane() + nextPane.showItem(new MarkdownPreviewView(editSession.buffer)) else activePane.splitRight(new MarkdownPreviewView(editSession.buffer)) activePane.focus() + + getExistingPreview: (editSession) -> + uri = "markdown-preview:#{editSession.getPath()}" + for previewPane in rootView.getPanes() + previewItem = previewPane.itemForUri(uri) + return {previewPane, previewItem} if previewItem? + {} From cfe03c108a14af1b69a08745dfcde295a461a680 Mon Sep 17 00:00:00 2001 From: Mutwin Kraus Date: Tue, 9 Apr 2013 18:53:56 +0200 Subject: [PATCH 13/15] Revert changes in src/app/text-buffer.coffee and src/app/pane.coffee --- src/app/pane.coffee | 6 +++--- src/app/text-buffer.coffee | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/app/pane.coffee b/src/app/pane.coffee index 21bdf4e5f..166fd7e90 100644 --- a/src/app/pane.coffee +++ b/src/app/pane.coffee @@ -135,11 +135,11 @@ class Pane extends View @trigger 'pane:item-added', [item, index] item - destroyActiveItem: (promptToSave=true) => - @destroyItem(@activeItem, promptToSave) + destroyActiveItem: => + @destroyItem(@activeItem) false - destroyItem: (item, promptToSave=true) -> + destroyItem: (item) -> container = @getContainer() reallyDestroyItem = => @removeItem(item) diff --git a/src/app/text-buffer.coffee b/src/app/text-buffer.coffee index 82aeb33a9..471af8fa5 100644 --- a/src/app/text-buffer.coffee +++ b/src/app/text-buffer.coffee @@ -96,8 +96,7 @@ class Buffer @trigger 'reloaded' updateCachedDiskContents: -> - if @file? - @cachedDiskContents = @file.read() + @cachedDiskContents = @file.read() getBaseName: -> @file?.getBaseName() From fe1b4c71a362c6dafa8da30d93665e05e5543063 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 9 Apr 2013 10:47:19 -0700 Subject: [PATCH 14/15] Use ? instead of or --- src/app/cursor.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 7f198145f..696cbfb4d 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -196,7 +196,7 @@ class Cursor if not endOfWordPosition?.isEqual(currentBufferPosition) stop() - endOfWordPosition or currentBufferPosition + endOfWordPosition ? currentBufferPosition getBeginningOfNextWordBufferPosition: (options = {}) -> currentBufferPosition = @getBufferPosition() From c9e1f89b60fb7b1a70bc826f6b654653de038b36 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 9 Apr 2013 12:04:31 -0700 Subject: [PATCH 15/15] Upgrade to git-utils 0.12 --- package.json | 2 +- src/app/git.coffee | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index c82ee7ea6..3bde864d6 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "ctags": "0.3.0", "oniguruma": "0.8.0", "mkdirp": "0.3.5", - "git-utils": "0.11.0", + "git-utils": "0.12.0", "underscore": "1.4.4", "d3": "3.0.8", "coffee-cache": "0.1.0", diff --git a/src/app/git.coffee b/src/app/git.coffee index 9bbe63117..b01cf826b 100644 --- a/src/app/git.coffee +++ b/src/app/git.coffee @@ -95,11 +95,7 @@ class Git @isStatusNew(@getPathStatus(path)) relativize: (path) -> - workingDirectory = @getWorkingDirectory() - if workingDirectory and path.indexOf("#{workingDirectory}/") is 0 - path.substring(workingDirectory.length + 1) - else - path + @getRepo().relativize(path) getShortHead: -> @getRepo().getShortHead()