From c96ac1638fc9876bb2b3d79e28baf1ecc5303d1e Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 17 Apr 2012 10:48:01 -0700 Subject: [PATCH] :lipstick: --- spec/app/autocomplete-spec.coffee | 46 +++++++++++++++---------------- src/app/autocomplete.coffee | 33 ++++++++++++++-------- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/spec/app/autocomplete-spec.coffee b/spec/app/autocomplete-spec.coffee index dde442ad6..c03fd4529 100644 --- a/spec/app/autocomplete-spec.coffee +++ b/spec/app/autocomplete-spec.coffee @@ -11,33 +11,33 @@ describe "Autocomplete", -> editor.setBuffer new Buffer(require.resolve('fixtures/sample.js')) autocomplete = new Autocomplete(editor) - describe '.matches(prefix, suffix)', -> - it 'returns matches on buffer starting with given prefix and ending with given suffix', -> - matches = autocomplete.matches("s", "").map (match) -> match[0] - expect(matches.length).toBe 2 - expect(matches).toContain("sort") - expect(matches).toContain("shift") + describe '.wordMatches(prefix, suffix)', -> + it 'returns wordMatches on buffer starting with given prefix and ending with given suffix', -> + wordMatches = autocomplete.wordMatches("s", "").map (match) -> match[0] + expect(wordMatches.length).toBe 2 + expect(wordMatches).toContain("sort") + expect(wordMatches).toContain("shift") - matches = autocomplete.matches("l", "t").map (match) -> match[0] - expect(matches.length).toBe 1 - expect(matches).toContain("left") + wordMatches = autocomplete.wordMatches("l", "t").map (match) -> match[0] + expect(wordMatches.length).toBe 1 + expect(wordMatches).toContain("left") it 'ignores case when finding matches', -> - matches = autocomplete.matches("S", "").map (match) -> match[0] - expect(matches.length).toBe 2 - expect(matches).toContain("sort") - expect(matches).toContain("shift") + wordMatches = autocomplete.wordMatches("S", "").map (match) -> match[0] + expect(wordMatches.length).toBe 2 + expect(wordMatches).toContain("sort") + expect(wordMatches).toContain("shift") - matches = autocomplete.matches("l", "t").map (match) -> match[0] - expect(matches.length).toBe 1 - expect(matches).toContain("left") + wordMatches = autocomplete.wordMatches("l", "t").map (match) -> match[0] + expect(wordMatches.length).toBe 1 + expect(wordMatches).toContain("left") - describe ".completeWordAtEditorCursorPosition()", -> + describe ".completeWord()", -> 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]) - autocomplete.completeWordAtEditorCursorPosition() + autocomplete.completeWord() expect(editor.lineForBufferRow(10)).toBe "extra:sort:extra" expect(editor.getCursorBufferPosition()).toEqual [10,10] @@ -46,7 +46,7 @@ describe "Autocomplete", -> it 'autocompletes word when there is only a suffix', -> editor.buffer.insert([10,0] ,"extra:e:extra") editor.setCursorBufferPosition([10,6]) - autocomplete.completeWordAtEditorCursorPosition() + autocomplete.completeWord() expect(editor.lineForBufferRow(10)).toBe "extra:while:extra" expect(editor.getCursorBufferPosition()).toEqual [10,10] @@ -55,7 +55,7 @@ describe "Autocomplete", -> it 'autocompletes word when there is a prefix and suffix', -> editor.buffer.insert([8,43] ,"q") editor.setCursorBufferPosition([8,44]) - autocomplete.completeWordAtEditorCursorPosition() + autocomplete.completeWord() expect(editor.lineForBufferRow(8)).toBe " return sort(left).concat(pivot).concat(quicksort(right));" expect(editor.getCursorBufferPosition()).toEqual [8,48] @@ -65,7 +65,7 @@ describe "Autocomplete", -> 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() + autocomplete.completeWord() expect(editor.lineForBufferRow(10)).toBe "extra:shift:extra" expect(editor.getCursorBufferPosition()).toEqual [10,11] @@ -74,7 +74,7 @@ describe "Autocomplete", -> 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() + autocomplete.completeWord() expect(editor.lineForBufferRow(10)).toBe "extra:quicksort:extra" expect(editor.getCursorBufferPosition()).toEqual [10,14] @@ -82,7 +82,7 @@ describe "Autocomplete", -> it 'autocompletes word when there is a prefix and suffix', -> editor.setSelectionBufferRange [[5,7],[5,12]] - autocomplete.completeWordAtEditorCursorPosition() + autocomplete.completeWord() expect(editor.lineForBufferRow(5)).toBe " concat = items.shift();" expect(editor.getCursorBufferPosition()).toEqual [5,11] diff --git a/src/app/autocomplete.coffee b/src/app/autocomplete.coffee index 739645792..dc6991656 100644 --- a/src/app/autocomplete.coffee +++ b/src/app/autocomplete.coffee @@ -1,14 +1,19 @@ +{View, $$} = require 'space-pen' _ = require 'underscore' Range = require 'range' module.exports = -class Autocomplete +class Autocomplete extends View + @content: -> + @div class: 'autocomplete', => + @ol outlet: 'matchesList' + editor: null currentBuffer: null wordList = null wordRegex: /\w+/g - constructor: (@editor) -> + initialize: (@editor) -> @setCurrentBuffer(@editor.buffer) @editor.on 'autocomplete:complete-word', => @completeWordAtEditorCursorPosition() @editor.on 'buffer-path-change', => @setCurrentBuffer(@editor.buffer) @@ -22,8 +27,19 @@ class Autocomplete buildWordList: () -> @wordList = _.unique(@currentBuffer.getText().match(@wordRegex)) - completeWordAtEditorCursorPosition: () -> - selectionRange = @editor.getSelection().getBufferRange() + completeWord: -> + selection = @editor.getSelection() + {prefix, suffix} = @prefixAndSuffixOfSelection(selection) + currentWord = prefix + @editor.getSelectedText() + suffix + + for match in @wordMatches(prefix, suffix) when match[0] != currentWord + startPosition = selection.getBufferRange().start + @editor.insertText(match[1]) + @editor.setSelectionBufferRange([startPosition, [startPosition.row, startPosition.column + match[1].length]]) + break + + prefixAndSuffixOfSelection: (selection) -> + selectionRange = selection.getBufferRange() lineRange = [[selectionRange.start.row, 0], [selectionRange.end.row, @editor.lineLengthForBufferRow(selectionRange.end.row)]] [prefix, suffix] = ["", ""] @@ -39,13 +55,8 @@ class Autocomplete 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([startPosition, [startPosition.row, startPosition.column + match[1].length]]) - break + {prefix, suffix} - matches: (prefix, suffix) -> + wordMatches: (prefix, suffix) -> regex = new RegExp("^#{prefix}(.+)#{suffix}$", "i") regex.exec(word) for word in @wordList when regex.test(word)