When I do ^R on the terminal to reverse search, I get the following:
(^R) was pressed. Waiting for second key of chord...
How do I fix this? I'm on OS X.
Also see Run recent command as a replacement for reverse search from the v1.70 Release Notes:
When shell integration is enabled, we're aiming run recent command to
be a cross-shell drop in replacement for the shell's reverse search
(kbstyle(Ctrl+R)). There is a new contiguous search mode that is the
default when triggering the command. This behaves like kbstyle(Ctrl+R)
in most shells, with the option of switching back to fuzzy search:
The new inTerminalRunCommandPicker context key is available that
allows setting up a keybinding like kbStyle(Ctrl+R) to go to the next
match. For example, the following keybindings are now a fairly
complete replacement for your shell's reverse search, with
kbstyle(Ctrl+Alt+R) as a fallback to the old behavior:
{ "key": "ctrl+r", "command": "workbench.action.terminal.runRecentCommand", "when": "terminalFocus" },
{ "key": "ctrl+alt+r", "command": "workbench.action.terminal.sendSequence", "args": { "text": "\u0012"/*^R*/ }, "when": "terminalFocus" },
{ "key": "ctrl+r", "command": "workbench.action.quickOpenNavigateNextInViewPicker", "when": "inQuickOpen && inTerminalRunCommandPicker" },
{ "key": "ctrl+c", "command": "workbench.action.closeQuickOpen", "when": "inQuickOpen && inTerminalRunCommandPicker" },
Perhaps you actually want both! Terminal keybindings that are of the form
Ctrl+R Ctrl+something else
that is, keybindings that are chords AND still use
Ctrl+R (a non-chord keybinding) to trigger a reverse search in the terminal.
You can have both - add this keybinding to your keybindings.json:
{
"key": "ctrl+r",
"command": "workbench.action.terminal.sendSequence",
"args": { "text": "\u0012" },
"when": "terminalFocus"
},
That sends a "Ctrl+R" to the terminal and thus starts a reverse search. Even if you have other terminal keychords that starts with Ctrl+R, the terminal will not wait for the second part of a keybinding.
Note if you have a frequently used search you can add text to the command like:
"args": { "text": "\u0012node" },
where it will already have started the search for commands with node in them.
I realized that this started happening with me after I installed "Visual Studio Keymap" extension.
That is how I solved:
Ctrl + Shift + P for the command. There write: "Settings JSON" and select the option that says "Preferences: Open Settings (JSON)"
There, write the following setting:
"terminal.integrated.allowChords": false
Save and be happy
The setting that fixed it for me:
"terminal.integrated.sendKeybindingsToShell": true
When you make a clean vscode install, there will be a popup that explains what is going on with editor and terminal shortcuts. There you can configure your settings.
I used this when I had your same problem. It should work for OS X since it's just about key bindings.
Related
Not sure if it's called the "cancel signal" but I'm talking about ctrl+c when you want to stop something running. I actually want Terminal: Copy Selection to be ctrl+c, and this I can change in Keyboard Shortcuts. But then I have no way of changing the cancel signal to what I want, which is: ctrl+shift+c. That's because I can't seem to find that key binding.
Ctrl+C is only valid for shells, which for VSCOde only run in terminal panes. The other key bindings you speak of apply to the VSCode IDE in general, not to any shell running in a terminal pane that might exist.
When a terminal pane has focus you should find that Ctrl+C works as usual. I do not think that key binding is reassignable since it is built into the shell running in the terminal pane.
However, VSCode provides the ability to kill the active terminal, or to relaunch it. Maybe you would like to assign hotkeys to those actions?
BTW, you can set the behavior for terminal panes, so they copy to clipboard whenever text is selected. No keystroke required. You can enable that feature by editing settings.json and adding this line:
"terminal.integrated.copyOnSelection": true,
You can send a control sequence to the terminal, see send text to a terminal like this:
{
"key": "ctrl+shift+c",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "\u0003\u000D" // Ctrl+C
},
// "when": "terminalFocus && !terminalTextSelected"
},
Use the when clause if you want it available only when the terminal has focus and with or without a selection.
\u003 is Ctrl+C see
/** End of Text (Caret = ^C) */
export const ETX = '\x03';
from escape sequences
and \u000D is a return from the same source.
And then your other code to set Ctrl+C to copy terminal text:
{
"key": "ctrl+c",
"command": "workbench.action.terminal.copySelection",
"when": "terminalFocus && terminalProcessSupported && terminalTextSelected && terminalTextSelected"
},
{
"key": "ctrl+shift+c",
"command": "-workbench.action.terminal.copySelection",
"when": "terminalFocus && terminalProcessSupported && terminalTextSelected && terminalTextSelected"
}
Demo already running a serve task :
How can I create the following hotkey in VScode:
while editing a file (curser/ focus within text file), execute the last terminal command
bring curser/ focus back to where it was in the text file, so i can seamlessly continue coding
This is intended for debugging code and running the code via terminal efficiently
You can also add some other helpful commands to the beginning of Mark's command sequence!
{
"key": "alt+x",
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
"workbench.action.files.saveAll",
"workbench.action.terminal.scrollToBottom",
{
"command": "workbench.action.terminal.sendSequence",
"args": {"text": "\u001b[A\u000D"},
},
"workbench.action.focusActiveEditorGroup",
]
},
"when": "editorFocus"
}
I simplified my previous answer. Nothing needed in the settings.
You will need a macro extension like multi-command. Using multi-command, make this keybinding:
{
"key": "alt+x", // whatever keybinding you want
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
// you may be able to use this command instead of the sendSquence command, see below
// "workbench.action.terminal.runRecentCommand",
{
"command": "workbench.action.terminal.sendSequence",
// send an uparrow to the terminal shell
"args": {"text": "\u001b[A\u000D"},
},
"workbench.action.focusActiveEditorGroup", // return focus to last active editor
]
},
// if you want this to work only when focus is in an editor
"when": "editorFocus"
}
You can use the following command instead of the sendSquence command object above
"workbench.action.terminal.runRecentCommand",
if you are using one of the currently supported shells - and you have enabled shell integration - see https://stackoverflow.com/a/55336498/836330 for more on this.
For explanation of the sendSequence command part above, see https://stackoverflow.com/a/55336498/836330 (Make a keybinding to run previous or last shell commands).
I'd like for cmd+c to have the same effect as pressing ctrl+c in the VS Code terminal in macOS (so that it terminates the current process and drops me back into a new command prompt).
How can I do that?
You can add a keybinding for cmd+c that triggers the workbench.action.terminal.sendSequence command:
{
"key": "cmd+c",
"command": "workbench.action.terminal.sendSequence",
"args": { "text": "\u0003" },
"when": "terminalFocus"
}
When the above keybinding is added to your keybindings.json file (F1, "keybindings") cmd+c will send the character \u0003 which is ^C (ETX), but only when you have focused the terminal.
You can find more documentation on this command in the official documentation.
I'm trying to add a new command for "Control C" on the integrated terminal but for some reason It just work when the terminal is not focused.
Here's the configuration:
{
"key": "shift+backspace",
"command": "workbench.action.terminal.sendSequence",
"args": { "text": "\u0003" },
}
I've also tried to remove the default command for "shift+backspace"
{
"key": "shift+backspace",
"command": "-deleteLeft",
"when": "textInputFocus && !editorReadonly"
}
Any ideas why it doesn't work?
The issue is that the integrated terminal "consumes" many keystrokes (like ctrl-c) preventing them from being used for keybindings since they are never passed to VScode when the integrated terminal has focus.
Basically, bind the key(s) you want to the desired command, like (in keybindings.json or using the keyboard short cut editor)
...
{
"key": "ctrl-x o",
"command": "workbench.action.focusActiveEditorGroup",
"when": "terminalFocus"
},
...
Then add the COMMAND (workbench.action.focusActiveEditorGroup here) to the setting Commands To Skip Shell. In this example, ctrl-x would not be passed to the terminal after this. (What does ctrl-x do, anyway? ) Note that this can remove the ability to send signals to the integrated terminal.
See the setting Terminal › Integrated: Commands To Skip Shell and the documentation at https://code.visualstudio.com/docs/editor/integrated-terminal#_forcing-key-bindings-to-pass-through-the-terminal for more information.
Some keychords seem to be consumed by vscode and never get to the terminal. I haven't been able to figure out which ones. I couldn't get Shift-backspace to work either, but other keychords do such as the following:
{
"key": "ctrl+shift+c",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "\u0003"
},
}
Perhaps you are ultimately trying to do something like terminate a process with a keybinding?
Is there a way to create a keybinding to execute a shell command on a file?
something like:
{
"key": "ctrl+shift+e",
"command": "run",
"command": "touch $file",
"when": "editorTextFocus"
}
I don't want to use tasks as this needs to be global for the whole editor, not to a particular workspace.
[See my edit below - this is now much easier to do.]
I figured out a way to do what you want but it is a bit of a hack. As you probably know it is easy to bind a task if you can create the task in .vscode/tasks.json and use something like the following:
{
"key": "shift+escape",
"command": "workbench.action.tasks.runTask",
"args": "Start server and process files"
},
It is much trickier to run a script via a keybinding without a pre-existing task. However, you can try the following which takes advantage of the "workbench.action.terminal.runSelectedText", command. But we need to get the script into a selection first so:
Use the macros extension (which is a little rough) so that we can tie together multiple commands. In your user settings:
"runCommandInTerminal": [
{
"command": "type",
"args": {
"text": "node -v"
}
},
{
"command": "cursorMove",
"args": {
"to": "wrappedLineStart",
"by": "wrappedLine",
"value": 1,
"select": true
}
},
"workbench.action.terminal.runSelectedText",
"editor.action.clipboardCutAction",
// "workbench.action.terminal.focus"
],
This is a general example of a setting "runCommandInTerminal" that you can then bind to any key chord you wish in keybindings.json, like
{
"key": "ctrl+shift+e",
"command": "macros.runCommandInTerminal"
},
Your example is a little harder because you want to access something like ${file} which you cannot do in the settings, only tasks.json and launch.json. Fortunately, there is a command which will get the current file: "copyFilePath". So try
"runCommandInTerminal": [
"copyFilePath",
{
"command": "type",
"args": {
"text": "touch "
}
},
"editor.action.clipboardPasteAction",
{
"command": "cursorMove",
"args": {
"to": "wrappedLineStart",
"by": "wrappedLine",
"value": 1,
"select": true
}
},
"workbench.action.terminal.runSelectedText",
"editor.action.clipboardCutAction",
// "workbench.action.terminal.focus"
],
First get the file path, then output the first part of your script command "touch".
Next append the filepath to the end of the command.
Move the cursor to select the preceding.
Run the selection in the terminal.
Cut the selection from the editor.
This can be run with your keybinding. You will see the flash of the script being typed and cut but your editor code will be unaffected. It is best to run it from a blank line in the editor but you can run it from the beginning of a line of unrelated code if you wish (but indentation may be lost for now).
It is hacky but seems to work. I would love to know if there is an extension or another way to do this cleaner.
EDIT May, 2019:
Since my original answer (as #Jeff indicated) vscode has added the sendSequence command. And the ability to use variables with that command. So now the OP's question is much easier to accomplish:
{
"key": "alt+x",
"command": "workbench.action.terminal.sendSequence",
"args": {"text": "touch ${file}"}
}
in your keybindings.json file. See variables with a sendSequnce command.
with Marks answer here I could resolve my case that was run an android command with some shortcut.
After that I decided to create an guide on my GitHub, hope that helps.
GitHub: LucasMMota
Run Shell Script with Keyboard Shortcuts
In this example I set a keyboard shortcut to run android reload on my react native project.
Install the macros extension to execute multiple commands.
After installed go to Preferences>Settings (or cmd+,)
Find Macros Configuration and use to edit in User Settings, or simply add the following in your user settings:
{
//... other configs you could have
"macros": {
"runCommandInTerminal": [
"editor.action.insertLineAfter", // go to new line below
{
"command": "type",
"args": {
"text": "adb shell input text \"RR\" " // exec cmd to reload android device (could be any else)
}
},
// select text typed above
{
"command": "cursorMove",
"args": {
"to": "wrappedLineStart",
"by": "wrappedLine",
"value": 1,
"select": true
}
},
"workbench.action.terminal.runSelectedText", //run command
"editor.action.clipboardCutAction", // remove cmd typed
//"editor.action.deleteLines", //couldn't use. When uncommented, command doesn't work
],
}
}
Now that we have the command set, we need to set a trigger shortcut. So go to Preferences>Keyboard Shortcuts (or cmd+k), open keybindings.json and edit like this:
{
"key": "alt+s",
"command":"macros.runCommandInTerminal"
}
Save your User Settings customizations and keybindings.json, respectively
Bind file format and indenting with save shortcut
keybindings.json:
{
"key": "cmd+s",
"command": "macros.saveContentAndIndent",
"when": "editorTextFocus && !editorReadonly"
},
User Settings:
"macros": {
"saveContentAndIndent": [
"editor.action.formatDocument", // format
"workbench.action.files.save", // as I used Save shorcut, I add the save bind again.
],
//....
}
UPDATE 2:
VS Code now provides variables for integrated terminal commands. https://code.visualstudio.com/updates/v1_32#_variable-support-in-send-sequence-command
If you'd like to do more powerful tasks such as running them in the background (instead of just sending text to the current terminal) get the Command Runner or macro-commander extension
Original:
I created an extension macro-commander to solve this with a non-hacky solution. It is an improved version of the macros extension that runs the commands in order (synchronously) and lets you inject the filepath/folderpath into the command. Commands can be run in the user's VS Code terminal or a hidden background terminal.
UPDATE 1:
As of today (months later) I realized, much to my dismay, there was an existing extension that can probably do what you (and I) wanted. It is Command Runner written by edonet. If I had known about it I probably would've never made my extension.
Command Runner doesn't have as much generic possibilities (multiple commands, user input, or javascript) but it has a better UX and is probably the extension you (the reader) should try first. However, if Command Runner can't do what you're looking for, then macro-commander probably can, albeit with less elegance.
Whenever I decide to do a full update to macro-commander I'll talk with edonet and see if we can combine/add the functionality into his extension, in which case I'll update the macro-commander README to redirect to his/her extension.