Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

Commit

Permalink
Added completions for symbols from unimported pkg if there are multip…
Browse files Browse the repository at this point in the history
…le matches for pkg name (#1900)

* Fix for issue 1884

* Trigger suggestions after user chooses fromt the list

* Include check for import block in tests

* Missing semicolon

* Fix failing test case
  • Loading branch information
Shreyas Karnik authored and ramya-rao-a committed Sep 20, 2018
1 parent 7885423 commit eff0139
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 9 deletions.
30 changes: 22 additions & 8 deletions src/goSuggest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,11 @@ export class GoCompletionItemProvider implements vscode.CompletionItemProvider {
if (suggestions.length === 0 && lineTillCurrentPosition.endsWith('.')) {

let pkgPath = this.getPackagePathFromLine(lineTillCurrentPosition);
if (pkgPath) {
if (pkgPath.length === 1) {
// Now that we have the package path, import it right after the "package" statement
let { imports, pkg } = parseFilePrelude(vscode.window.activeTextEditor.document.getText());
let posToAddImport = document.offsetAt(new vscode.Position(pkg.start + 1, 0));
let textToAdd = `import "${pkgPath}"\n`;
let textToAdd = `import "${pkgPath[0]}"\n`;
inputText = inputText.substr(0, posToAddImport) + textToAdd + inputText.substr(posToAddImport);
offset += textToAdd.length;

Expand All @@ -131,11 +131,28 @@ export class GoCompletionItemProvider implements vscode.CompletionItemProvider {
// add additionalTextEdits to do the same in the actual document in the editor
// We use additionalTextEdits instead of command so that 'useCodeSnippetsOnFunctionSuggest' feature continues to work
newsuggestions.forEach(item => {
item.additionalTextEdits = getTextEditForAddImport(pkgPath);
item.additionalTextEdits = getTextEditForAddImport(pkgPath[0]);
});
resolve(newsuggestions);
}, reject);
}
if (pkgPath.length > 1) {
pkgPath.forEach(pkg => {
let item = new vscode.CompletionItem(
`${lineTillCurrentPosition.replace('.', '').trim()} (${pkg})`,
vscode.CompletionItemKind.Module
);
item.additionalTextEdits = getTextEditForAddImport(pkg);
item.insertText = '';
item.detail = pkg;
item.command = {
title: 'Trigger Suggest',
command: 'editor.action.triggerSuggest'
};
suggestions.push(item);
});
resolve(suggestions);
}
}
resolve(suggestions);
}, reject);
Expand Down Expand Up @@ -396,7 +413,7 @@ export class GoCompletionItemProvider implements vscode.CompletionItemProvider {
}

// Given a line ending with dot, return the word preceeding the dot if it is a package name that can be imported
private getPackagePathFromLine(line: string): string {
private getPackagePathFromLine(line: string): string[] {
let pattern = /(\w+)\.$/g;
let wordmatches = pattern.exec(line);
if (!wordmatches) {
Expand All @@ -411,9 +428,6 @@ export class GoCompletionItemProvider implements vscode.CompletionItemProvider {
matchingPackages.push(pkgPath);
}
});

if (matchingPackages && matchingPackages.length === 1) {
return matchingPackages[0];
}
return matchingPackages;
}
}
5 changes: 5 additions & 0 deletions test/fixtures/completions/unimportedMultiplePkgs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package main

func main() {
template.
}
2 changes: 1 addition & 1 deletion test/fixtures/fillStruct/golden_2.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
func main() {
_ = http.Client{
Transport: nil,
CheckRedirect: nil,
CheckRedirect: func(*http.Request, []*http.Request) error { panic("not implemented") },
Jar: nil,
Timeout: 0,
}
Expand Down
36 changes: 36 additions & 0 deletions test/go.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ suite('Go Extension Tests', () => {
fs.copySync(path.join(fixtureSourcePath, 'buildTags', 'hello.go'), path.join(fixturePath, 'buildTags', 'hello.go'));
fs.copySync(path.join(fixtureSourcePath, 'testTags', 'hello_test.go'), path.join(fixturePath, 'testTags', 'hello_test.go'));
fs.copySync(path.join(fixtureSourcePath, 'completions', 'unimportedPkgs.go'), path.join(fixturePath, 'completions', 'unimportedPkgs.go'));
fs.copySync(path.join(fixtureSourcePath, 'completions', 'unimportedMultiplePkgs.go'), path.join(fixturePath, 'completions', 'unimportedMultiplePkgs.go'));
fs.copySync(path.join(fixtureSourcePath, 'completions', 'snippets.go'), path.join(fixturePath, 'completions', 'snippets.go'));
fs.copySync(path.join(fixtureSourcePath, 'completions', 'nosnippets.go'), path.join(fixturePath, 'completions', 'nosnippets.go'));
fs.copySync(path.join(fixtureSourcePath, 'completions', 'exportedMemberDocs.go'), path.join(fixturePath, 'completions', 'exportedMemberDocs.go'));
Expand Down Expand Up @@ -948,6 +949,41 @@ It returns the number of bytes written and any write error encountered.
}).then(() => done(), done);
});

test('Test Completion on unimported packages (multiple)', (done) => {
let config = Object.create(vscode.workspace.getConfiguration('go'), {});
let provider = new GoCompletionItemProvider();
let position = new vscode.Position(3, 14);
let expectedItems = [
{
label: 'template (html/template)',
import: '\nimport (\n\t"html/template"\n)\n'
},
{
label: 'template (text/template)',
import: '\nimport (\n\t"text/template"\n)\n'
}
];
let uri = vscode.Uri.file(path.join(fixturePath, 'completions', 'unimportedMultiplePkgs.go'));
vscode.workspace.openTextDocument(uri).then((textDocument) => {
return vscode.window.showTextDocument(textDocument).then(editor => {
return provider.provideCompletionItemsInternal(editor.document, position, null, config).then(items => {
let labels = items.map(x => x.label);
expectedItems.forEach(expectedItem => {
const actualItem: vscode.CompletionItem = items.filter(item => item.label === expectedItem.label)[0];
if (!actualItem) {
assert.fail(actualItem, expectedItem, `Missing expected item in completion list: ${expectedItem.label} Actual: ${labels}`);
return;
}
assert.equal(actualItem.additionalTextEdits.length, 1);
assert.equal(actualItem.additionalTextEdits[0].newText, expectedItem.import);
});
}).then(() => vscode.commands.executeCommand('workbench.action.closeActiveEditor'));
});
}, (err) => {
assert.ok(false, `error in OpenTextDocument ${err}`);
}).then(() => done(), done);
});

test('Test Completion on Comments for Exported Members', (done) => {
let provider = new GoCompletionItemProvider();
let testCases: [vscode.Position, string[]][] = [
Expand Down

0 comments on commit eff0139

Please sign in to comment.