diff --git a/src/goSuggest.ts b/src/goSuggest.ts index f6493bab7..9a7127ad1 100644 --- a/src/goSuggest.ts +++ b/src/goSuggest.ts @@ -41,10 +41,16 @@ function vscodeKindFromGoCodeClass(kind: string, type: string): vscode.Completio interface GoCodeSuggestion { class: string; + package?: string; name: string; type: string; } +class ExtendedCompletionItem extends vscode.CompletionItem { + package?: string; + fileName: string; +} + const lineCommentRegex = /^\s*\/\/\s+/; const exportedMemberRegex = /(const|func|type|var)(\s+\(.*\))?\s+([A-Z]\w*)/; const gocodeNoSupportForgbMsgKey = 'dontshowNoSupportForgb'; @@ -75,6 +81,49 @@ export class GoCompletionItemProvider implements vscode.CompletionItemProvider { }); } + public resolveCompletionItem(item: vscode.CompletionItem, token: vscode.CancellationToken): vscode.ProviderResult { + const goRuntimePath = getBinPath('go'); + if (!goRuntimePath || !(item instanceof ExtendedCompletionItem)) { + return; + } + + if (typeof item.package === 'undefined') { + promptForUpdatingTool('gocode'); + return; + } + + const env = getToolsEnvVars(); + const cwd = path.dirname(item.fileName); + + return new Promise(resolve => { + const args = ['doc', '-c', '-cmd', '-u']; + if (item.package) { + args.push(item.package, item.label); + } else { + // item.package would be empty for symbols from the current package + args.push(item.label); + } + + cp.execFile(goRuntimePath, args, { cwd, env }, (err, stdout) => { + if (err) { + console.log(err); + return resolve(item); + } + + let doc = ''; + const goDocLines = stdout.toString().split('\n'); + // i = 1 to skip the func signature line + for (let i = 1; i < goDocLines.length && goDocLines[i].startsWith(' '); i++) { + doc += goDocLines[i].substring(4) + '\n'; + } + + item.documentation = doc; + resolve(item); + }); + }); + + } + public provideCompletionItemsInternal(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, config: vscode.WorkspaceConfiguration): Thenable { return this.ensureGoCodeConfigured(document.uri).then(() => { return new Promise((resolve, reject) => { @@ -228,9 +277,11 @@ export class GoCompletionItemProvider implements vscode.CompletionItemProvider { if (results && results[1]) { for (let suggest of results[1]) { if (inString && suggest.class !== 'import') continue; - let item = new vscode.CompletionItem(suggest.name); + let item = new ExtendedCompletionItem(suggest.name); item.kind = vscodeKindFromGoCodeClass(suggest.class, suggest.type); item.detail = suggest.type; + item.package = suggest.package; + item.fileName = document.fileName; if (inString && suggest.class === 'import') { item.textEdit = new vscode.TextEdit( new vscode.Range( @@ -454,4 +505,4 @@ export class GoCompletionItemProvider implements vscode.CompletionItemProvider { }); return matchingPackages; } -} \ No newline at end of file +}