A few words from Agical

VS Code runCommands for multi-commands keyboard shortcuts

Visual Studio Code has a command for stringing multiple commands together: runCommands. It’s designed to be used from keyboard shortcuts. Here’s an example:

{
  "key": "shift+ctrl+alt+n",
  "when": "editorTextFocus && editorHasSelection",
  "command": "runCommands",
  "args": {
    "commands": [
      "editor.action.clipboardCopyAction",
      {
        "command": "workbench.action.files.newUntitledFile",
        "args": {
          "languageId": "json"
        }
      },
      {
        "command": "editor.action.insertSnippet",
        "args": {
          "snippet": "${1:$CLIPBOARD}"
        }
      },
      "editor.action.formatSelection",
      "editor.action.clipboardCutAction",
      {
        "command": "editor.action.insertSnippet",
        "args": {
          "snippet": "${1:``` json\n$CLIPBOARD\n```}"
        }
      },
    ]
  }
}

When we are in an editor that has a selection we bind shift+ctrl+alt+n to runCommands, which takes an array of commands. The commands specified here will:

  1. copy whatever is selected

  2. open a new untitled file with the json language mode

  3. insert the copied text

  4. format the text,

  5. cut it to the clipboard again

  6. insert the formatted text in a markdown code fence

Yes I used the command to get it formatted as a code fence for this article. Note that for it to work you will need to have a formatter for json configured in VS Code.

The syntax for each command in the runCommand array is exactly as for when binding any command. So you can either specify a Command ID string or an object with "command" (ID) and "args". The format of the args depends on the command.

The runCommands command is very powerful and offers easy automation of common tasks. I recommend using the Keyboard Shortcuts editor to search for commands. If you don’t know the command title, maybe you know the keybinding, which is also searchable here. Right-click on a command to copy the command id.

Stringing commands together like this depends on that any asynchronous command used is implemented such that it returns a promise that runCommands can await. Some commands provided by extensions may not do this correctly. The extension author will probably want to know this, so please report should you find this being an issue with some command you want to use with runCommands.

There is no way to use the return values of commands, so you can’t build command strings that depend on knowing about some particular result. Should you find that you need something like that I recommend having a look at Joyride, which lets you script VS Code in any way you fancy that the Extension API allows. Joyride code can be used from runCommands so they form a formidable pair for VS Code users who want command over their editor.