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

Commit

Permalink
When using go-languageserver, also use code completion feature (#1607)
Browse files Browse the repository at this point in the history
* When using go-languageserver, also use code completion

Instead of using go-code, use go-languageserver for providing
code completion results when enabled. Solves #1593

* Add naive feature detect for language server feature

In case executing the binary with an unknown flag does not yield
the -gocodecompletion flag in the help output, we assume the version
installed is out of date and prompt for updating

* Also consider case where -help might be added at some point in the future

* Pass func snippet completion pref, fall back to non-server completion when unsupported

* Check supported language server flags and filter before passing

* Use initializationOptions for triggering langserver based features

* Revert changes to langserver detection, merge onReady callbacks, show message about outdated langserver version

* Refactoring

* stricter checks
  • Loading branch information
m90 authored and ramya-rao-a committed May 27, 2018
1 parent fbf84b8 commit 372b0fe
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 18 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ The Go extension is ready to use on the get go. If you want to customize the fea

The Go extension uses a host of Go tools to provide the various language features. An alternative is to use a single language server that provides the same feature.

Set `go.useLanguageServer` to `true` to use the Go language server from [Sourcegraph](https://github.com/sourcegraph/go-langserver) for features like Hover, Definition, Find All References, Signature Help, Go to Symbol in File and Workspace.
Set `go.useLanguageServer` to `true` to use the Go language server from [Sourcegraph](https://github.com/sourcegraph/go-langserver) for features like Code completion, Hover, Definition, Find All References, Signature Help, Go to Symbol in File and Workspace.
* This is an experimental feature and is not available in Windows yet.
* Since only a single language server is spun up for given VS Code instance, having multi-root setup where the folders have different GOPATH is not supported.
* If set to true, you will be prompted to install the Go language server. Once installed, you will have to reload VS Code window. The language server will then be run by the Go extension in the background to provide services needed for the above mentioned features.
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -702,10 +702,16 @@
"type": "boolean",
"default": false,
"description": "If true, gofmt is used by the language server to format files."
},
"autoComplete": {
"type": "boolean",
"default": false,
"description": "If true, the language server will provide code completion results."
}
},
"default": {
"format": false
"format": false,
"autoComplete": false
},
"description": "Use this setting to enable/disable experimental features from the language server."
},
Expand Down
7 changes: 1 addition & 6 deletions src/goInstallTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ function installTools(goVersion: SemVersion, missing?: string[]) {
outputChannel.appendLine(''); // Blank line for spacing
let failures = res.filter(x => x != null);
if (failures.length === 0) {
if (missing.indexOf('langserver-go') > -1) {
if (missing.indexOf('go-langserver') > -1) {
outputChannel.appendLine('Reload VS Code window to use the Go language server');
}
outputChannel.appendLine('All tools successfully installed. You\'re ready to Go :).');
Expand Down Expand Up @@ -411,8 +411,3 @@ function allFoldersHaveSameGopath(): boolean {
let tempGopath = getCurrentGoPath(vscode.workspace.workspaceFolders[0].uri);
return vscode.workspace.workspaceFolders.find(x => tempGopath !== getCurrentGoPath(x.uri)) ? false : true;
}





45 changes: 35 additions & 10 deletions src/goMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import * as goGenerateTests from './goGenerateTests';
import { addImport } from './goImport';
import { installAllTools, checkLanguageServer } from './goInstallTools';
import { isGoPathSet, getBinPath, sendTelemetryEvent, getExtensionCommands, getGoVersion, getCurrentGoPath, getToolsGopath, handleDiagnosticErrors, disposeTelemetryReporter, getToolsEnvVars } from './util';
import { LanguageClient, RevealOutputChannelOn, FormattingOptions, ProvideDocumentFormattingEditsSignature } from 'vscode-languageclient';
import { LanguageClient, RevealOutputChannelOn, FormattingOptions, ProvideDocumentFormattingEditsSignature, ProvideCompletionItemsSignature } from 'vscode-languageclient';
import { clearCacheForTools, fixDriveCasingInWindows } from './goPath';
import { addTags, removeTags } from './goModifytags';
import { runFillStruct } from './goFillStruct';
Expand All @@ -52,10 +52,8 @@ export let warningDiagnosticCollection: vscode.DiagnosticCollection;
export function activate(ctx: vscode.ExtensionContext): void {

let useLangServer = vscode.workspace.getConfiguration('go')['useLanguageServer'];
let langServerFlags: string[] = vscode.workspace.getConfiguration('go')['languageServerFlags'] || [];

updateGoPathGoRootFromConfig().then(() => {
const languageServerExperimentalFeatures = vscode.workspace.getConfiguration('go').get('languageServerExperimentalFeatures') || {};
const updateToolsCmdText = 'Update tools';
const prevGoroot = ctx.globalState.get('goroot');
const currentGoroot = process.env['GOROOT'];
Expand Down Expand Up @@ -87,9 +85,10 @@ export function activate(ctx: vscode.ExtensionContext): void {
ctx.globalState.update('goroot', currentGoroot);

offerToInstallTools();
let langServerAvailable = checkLanguageServer();
if (langServerAvailable) {
if (checkLanguageServer()) {
const languageServerExperimentalFeatures = vscode.workspace.getConfiguration('go').get('languageServerExperimentalFeatures') || {};
let langServerFlags: string[] = vscode.workspace.getConfiguration('go')['languageServerFlags'] || [];

const c = new LanguageClient(
'go-langserver',
{
Expand All @@ -100,6 +99,10 @@ export function activate(ctx: vscode.ExtensionContext): void {
}
},
{
initializationOptions: {
funcSnippetEnabled: vscode.workspace.getConfiguration('go')['useCodeSnippetsOnFunctionSuggest'],
gocodeCompletionEnabled: languageServerExperimentalFeatures['autoComplete']
},
documentSelector: ['go'],
uriConverters: {
// Apply file:/// scheme to all file paths.
Expand All @@ -113,20 +116,43 @@ export function activate(ctx: vscode.ExtensionContext): void {
return next(document, options, token);
}
return [];
},
provideCompletionItem: (document: vscode.TextDocument, position: vscode.Position, context: vscode.CompletionContext, token: vscode.CancellationToken, next: ProvideCompletionItemsSignature) => {
if (languageServerExperimentalFeatures['autoComplete'] === true) {
return next(document, position, context, token);
}
return [];
}
}
}
);

ctx.subscriptions.push(c.start());

c.onReady().then(() => {
if (!languageServerExperimentalFeatures['format'] ||
!(c.initializeResult && c.initializeResult.capabilities && c.initializeResult.capabilities.documentFormattingProvider)) {
const capabilities = c.initializeResult && c.initializeResult.capabilities;
if (!capabilities) {
return vscode.window.showErrorMessage('The language server is not able to serve any features at the moment.');
}

const outdatedMsg = `Your installed version of "go-langserver" is out of date and does not support {0}. Falling back to default behavior.`;

if (languageServerExperimentalFeatures['autoComplete'] !== true || !capabilities.completionProvider) {
ctx.subscriptions.push(vscode.languages.registerCompletionItemProvider(GO_MODE, new GoCompletionItemProvider(), '.', '\"'));
if (languageServerExperimentalFeatures['autoComplete'] === true) {
vscode.window.showInformationMessage(outdatedMsg.replace('{0}', 'code completion'));
}
}

if (languageServerExperimentalFeatures['format'] !== true || !capabilities.documentFormattingProvider) {
ctx.subscriptions.push(vscode.languages.registerDocumentFormattingEditProvider(GO_MODE, new GoDocumentFormattingEditProvider()));
if (languageServerExperimentalFeatures['format'] === true) {
vscode.window.showInformationMessage(outdatedMsg.replace('{0}', 'code formatting'));
}
}
});

ctx.subscriptions.push(c.start());
} else {
ctx.subscriptions.push(vscode.languages.registerCompletionItemProvider(GO_MODE, new GoCompletionItemProvider(), '.', '\"'));
ctx.subscriptions.push(vscode.languages.registerHoverProvider(GO_MODE, new GoHoverProvider()));
ctx.subscriptions.push(vscode.languages.registerDefinitionProvider(GO_MODE, new GoDefinitionProvider()));
ctx.subscriptions.push(vscode.languages.registerReferenceProvider(GO_MODE, new GoReferenceProvider()));
Expand All @@ -147,7 +173,6 @@ export function activate(ctx: vscode.ExtensionContext): void {
let testCodeLensProvider = new GoRunTestCodeLensProvider();
let referencesCodeLensProvider = new GoReferencesCodeLensProvider();

ctx.subscriptions.push(vscode.languages.registerCompletionItemProvider(GO_MODE, new GoCompletionItemProvider(), '.', '\"'));
ctx.subscriptions.push(vscode.languages.registerRenameProvider(GO_MODE, new GoRenameProvider()));
ctx.subscriptions.push(vscode.languages.registerCodeActionsProvider(GO_MODE, new GoCodeActionProvider()));
ctx.subscriptions.push(vscode.languages.registerCodeLensProvider(GO_MODE, testCodeLensProvider));
Expand Down

0 comments on commit 372b0fe

Please sign in to comment.