0

How do I create a custom snippet that will automatically enter a variable's value that I type into its prefix?

I want a snippet that will create a html start-end tag comment block. For example if I type /se hello I want the result to be

<!-- $var start-->

<!-- $var end-->

Where $var is replaced with "hello". Thank you for reading!

1 Answer 1

4

As the VSCode snippet docs says, it uses TextMate to power its snippets. TextMate uses variables of the form $name and ${name:default}, and luckily supplies $TM_CURRENT_WORD which may be sufficient for your needs. However there is no built in variable to get multiple arguments directly after the snippet name i.e. $arg1 and $arg2 as variables. Thought you could do a similar effect with interpolated shell code, but unfortunately:

The snippet syntax follows the TextMate snippet syntax with the exceptions of 'interpolated shell code' and the use of \u; both are not supported.

Emphasis mine

However for this simple example, the following indexed variable example is probably sufficient.

<!-- $1 start-->
    $0
<!-- $1 end-->

$i gives you a value to fill in, you can go between each one with tabbing. The $0 is where the cursor goes at the end(the end of the snippet by default). Optionally you can do something like:

<!-- ${1: default text} start-->
    $0
<!-- $1 end-->

and it'll start looking like:

<!-- default text start-->

<!-- default text end-->

with both of the defaults selected to edit.

This all put together would look like this together in the snippets.json file:

{
    "se": {
        "scope": "html",
        "prefix": "se",
        "body": [
            "<!-- ${1:default text} start-->",
            "\t$0",
            "<!--$1 end-->"
        ]
    }
}

As @Mark pointed out, if you want it to work for more than just HTML you can use $BLOCK_COMMENT_START and $BLOCK_COMMENT_END which will vary for each language. The snippet would then look like this:

{
    "se": {
        // Leaving scope off will make it a global snippet
        "prefix": "se",
        "body": [
            "$BLOCK_COMMENT_START ${1:default text} start $BLOCK_COMMENT_END",
            "\t$0",
            "$BLOCK_COMMENT_START$1 end $BLOCK_COMMENT_END"
        ]
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

I suggest "$BLOCK_COMMENT_START $1 start $BLOCK_COMMENT_END", and "$BLOCK_COMMENT_START $1 end $BLOCK_COMMENT_END", - it'll work in more file types than just html. And with the $0 in the middle line. It'll insert the proper comment types automatically.
I hadn't been thinking about making it language agnostic, and since it's an important point I've incorporated it into my answer now to give it more visibility, thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.