microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
161.92k stars 28.46k forks source link

Macro like keybindings #871

Open TheColorRed opened 8 years ago

TheColorRed commented 8 years ago

When creating keyboard shortcuts, it would be nice if you could pass an array of commands (to execute like a macro) that would run the commands in that order.

So take this for example:

{
    "key": "ctrl+s",
    "command": [
        "editor.action.format",
        "editor.action.trimTrailingWhitespace",
        "workbench.action.files.save"
    ],
    "when": "editorTextFocus"
}

It would format the file, remove trailing white space then save the file.

Davidnet commented 3 years ago

I'd love this to be supported natively

ldarshan1991 commented 3 years ago

I see this issue has been reported way back in 2015 and so many people have voiced to have this feature and its 2020! Still I don't see this feature has been included in VSCode! Surprising to see such a support from Microsoft. Not even a response from the core team.

Nowaker commented 3 years ago

It's a TOP 5 most upvoted feature request: https://github.com/microsoft/vscode/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc. 😢

ItsCubeTime commented 3 years ago

Bind one key to multiple commands via user level tasks, no extensions required. Not a perfect way, but it works.

Theres no way of running commands like: editor.action.insertSnippet in tasks right?

usernamehw commented 3 years ago

Created another extension that can run multiple commands:

https://marketplace.visualstudio.com/items?itemName=usernamehw.commands

{
    "key": "ctrl+s",
    "command": "commands.run",
    "args": [
        "editor.action.format",
        "editor.action.trimTrailingWhitespace",
        "workbench.action.files.save"
    ],
    "when": "editorTextFocus"
}
ItsCubeTime commented 3 years ago

Created another extension that can run multiple commands:

https://marketplace.visualstudio.com/items?itemName=usernamehw.commands

Looks great 😀

bersbersbers commented 3 years ago

Created another extension that can run multiple commands:

https://marketplace.visualstudio.com/items?itemName=usernamehw.commands

You mean, like https://marketplace.visualstudio.com/items?itemName=ryuta46.multi-command? ;)

usernamehw commented 3 years ago

Yes, but like, better with more features.

vec715 commented 1 year ago

Jesus, it's 2023 out there and it's still a problem

a-pav commented 1 year ago

I think that @ liangjiancang's suggestion above about the ability to define "key" as an array is also valid. It can save us from copy-pasting for just a minor change.

ulugbekna commented 1 year ago

Hello everyone! 👋

VS Code team engineer here 🙂

Just wanted to let you know that we added a built-in command runCommands that can run multiple commands sequentially. This is not first-class support for macros as described in the feature request (this feature request remains open), but this should be quite a handy command, especially given it supports auto-completion/linting for command name and command argument names.

We encourage people to try it out and report issues/suggest improvements in new issues (there is now a GitHub issue label runCommands)

You can read more about the command here: https://code.visualstudio.com/docs/getstarted/keybindings#_running-multiple-commands

Make sure you're on latest VS Code version - 1.77.

EugeneDae commented 1 year ago

@ulugbekna That's a great news, thanks so much!

sandeepkambham08 commented 1 year ago

Tested and it works 😉 Thank you 👍

jhuitema commented 1 year ago

Thanks, this works great!

Would it be possible to add an argument to the runCommands action to optionally compress the commands into a single Undo action? If that is a big ask I can create a new issue for it.

For example, I am using a "Join Lines without inserting whitespace" key binding like so:

    {
        "key": "ctrl+shift+j",
        "command": "runCommands",
        "args": {
            "commands": [
                "editor.action.joinLines",
                "deleteRight"
            ]
        },
        "when": "textInputFocus"
    }

This works great but to undo it you need to Undo twice. Being able to only Undo once would be ideal.

nikitavoloboev commented 9 months ago

Hello everyone! 👋

VS Code team engineer here 🙂

Just wanted to let you know that we added a built-in command runCommands that can run multiple commands sequentially. This is not first-class support for macros as described in the feature request (this feature request remains open), but this should be quite a handy command, especially given it supports auto-completion/linting for command name and command argument names.

We encourage people to try it out and report issues/suggest improvements in new issues (there is now a GitHub issue label runCommands)

You can read more about the command here: https://code.visualstudio.com/docs/getstarted/keybindings#_running-multiple-commands

Make sure you're on latest VS Code version - 1.77.

