2

I have an extension that provides some snippets. I want to add a command that creates a new file with the snippet automatically triggered for the user. The idea is to get the user to edit the tabstops immediately without any further action. Something like:

  1. Run the command (from the command palette, or a keybinding)
  2. VSCode opens a new file with the snippet already evaluated and waiting on the first tabstop for user input

I have scouted the APIs but I haven't found anything to trigger a snippet. The most relevant APIs are those about the CompletionItemProvider, which can be used to provide a snippet.

Does anybody know how to trigger/expand a snippet automatically?

1 Answer 1

4

There is also an insertSnippet method on the TextEditor, see https://code.visualstudio.com/api/references/vscode-api#TextEditor.

So you could do this:

const editor = vscode.window.activeTextEditor;

// build your snippet with the SnippetString methods
const snippet = new vscode.SnippetString("option1 attr1=${2:Option 1 Placeholder 1} attr2=${3:Option 1 Placeholder 2}");

await editor.insertSnippet(snippet);

You can also run the command insertSnippet like this:

// body of snippet here is exactly as you would write it in a keybinding
await vscode.commands.executeCommand("editor.action.insertSnippet", { "snippet": "${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}T${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}Z" });

// the below uses a pre-existing snippet with a name 'Custom Header'
await vscode.commands.executeCommand("editor.action.insertSnippet", { "name": "Custom Header"});

This last executeCommand can have a reference to a pre-existing snippet that you contributed in your extension. For more see below.

All these commands will insert at the cursor with the snippets in the first tabstop position as you wanted.


Contributing snippets in your extension:

In your package.json:

"contributes": {
  "snippets": [
    {
      "language": "javascript",
      "path": "./snippets/javascript.json"
    }
  ]
}

You create a folder named snippets in your extension and a file named javascript.json for javascript snippets. And then use the usual snippet format in that file, like:

{
  "Custom Header2": {             // use this 'name'
    "prefix": "reactpure",
    "body": [
        "import React from 'react';",
        "import PropTypes from 'prop-types';",
        "import './${1:ComponentName}.module.css';",
        "const ${1:ComponentName} = ({ ${2:propValue=[] } }) => (",
        "<${3:rootelement}>${4:content}</${3:rootelement}>",
        ")",
        "${1:ComponentName}.propTypes = {",
        "${5:propValue}: PropTypes.string",
        "};",
        "export default ${1:ComponentName};",
        "$0"
    ],
    "description": "Create a react pure component"
    }
}

Then you can use that name in your extension

// using an extension-contributed snippet
await vscode.commands.executeCommand("editor.action.insertSnippet", { "name": "Custom Header2"});
``
Sign up to request clarification or add additional context in comments.

1 Comment

Ah! Thanks! I did indeed try insertSnippet at first, but wasn't working to me. The error was that I was doing: await vscode.commands.executeCommand("editor.action.insertSnippet", "Custom Header"); instead of the correct await vscode.commands.executeCommand("editor.action.insertSnippet", { "name": "Custom Header"});

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.