4

I’m able to save my code snippets with tabbed spacing in VS code for Powershell, but it keeps ignoring my variables by not displaying the $ for my variables when I call the snippet. It will just paste in the name and omit the $.

How do you get VS code to paste in the $ when you select your code snippet?

Here is the VS Code JSON file I'm using for my "template" snippet

{
    // Place your snippets for powershell here. Each snippet is defined under a snippet name and has a prefix, body and 
    // description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
    // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the 
    // same ids are connected.
    // Example:
    // "Print to console": {
    //  "prefix": "log",
    //  "body": [
    //      "console.log('$1');",
    //      "$2"
    //  ],
    //  "description": "Log output to console"
    // }

"Template": {
    "prefix": "template",
    "body": [
        "<#",
        ".SYNOPSIS",
        "\t<Overview of script>",
        "",
        ".SYNTAX",
        "\t<Cmdlet-Name> -Parameter <value>",
        "",
        ".DESCRIPTION",
        "\t<Brief description of script>",
        "",
        ".PARAMETER <Parameter_Name>",
        "\t<Brief description of parameter input required. Repeat this attribute if required>",
        "",
        ".INPUTS",
        "\t<Inputs if any, otherwise state None>",
        "",
        ".OUTPUTS",
        "\t<Outputs if any, otherwise state None - example: Log file stored in C:\file.log>",
        "", 
        ".EXAMPLE",
        "\t<Example goes here. Repeat this attribute for more than one example>",
        "",
        ".REMARKS",
        "\tVersion:        1.0",
        "#>",
        "",
        "#---------------------------------------------------------[Variables]------------------------------------------------------------",
        "",
        "$var1 = <stuff>",
        "$var2 = <stuff>",
        "",
        "#---------------------------------------------------------[Import Modules]--------------------------------------------------------",
        "",
        "Import-Module <name>",
        "",
        "#-----------------------------------------------------------[Functions]------------------------------------------------------------",
        "",
        "Function <FunctionName> {",
        "\t[CmdletBindinging()]",
        "\tparam(",
        "\t\t[Parameter()]",
        "\t\t[string]$MyOptionalParameter,",
        "",
        "\t\t[Parameter(Mandatory)]",
        "\t\t[int]$MyMandatoryParameter",
        "\t)",
        "",   
        "\tTry{",
        "\t\t<code goes here>",
        "\t}",
        "", 
        "\tCatch {",
        "\t\tWrite-Host $Error.Exception",
        "\t\t$Error.Exception | Out-File Out-File $env:TEMP\file.log",
        "\t\tBreak",
        "\t}",
        "",
        "\tFinally {",
        "\t\t$time = Get-Date",
        "\t\tcompleted at $time | Out-File $env:TEMP\file.log",
        "\t}",
        "}",
        "",
        "#-----------------------------------------------------------[Execution]------------------------------------------------------------",
        "",
        "<FunctionName>",
    ],
    "description": "test"
}

}

When I call this snippet to paste the template into a new .ps1 file, it omits the all the $. How do you get those to stay?

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
dcvl
  • 485
  • 1
  • 7
  • 21
  • 1
    https://stackoverflow.com/questions/3215705/escaping-the-character-in-snippets – vrdse Feb 22 '20 at 22:14
  • 2
    While the post that @vrdse linked to is about _Visual Studio_ rather than _Visual Studio Code_, one of the answers there does address the latter: https://stackoverflow.com/a/43427442/45375; in short: use `\\$` – mklement0 Feb 23 '20 at 18:45
  • 1
    Or `$$` works. You can escape a `$` with another `$`. – Mark Feb 24 '20 at 16:51
  • 1
    @Mark, using `$$` _accidentally, somewhat_ works, but its purpose is not to escape, and it results in *different behavior* - please see my answer. – mklement0 Feb 25 '20 at 23:41

1 Answers1

4

Use \\$ inside a Visual Studio Code snippet body to embed a literal $.

For instance, to embed PowerShell variable $HOME, use \\$HOME.

Note: From the snippet parser's perspective, a single \ is required for escaping, but since snippets are defined as JavaScript strings, which themselves use \ as an escape character, \\ is need in order to pass a single \ through to the snippet parser.

See the docs.


As an aside:

Using $$ accidentally, somewhat works, but its purpose is not to escape, and it results in different behavior:

The location of a $$-prefixed identifier becomes a tab-stop, because Visual Studio Code interprets the sequence as follows:

The first $ becomes a literal[1], but the second $ and the identifier that follows is interpreted as a Visual Studio Code variable reference; if a built-in variable by that name doesn't exist, it is used as placeholder text.


[1] Any $ not followed by a valid Visual Studio Code placeholder name or variable reference is treated literally.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    I see you are absolutely right. ` the second $ and the identifier that follows is interpreted as a Visual Studio Code variable reference; if a built-in variable by that name doesn't exist, it is used as placeholder text.` is that in the docs somewhere? – Mark Feb 26 '20 at 01:11
  • 1
    @Mark: The part about a non-existing variable name turning into placeholder text is documented (see the link I've added to the answer); that `$` followed by a non-name character (another `$` in this case) is treated literally isn't, as far as I can tell. – mklement0 Feb 26 '20 at 01:22
  • The new link doesn't actually link to anything? – Mark Feb 26 '20 at 03:43
  • @Mark: It links to https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax When I click the link in the answer, it works just fine. – mklement0 Feb 26 '20 at 03:47
  • 1
    I thought you were referring to the superscript - sorry. I see `When a variable is unknown (that is, its name isn't defined) the name of the variable is inserted and it is transformed into a placeholder.` in the docs - that explains it becoming a placeholder and thus a tabstop. Thank you for the clarification. – Mark Feb 26 '20 at 04:21
  • 1
    It would be nice if there was a snippet creator that interpreted this for Powershell. Based on the language it could then put \\ in front of each $. – Daniel4711 Apr 25 '21 at 12:39