From 1353da9b5d58ad02712bf7145ff23d49c8df2ac1 Mon Sep 17 00:00:00 2001 From: Joe Fitzgerald Date: Mon, 2 Apr 2018 11:41:49 -0600 Subject: [PATCH] Fix prefix calculation when caching - Fixes #745 Co-authored by: Zac Bergquist --- lib/autocomplete/gocodeprovider.js | 12 ++-- spec/autocomplete/gocodeprovider-spec.js | 73 +++++++++++++++++++++++- spec/fixtures/go-plus-issue-745/main.go | 10 ++++ 3 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 spec/fixtures/go-plus-issue-745/main.go diff --git a/lib/autocomplete/gocodeprovider.js b/lib/autocomplete/gocodeprovider.js index 0656f15a..0c56dce3 100644 --- a/lib/autocomplete/gocodeprovider.js +++ b/lib/autocomplete/gocodeprovider.js @@ -30,6 +30,7 @@ class GocodeProvider implements AutocompleteProvider { subscriptions: CompositeDisposable subscribers: Array<(Promise) => void> currentSuggestions: Array + currentPrefixStartIndex: number proposeBuiltins: bool unimportedPackages: bool selector: string @@ -50,6 +51,7 @@ class GocodeProvider implements AutocompleteProvider { this.subscriptions = new CompositeDisposable() this.subscribers = [] this.currentSuggestions = [] + this.currentPrefixStartIndex = -1 this.currentFile = '' this.currentRow = -1 this.currentColumn = -1 @@ -179,12 +181,13 @@ class GocodeProvider implements AutocompleteProvider { this.currentFile = '' this.currentRow = -1 this.currentColumn = -1 + this.currentPrefixStartIndex = -1 } getSuggestions (options: SuggestionRequest): Promise> { // only invoke gocode when a new word starts or the '.' char is entered // on all other keystrokes we just fuzzy filter the previous set of suggestions - let {prefix, bufferPosition, editor} = options + let {prefix, bufferPosition, editor, scopeDescriptor} = options prefix = prefix.trim() if (prefix === '') { if (!options.activatedManually) { @@ -203,8 +206,9 @@ class GocodeProvider implements AutocompleteProvider { if (useCache && this.currentSuggestions.length && prefix.length > 0 && !prefix.endsWith('.')) { // fuzzy filter on this.currentSuggestions const p = new Promise((resolve) => { + const newPrefix = editor.getTextInBufferRange([[bufferPosition.row, bufferPosition.column - this.currentPrefixStartIndex - 1], bufferPosition]) const fil = filter(this.currentSuggestions, prefix, {key: 'fuzzyMatch'}) - .map(s => Object.assign({}, s, {replacementPrefix: prefix})) + .map(s => Object.assign({}, s, {replacementPrefix: newPrefix})) this.currentFile = editor.getPath() this.currentRow = bufferPosition.row this.currentColumn = bufferPosition.column @@ -351,8 +355,8 @@ class GocodeProvider implements AutocompleteProvider { if (candidates[0] && candidates[0].class === 'PANIC' && candidates[0].type === 'PANIC' && candidates[0].name === 'PANIC') { this.bounceGocode() } - const numPrefix: number = res[0] - const prefix = editor.getTextInBufferRange([[position.row, position.column - numPrefix], position]) + this.currentPrefixStartIndex = res[0] + const prefix = editor.getTextInBufferRange([[position.row, position.column - this.currentPrefixStartIndex], position]) let suffix = '' try { suffix = editor.getTextInBufferRange([position, [position.row, position.column + 1]]) diff --git a/spec/autocomplete/gocodeprovider-spec.js b/spec/autocomplete/gocodeprovider-spec.js index bc12df2f..1fdbe657 100644 --- a/spec/autocomplete/gocodeprovider-spec.js +++ b/spec/autocomplete/gocodeprovider-spec.js @@ -250,6 +250,78 @@ describe('gocodeprovider', () => { }) }) + describe('when the go-plus-issue-745 file is opened', () => { + let suggestions = null + beforeEach(() => { + waitsForPromise(() => { + return atom.workspace.open('go-plus-issue-745' + path.sep + 'main.go').then((e) => { + editor = e + editorView = atom.views.getView(editor) + }) + }) + }) + + it('calculates the prefix correctly', () => { + runs(() => { + expect(provider).toBeDefined() + expect(provider.getSuggestions).not.toHaveBeenCalled() + expect(editorView.querySelector('.autocomplete-plus')).not.toExist() + editor.setCursorBufferPosition([4, 10]) + editor.backspace() + editor.backspace() + editor.backspace() + suggestions = null + suggestionsPromise = null + advanceClock(completionDelay) + }) + + runs(() => { + expect(provider.getSuggestions.calls.length).toBe(0) + expect(suggestionsPromise).toBeFalsy() + editor.insertText('t') + advanceClock(completionDelay) + }) + + waitsFor(() => { + return provider.getSuggestions.calls.length === 1 && suggestionsPromise !== null + }) + + waitsForPromise(() => { + return suggestionsPromise.then((s) => { + suggestions = s + }) + }) + + runs(() => { + expect(provider.getSuggestions.calls.length).toBe(1) + expect(suggestionsPromise).toBeTruthy() + suggestionsPromise = null + editor.insertText('t') + advanceClock(completionDelay) + }) + + waitsFor(() => { + return provider.getSuggestions.calls.length === 2 && suggestionsPromise !== null + }) + + waitsForPromise(() => { + return suggestionsPromise.then((s) => { + suggestions = s + }) + }) + + runs(() => { + expect(provider.getSuggestions).toHaveBeenCalled() + expect(provider.getSuggestions.calls.length).toBe(2) + expect(suggestions).toBeTruthy() + expect(suggestions.length).toBeGreaterThan(0) + expect(suggestions[0]).toBeTruthy() + expect(suggestions[0].text).toBe('net/http') + expect(suggestions[0].replacementPrefix).toBe('net/htt') + }) + }) + }) + describe('when the go-plus-issue-307 file is opened', () => { let suggestions = null beforeEach(() => { @@ -410,7 +482,6 @@ describe('gocodeprovider', () => { runs(() => { expect(provider.getSuggestions.calls.length).toBe(0) expect(suggestionsPromise).toBeFalsy() - console.log('insert .') editor.insertText('.') advanceClock(completionDelay) diff --git a/spec/fixtures/go-plus-issue-745/main.go b/spec/fixtures/go-plus-issue-745/main.go new file mode 100644 index 00000000..7d0c6463 --- /dev/null +++ b/spec/fixtures/go-plus-issue-745/main.go @@ -0,0 +1,10 @@ +package main + +import ( + "fmt" + "net/http" +) + +func main() { + fmt.Println(string(http.MethodGet)) +}