From c13b45df99cef32cf0e5c2654351c17230eb8f6d Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Mon, 28 Jan 2013 16:04:08 -0700 Subject: [PATCH] Hard tabs in snippets are translated to soft-tabs if necessary --- src/app/edit-session.coffee | 7 ++++- src/app/selection.coffee | 2 ++ .../snippets/spec/snippets-spec.coffee | 28 ++++++++++++++++--- .../snippets/src/snippet-expansion.coffee | 3 +- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 8e64e2012..74fe4a2a3 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -211,6 +211,10 @@ class EditSession autoIndentSelectedRows: -> @mutateSelectedText (selection) -> selection.autoIndentSelectedRows() + normalizeTabsInBufferRange: (bufferRange) -> + return unless @softTabs + @scanInRange /\t/, bufferRange, (match, range, {replace}) => replace(@getTabText()) + cutToEndOfLine: -> maintainPasteboard = false @mutateSelectedText (selection) -> @@ -251,8 +255,9 @@ class EditSession undo: (editSession) -> editSession?.setSelectedBufferRanges(oldSelectedRanges) if fn - fn() + result = fn() @commit() if isNewTransaction + result commit: -> newSelectedRanges = @getSelectedBufferRanges() diff --git a/src/app/selection.coffee b/src/app/selection.coffee index f30eea09a..8123d1157 100644 --- a/src/app/selection.coffee +++ b/src/app/selection.coffee @@ -185,6 +185,8 @@ class Selection else @editSession.autoDecreaseIndentForRow(newBufferRange.start.row) + newBufferRange + indent: ({ autoIndent }={})-> { row, column } = @cursor.getBufferPosition() diff --git a/src/packages/snippets/spec/snippets-spec.coffee b/src/packages/snippets/spec/snippets-spec.coffee index 872bd25f1..c8d5b99ae 100644 --- a/src/packages/snippets/spec/snippets-spec.coffee +++ b/src/packages/snippets/spec/snippets-spec.coffee @@ -8,12 +8,13 @@ _ = require 'underscore' fs = require 'fs' describe "Snippets extension", -> - [buffer, editor] = [] + [buffer, editor, editSession] = [] beforeEach -> rootView = new RootView(require.resolve('fixtures/sample.js')) spyOn(LoadSnippetsTask.prototype, 'start') atom.loadPackage("snippets") editor = rootView.getActiveEditor() + editSession = rootView.getActiveEditSession() buffer = editor.getBuffer() rootView.simulateDomAttachment() rootView.enableKeymap() @@ -42,7 +43,7 @@ describe "Snippets extension", -> prefix: "t3" body: """ line 1 - line 2$1 + \tline 2$1 """ @@ -162,7 +163,24 @@ describe "Snippets extension", -> editor.trigger keydownEvent('tab', shiftKey: true, target: editor[0]) expect(editor.getCursorBufferPosition()).toEqual [4, 15] - describe "when a the start of the snippet is indented", -> + describe "when the snippet contains hard tabs", -> + describe "when the edit session is in soft-tabs mode", -> + it "translates hard tabs in the snippet to the appropriate number of spaces", -> + expect(editSession.softTabs).toBeTruthy() + editor.insertText("t3") + editor.trigger keydownEvent('tab', target: editor[0]) + expect(buffer.lineForRow(1)).toBe " line 2" + expect(editSession.getCursorBufferPosition()).toEqual [1, 8] + + describe "when the edit session is in hard-tabs mode", -> + it "inserts hard tabs in the snippet directly", -> + editSession.setSoftTabs(false) + editor.insertText("t3") + editor.trigger keydownEvent('tab', target: editor[0]) + expect(buffer.lineForRow(1)).toBe "\tline 2" + expect(editSession.getCursorBufferPosition()).toEqual [1, 7] + + describe "when the snippet prefix is indented", -> describe "when the snippet spans a single line", -> it "does not indent the next line", -> editor.setCursorScreenPosition([2, Infinity]) @@ -172,6 +190,7 @@ describe "Snippets extension", -> describe "when the snippet spans multiple lines", -> it "indents the subsequent lines of the snippet to be even with the start of the first line", -> + expect(editSession.softTabs).toBeTruthy() editor.setCursorScreenPosition([2, Infinity]) editor.insertText ' t3' editor.trigger 'snippets:expand' @@ -202,9 +221,10 @@ describe "Snippets extension", -> describe "when a snippet expansion is undone and redone", -> it "recreates the snippet's tab stops", -> editor.insertText ' t6\n' - editor.setCursorBufferPosition [0, 6] + editor.setCursorBufferPosition [0, Infinity] editor.trigger keydownEvent('tab', target: editor[0]) expect(buffer.lineForRow(0)).toBe " first line" + expect(editor.getCursorBufferPosition()).toEqual [0, 14] editor.undo() editor.redo() expect(editor.getCursorBufferPosition()).toEqual [0, 14] diff --git a/src/packages/snippets/src/snippet-expansion.coffee b/src/packages/snippets/src/snippet-expansion.coffee index b1a62e496..1b5b661ed 100644 --- a/src/packages/snippets/src/snippet-expansion.coffee +++ b/src/packages/snippets/src/snippet-expansion.coffee @@ -11,7 +11,7 @@ class SnippetExpansion @editSession.selectToBeginningOfWord() startPosition = @editSession.getCursorBufferPosition() @editSession.transact => - @editSession.insertText(snippet.body, autoIndent: false) + [newRange] = @editSession.insertText(snippet.body, autoIndent: false) if snippet.tabStops.length > 0 editSession.pushOperation do: => @@ -19,6 +19,7 @@ class SnippetExpansion @placeTabStopAnchorRanges(startPosition, snippet.tabStops) @editSession.snippetExpansion = this undo: => @destroy() + @editSession.normalizeTabsInBufferRange(newRange) @indentSubsequentLines(startPosition.row, snippet) if snippet.lineCount > 1 cursorMoved: ({oldBufferPosition, newBufferPosition}) ->