Golang VS Code Snippet: Mimic "built-in" `variable.print!` snippet - visual-studio-code

Context: The Golang VS Code extension has built-in snippets/macros for creating a fmt.PrintX statement from a given variable:
Note how the variable name is filled in for me.
I frequently write methods, and the Golang extension's meth snippet, in my opinion, is slow, since there are 5 (!) tab stops:
So far, I've written a snippet that mimics the meth snippet:
"Struct Method": {
"prefix": ".meth",
"body": [
"func ($1 $2) $3($4) $5 {",
"\t$6",
"}"
],
"description": "some description"
}
And I would like this snippet to mimic the print! macro/snippet, where it fills in the variable name; for the method snippet, instead of filling a variable, it would automatically fill in the method receiver ($1 and $2) with the first letter of the struct name, and the full struct name in the second.
So, if I have the following struct:
type SomeStruct struct {}
and type:
SomeStruct.meth
then activate the snippet, it should output:
func (s SomeStruct) .(.) . {
.
}
where each . is a tab stop.
Is this sort of snippet possible? If so, how can I write it so it does this?

One thing you can do is to make a snippet in a keybinding that can parse the current line. Put this into your keybindings.json:
{
"key": "alt+w",
"command": "editor.action.insertSnippet",
"args": {
"snippet": "\n\nfunc (${TM_CURRENT_LINE/\\s*type\\s*(.)(.*)\\s* struct\\s*{}/${1:/downcase} $1$2)/} $1($2) $3 {\n\t$4\n}"
},
// "when": "langId == golang"
}
The workflow is different than what you mentioned but is also easier - you don't have to type SomeStruct.meth. Just trigger the keybinding at the end of the type SomeStruct struct {} line as in the demo.
If you want to be anywhere in the document and trigger a snippet completion, then the HyperSnips extension may be the way to go.

Related

VSCode - Make custom user snippets overwriting default suggestion

To match my company's coding standards, I'm making custom snippets like so:
// php.json
{
"If block": {
"prefix": ["if"],
"body": ["if ( ${1:condition} )", "{", "\t$0", "}"],
"description": "if block",
},
// ...
}
Then, when I type if + Tab, I have two suggestions:
I'm forced to press enter to actually select the first one, which is my custom made snippet ; the second being PHP's default snippet.
Is there a way to actually ignore PHP's default snippets in case I have the exact same prefix?

Variable does not expand in transformation

I am working on a VS code extension for a custom language. This contains a snippet that allows the user to create a function with parameters and start to set up some documentation inside the function. The way I am achieving this is to use variable transforms on the parameter variable (${2}) using some matching tricks to extract each individual parameter and data type. In this simpler example, each parameter name will be on its own line inside a block comment.
"function": {
"prefix": "func",
"body": [
"function ${1:functionName}(${2:params})",
"${2/([^,]+), *|([^,]+$)/\t${BLOCK_COMMENT_START} ${1}${2} ${BLOCK_COMMENT_END}\n/g}",
"end"
]
}, ...
The expected output is this:
function functionName(hello,world)
{ hello }
{ world }
end
The actual output is this:
function functionName(hello,world)
${BLOCK_COMMENT_START} hello ${BLOCK_COMMENT_END}
${BLOCK_COMMENT_START} world ${BLOCK_COMMENT_END}
end
The issue is that ${BLOCK_COMMENT_START} and _END do not expand inside the transform. I can easily get around this issue by hardcoding the curly braces in the snippet, but I would prefer to find a way where I do not have to do that.
"body": [
"function ${1:functionName}(${2:params})",
"${2/([^,]+), *|([^,]+$)/\t{ ${1}${2} }\n/g}",
"end"
]
Is there a way that I can have a variable expand in the transform?

how to use Indentation folding strategy and custom folding rules?

