diff --git a/spec/app/autocomplete-spec.coffee b/spec/app/autocomplete-spec.coffee index c3d6c6988..f0488a2bd 100644 --- a/spec/app/autocomplete-spec.coffee +++ b/spec/app/autocomplete-spec.coffee @@ -190,23 +190,39 @@ describe "Autocomplete", -> expect(autocomplete.buildWordList).not.toHaveBeenCalled() describe "when the change was not caused by autocomplete", -> - it "rebuilds the match list based on the new prefix and suffix", -> - editor.buffer.insert([10, 0] ,"t") - editor.setCursorBufferPosition [10, 0] - editor.trigger "autocomplete:toggle" - expect($(document).find('#autocomplete')).toExist() + describe "when the change produces a prefix that still has matches in the word list", -> + it "rebuilds the match list based on the new prefix and suffix", -> + editor.buffer.insert([10, 0] ,"t") + editor.setCursorBufferPosition [10, 0] + editor.trigger "autocomplete:toggle" + expect($(document).find('#autocomplete')).toExist() - editor.insertText('c') + editor.insertText('c') - expect($(document).find('#autocomplete')).toExist() + expect($(document).find('#autocomplete')).toExist() - expect(editor.lineForBufferRow(10)).toBe "current" - expect(editor.getCursorBufferPosition()).toEqual [10,6] - expect(editor.getSelection().getBufferRange()).toEqual [[10,1], [10,6]] + expect(editor.lineForBufferRow(10)).toBe "current" + expect(editor.getCursorBufferPosition()).toEqual [10,6] + expect(editor.getSelection().getBufferRange()).toEqual [[10,1], [10,6]] - expect(autocomplete.matchesList.find('li').length).toBe 2 - expect(autocomplete.matchesList.find('li:eq(0)')).toHaveText('current') - expect(autocomplete.matchesList.find('li:eq(1)')).toHaveText('concat') + expect(autocomplete.matchesList.find('li').length).toBe 2 + expect(autocomplete.matchesList.find('li:eq(0)')).toHaveText('current') + expect(autocomplete.matchesList.find('li:eq(1)')).toHaveText('concat') + + describe "when the change produces a prefix that has no matches in the word list", -> + it "accepts the selected match and appends the change after it", -> + editor.buffer.insert([10, 0] ,"c") + editor.setCursorBufferPosition [10, 1] + editor.trigger "autocomplete:toggle" + expect($(document).find('#autocomplete')).toExist() + + editor.insertText(' ') + + expect(editor.lineForBufferRow(10)).toBe "current " + expect(editor.getCursorBufferPosition()).toEqual [10,8] + expect(editor.getSelection().getBufferRange()).toEqual [[10,8], [10,8]] + + expect($(document).find('#autocomplete')).not.toExist() describe "when editor's buffer is assigned a new buffer", -> it 'creates and uses a new word list based on new buffer', -> diff --git a/src/app/autocomplete.coffee b/src/app/autocomplete.coffee index fd9dee406..240550d3c 100644 --- a/src/app/autocomplete.coffee +++ b/src/app/autocomplete.coffee @@ -37,7 +37,7 @@ class Autocomplete extends View @currentBuffer = buffer @buildWordList() - @currentBuffer.on 'change.autocomplete', => @bufferChanged() + @currentBuffer.on 'change.autocomplete', (e) => @bufferChanged(e) cancel: -> @detach() @@ -86,13 +86,27 @@ class Autocomplete extends View nextIndex = (@currentMatchIndex + 1) % @matches.length @selectMatch(nextIndex) - bufferChanged: -> - @buildMatchList() if @parent()[0] and not @isAutocompleting + bufferChanged: (e) -> + if @parent()[0] and not @isAutocompleting + selectedMatch = @selectedMatch() + @buildMatchList() + if @matches.length == 0 + @detach() + @currentBuffer.undo() + @completeUsingMatch(selectedMatch) + @editor.getSelection().clearSelection() + @editor.insertText(e.newText) + return + @buildWordList() unless @isAutocompleting buildMatchList: -> selection = @editor.getSelection() {prefix, suffix} = @prefixAndSuffixOfSelection(selection) + if (prefix.length + suffix.length) == 0 + @matches = [] + return + currentWord = prefix + @editor.getSelectedText() + suffix @matches = (match for match in @wordMatches(prefix, suffix) when match[0] != currentWord) @@ -121,10 +135,12 @@ class Autocomplete extends View @currentMatchIndex = index @matchesList.find("li").removeClass "selected" @matchesList.find("li:eq(#{index})").addClass "selected" - @completeUsingMatch(index) + @completeUsingMatch(@selectedMatch()) - completeUsingMatch: (matchIndex) -> - match = @matches[matchIndex] + selectedMatch: -> + @matches[@currentMatchIndex] + + completeUsingMatch: (match) -> selection = @editor.getSelection() startPosition = selection.getBufferRange().start @isAutocompleting = true