Shortcut for running terminal command in VS code - terminal

Is there a way to make a hotkey for running specific command in terminal? Say I want to compile my TypeScript files by hotkey and not to type to terminal "tsc" or any other variation of that command. (Edit: I know it is possible to recompile TS on save, but the question is still the same)

Typically you would set up a build or another task or an npm script and then trigger that with a hotkey.
There is another new way to do it with send text to the terminal.
For example, try this in your keybindings (Preferences: Open Keyboard Shortcuts (JSON)):
{
"key": "ctrl+alt+u",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "node -v\u000D"
}
}
for an npm script:
{
"key": "ctrl+alt+u",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "npm run-script test\u000D"
}
}
The first will run the node -v command (the \u000D is a return so it runs). I still recommend actually setting up a build task though, and then there are keychords for running your build task: Ctrl-shift-B. Or an npm script.
For example, if you had a more complex script to run, see how to bind a task to a keybinding or how to keybind an external command.
EDIT: As of v1.32 you can now do something like this:
{
"key": "ctrl+shift+t",
"command": "workbench.action.terminal.sendSequence",
"args": { "text": "tsc '${file}'\u000D" }
}
You can now use the built-in variables, like ${file}, with the sendSequence command in a keybinding. I wrapped ${file} in single quotes in case your directory structure has a folder with a space in the name. And \u000D is a return.

You can accomplish this with VSCode tasks and then wire up your task to a keybinding. The downside to this approach is you have to have a tasks.json file in your workspace .vscode folder (it can't be global).
Here is an example where I wanted to open a file in a custom GitHub remote:
// tasks.json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Open in remote",
"type": "shell",
"command": "open https://github.custom.com/org/repo/blob/master/${relativeFile}#L${lineNumber}"
}
]
}
// keybindings.json
{
"key": "ctrl+o",
"command": "workbench.action.tasks.runTask",
"args": "Open in remote"
},
Here are some more VS Code variables you can use if you are curious: https://code.visualstudio.com/docs/editor/variables-reference
There is a long standing issue open here which should make this easier to do without tasks: https://github.com/microsoft/vscode/issues/871

I don't think vscode by default can do this, but you can try this extension. That work for me.
https://marketplace.visualstudio.com/items?itemName=mkloubert.vs-script-commands

in addition to #mark ..
"args": { "text": "npm run-script test | tee /dev/null \u000D" }
this way it will run any script including bash scripts, that doesn't conflict to their arguments
(e.g try rsync without the tee)

Related

WSL bash in Visual Studio Code running .bashrc but not .bash_profile

Until recently, when I've launched the integrated terminal in Visual Studio Code, bash runs both my .bashrc and my .bash_profile files. But now it's only running the .bashrc file. I need it to run both.
Some details: VSC 1.70.1 (latest), with the "Remote - SSH" extension, running under Windows 10 (updated) with WSL 2 installed. When I launch a Microsoft terminal, it runs both .bashrc and .bash_profile, but VSC's integrated terminal only runs the former. This probably means I have s.t. wrong in my VSC config, but the settings there seem to change frequently and it's hard to keep up. The relevant parts seem to be
"terminal.integrated.defaultProfile.windows": "WSL",
"terminal.integrated.profiles.windows": {
"bash":{
"path": "C:\\Windows\\System32\\bash.exe",
"args": ["-l"]
},
"WSL": {
"path": "C:\\WINDOWS\\System32\\wsl.exe",
"args": [ ],
"icon": "terminal-ubuntu"
}
},
but that doesn't work, nor do any of the variants I've tried on the two "args" parameters, nor changing the defaultProfile to "bash" instead of "WSL".
Before I give in and put all my startup settings in my .bashrc file and get rid of my .bash_profile file, what do I yet lack?
The historical presumption on UNIX is that .bash_profile runs once when you log in, then .bashrc runs in each new shell. Thus, things that are inherited by child processes (like environment variables) go in .bash_profile so they can only run once per login (often, as a parent process to xinit or otherwise GUI startup), whereas things that need to be separately configured for each new shell (like aliases, non-exported functions, prompt settings, etc) go in .bashrc.
If, however, you're in an environment where .bash_profile isn't run during session creation, you might want to invoke it during .bashrc operation (so it happens during setup of any new interactive shell). Consider adding the following to your .bash_profile:
# put this at the top of your .bash_profile
[[ $profile_already_sourced ]] && return
declare -x profile_already_sourced=1 # export so we only run once per process tree
# ...set up your environment variables here...
[[ -s ~/.bashrc ]] && source ~/.bashrc
...and the following to your .bashrc:
# put this at the top of your .bashrc
[[ $bashrc_already_sourced ]] && return
declare -- bashrc_already_sourced=1 # do not export this!
# ...do your non-exported shell-local configuration here...
[[ -s ~/.bash_profile ]] && source ~/.bash_profile
...that way you can have each file source the other when needed without causing an infinite loop.
I can't reproduce this after even after upgrading to 1.70.1, so I'd recommend trying out these things:
try
"path": "C:\\WINDOWS\\System32\\wsl.exe",
"args": ["-e", "bash", "-li"]
to make sure that a login shell is started
if this changed after upgrading, read Help -> Release Notes to find out what might be responsible, e.g. the Shell integration is now enabled by default, so you might try "terminal.integrated.shellIntegration.enabled": false
sync / backup your settings, re-install vanilla VSC, check if behaviour is still the same

