From 5b67feff54ef7d3cfbd4c0103d715f7ac6f0476d Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Mon, 16 Apr 2012 16:26:09 -0700 Subject: [PATCH] Autocomplete will match on either side of selected text when completing words --- spec/app/autocomplete-spec.coffee | 52 +++++++++++++++++++++++-------- src/app/autocomplete.coffee | 33 ++++++++++---------- 2 files changed, 56 insertions(+), 29 deletions(-) diff --git a/spec/app/autocomplete-spec.coffee b/spec/app/autocomplete-spec.coffee index a7a5519cd..dde442ad6 100644 --- a/spec/app/autocomplete-spec.coffee +++ b/spec/app/autocomplete-spec.coffee @@ -35,31 +35,58 @@ describe "Autocomplete", -> describe ".completeWordAtEditorCursorPosition()", -> describe "when no text is selected", -> it 'autocompletes word when there is only a prefix', -> - editor.buffer.insert([10, 0] ,"extra:s:extra") - editor.setCursorBufferPosition([10, 7]) + editor.buffer.insert([10,0] ,"extra:s:extra") + editor.setCursorBufferPosition([10,7]) autocomplete.completeWordAtEditorCursorPosition() expect(editor.lineForBufferRow(10)).toBe "extra:sort:extra" - expect(editor.getCursorBufferPosition()).toEqual [10, 10] - expect(editor.getSelection().getBufferRange()).toEqual [[10, 7], [10,10]] + expect(editor.getCursorBufferPosition()).toEqual [10,10] + expect(editor.getSelection().getBufferRange()).toEqual [[10,7], [10,10]] it 'autocompletes word when there is only a suffix', -> - editor.buffer.insert([10, 0] ,"extra:e:extra") - editor.setCursorBufferPosition([10, 6]) + editor.buffer.insert([10,0] ,"extra:e:extra") + editor.setCursorBufferPosition([10,6]) autocomplete.completeWordAtEditorCursorPosition() expect(editor.lineForBufferRow(10)).toBe "extra:while:extra" - expect(editor.getCursorBufferPosition()).toEqual [10, 10] - expect(editor.getSelection().getBufferRange()).toEqual [[10, 6], [10,10]] + expect(editor.getCursorBufferPosition()).toEqual [10,10] + expect(editor.getSelection().getBufferRange()).toEqual [[10,6], [10,10]] it 'autocompletes word when there is a prefix and suffix', -> - editor.buffer.insert([8, 43] ,"q") - editor.setCursorBufferPosition([8, 44]) + editor.buffer.insert([8,43] ,"q") + editor.setCursorBufferPosition([8,44]) autocomplete.completeWordAtEditorCursorPosition() expect(editor.lineForBufferRow(8)).toBe " return sort(left).concat(pivot).concat(quicksort(right));" - expect(editor.getCursorBufferPosition()).toEqual [8, 48] - expect(editor.getSelection().getBufferRange()).toEqual [[8, 44], [8,48]] + expect(editor.getCursorBufferPosition()).toEqual [8,48] + expect(editor.getSelection().getBufferRange()).toEqual [[8,44], [8,48]] + + describe "when text is selected", -> + it 'autocompletes word when there is only a prefix', -> + editor.buffer.insert([10,0] ,"extra:sort:extra") + editor.setSelectionBufferRange [[10,7], [10,10]] + autocomplete.completeWordAtEditorCursorPosition() + + expect(editor.lineForBufferRow(10)).toBe "extra:shift:extra" + expect(editor.getCursorBufferPosition()).toEqual [10,11] + expect(editor.getSelection().getBufferRange()).toEqual [[10,7],[10,11]] + + it 'autocompletes word when there is only a suffix', -> + editor.buffer.insert([10,0] ,"extra:current:extra") + editor.setSelectionBufferRange [[10,6],[10,12]] + autocomplete.completeWordAtEditorCursorPosition() + + expect(editor.lineForBufferRow(10)).toBe "extra:quicksort:extra" + expect(editor.getCursorBufferPosition()).toEqual [10,14] + expect(editor.getSelection().getBufferRange()).toEqual [[10,6],[10,14]] + + it 'autocompletes word when there is a prefix and suffix', -> + editor.setSelectionBufferRange [[5,7],[5,12]] + autocomplete.completeWordAtEditorCursorPosition() + + expect(editor.lineForBufferRow(5)).toBe " concat = items.shift();" + expect(editor.getCursorBufferPosition()).toEqual [5,11] + expect(editor.getSelection().getBufferRange()).toEqual [[5,7], [5,11]] describe 'when changes are made to the buffer', -> it 'updates word list', -> @@ -93,4 +120,3 @@ describe "Autocomplete", -> previousBuffer.change([[0,0],[0,1]], "sauron") expect(autocomplete.buildWordList).not.toHaveBeenCalled() - diff --git a/src/app/autocomplete.coffee b/src/app/autocomplete.coffee index 2dd413eb1..739645792 100644 --- a/src/app/autocomplete.coffee +++ b/src/app/autocomplete.coffee @@ -15,7 +15,6 @@ class Autocomplete setCurrentBuffer: (buffer) -> @currentBuffer.off '.autocomplete' if @currentBuffer - @currentBuffer = buffer @currentBuffer.on 'change.autocomplete', => @buildWordList() @buildWordList() @@ -24,26 +23,28 @@ class Autocomplete @wordList = _.unique(@currentBuffer.getText().match(@wordRegex)) completeWordAtEditorCursorPosition: () -> - position = @editor.getCursorBufferPosition() - lineRange = [[position.row, 0], [position.row, @editor.lineLengthForBufferRow(position.row)]] + selectionRange = @editor.getSelection().getBufferRange() + lineRange = [[selectionRange.start.row, 0], [selectionRange.end.row, @editor.lineLengthForBufferRow(selectionRange.end.row)]] [prefix, suffix] = ["", ""] @currentBuffer.scanInRange @wordRegex, lineRange, (match, range, {stop}) -> - if range.start.isLessThan(position) - if range.end.isEqual(position) - prefix = match[0] - else if range.end.isGreaterThan(position) - index = position.column - range.start.column - prefix = match[0][0...index] - suffix = match[0][index..] - stop() - else if range.start.isEqual(position) - suffix = match[0] - stop() + if range.intersectsWith(selectionRange) + prefixOffset = selectionRange.start.column - range.start.column + suffixOffset = selectionRange.end.column - range.end.column - if match = @matches(prefix, suffix)[0] + if range.start.isLessThan(selectionRange.start) + prefix = match[0][0...prefixOffset] + + if range.end.isGreaterThan(selectionRange.end) + suffix = match[0][suffixOffset..] + stop() + + for match in @matches(prefix, suffix) + continue if match[0] == prefix + @editor.getSelectedText() + suffix + startPosition = @editor.getSelection().getBufferRange().start @editor.insertText(match[1]) - @editor.setSelectionBufferRange([position, [position.row, position.column + match[1].length]]) + @editor.setSelectionBufferRange([startPosition, [startPosition.row, startPosition.column + match[1].length]]) + break matches: (prefix, suffix) -> regex = new RegExp("^#{prefix}(.+)#{suffix}$", "i")