[vscode-go] goImpl: improvements

9 views
Skip to first unread message

Gerrit Bot (Gerrit)

unread,
Aug 12, 2023, 9:10:41 AM8/12/23
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Gerrit Bot has uploaded this change for review.

View Change

goImpl: improvements

Improvements:
1. Now variable and type can be deduced from cursor selection
2. Now you can implement multiple interfaces at once

Note: I'm assuming that PR will be rejected due to Commit/PR guidelines, but c'mon this is useful change.
If you are planning to add this change anyway but with correct Commit/PR, just add credits, or smth.

Change-Id: Ie9649ae6afc957c12c41045fb8b720ea2e3f49a9
GitHub-Last-Rev: 93b18612d4f018b0561303a66b9603c86732fe86
GitHub-Pull-Request: golang/vscode-go#2936
---
M src/goImpl.ts
1 file changed, 55 insertions(+), 29 deletions(-)

diff --git a/src/goImpl.ts b/src/goImpl.ts
index 61ac926..ea8b649 100644
--- a/src/goImpl.ts
+++ b/src/goImpl.ts
@@ -15,8 +15,12 @@
import vscode = require('vscode');
import { CommandFactory } from './commands';

-// Supports only passing interface, see TODO in implCursor to finish
-const inputRegex = /^(\w+\ \*?\w+\ )?([\w\.\-\/]+)$/;
+// Accepts input of the form:
+// [f *File] io.Closer [, ...]
+// [f *File] io.Closer
+// io.Closer (type name will be deduced from variable name from cursor position)
+// io.Closer, io.Reader (same as above)
+const inputRegex = /^(?<identifier>(?<variable>[\p{Letter}_][\p{Letter}_\p{Number}\d]*) *(?<type>[*]? *[\p{Letter}_][\p{Letter}_\p{Number}\d]*) +)?(?<interfaces>(?:[\p{Letter}_][\p{Letter}_\p{Number}\d\.\-\/]*)+(?: *, *(?:[\p{Letter}_][\p{Letter}_\p{Number}\d\.\-\/]*)+)*)$/u;

export const implCursor: CommandFactory = () => () => {
const editor = vscode.window.activeTextEditor;
@@ -27,7 +31,7 @@
const cursor = editor.selection;
return vscode.window
.showInputBox({
- placeHolder: 'f *File io.Closer',
+ placeHolder: '[f *File] io.Closer [, ...]',
prompt: 'Enter receiver and interface to implement.'
})
.then((implInput) => {
@@ -35,42 +39,64 @@
return;
}
const matches = implInput.match(inputRegex);
- if (!matches) {
+ if (!matches || !matches.groups || !matches.groups.interfaces) {
vscode.window.showInformationMessage(`Not parsable input: ${implInput}`);
return;
}

- // TODO: automatically detect type name at cursor
- // if matches[1] is undefined then detect receiver type
- // take first character and use as receiver name
+ let identifier = matches.groups?.identifier;
+ if (!identifier) {
+ const beforeCursor = new vscode.Range(new vscode.Position(cursor.start.line, 0), cursor.start);
+ const beforeCursorText = editor.document.getText(beforeCursor);
+ const typeIndex = beforeCursorText.lastIndexOf('type');
+ if (typeIndex === -1) {
+ vscode.window.showInformationMessage('No identifier found at cursor.');
+ return;
+ }

- runGoImpl([matches[1], matches[2]], cursor.start, editor);
+ const variable = editor.document.getText(cursor)[0].toLowerCase();
+ identifier = editor.document.getText(cursor);
+ identifier = `${variable} *${identifier}`;
+
+ let newPosition = cursor.start.with(cursor.start.line + 1, 0);
+ newPosition = newPosition.translate(1, 0);
+ editor.selection = new vscode.Selection(newPosition, newPosition);
+ }
+ const interfaces = matches.groups?.interfaces.trim().split(',');
+ interfaces.forEach((iface, i) => {
+ interfaces[i] = iface.trim();
+ });
+ runGoImpl([identifier, interfaces], editor);
});
};

-function runGoImpl(args: string[], insertPos: vscode.Position, editor: vscode.TextEditor) {
+function runGoImpl(prompt: [string, string[]], editor: vscode.TextEditor) {
const goimpl = getBinPath('impl');
- const p = cp.execFile(
- goimpl,
- args,
- { env: toolExecutionEnvironment(), cwd: dirname(editor.document.fileName) },
- (err, stdout, stderr) => {
- if (err && (<any>err).code === 'ENOENT') {
- promptForMissingTool('impl');
- return;
- }
+ prompt[1].forEach((iface) => {
+ const p = cp.execFile(
+ goimpl,
+ [prompt[0], iface],
+ { env: toolExecutionEnvironment(), cwd: dirname(editor.document.fileName) },
+ (err, stdout, stderr) => {
+ if (err && (<any>err).code === 'ENOENT') {
+ promptForMissingTool('impl');
+ return;
+ }

- if (err) {
- vscode.window.showInformationMessage(`Cannot stub interface: ${stderr}`);
- return;
- }
+ if (err) {
+ vscode.window.showInformationMessage(`Cannot stub interface: ${stderr}`);
+ return;
+ }

- editor.edit((editBuilder) => {
- editBuilder.insert(insertPos, stdout);
- });
+ (function (out: string) {
+ editor.edit((editBuilder) => {
+ editBuilder.insert(editor.selection.start, out);
+ });
+ })(stdout);
+ }
+ );
+ if (p.pid) {
+ p.stdin?.end();
}
- );
- if (p.pid) {
- p.stdin?.end();
- }
+ });
}

To view, visit change 519035. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: vscode-go
Gerrit-Branch: master
Gerrit-Change-Id: Ie9649ae6afc957c12c41045fb8b720ea2e3f49a9
Gerrit-Change-Number: 519035
Gerrit-PatchSet: 1
Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>

Gopher Robot (Gerrit)

unread,
Aug 12, 2023, 9:11:36 AM8/12/23
to Gerrit Bot, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Congratulations on opening your first change. Thank you for your contribution!

Next steps:
A maintainer will review your change and provide feedback. See
https://go.dev/doc/contribute#review for more info and tips to get your
patch through code review.

Most changes in the Go project go through a few rounds of revision. This can be
surprising to people new to the project. The careful, iterative review process
is our way of helping mentor contributors and ensuring that their contributions
have a lasting impact.

View Change

    To view, visit change 519035. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-MessageType: comment
    Gerrit-Project: vscode-go
    Gerrit-Branch: master
    Gerrit-Change-Id: Ie9649ae6afc957c12c41045fb8b720ea2e3f49a9
    Gerrit-Change-Number: 519035
    Gerrit-PatchSet: 1
    Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
    Gerrit-CC: Gopher Robot <go...@golang.org>
    Gerrit-Comment-Date: Sat, 12 Aug 2023 13:11:31 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: No
    Reply all
    Reply to author
    Forward
    0 new messages