I just tried it with this:

  {
    "key": "cmd+shift+;",
    "command": "runCommands",
    "args": {
      "commands": [
        "breadcrumbs.focus",
        "cursorLeft"
      ]
    }
  },

And it failed. It did not do arrow left after breadcrumbs were focused.

a-pav commented 9 months ago
"commands": [
        "breadcrumbs.focus",
        "cursorLeft"
      ]

Instead of cursorLeft, you can use breadcrumbs.focusPrevious.

ATXadam commented 6 months ago

Having an issue with workbench.action.open*Settings* commands in runCommands. While it does work, it does throw an error, and prevents further execution of commands from running.

What I'm trying to accomplish is opening the settings.json files on keybind. If I run one of these commands as a root action for the keybind, it does work without issue.

Example Keybind:

[
    {
        "key": "ctrl+shift+/",
        "command": "runCommands",
        "args": {
            "commands": [
                "workbench.action.openApplicationSettingsJson",
                "workbench.action.openSettingsJson"
            ]
        }
    }
]

When executing the keybind, I get a VS Code alert:

Converting circular structure to JSON
    --> starting at object with constructor 'Y'
    |     property 'C' -> object with constructor 'Array'
    |     index 0 -> object with constructor 's'
    |     ...
    |     index 1 -> object with constructor 'a'
    --- property 'j' closes the circle
    */

As well as the following Output -> Window log:

2024-02-17 08:26:04.812 [error] Method not found: toJSON: CodeExpectedError: Method not found: toJSON
    at Object.call (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:42:5090)
    at C.s (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:40:5128)
    at C.q (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:40:4644)
    at $.value (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:40:4051)
    at h.y (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:35:1902)
    at h.z (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:35:1972)
    at h.fire (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:35:2188)
    at $.value (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:33:28530)
    at h.y (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:35:1902)
    at h.fire (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:35:2119)
    at $.value (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:33:28733)
    at h.y (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:35:1902)
    at h.fire (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:35:2119)
    at ge (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:33:31158)
    at IpcMainImpl.l (C:\Program Files\Microsoft VS Code\resources\app\out\vs\code\electron-main\main.js:42:18908)
    at IpcMainImpl.emit (node:events:514:28)
    at WebContents.<anonymous> (node:electron/js2c/browser_init:2:79287)
    at WebContents.emit (node:events:514:28)

With VS Code Web, I do get a different alert: cyclic object value

With the following log in console:

TypeError: cyclic object value
    run commands.contribution.ts:106
    handler actions.ts:592
    handler commands.ts:98
    invokeFunction instantiationService.ts:68
    n commandService.ts:95
    executeCommand commandService.ts:60
    M abstractKeybindingService.ts:372
    J abstractKeybindingService.ts:225
    W keybindingService.ts:281
    d dom.ts:136
    a dom.ts:157
    W keybindingService.ts:273
    x keybindingService.ts:244
    ie event.ts:621
    x keybindingService.ts:244
    j instantiationService.ts:119
    t instantiationService.ts:245
    s instantiationService.ts:234
    r instantiationService.ts:223
    q instantiationService.ts:163
    m instantiationService.ts:147
    get instantiationService.ts:61
    ob layout.ts:306
    startup workbench.ts:155
    invokeFunction instantiationService.ts:68
    startup workbench.ts:146
    open web.main.ts:131
    m web.factory.ts:62
    main (index):9
    i (index):9
    i (index):9
    97 (index):9
    a (index):9
    <anonymous> (index):9
    <anonymous> (index):9
notificationsAlerts.ts:40:13

This is without any extensions running (fresh profile). Produced identical results with no extensions and a default profile:

Also, it would be great (and enough to get me by) if there was a way to execute commands and continue regardless of failure? In my example, I may not have a workspace open, so if I opened Application -> Workspace -> User, and no workspace, user would also not open.

vanowm commented 3 months ago

Just wanted to let you know that we added a built-in command runCommands that can run multiple commands sequentially. This is not first-class support for macros as described in the feature request (this feature request remains open), but this should be quite a handy command, especially given it supports auto-completion/linting for command name and command argument names.

We encourage people to try it out and report issues/suggest improvements in new issues (there is now a GitHub issue label runCommands)

I'm confused, was it easier to implement completely new command, rather than check for type of value in existing command, and if it's a string execute it, if it's an array execute each item in the array?