How to add the custom compile commands in VS Code?

I usually do competitive programming in Geany IDE and have the following custom compile command to compile C++ programs -
g++ -std=c++17 -Wshadow -Wall -o "%e" "%f" -g -fsanitize=address -fsanitize=undefined -D_GLIBCXX_DEBUG
The compile command is binded by f9 key. I just have to press f9, which saves and compiles the file and then I switch to bash terminal (f2 key shortcut) to execute the binary file.
The terminal also follows the path of the current file opened in editor.
I want the same settings in VS Code.
So far, I have managed to bring the editor and terminal side by side and to easily toggle the focus between them via f1 and f2.
But I am unable to set the custom compile command, bind it with f9 key and to configure the terminal so that it follows the path of file in editor currently in focus.
Please give me a complete solution. It would be much better to edit the json setting files directly.
Here is a snapshot of the settings in my Geany IDE :-
This is how my Geany looks and the Setting boxes
You can set a custom task in VS Code. Edit the tasks.json file in the .vscode folder of your workspace like:
{
"version": "2.0.0",
"tasks": [
{
"label": "My build task",
"type": "shell",
// Assign output file name with VSCode inner variables like ${fileBasename}
"command": "g++ -std=c++17 -Wshadow -Wall -o ${fileBasename} -g -fsanitize=address -fsanitize=undefined -D_GLIBCXX_DEBUG",
"options": {
},
"problemMatcher": ["$gcc"],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
You can write the compile command directly into "command" attribute, or write it with more commands into a script then write the simple executing script command in the attribute instead.
And the "isDefault": true attribute make this default task which could be invoked simply binding with ctrl+shift+B.

Keybindings not working from VSCode integrated terminal

I'm attempting to map the vscode commands workbench.action.navigateLeft and workbench.action.navigateRight to alt+i and alt+o, respectively. This was pretty straightforward with the following changes to keybindings.json:
{
"key": "alt+o",
"command": "workbench.action.navigateRight"
},
{
"key": "alt+i",
"command": "workbench.action.navigateLeft"
},
This works perfectly when I'm in the context of editors, but does not work when my focus is on the integrated terminal. I've added these two commands to terminal.integrated.commandsToSkipShell in settings.json but that seemed to have no effect. Nothing happens when I press alt+i or alt+o from within the integrated terminal.
"terminal.integrated.commandsToSkipShell": [
"workbench.action.navigateLeft",
"workbench.action.navigateRight"
]
I'm on a linux system using bash as my shell. It seems like maybe bash is capturing my keystrokes before vscode has the opportunity to interpret them, but I don't know how to verify if that's happening or how to change it if it is. Any help would be appreciated.
The problem ended up being with a different setting in my settings.json file. I had terminal.integrated.sendKeyBindingsToShell set to true which was intercepting some commands before they could be received by vscode.
This makes sense given the description of that setting. Setting this value to false (or removing from my settings.json file as the default is false) caused my key bindings to work as expected.

Want ${workspaceFolder} to emit forward slashes on Windows?

I'm configuring a VSCode task in tasks.json, and I need to pass the ${workspaceFolder} to a 'make' command, however it needs to be forward slashes, not back slashes.
{
"version": "2.0.0",
"echoCommand": true,
"tasks": [
{
"label": "build",
"type": "shell",
"group": {
"kind": "build",
"isDefault": true
},
"command": "make",
"args": [
"APPDIR=\"${workspaceFolder}\""
]
. . .
Is there any way to modify ${workspaceFolder} to emit forward slashes on Windows?
Or, is there such a thing as a macro, where I can search and replace?
EDIT:
My root issue is that GNU make seems to escape the backslashes incoming from APPDIR, for example: C:\somedirectory\someotherdirectory\athirddirectory.
I thought if I could switch to forward slashes, it would fix the issue.
I have no control over, and cannot edit, the make file.
Thanks
-John
Although not explicitly stated, it sounds like you're on Windows and using Cygwin make.
Basically using Johan's suggestion, here is a complete tasks.json that uses cygpath -m to pass forward slashes to make:
{
"version": "2.0.0",
"tasks": [
{
"label": "build hello world",
"type": "shell",
"command": "d:/cygwin64/bin/sh",
"args": [
"-c",
"make APPDIR=$(cygpath -m '${workspaceFolder}')"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
And here is a sample Makefile to be called:
$(info APPDIR is "$(APPDIR)")
helloworld.exe: helloworld.cpp
g++ -g -Wall -std=c++11 -o $# helloworld.cpp
When I press Ctrl+Shift+B to invoke this task, I see in the Terminal window:
> Executing task in folder cpphello: d:/cygwin64/bin/sh -c "make APPDIR=$(cygpath -m 'D:\wrk\learn\vscode\cpphello')" <
APPDIR is "D:/wrk/learn/vscode/cpphello"
make: 'helloworld.exe' is up to date.
Terminal will be reused by tasks, press any key to close it.
This uses the -m (mixed) switch to cygpath to get what looks like a Windows path but using forward slashes. cygpath has other options; see cygpath --help.
Two subtleties here:
I specify the path to sh explicitly. That is because I also
have git for Windows on my $PATH,
and it comes before my Cygwin path so that vscode will use that
git. But git for Windows also has sh.exe, and if that one
is used here, make blows up with a Cygwin DLL error.
I had to change the default VSCode shell to cmd.exe, whereas
the default is powershell.exe. The problem with powershell
here is that VSCode uses single quotes when passing arguments to
it, whereas my solution requires that VSCode use double-quotes,
which it does with cmd.exe. To change the shell, use the
"Terminal: Select Default Shell" command from the palette
(Ctrl+Shift+P).
Finally, I'll note that all of this nonsense can be avoided if, in your situation, you can create an intermediate bash shell script rather than invoking make directly. The tasks.json language is not very powerful, and the quirky shells VSCode knows how to invoke on Windows (namely cmd.exe and powershell.exe) add extra complexity and fragility.
Use variable extension.commandvariable.workspace.workspaceFolderPosix from extension command-variable where you need ${workspaceFolder} with forward slashes. There are also other useful substitutions in this extension.

Setting up Sublime to use bash aliases & functions

I'm using sublime and would like to set it up so that my custom build system can see and use aliases and bash functions which I've setup in my ~/.bashrc, which works from my terminal.
In my .bashrc file I have a build function:
function build() {
// various bash commands
}
In my ~/Library/Application Support/Sublime Text 3/Packages/User directory I have a project.sublime-build file:
{
"cmd": ["build"],
"working_dir": "~/Mozilla/git-master",
"shell" : "true"
}
which doesn't work. How can I get sublime to see and use the build function defined in my .bashrc file?
Sublime can not read your .bashrc, so in order to use custom functions you'll have to create a build file:
#!/bin/bash
#contents of build() go here...
Save the file in ~/bin and set it to be executable. Then, modify your project.sublime-build file like so:
{
"cmd": ["build"],
"path": "~/bin:$PATH",
"working_dir": "~/Mozilla/git-master",
"shell" : "true"
}
And you should be all set.

Resources