diff --git a/lib/snippet-expansion.coffee b/lib/snippet-expansion.coffee index e306aff..bf71a18 100644 --- a/lib/snippet-expansion.coffee +++ b/lib/snippet-expansion.coffee @@ -1,5 +1,7 @@ _ = require 'underscore-plus' {Subscriber} = require 'emissary' +{Point, Range} = require 'atom' +Snippet = require './snippet' module.exports = class SnippetExpansion @@ -9,9 +11,10 @@ class SnippetExpansion tabStopMarkers: null settingTabStop: false + constructor: (@snippet, @editor) -> - @editor.selectToBeginningOfWord() - startPosition = @editor.getCursorBufferPosition() + startPosition = @selectToBoundaryPosition() + @editor.transact => [newRange] = @editor.insertText(snippet.body, autoIndent: false) if snippet.tabStops.length > 0 @@ -21,6 +24,21 @@ class SnippetExpansion @editor.normalizeTabsInBufferRange(newRange) @indentSubsequentLines(startPosition.row, snippet) if snippet.lineCount > 1 + selectToBoundaryPosition: -> + cursor = @editor.getCursor() + line = cursor.getCurrentBufferLine() + newColumn = cursor.getBufferColumn() + column = newColumn + row = cursor.getBufferRow() + while newColumn >= 0 + break if Snippet.prefixBoundary.test line[newColumn - 1] + newColumn-- + if newColumn < 0 then newColumn = 0 + startPoint = new Point(row, newColumn) + endPoint = new Point(row, column) + @editor.setSelectedBufferRange new Range(startPoint, endPoint) + startPoint + cursorMoved: ({oldBufferPosition, newBufferPosition, textChanged}) -> return if @settingTabStop or textChanged oldTabStops = @tabStopsForBufferPosition(oldBufferPosition) diff --git a/lib/snippet.coffee b/lib/snippet.coffee index c0cda07..b9471b6 100644 --- a/lib/snippet.coffee +++ b/lib/snippet.coffee @@ -3,6 +3,7 @@ _ = require 'underscore-plus' module.exports = class Snippet + @prefixBoundary: /\s/ name: null prefix: null body: null diff --git a/lib/snippets.coffee b/lib/snippets.coffee index 116e46c..7522738 100644 --- a/lib/snippets.coffee +++ b/lib/snippets.coffee @@ -92,14 +92,24 @@ module.exports = getBodyParser: -> @bodyParser ?= require './snippet-body-parser' + getPrefixText: (cursor) -> + line = cursor.getCurrentBufferLine() + i = cursor.getBufferColumn() - 1 + prefix = [] + while i >= 0 + break if Snippet.prefixBoundary.test line[i] + prefix.unshift line[i] + i-- + + prefix.join '' + enableSnippetsInEditor: (editorView) -> editor = editorView.getEditor() editorView.command 'snippets:expand', (e) => unless editor.getSelection().isEmpty() e.abortKeyBinding() return - - prefix = editor.getCursor().getCurrentWordPrefix() + prefix = @getPrefixText editor.getCursor() if snippet = atom.syntax.getProperty(editor.getCursorScopes(), "snippets.#{prefix}") editor.transact -> new SnippetExpansion(snippet, editor) diff --git a/spec/snippets-spec.coffee b/spec/snippets-spec.coffee index 1482290..6646d7c 100644 --- a/spec/snippets-spec.coffee +++ b/spec/snippets-spec.coffee @@ -37,6 +37,10 @@ describe "Snippets extension", -> prefix: "t1" body: "this is a test" + "special chars": + prefix: "@unique" + body: "@unique see" + "tab stops": prefix: "t2" body: """ @@ -232,6 +236,22 @@ describe "Snippets extension", -> editorView.trigger keydownEvent('tab', target: editorView[0]) expect(buffer.lineForRow(0)).toBe "first line" + describe "when text contains special characters", -> + it "should see the special character as part of the tab boundary", -> + editor.insertText("@unique") + expect(editor.getCursorScreenPosition()).toEqual [0, 7] + + editorView.trigger keydownEvent('tab', target: editorView[0]) + expect(buffer.lineForRow(0)).toBe "@unique seevar quicksort = function () {" + expect(editor.getCursorScreenPosition()).toEqual [0, 11] + it "should see the special character as part of the tab boundary and select only the prefix", -> + editor.insertText("a; @unique") + expect(editor.getCursorScreenPosition()).toEqual [0, 10] + + editorView.trigger keydownEvent('tab', target: editorView[0]) + expect(buffer.lineForRow(0)).toBe "a; @unique seevar quicksort = function () {" + expect(editor.getCursorScreenPosition()).toEqual [0, 14] + describe "snippet loading", -> [configDirPath, packageWithSnippets, packageWithBrokenSnippets] = []