I am working with a Golang and I'm tired of having to copy and paste the name of the func anytime I want to document what the func does. So I decided to build an extension, I have create a functionality that writes the name of func to the line above when I call a command on the func declaration line. This is good but not what I am trying to build.
Here is the code I am working with presently
let disposable = vscode.commands.registerCommand('go-func-doc.helloWorld', function () {
// The code you place here will be executed every time your command is executed
const editor = vscode.window.activeTextEditor;
if (editor) {
// Get the current position of the cursor
const position = editor.selection.active;
// Get the current line
const currentLine = editor.document.lineAt(position.line).text;
// Check if the current line contains a function declaration
const functionRegex = /^func(\s+\([a-zA-Z0-9_\s\*]+\))?\s+(?<functionName>[a-zA-Z_][a-zA-Z0-9_]*)\s*/;
const match = currentLine.match(functionRegex);
if (match && match.groups && match.groups['functionName']) {
// Get the function name
const functionName = match.groups['functionName'];
// Create a TextEdit to insert the function name on the line above
// const edit = new vscode.TextEdit(
// new vscode.Range(position.with(position.line - 1, 0), position.with(position.line - 1, 0)),
// `// ${functionName} `
// );
// Check if there's an empty line above the function declaration
const previousLine = editor.document.lineAt(position.line - 1).text;
if (previousLine.trim() === '') {
// Create a TextEdit to insert the suggested function name on the line above
const edit = new vscode.TextEdit(
new vscode.Range(position.with(position.line - 1, 0), position.with(position.line - 1, 0)),
`// ${functionName} `
);
// Apply the edit to the document
const workspaceEdit = new vscode.WorkspaceEdit();
workspaceEdit.set(editor.document.uri, [edit]);
vscode.workspace.applyEdit(workspaceEdit);
}
editor.edit(editBuilder => {
editBuilder.insert(position.with(position.line - 1, 0), `// ${functionName} `);
const newPosition = position.with(position.line - 1, 6);
editor.selection = new vscode.Selection(newPosition, newPosition);
});
} else {
vscode.window.showInformationMessage('No function declaration found on the current line.');
}
}
What I want however, is for vscode to suggest the name of the func (example: "// fooBar ") anytime I create a new line above the func. I am reading the API docs but I cant figure out what I should do.
I thought it would be more difficult, but a CompletionProvider
- which is what you want - can take a \n
as a trigger character!
Here is a completionProvider file, say providers.js
:
exports.makeCompletionProvider = async function (context) {
const provider1 = vscode.languages.registerCompletionItemProvider(
'javascript', // change to golang here
{
provideCompletionItems(document, position, token, context) {
// I simplified your regex because I am not familiar with golang
const re = /^func\s+([a-zA-Z_][a-zA-Z0-9_]*)/;
let funcLine;
let funcName;
if (document.lineAt(position).text === '') {
funcLine = document.lineAt(new vscode.Position(position.line + 1, position.character)).text;
funcName = funcLine.match(re)[1];
if (funcName) {
const funcNameCompletionItem = new vscode.CompletionItem(`// ${ funcName }`);
funcNameCompletionItem.kind = vscode.CompletionItemKind.Function;
return [
funcNameCompletionItem
];
}
else return undefined;
}
else if (document.lineAt(new vscode.Position(position.line - 1, position.character)).text === '') {
funcLine = document.lineAt(position).text;
funcName = funcLine.match(re)[1];
if (funcName) {
const funcNameCompletionItem = new vscode.CompletionItem(`// ${ funcName }\n`);
funcNameCompletionItem.kind = vscode.CompletionItemKind.Function;
funcNameCompletionItem.command = { command: 'cursorUp', title: 'cursorUp' };
return [
funcNameCompletionItem
];
}
else return undefined;
}
else return undefined;
},
'\n' // trigger intellisense/completion with a newline
);
};
And in your extension.js
:
const providers = require('./providers');
async function activate(context) {
providers.makeCompletionProvider(context);
}
The entire else if
option can be deleted if you wish. It is only triggered when you insert a newline with the cursor at the beginning of the function line, which may be a rare situation for you.
If you use a SnippetString
as the CompletionItem
you can much fancier with cursor placement and other typical snippet options.