Search code examples
visual-studio-codevscode-snippets

Filter a snippet by filename or extension, like *.spec.ts and *.spec.js?


I want to add a couple of snippets to use when creating javascript/typescript unit tests but I do not find any way to set the global scope of the snippet to *.spec.ts or *.spec.js

Is this possible? In the documentation they say that the scope is bases on the language identifier but I just see a way to add another extensions to each language there.


Solution

  • You can do this for snippets. In your keybindings.json:

    {
        "key": "shift+alt+2",
        "command": "editor.action.insertSnippet",
    
        "when": "resourceFilename =~ /\\.spec\\.[tj]s$/",
    
        // with the snippet text directly in the keybinding   
    
        "args": {
          "snippet": "console.log($1)$0"
        }
    },
    

    or this keybinding:

    {
      "key": "shift+alt+2",
      "command": "editor.action.insertSnippet",
      "when": "resourceFilename =~ /\\.spec\\.[tj]s$/",
      "args": {
        "name": "unit tests"
      }
    }
    

    with this snippet in a snippet file:

    "unit tests": {
        //  "prefix": "",  // not used here
    
        "body": [
          "console.log($1)$0",
        ],
    

    The key to limiting the scope of the snippet is this when clause:

    "when": "resourceFilename =~ /\\.spec\\.[tj]s$/",
    

    which as a regular expression would look for a filename ending with .spec.ts or .spec.js (note that you need double escapes before the period). So use the resourceFileName and construct a regex that looks at the end of it.

    Now your chosen keybinding will work in a *.spec.ts or *.spec.js file only.

    See a when clause acting as a regular expression, in keybindings documentation:

    key-value when clause operator

    There is a key-value pair operator for when clauses. The expression key =~ value treats the right hand side as a regular expression to match against the left hand side. For example, to contribute context menu items for all Docker files, one could use:

    "when": "resourceFilename =~ /docker/"
    

    I found this thanks to this issue: resourceExtname with two dots not working