Search code examples
visual-studio-codevscode-snippets

In VS Code, is there a way (or extension) to run a command ( I.E. 'editor.action.insertSnippet') on each line of text that is selected in the editor?


I have a snippet called Quick Log Write-Host defined like this:

"Quick Log Write-Host": {
    "prefix": ["quicklog"],
    "body": [
            "Write-Host -f Green \"`$TM_SELECTED_TEXT:\" $TM_SELECTED_TEXT"
    ],
    "description": "Quick Log"
},

I then have a keybinding defined to Ctrl+Q like this:

{
    "key"     :  "ctrl+q",
    "command" :  "editor.action.insertSnippet",
    "args"    :  { "name": "Quick Log Write-Host" },
    "when"    :  "editorTextFocus && editorLangId == powershell"
},

So now, when I select a variable and press Ctrl+Q, it transforms it into a logging string so I can easily inspect the value of that variable when I run my script. It's just a useful debugging tool.

A simple example:

$MyObjectCollection | % {
    $_
}

Now I select $_ and press Ctrl+Q, and the code becomes:

$MyObjectCollection | % {
    Write-Host -f Green "`$_:" $_
}

This is useful when I want to inspect a variable quickly.

But it doesn't work on multiple selections. I'd like to be able to select multiple lines and perform the same command on each line one at once.

What I want to do is start with this:

$HArrMemberType.GetType()
$HArrMemberType.GetType().BaseType
$HArrMemberType.GetType().FullName
$HArrMemberType.GetType().Name
$HArrMemberType.GetType().IsEnum
$HArrMemberType.GetType().IsValueType
$HArrMemberType.GetType().MemberType

Then select all of the above, press a shortcut, and have that shortcut transform my selection to:

Write-Host -f Green "`$HArrMemberType.GetType():" $HArrMemberType.GetType()
Write-Host -f Green "`$HArrMemberType.GetType().BaseType:" $HArrMemberType.GetType().BaseType
Write-Host -f Green "`$HArrMemberType.GetType().FullName:" $HArrMemberType.GetType().FullName
Write-Host -f Green "`$HArrMemberType.GetType().Name:" $HArrMemberType.GetType().Name
Write-Host -f Green "`$HArrMemberType.GetType().IsEnum:" $HArrMemberType.GetType().IsEnum
Write-Host -f Green "`$HArrMemberType.GetType().IsValueType:" $HArrMemberType.GetType().IsValueType
Write-Host -f Green "`$HArrMemberType.GetType().MemberType:" $HArrMemberType.GetType().MemberType

Does anyone know if this kind of transformation is possible without writing my own VS Code extension? Whether through an extension, or some native VS Code shortcut settings?

Any help would be greatly appreciated!


Solution

  • If your text is contiguous like you showed then this keybinding will work:

      "key": "ctrl+q",
      "command": "runCommands",
      "args": {
        "commands": [
          "editor.action.insertCursorAtEndOfEachLineSelected",
          "cursorHomeSelect",
          {
            "command": "editor.action.insertSnippet",
            "args": {
              "name": "Quick Log Write-Host"
              // "snippet": "Write-Host -f Green \"`$TM_SELECTED_TEXT:\" $TM_SELECTED_TEXT"  // or this
            }
          }
        ]
      },
      "when": "editorTextFocus && editorLangId == powershell"
    },
    

    The key is to "split" the lines first, with the editor.action.insertCursorAtEndOfEachLineSelected command and then the snippet will be applied on a line-by-line basis.

    If you are selecting text that is not on adjoining lines, just put a cursor at the end of each line you want to change.