Is there a way to add a continuous placeholder in vs code snippets? - visual-studio-code

I created a simple js snippet for objects:
"object": {
"prefix": "ob",
"body": [
"const ${1} = {",
"",
"${2}: ${3},",
"",
"};",
],
"description": "object"
},
I want it to continue to add names and values until I stop writing, not just one name and value like my snippets.

Related

make VSCode snippets for a writer

I am a writer and use VSCode as an editor. because its awesome!
but it's little bit uncomfortable on typing. like curly quotes.
So to solve problem, I make 'markdown.json file' to change smart quotes('') to curly quotes(“”) automatically.
"smart quotes in markdown": {
"prefix": "\"\"",
"body": [ "“$1”$2" ],
"description": "to use curly quotes instead of straight quotes"
},
it works on txt file! (which is open by VSCode)
So happy and I try one more things...
"( in markdown": {
"prefix": "\u0028",
"body": [ "($1)$2" ],
"description": "to type (any word) easy"
},
"{ in markdown": {
"prefix": "\u007B",
"body": [ "{$1}$2" ],
"description": "to type {any word} easy"
},
"[ in markdown": {
"prefix": "\u005B",
"body": [ "[$1]$2" ],
"description": "to type [any word] easy"
},
"| in markdown": {
"prefix": "\u007C",
"body": [ "|$1|$2" ],
"description": "to type |any word| easy"
},
"< in markdown": {
"prefix": "\u003C",
"body": [ "<$1>$2" ],
"description": "to type <any word> easy"
},
"memo in markdown": {
"prefix": "\u003D",
"body": [ "=$1=$2" ],
"description": "to use memo destinguisher instead of //"
}
this time it doesn't work. :( where is the problem? prefix unicode charactor number is wrong? or these special charactors are Un-usable? how can I fix this?

How do I add a code snippet with a number as a tabstop

Consider the following JSON schema snippet:
{
"label": "New spell",
"description": "Creates a new spell",
"body": {
"name": "$1",
"source": "$2",
"page": "${3}",
"tradition": "$4",
"type": "${5|U,A|}",
"level": "${6}",
"description": ["$7"]
}
}
Both page and level need to be an integer (can default to 0), but also be a tabstop. I have tried a few things, but the only value that acts as a tabstop is enclosed in quotes, so it ends up being a string.
Is there a way to add a tabstop where the default value is a number?
This would work to set a tabstop 3 and 6 with defaults of 0. Note that the quotes must be escaped.
"\"page\": \"${3:0}\""
Also the general form of a snippet is as follows:
"new spell": {
"description": "Creates a new spell",
// "scope": "javascript,typescript",
"prefix": "new spell", // whatever prefix you want
"body": [ // array
"\"page\": \"${3:0}\"",
"\"level\": \"${6:0}\"",
]
}
There is no label property and there should be a prefix property. And body, if multiple statements is an array.
As it says in the documentation:
If a string starts with ^, the string content will be inserted as-is, not stringified. You can use this to specify snippets for numbers and booleans.
The value string needs to be specified as "^${3:0}".
So, the snippet fixed:
{
"label": "New spell",
"description": "Creates a new spell",
"body": {
"name": "$1",
"source": "$2",
"page": "^${3:0}",
"tradition": "$4",
"type": "${5|U,A|}",
"level": "^${6:0}",
"description": ["$7"]
}
}

VSCode nested snippets (or include a snippet inside another snippet)

