Skip to content

Commit

Permalink
Use gopls for Add Import feature
Browse files Browse the repository at this point in the history
  • Loading branch information
marwan-at-work committed Dec 23, 2020
1 parent 6c7bfb3 commit b7b1f68
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 9 deletions.
38 changes: 31 additions & 7 deletions src/goImport.ts
Expand Up @@ -6,9 +6,11 @@
'use strict';

import cp = require('child_process');
import { lang } from 'moment';
import vscode = require('vscode');
import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import { AddImportRequest, KnownPackagesRequest, languageClient } from './goLanguageServer';
import { documentSymbols, GoOutlineImportsOptions } from './goOutline';
import { getImportablePackages } from './goPackages';
import { getBinPath, getImportPath, parseFilePrelude } from './util';
Expand Down Expand Up @@ -37,6 +39,22 @@ export async function listPackages(excludeImportedPkgs: boolean = false): Promis
return [...stdLibs.sort(), ...nonStdLibs.sort()];
}

async function golist(): Promise<string[]> {
const editor = vscode.window.activeTextEditor;
if (editor && languageClient && !languageClient.needsStart() ) {
try {
const document = languageClient.code2ProtocolConverter.asTextDocumentIdentifier(editor.document);
const resp = await languageClient.sendRequest(KnownPackagesRequest.type, { textDocument: document });
return resp;
} catch (error) {
console.log(error);
}
}
// fallback to gopkgs, once/if deprecated we can show
// an error message about gopls not being turned on instead.
return listPackages(true);
}

/**
* Returns the imported packages in the given file
*
Expand All @@ -62,7 +80,7 @@ async function getImports(document: vscode.TextDocument): Promise<string[]> {

async function askUserForImport(): Promise<string | undefined> {
try {
const packages = await listPackages(true);
const packages = await golist();
return vscode.window.showQuickPick(packages);
} catch (err) {
if (typeof err === 'string' && err.startsWith(missingToolMsg)) {
Expand Down Expand Up @@ -128,15 +146,21 @@ export function addImport(arg: { importPath: string; from: string }) {
return;
}
const p = arg && arg.importPath ? Promise.resolve(arg.importPath) : askUserForImport();
p.then((imp) => {
p.then(async (imp) => {
if (!imp) {
return;
}
const edits = getTextEditForAddImport(imp);
if (edits && edits.length > 0) {
const edit = new vscode.WorkspaceEdit();
edit.set(editor.document.uri, edits);
vscode.workspace.applyEdit(edit);
const editor = vscode.window.activeTextEditor;
if (editor) {
try {
const document = languageClient.code2ProtocolConverter.asTextDocumentIdentifier(editor.document);
await languageClient.sendRequest(AddImportRequest.type, {
textDocument: document,
importPath: imp,
});
} catch (error) {
vscode.window.showErrorMessage(`could not add improt: ${error}`);
}
}
});
}
Expand Down
26 changes: 24 additions & 2 deletions src/goLanguageServer.ts
Expand Up @@ -24,11 +24,14 @@ import {
HandleDiagnosticsSignature,
InitializeError,
Message,
ProtocolRequestType,
ProvideCodeLensesSignature,
ProvideCompletionItemsSignature,
ProvideDocumentLinksSignature,
ResponseError,
RevealOutputChannelOn
RevealOutputChannelOn,
TextDocumentIdentifier,
WorkDoneProgressParams
} from 'vscode-languageclient';
import {
LanguageClient
Expand Down Expand Up @@ -66,6 +69,25 @@ import {
} from './util';
import { getToolFromToolPath } from './utils/pathUtils';

interface KnownPackagesRequestParams {
textDocument: TextDocumentIdentifier;
}

export namespace KnownPackagesRequest {
export const method: 'gopls/knownPackages' = 'gopls/knownPackages';
export const type = new ProtocolRequestType<KnownPackagesRequestParams, never, never, void, void>(method);
}

interface AddImportRequestParams extends WorkDoneProgressParams {
textDocument: TextDocumentIdentifier;
importPath: string;
}

export namespace AddImportRequest {
export const method: 'gopls/addImport' = 'gopls/addImport';
export const type = new ProtocolRequestType<AddImportRequestParams, never, never, void, void>(method);
}

export interface LanguageServerConfig {
serverName: string;
path: string;
Expand All @@ -84,7 +106,7 @@ export interface LanguageServerConfig {
// Global variables used for management of the language client.
// They are global so that the server can be easily restarted with
// new configurations.
let languageClient: LanguageClient;
export let languageClient: LanguageClient;
let languageServerDisposable: vscode.Disposable;
let latestConfig: LanguageServerConfig;
export let serverOutputChannel: vscode.OutputChannel;
Expand Down

0 comments on commit b7b1f68

Please sign in to comment.