Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src/goImpl: improve goimpl implememtations (#1547) #1592

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
17 changes: 16 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"diff": "^4.0.2",
"glob": "^7.1.6",
"json-rpc2": "^2.0.0",
"lodash": "^4.17.21",
"moment": "^2.24.0",
"semver": "^7.3.2",
"tree-kill": "file:third_party/tree-kill",
Expand All @@ -68,6 +69,7 @@
"@types/deep-equal": "^1.0.1",
"@types/fs-extra": "^8.1.0",
"@types/glob": "^7.1.1",
"@types/lodash": "^4.14.178",
"@types/mocha": "^7.0.2",
"@types/node": "^13.11.1",
"@types/semver": "^7.1.0",
Expand Down
82 changes: 58 additions & 24 deletions src/goImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,21 @@ import { toolExecutionEnvironment } from './goEnv';
import { promptForMissingTool } from './goInstallTools';
import { getBinPath } from './util';
import vscode = require('vscode');
import { debounce } from 'lodash';

// Supports only passing interface, see TODO in implCursor to finish
const inputRegex = /^(\w+\ \*?\w+\ )?([\w\.\-\/]+)$/;
class InterfaceItem implements vscode.QuickPickItem {
public label: string;
public description: string;
public name: string;
public package: string;

constructor(symbol: vscode.SymbolInformation) {
this.label = symbol.name;
this.description = symbol.containerName;
this.name = symbol.name.split('.').pop(); // in case, symbol contains package name.
this.package = symbol.containerName;
}
}

export function implCursor() {
const editor = vscode.window.activeTextEditor;
Expand All @@ -24,27 +36,45 @@ export function implCursor() {
return;
}
const cursor = editor.selection;
return vscode.window
.showInputBox({
placeHolder: 'f *File io.Closer',
prompt: 'Enter receiver and interface to implement.'
})
.then((implInput) => {
if (typeof implInput === 'undefined') {
return;
}
const matches = implInput.match(inputRegex);
if (!matches) {
vscode.window.showInformationMessage(`Not parsable input: ${implInput}`);
return;
}
const quickPick = vscode.window.createQuickPick();
quickPick.placeholder = 'Input interface name (e.g. Client)';

// TODO: automatically detect type name at cursor
// if matches[1] is undefined then detect receiver type
// take first character and use as receiver name
const search = function (keyword: string) {
quickPick.busy = true;
vscode.commands
.executeCommand<vscode.SymbolInformation[]>('vscode.executeWorkspaceSymbolProvider', keyword)
.then((symbols) => {
if (symbols === undefined) {
return;
}

quickPick.items = symbols
.filter((symbol) => symbol.kind === vscode.SymbolKind.Interface)
.map((symbol) => {
return new InterfaceItem(symbol);
});
});

runGoImpl([matches[1], matches[2]], cursor.start, editor);
});
quickPick.busy = false;
};

quickPick.onDidChangeValue(debounce(search, 250));

quickPick.onDidChangeSelection((selections: readonly vscode.QuickPickItem[]) => {
if (typeof selections === 'undefined') {
return;
}
console.debug('onDidChangeSelection ', selections);
const item = selections[0];
if (item instanceof InterfaceItem) {
console.debug(item);
runGoImpl(['ReceiverName__ *Receiver__', item.package + '.' + item.name], cursor.start, editor);
}
});

quickPick.show();

return;
}

function runGoImpl(args: string[], insertPos: vscode.Position, editor: vscode.TextEditor) {
Expand All @@ -64,9 +94,13 @@ function runGoImpl(args: string[], insertPos: vscode.Position, editor: vscode.Te
return;
}

editor.edit((editBuilder) => {
editBuilder.insert(insertPos, stdout);
});
// replace ReceiverName_ and Receiver__ with placeholders
let stub = '\n' + stdout + '\n';
stub = stub.replace(new RegExp('ReceiverName__', 'g'), '${0:r}');
stub = stub.replace(new RegExp('Receiver__', 'g'), '${1:receiver}');

const snippet = new vscode.SnippetString(stub);
editor.insertSnippet(snippet, insertPos);
}
);
if (p.pid) {
Expand Down
Loading