I write some code on GDscript which is similar to python.
It has an indentation folding strategy that is fine.
But I also like #region which is very useful when need to split code into sections:
variables, setters and getters, public functions...
I found several extensions which can manage folding strategy, but they have a side-effect:
The indentation folding strategy is gone.
The only way I found is to write some comment or special symbols when folding should be ended.
"explicitFolding.rules": {
"gdscript": [
{
"begin": "#spoiler",
"end": "#end"
},
{
"begin": "func",
"endRegex": "\t$"
}
]
},
But can I use indentation folding strategy and region folding together in vs-code?
So to solve that, need to change folding rules in language-extension settings.
C:\Users\usr\.vscode\extensions\geequlim.godot-tools-1.1.2\configurations\gdscript-configuration.json
Now, need to put this to end of language settings:
"folding": {
"offSide": true,
"markers": {
"start": "#\\s*region\\b",
"end": "#\\s*end\\b"
}
}
Or what you need.
Actually, I notice that there already was some Implementation of #region, but a bit harder to match that pattern.
Sorry for wasting ur time.

How can I select a part of TM_DIRECTORY variable?

I want to select a part of the TM_DIRECTORY variable on VScode snippet. I mean I want to select Tests\Setup of the d:\Projects\Hakhsin\hakhsin\tests\Setup in code-snippet file. Look at this:
// On snippet file
"PHP Class": {
"scope": "",
"prefix": ["phpClass"],
"body": [
"<?php\n\nnamespace ${TM_DIRECTORY/(?<=(?:[\w:\\]hakhsin\\)).+(?=\\)//};\n\nclass ${TM_FILENAME_BASE} {\n\t$2\n}"
],
"description": "New PHP Class"
},
And I want to get this result:
namespace Tests\Setup;
class StorageFactory {
}
But I get this result:
<?php
namespace d:\Projects\Hakhsin\hakhsin\tests\Setup;
class StorageFactory {
}
It doesn't appear you can use variables inside of other variables in a snippet transform.
You can try this code which is more "dynamic" than yours but not perfect:
"${TM_DIRECTORY/([^\\\\]*\\\\){4}(.*)/${2:/capitalize}/}",
The {4} in that is if you have 4 segments in the directory structure before the part you want, like d:\Projects\Hakhsin\hakhsin\tests\Setup The segments are d:\, Projects\, Hakhsin\ and hakhsin\. If that number of segments is known and stable than the snippet I showed works well.
I doubt the number of those segments would vary within a project but might very well between projects - you would just have to change the {x} item for each project if so.
I solved it but it is not dynamic.
namespace ${TM_DIRECTORY/(.*hakhsin\\\\)(.*)/${2:/capitalize}/};
Is there a better way? anything like this:
namespace ${TM_DIRECTORY/(.*${WORKSPACE_NAME}\\\\)(.*)/${2:/capitalize}/};
This is the result:
<?php
namespace Tests\Setup;
class StorageFactory {
}

Add tasks to tasks.json for users of a vscode extension

I am writing a vscode extention for a specification language. I would like to provide the users of the plugin with a specific task. The task could be made available using tasks.json.
Is there a way to add tasks to the tasks.json of a user that uses that extension?
The documentation didn't help me here either. When you provide tasks through the extension there is the TaskProvider API. The example doesn't go into much detail about how these tasks are created though, compared to the classical tasks.json approach.
In your package.json you need to define the types of tasks this extension contributes. This has nothing to do with the type in tasks.json. It's rather a freeform string. If you need custom problem matchers you also need to define theme here.
"contributes": {
"taskDefinitions": [
{
"type": "mytask"
}
],
"problemMatchers": [
{
"name": "mywarnings",
"base": "$gcc",
"fileLocation": [
"relative",
"/"
]
}
]
},
In extension.ts you need to provide the tasks. Say we have an array of vscode.Task in tasks you can do:
vscode.tasks.registerTaskProvider('mytask', {
provideTasks: () => {
return tasks;
},
resolveTask(_task: vscode.Task): vscode.Task | undefined {
// as far as I can see from the documentation this just needs to return undefined.
return undefined;
}
});
If you want to create a shell task you need the following:
new vscode.Task (
{type: 'shell'}, // this is the same type as in tasks.json
ws, // The workspace folder
'name', // how you name the task
'MyTask', // Shows up as MyTask: name
new vscode.ShellExecution(command),
["mywarnings"] // list of problem matchers (can use $gcc or other pre-built matchers, or the ones defined in package.json)
);
I hope this helps. The bigges issue I see is the overloading of various names (like type), and that the format in tasks.json is completely different to the way tasks are built with TaskProvider API.