VS Code Snippet - Change position of linked tabstops - visual-studio-code

I am currently switching from IntelliJ to VS Code for a project and want to take some of my custom live templates with me.
VS Code supports "User Snippets", but I can't get them to work like they do in IntelliJ.
I want to achieve the following output:
console.log('variableName', variableName);
Now the thing is, I want my cursor to start right after the , so I get IntelliSense for auto completion of a defined variable. Then that variable name should be placed in the string.
I am right at the start and know that tabstops with the same ID get the same value:
"console.log variable": {
"scope": "javascript,typescript",
"prefix": "cl",
"body": [
"console.log('${1}', ${1});",
"$0"
],
"description": "console.log variable with name"
}
The problem with this is though, that the first tabstop is the start of the snippet and since I am inside a string I don't get IntelliSense for the variable name.
Is there a way to reverse the tabstop order of linked tabstops or anything similar that helps with the problem at hand?

"Print to console": {
"prefix": "clog",
"body": [
"console.log('${1:variable}', ${1:variable});$0"
],
"description": "Log output to console"
}
Works but you have to press Ctrl+Space to get completion items.

Related

VS Code Snippets too greedy with dot character

I have the following snippet configured.
{
"Pandas Display All Columns": {
"scope": "python",
"prefix": "pd.options.display.max_columns",
"body": [
"pd.options.display.max_columns = None"
],
"description": "Allows all columns of the dataframe to print"
}
The problem is every time I type a period . and hit enter it auto-completes with this snippet. For example if I'm typing a doc string and use a period and hit enter. I know, I know... working as designed.
If I shorten the prefix so it does not contain and dot character . so only pd is used, it is not intuitive when the intellisense pops up. How do you suggest I formulate my snippet so it is intuitive and not showing every time I type . all by itself?

use dollar sign in a vscode snippet regex

I am trying to make a vs code php snippet which generate this line from the $code placeholder input:
Utils::getLogger.debug("code", ["code" => $code])
The regex I use for this is /(\$?)(.*)/ (I am interested in the second capture group to get the variable name).
This is my snippet code :
"log debug": {
"prefix": ["log debug", "debug"],
"body": ["Utils::getLogger.debug(\"${1/(^\\$?)(.*)/$2/}\", [\"${1/(^\\$?)(.*)/$2/}\" => ${1:variable}])"],
"description": "Quick variable debug."
},
The problem is that it doesn't replace the dollar sign from my input. If I give $variable as placeholder, it generates Utils::getLogger.debug("$variable", ["$variable" => $variable]).
I got it working for a charater different than the dollar sign, for example a comma or another letter and also I got it working using TM_SELECTED_TEXT variable and selecting my variable before.
I suspect that it is a conflict with vs code php variable name autocompletion in vscode as if I copy my variable then call the snippet and paste the variable inside the placeholder (instead of typing it), it also works.
I was tempted to post this as an issue on vscode github but maybe am doing something wrong here.
ps: I know that is can also type in the variable name without the $ and add it in the replacement regex, but you know how developpers can be...
This works:
"body": ["Utils::getLogger.debug(\"${2:${1/\\$?(.*)/$1/}}\", [\"$2\" => ${1:variable}])"],
Note that since you are reusing the first transform, I set it to a placeholder ${2} by wrapping it like so:
${2:${1/\\$?(.*)/$1/}}
Now you can reuse that $2 placeholder wherever you want the result of the same transform - as in \"$2\" =>.
Thanks to https://stackoverflow.com/a/66449064/836330 for that usage.
After discussions and further testing, I think there is nothing wrong with the snippet code and it is a "conflict" with php variable autocompletion.
There are some optimisations in the answers that are interesting tho.
For information, I finally took the solution to enter the variable name without the $ and add it in the transform.
"log debug quick": {
"prefix": ["log debug quick", "debug quick"],
"body": ["Utils::getLogger.debug(\"${1:variable}\", [\"${1}\" => \\$${1}]);"],
"description": "Quick variable debug."
},
Note that the original method works with the TM_SELECTED_TEXT variable (as the autocompletion does not happen), so the folowing is working :
"log debug selection": {
"prefix": ["log debug selection", "debug selection"],
"body": ["Utils::getLogger.debug(\"${1:${TM_SELECTED_TEXT/^\\$?(.*)/$1/}}\", [\"${1}\" => $TM_SELECTED_TEXT]);"],
"description": "Quick variable debug."
},
Note that I optimized the snippet with both #Mark and #rioV8 suggestions

vscode Nest snippet choices and add tab stops to choices

I want to do something like that in my snippets for visual studio code:
"V.G.${1|BLOCK_NR,MASS_MM,MASS_360,I,J,K,R,FEEDRATE,FEEDRATE_SCALE,MERR[${2}]|}"
So after choose the option MERR[] I will see the cursor inside the brackets.
and how i have to manage sub choices like:
"V.G.${1|choice${2|subchoiceA,subchoiceB|},choice, choice......}"
If I choose MERR[] Option I will jump into [Cursor should be here]. How can i handle this?
Here is a workaround to your subchoiceA/B question because you cannot have anything except plain text as choices - no tabstops or subchoices, etc. Your example:
V.G.${1|choice${2|subchoiceA,subchoiceB|},choice, choice......}"
This can be achieved however with 2 snippets:
"choices with subchoices": {
"prefix": "_choices", // whatever prefix you want
"body": [
"V.G.${1|choice1, _subchoices,choice2,choice3|}"
],
"description": "variables in a choice element"
},
"my subchoice list": {
"prefix": "_subchoices", // this prefix must be what you used in the main snippet
// as your subchoice option
"body": [ "${1|subchoiceA,subchoiceB|}" ],
"description": "subChoices"
},
What happens is that when you choose the subchoices option in the main snippet it will see it as the prefix for the second snippet - that is pretty neat. But it will not do so until you trigger that recognition with Ctrl+Space the usual intellisense trigger and then tab to select the second snippet.
It is only one or two extra keystrokes to get subchoices working inside of a parent choice element when otherwise it can't be done at all.
The only issue is that your second prefix - here subchoices cannot be a continuation of another string with no spaces otherwise it won't be recognized as a standalone snippet prefix by vscode. That is why I added the space before subchoices in the main snippet since your example has "V.G.${1....} with no space before the option would be inserted.
Here is a demo:

VSCode - Create shortcut to insert string

I want to create a shortcut to insert a specific string into the editor (I am tired of typing "#---------------------..." every single time when separating code blocks).
How do I implement this correctly in VSCode?
I believe File->Preferences->User Snippets is what you're looking for. The example shown looks like:
"Print to console": {
"scope": "javascript,typescript",
"prefix": "log",
"body": [
"console.log('$1');",
"$2"
],
"description": "Log output to console"
Which I read as being able to do what you want. There seem to be files for specific languages or you can start a 'global' snippets file.

How to do IntelliSense for snippets when some text is selected in VSCode?

I wrote my first snippet which would wrap the selected text in if() { selected text } block.
"if block - snippet": {
"prefix": "if block - snippet",
"body": [
"if( $1 ) {",
"$TM_SELECTED_TEXT",
"}",
"$0"
],
"description": "if block - snippet"
}
When I select the text and hit CTRL+SPACE it shows the intellisense but, when I start searching for my snippet "if block - snippet" instead of searching it clears-out the selected text and start writing the "if blo...." :P
One workaround is to have a dedicated keybinding to trigger snippets but I want it more implicit like in the intellisense suggestions itself. is it possible?
Update: vscode now "remembers the $TM_SELECTED_TEXT even though it appears to disappear as you write your snippet prefix. So your original snippet works as you expect. No need to use $CLIPBOARD.
Previous answer:
It is if you copy the selection to the clipboard first so you can use:
"if block - snippet": {
"prefix": "if block - snippet",
"body": [
"if( $1 ) {",
"$CLIPBOARD",
"}",
"$0"
],
"description": "if block - snippet"
}
Once hitting CTRL+SPACE and intellisense shows, instead of searching the snippet by typing its name, use the UP/DOWN buttons to search it.
On the editor.action.showSnippets key binding, you can also do a when clause of editorHasSelection, and then you can use Ctrl+Space for both functionalities. It's not the nice inline snippet Intellisense, but it's closer to what we want.