Related
Having found the VSCode command workbench.action.terminal.newWithCwd
{
"key": "cmd+shift+alt+h",
"command": "workbench.action.terminal.newWithCwd",
"args": {
"cwd": "${fileDirname}"
}
}
I cannot get it to work.
I have inserted the JSON above into the ~\Code\User\keybindings.json file, but how do I actually get it to execute?
This works as a keybinding, using the macro extension multi-command:
{
"key": "alt+k", // whatever you want here
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
{
"command": "workbench.action.terminal.newWithProfile",
"args": {
"profileName": "Git Bash",
"shouldForwardArgs": true,
}
}
{
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "cd '${fileDirname}'\u000D"
}
}
]
},
"when": "editorTextFocus"
},
What I think should work is this profile in settings.json:
"terminal.integrated.profiles.windows": {
"PowerShell": {
"source": "PowerShell",
"icon": "terminal-powershell"
},
"Command Prompt": {
"path": [
"${env:windir}\\Sysnative\\cmd.exe",
"${env:windir}\\System32\\cmd.exe"
],
"args": [],
"icon": "terminal-cmd"
},
"Git Bash": {
"source": "Git Bash",
"path": "C:\\Program Files\\Git\\git-bash.exe"
},
"Git Bash at fileDirname": {
"source": "Git Bash",
"path": "C:/Program Files/Git/git-bash.exe",
"args": [
"cd ${fileDirname}" // variables are supported here according to the docs
]
}
},
and then this associated keybinding:
{
"key": "alt+k",
"command": "workbench.action.terminal.newWithProfile",
"args": {
"profileName": "Git Bash at fileDirname",
"shouldForwardArgs": true
}
},
But it doesn't quite work for me. It almost works, but it says no such file exists. I see a couple of issues filed on variable resolution in profiles.
I use sublime text editor for writing code, and I want to set up a key binding for arrow keys, so I don't need to move my right hand frequently. To do so, I added code in sublime-keymap:
[
{ "keys": ["alt+j"], "command": "move", "args": {"by": "characters", "forward": false} },
{ "keys": ["alt+l"], "command": "move", "args": {"by": "characters", "forward": true} },
{ "keys": ["alt+i"], "command": "move", "args": {"by": "lines", "forward":false} },
{ "keys": ["alt+k"], "command": "move", "args": {"by": "lines", "forward": true} },
]
But, alt+j and alt+k are not working. Please help.
I tried to key bind in VS code too, the same problem occurs.
I am using OS Windows 10; the hotkeys defined by windows is creating this issue?
For vscode only, the commands are a little different (in your keybindings.json):
{
"key": "alt+j",
"command": "cursorMove",
"args": {
"to": "left",
"by": "character"
},
"when": "editorTextFocus"
},
{
"key": "alt+l",
"command": "cursorMove",
"args": {
"to": "right",
"by": "character"
},
"when": "editorTextFocus"
},
{
"key": "alt+i",
"command": "cursorMove",
"args": {
"to": "up",
"by": "line"
},
"when": "editorTextFocus"
},
{
"key": "alt+k",
"command": "cursorMove",
"args": {
"to": "down",
"by": "line"
},
"when": "editorTextFocus"
}
This is for moving the cursor within an editor. If you wanted arrow key-like functionality in a list - like the Explorer files - you would have to add some more keybindings with different commands. But it looks like you just want within a text editor.
~400 times by year 1 :
open VS Code
open one terminal
divide the terminal into 2 parts
run "npm run hot" (first split)
leave the other split terminal empty
open a second terminal (with "+" button)
split it into 3 parts
run "php artisan websockets:serve" (first part)
run "php artisan queue:words" (second part)
run "maidev --ip=localhost" (third part)
and finally I can start to work
I'm sure I am not alone with this problem.
Would anyone have a method to optimize that with one command or configuration ?
Thanks for your help !
Use this setting:
"terminal.integrated.windowsEnableConpty": false // true is the default
In tasks.json:
{
"label": "Run 2 terminals from tasks",
"dependsOrder": "sequence", // or parallel
"dependsOn": [
"OpenTerminal1",
"RunInTerminal1",
"RenameTerminal1", // if you care to rename each terminal
"SplitTerminal1",
"OpenTerminal2",
"RunInTerminal2a",
"RenameTerminal2a", // if you care to rename each terminal
"SplitTerminal2",
"RunInTerminal2b",
"RenameTerminal2b", // if you care to rename each terminal
"SplitTerminal2",
"RunInTerminal2c",
"RenameTerminal2c", // if you care to rename each terminal
],
// "runOptions": { "runOn": "folderOpen" } // or trigger with keybinding
},
That is the "master" task which calls all the constituent tasks, which are:
{
"label": "OpenTerminal1",
"command": "${command:workbench.action.terminal.new}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RunInTerminal1",
"command": "${input:runTerminal1}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RenameTerminal1",
"command": "${input:renameTerminal1}",
"type": "shell",
"problemMatcher": []
},
{
"label": "SplitTerminal1",
"command": "${command:workbench.action.terminal.split}",
"type": "shell",
"problemMatcher": []
},
// ------------------------------------------------------------------
{
"label": "OpenTerminal2",
"command": "${command:workbench.action.terminal.new}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RunInTerminal2a",
"command": "${input:runTerminal2a}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RenameTerminal2a",
"command": "${input:renameTerminal2a}",
"type": "shell",
"problemMatcher": []
},
// ------------------------------------------------------------------
{
"label": "SplitTerminal2",
"command": "${command:workbench.action.terminal.split}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RunInTerminal2b",
"command": "${input:runTerminal2b}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RenameTerminal2b",
"command": "${input:renameTerminal2b}",
"type": "shell",
"problemMatcher": []
},
// ------------------------------------------------------------------
{
"label": "RunInTerminal2c",
"command": "${input:runTerminal2c}",
"type": "shell",
"problemMatcher": []
},
{
"label": "RenameTerminal2c",
"command": "${input:renameTerminal2c}",
"type": "shell",
"problemMatcher": []
},
You might think that is enough but you can see that task require args (what to send to the terminals) so that I had to use this form:
"command": "${input:runTerminal2c}",
so that that input can provide the needed arguments and commands. Those go into the inputs section of your tasks file like so:
"inputs": [
{
"id": "openTerminal1",
"type": "command",
"command": "workbench.action.terminal.new",
},
{
"id": "runTerminal1",
"type": "command",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "npm run test\u000D"
}
},
{
"id": "renameTerminal1",
"type": "command",
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "npm run hot"
}
},
{
"id": "openTerminal2",
"type": "command",
"command": "workbench.action.terminal.new",
},
{
"id": "runTerminal2a",
"type": "command",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "php artisan websockets:serve"
}
},
{
"id": "renameTerminal2a",
"type": "command",
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "websockets:serve"
}
},
{
"id": "runTerminal2b",
"type": "command",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "php artisan queue:words"
}
},
{
"id": "renameTerminal2b",
"type": "command",
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "queue:words"
}
},
{
"id": "runTerminal2c",
"type": "command",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "maidev"
}
},
{
"id": "renameTerminal2c",
"type": "command",
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "maidev"
}
}
Again maybe you don't care about all the renaming the terminal commands and can eliminate those. Here, I just sent your command to the terminal:
{
"id": "runTerminal2c",
"type": "command",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "maidev"
}
},
but did not automatically start them. To have them start immediately, add the return unicode to the text that is sent to the terminal like:
{
"id": "runTerminal2c",
"type": "command",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "maidev --ip=localhost"
}
},
And finally a keybinding to trigger the master task (if you don't use the run on folder open option):
{
"key": "alt+z",
"command": "workbench.action.tasks.runTask",
"args": "Run 2 terminals from tasks"
},
I prefer the macro version - it is much shorter and less prone to set-up error. Both are very fast.
Okay, a day after answering this with other two answers, I saw this extension: Restore Terminals at this other question https://stackoverflow.com/a/62595681/836330
This extension seems to work quite well. Put this into your settings.json:
"restoreTerminals.runOnStartup": false, // true is the default
// set to false if using a keybinding or the command palette
"restoreTerminals.terminals": [
{
"splitTerminals": [
{
"name": "server",
"commands": [
"npm run test"
]
},
{
"name": "empty",
}
]
},
{
"splitTerminals": [
{
"name": "websockets",
"commands": [
"ls -l"
]
},
{
"name": "queue",
"commands": [
"cd zip",
"gulp sass"
]
},
{
"name": "maidev",
"commands": [
"cd zip-multiple",
"gulp"
]
}
]
}
],
And a keybinding:
{
"key": "shift+alt+t", // whatever keybinding if you wish
"command": "restore-terminals.restoreTerminals",
},
If on Windows, I would still use the setting:
"terminal.integrated.windowsEnableConpty": false
as the same issue occurs when using this extension as any other method to open and write to terminals quickly - if you then try to close the terminals vscode will hang and eventually timeout and need to be reopened.
I'll make this two answers as one version is particularly long. One answer uses a macro extension to help solve this and the other uses only tasks.
For both solutions, use this setting:
"terminal.integrated.windowsEnableConpty": false // true is the default
There is a nasty unsolved bug affecting Winpty and vscode when you try to delete a terminal opened by these methods.
Using the macro extension multi-command. This goes into your tasks.json:
{
"label": "Run 2 terminals with macro",
"dependsOrder": "sequence", // or parallel
"dependsOn": [
"terminal1",
"terminal2"
],
// "runOptions": { "runOn": "folderOpen" }
},
{
"label": "terminal1",
"command": "${command:multiCommand.startFirstTerminal}"
},
{
"label": "terminal2",
"command": "${command:multiCommand.startSecondTerminal}"
},
The two tasks are run by the macro. This goes into your settings.json:
"multiCommand.commands": [
{
"command": "multiCommand.startFirstTerminal",
"sequence": [
"workbench.action.terminal.newInActiveWorkspace",
{
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "npm run test\u000D"
}
},
{
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "npm run hot"
}
},
"workbench.action.terminal.split",
]
},
{
"command": "multiCommand.startSecondTerminal",
"sequence": [
"workbench.action.terminal.newInActiveWorkspace",
{
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "websockets:serve"
}
},
{
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "ls -lrt\u000D"
}
},
"workbench.action.terminal.split",
{
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "queue:words"
}
},
{
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "ls -lrt\u000D"
}
},
"workbench.action.terminal.split",
{
"command": "workbench.action.terminal.renameWithArg",
"args": {
"name": "maidev"
}
},
{
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "ls -lrt\u000D"
}
},
]
}
]
I renamed the terminals to match your commands - perhaps you don't care about that and can eliminate the renameWithArg sections to shorten the whole thing.
I couldn't test with your php setup, so I substituted ls -lrt\u000D running in each terminal. Just substitute your
{
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "php artisan websockets:serve\u000D"
}
},
for example. The \u000D is a return so the command runs immediately. Now you can either use the "runOptions": { "runOn": "folderOpen" } option so the master task runs when the workspace opens or assign a keybinding to the master task like
{
"key": "alt+z", // or watever you want
"command": "workbench.action.tasks.runTask",
"args": "Run 2 terminals with macro"
},
I like the use the German umlauts "ö", "Ö", "ä", and "Ä" on my keyboard for coding in VSCode, i.e., use these keys to type square and curly brackets. Here is what I tried in keybindings.json:
{ "key": "ö", "command": "type", "args": { "text": "[" }, "when": "editorTextFocus" },
{ "key": "ä", "command": "type", "args": { "text": "]" }, "when": "editorTextFocus" },
{ "key": "Shift+ö", "command": "type", "args": { "text": "{" }, "when": "editorTextFocus" },
{ "key": "Shift+ä", "command": "type", "args": { "text": "}" }, "when": "editorTextFocus" },
{ "key": "Alt-ö", "command": "type", "args": { "text": "ö" }, "when": "editorTextFocus" },
{ "key": "Alt-ä", "command": "type", "args": { "text": "ä" }, "when": "editorTextFocus" },
{ "key": "Alt-Shift+ö", "command": "type", "args": { "text": "Ö" }, "when": "editorTextFocus" },
{ "key": "Alt-Shift+ä", "command": "type", "args": { "text": "Ä" }, "when": "editorTextFocus" }
VSCode complains:
You won't be able to produce this key combination under your current
keyboard layout.
Is there an easy way to teach VSCode to allow bindings for any key instead of just the predefined ones?
These are allowed, the pre-defined "Toggle Integrated Terminal" shortcut is Ctrl+ö after all. You just can't write the characters literally in JSON.
I usually prefer to use the JSON editor myself as well, but this is actually a case where the UI is quite helpful. In the "please enter desired key combination" popup, you can see that with a QWERTZ keyboard...
...ö turns in to oem_3
...ä turns in to oem_7
...ü turns in to oem_1
Thanks #Gama11 for the hint regarding the UI. I tried it and got the keys [Semicolon], [Quote], and [BracketLeft], for ö, ä, and ü for my German keyboard + layout.
Here is my working keybindings.json:
{ "key": "[Semicolon]", "command": "type", "args": { "text": "[" }, "when": "editorTextFocus" },
{ "key": "[Quote]", "command": "type", "args": { "text": "]" }, "when": "editorTextFocus" },
{ "key": "Shift+[Semicolon]", "command": "type", "args": { "text": "{" }, "when": "editorTextFocus" },
{ "key": "Shift+[Quote]", "command": "type", "args": { "text": "}" }, "when": "editorTextFocus" },
{ "key": "Alt+[Semicolon]", "command": "type", "args": { "text": "ö" }, "when": "editorTextFocus" },
{ "key": "Alt+[Quote]", "command": "type", "args": { "text": "ä" }, "when": "editorTextFocus" },
{ "key": "Shift+Alt+[Semicolon]", "command": "type", "args": { "text": "Ö" }, "when": "editorTextFocus" },
{ "key": "Shift+Alt+[Quote]", "command": "type", "args": { "text": "Ä" }, "when": "editorTextFocus" }
It works perfectly for the mapped umlaut keys and does not interfere with the regular ; and " keys.
When I scroll using ctrl + up/down, the cursor is moved to the first non-whitespace character on the line, when it goes outside of the view. This is a bit annoying when I've placed the cursor in the left-most column on purpose (this is how I edit, sometimes).
You can see the effect more clearly with this keybinding:
[
{
"key": "ctrl+down",
"command": "editorScroll",
"args": {
"to": "down",
"by": "line",
"revealCursor": true
}
},
{
"key": "ctrl+up",
"command": "editorScroll",
"args": {
"to": "up",
"by": "line",
"revealCursor": true
}
}
]
Can I toggle this behaviour off so that the cursor stays in the column where I've placed it?
If you want to use keyboard scrolling while keeping the cursor position at the same column, one workaround would be to use the macros extension so that you can both scroll down and move the cursor down at the same time.
Add this to settings.json
"macros": {
"keyboardScrollDown": [
{
"command": "editorScroll",
"args": {
"to": "down",
"by": "line",
"revealCursor": true
}
},
"cursorDown"
],
"keyboardScrollUp": [
{
"command": "editorScroll",
"args": {
"to": "up",
"by": "line",
"revealCursor": true
}
},
"cursorUp"
]
},
Add this to keybindings.json
{
"key": "ctrl+down",
"command": "macros.keyboardScrollDown"
},
{
"key": "ctrl+up",
"command": "macros.keyboardScrollUp",
},