I'm wondering if I can refer to another snippet within a snippet in VSCode user defined snippet.
Say I have
"Test1": {
"prefix": "snippet_test1",
"body":
"something"
}
and is there a way to insert snippet_test1 in another snippet like
"Test2": {
"prefix": "snippet_test2",
"body":
"${1:snippet_test1}"
}
Now snippet_test2 just outputs snippet_test1 instead of the content of snippet_test1.
#Mark provides a good answer to use macros and I got another possible answer for who are interested.
"Test1": {
"prefix": "snippet_test1",
"body":
"something"
}
"Test2": {
"prefix": "snippet_test2",
"body":
"${1:snippet_test1}"
}
For Test2, it does only show snippet_test1 other than Test1 content but if you hit ctrl+space at snippet_test1, it will show a list of possible snippet available and you can expand text in snippet_test2 to the full content in snippet_test1.
I think the only way to include or nest snippets within each other is to use a macro or some other programmatic way. Here is a solution using the macro extension multi-command.
Lets say you have these three snippets (in some snippets file):
"Master Snippet": {
"prefix": "master_snippet",
"body": [
"body of master",
"snippet2 = $2",
"$1",
"some other stuff",
"$1",
],
"description": "build the multi-snippet"
},
"snippet1": {
"prefix": "sn1",
"body": [
"body of snippet1",
],
"description": "insert1"
},
"snippet2": {
"prefix": "sn2",
"body": [
"I am snippet2",
],
"description": "insert2"
},
Then your macro would print Master Snippet first and then wherever the cursor is - the cursor will be in both $1 tabstop positions initally - the macro will insert the snippet1.
Then with the "jumpToNextSnippetPlaceholder", command in the macro you will jump to the next tabstop $2 which could be anywhere - I put it before $1 (where snippet1 got inserted) and snippet2 will be inserted at tabstop $2.
You can see that the Master Snippet is where you build the structure for inserting the other snippets - according to tabstops.
The macro would look like this (in your settings.json):
"multiCommand.commands": [
{
"command": "multiCommand.insertMultipleSnippets",
"sequence": [
{
"command": "editor.action.insertSnippet",
"args": {
"name": "Master Snippet",
}
},
{
"command": "editor.action.insertSnippet",
"args": {
"name": "snippet1",
}
},
"jumpToNextSnippetPlaceholder",
{
"command": "editor.action.insertSnippet",
"args": {
"name": "snippet2",
}
},
]
}
],
and then trigger the macro with some keybinding (keybindings.json):
{
"key": "alt+m", // or whichever keybinding you choose
"command": "extension.multiCommand.execute",
"args": { "command": "multiCommand.insertMultipleSnippets" },
"when": "editorTextFocus"
},
You cannot use any snippet prefix to trigger the whole macro, but you can still use the individual snippet prefixes to trigger each snippet individually if you wish.
With the above Master Snippet, snippet1 and snippet2 the result of running the macro would be:
body of master snippet
snippet2 = I am snippet2
body of snippet1
some other stuff
body of snippet1
You do lose some functionality, like the inserted snippet cannot be pre-selected like placeholder text would be - if used like ${1:howdy}, the placeholder text howdy is just overwritten by the first snippet inserted.

How can I author a Snippet Collection to multiple languages in VSCode Marketplace?

My goal is to create a collection of Snippets that will be available in the VSCode Marketplace. These snippets will be for 3 languages (html, css, and JS). This will be helpful for anyone who works on the specific framework, but especially my team.
I know that I can scope snippets (How can I add language-agnostic snippets in vscode?) to multiple languages. I also know that according to the docs I'm supposed to have a contributes object that has a snippets array in it. In my package.json for my vsc-extension the default is like the below:
"contributes": {
"snippets": [
{
"language": "markdown",
"path": "./snippets/markdown.json"
}
]
}
Is it correct for me to then update my package.json to something like:
"contributes": {
"snippets": [
{
"language": "html",
"path": "./snippets/snippets.json"
},
{
"language": "javacript",
"path": "./snippets/snippets.json"
}
]
}
and then have my snippets declare their own scope ("scope": "html")?
The way I went about this was to create a file for each type of snippet: php-snippets.json, js-snippets.json, etc. and then add those files to the snippets array.
"contributes": {
"snippets": [
{
"language": "php",
"path": "./snippets/php-snippets.json"
},
{
"language": "javascript",
"path": "./snippets/js-snippets.json"
}
]
}
One piece of information I left out from my question is that I used the Yo generator to create my snippet project. This was the recommended action in the documentation.
This worked. I added several languages to the snippets array in contributes as seen below.
"contributes": {
"snippets": [
{
"language": "html",
"path": "./snippets/snippets.json"
},
{
"language": "javacript",
"path": "./snippets/snippets.json"
}
,
{
"language": "scss",
"path": "./snippets/snippets.json"
}
]
}
Then inside snippets/snippets.json there is one large object that contains all of my snippets. You can see an example of that below. The key lines for each are "scope": "html and "scope": "scss".
"Each Helper": {
"scope": "html",
"prefix": "each",
"body": [
"{{#each $1}}",
" $2",
"{{/each}}"
],
"description": "Creates each helper -- handlebars"
},
"Break Point Small": {
"scope": "scss",
"prefix": "bps",
"body": [
"",
"#include breakpoint(\"small\") {// 551px and up",
" $1",
"}"
],
"description": "Tablet Break Point --Stencil"
},
I suppose I should have just tried it after not being able to find the answer here or in documentation.

Visual studio code: How to create multilines indented snippets?

I try to create multilines snippet like so:
"mySnippet": {
"prefix": "test",
"body": [
"<div>",
"<p></p>",
"</div>"
]
}
But it's not indented...
Reading the doc doesnt' help
You need to add the indentation inside the second string element of the body array:
"mySnippet": {
"prefix": "test",
"body": [
"<div>",
" <p></p>",
"</div>"
]
}
You can use the \tfor TAB on each line:
"table": {
"prefix": "table",
"body": [
"<table cellspacing=\"0\" cellpadding=\"0\">",
"\t<tr>",
"\t\t<td>",
"\t\t\t<i class=\"fas fa-bullhorn\"></i>",
"\t\t</td>",
"\t\t<td>",
"\t\t\t${1:element}",
"\t\t</td>",
"\t</tr>",
"</table>"
],
"description": "Text with a bullhorn icon on the left"
}