Growing with the Web

Mastering VS Code's Terminal

Published , updated
Tags:

Visual Studio Code’s integrated terminal can be launched with ctrl+`. This article goes into some of the lesser known things you can do with the terminal.

This article makes heavy use of custom settings and keybindings, so make sure you know how they work to get the most out of it.

Choose your shell

VS Code will try to pick your preferred terminal on Linux and macOS by looking at the $SHELL environment variable, on Windows Powershell is the default. You can customize which shell using the following settings:

  • terminal.integrated.shell.linux
  • terminal.integrated.shell.osx
  • terminal.integrated.shell.windows

There are also settings that specify the arguments that the shell is launched with. For example you could launch bash on macOS as a login shell with the following:

{
  "terminal.integrated.shell.osx": "/bin/bash",
  "terminal.integrated.shellArgs.osx": ["-l"]
}

There are some good recommendations on how to configure the various Windows shells on the official documentation page.

Text style

The text style of the terminal can be set using the following settings:

  • terminal.integrated.fontFamily
  • terminal.integrated.fontLigatures
  • terminal.integrated.fontSize
  • terminal.integrated.lineHeight

Terminal colors

Added in v1.12

Terminal colors are set by themes but can also also be overridden like so:

{
  // Use Terminal.app's default colors
  "workbench.colorCustomizations": {
    "terminal.ansiBlack": "#000000",
    "terminal.ansiRed": "#c23621",
    "terminal.ansiGreen": "#25bc24",
    "terminal.ansiYellow": "#adad27",
    "terminal.ansiBlue": "#492ee1",
    "terminal.ansiMagenta": "#d338d3",
    "terminal.ansiCyan": "#33bbc8",
    "terminal.ansiWhite": "#cbcccd",
    "terminal.ansiBrightBlack": "#818383",
    "terminal.ansiBrightRed": "#fc391f",
    "terminal.ansiBrightGreen": "#31e722",
    "terminal.ansiBrightYellow": "#eaec23",
    "terminal.ansiBrightBlue": "#5833ff",
    "terminal.ansiBrightMagenta": "#f935f8",
    "terminal.ansiBrightCyan": "#14f0f0",
    "terminal.ansiBrightWhite": "#e9ebeb",
  }
}

Terminal cursor

The terminal cursor can be set to a block (default), line/bar or underline. It can also be made to blink:

{
  "terminal.integrated.cursorBlinking": true,
  "terminal.integrated.cursorStyle": "line"
}

Increasing the buffer size

The terminal keeps 1000 lines of data by default before it starts discarding them, this number can be customized with terminal.integrated.scrollback:

{
  "terminal.integrated.scrollback": 5000
}

Maximizing the terminal

The panel can be maximized by adding a keybinding. Once maximized, triggering the command again will restore the panel to its previous size. This is useful when you need to look at a diff or need to do some heavy terminal work.

[
  { "key": "ctrl+shift+q", "command": "workbench.action.toggleMaximizedPanel" }
]

Working with multiple terminals

There are several commands that make managing multiple terminals much easier, they do not have default keybindings but you can easily bind them in your keybindings.json file:

[
  { "key": "ctrl+shift+x", "command": "workbench.action.terminal.kill" },
  { "key": "ctrl+shift+j", "command": "workbench.action.terminal.focusNext" },
  { "key": "ctrl+shift+k", "command": "workbench.action.terminal.focusPrevious" },
]

Copy and paste

Standards for copying and pasting in terminals vary between platforms:

  • Linux:
    • Copy: ctrl+shift+c
    • Paste: ctrl+shift+v
  • macOS:
    • Copy: +c
    • Paste: +v
  • Windows:
    • Copy: ctrl+c when there is a selection
    • Paste: ctrl+v
    • Right clicking on terminal copies when there is a selection and pastes when there is no selection

Luckily most of this was implemented in a generic way so you can configure it however you want. For example if a Linux user wanted to adopt the Windows settings they could add the following to their keybindings.json file:

[
  { "key": "ctrl+c", "command": "workbench.action.terminal.copySelection",
                        "when": "terminalFocus && terminalTextSelected" },
  { "key": "ctrl+v", "command": "workbench.action.terminal.paste",
                        "when": "terminalFocus" }
]

And this to their settings.json:

{
  "terminal.integrated.rightClickCopyPaste": true
}

You can even unbind default keybindings if desired by prepending the keybinding command with -:

[
  { "key": "ctrl+shift+c", "command": "-workbench.action.terminal.copySelection",
                              "when": "terminalFocus && terminalTextSelected" },
  { "key": "ctrl+shift+v", "command": "-workbench.action.terminal.paste",
                              "when": "terminalFocus" },
]

Select all

Added in v1.14

Select all works out of the box on macOS with +a, unfortunately on other platforms ctrl+a is used as a common shortcut for terminal applications so it is passed to the shell by default. To make ctrl+a trigger select all, you can add this keybinding:

[
  { "key": "ctrl+a", "command": "workbench.action.terminal.selectAll",
                        "when": "terminalFocus" },
]

Focus when already open

A nice trick to make focusing the terminal using the keybinding less frustrating is to override the ctrl+` keybinding to focus when the terminal is not focused:

[
  { "key": "ctrl+`", "command": "workbench.action.terminal.focus",
                        "when": "!terminalFocus" }
]

A tweak to this is to make it focus the last active editor instead of the terminal which may be better if you find you don’t hide the terminal very often:

[
  { "key": "ctrl+`", "command": "workbench.action.terminal.focus",
                        "when": "!terminalFocus" },
  { "key": "ctrl+`", "command": "workbench.action.focusActiveEditorGroup",
                        "when": "terminalFocus" }
]

Configure which keys are sent to the terminal

VS Code sends all key strokes to the terminal except for those specified in the terminal.integrated.commandsToSkipShell setting. This contains a bunch of generally useful commands like quick open, debugging and all of the terminal keybindings by default. For example since function keys are consumed by the terminal, if you wanted to be able to toggle full screen (F11) when the terminal is focused you would add the command like so:

{
  "terminal.integrated.commandsToSkipShell": [
    ...,
    "workbench.action.toggleFullScreen"
  ]
}

Another related example is using ctrl+e to go to the end of the prompt in bash, this doesn’t work out of the box because ctrl+e is one of the keybindings assigned to workbench.action.quickOpen which is included in the default terminal.integrated.commandsToSkipShell list. You could remove it from the list but the best fix for this is likely to remove the keybinding all together:

[
  { "key": "ctrl+e", "command": "-workbench.action.quickOpen" }
]

Added in v1.10

You can open links to both URLs and local file paths that are output to the terminal by holding ctrl ( on macOS) and clicking on the link. Line/column annotations are also supported for files.

Drag and drop file paths

Added in v1.13

You can drag files from the OS file explorer or from the VS Code explorer into the terminal to paste the path.

Run selected text and active file

There are two useful commands that can be very useful if you deal a lot with scripting languages:

  • workbench.action.terminal.runSelectedText: Runs the selected text in the terminal, if there is no selection then the current line will be run
  • workbench.action.terminal.runActiveFile: Runs the active file in the terminal

Confirm when exiting VS Code with active terminal sessions

Added in v1.11

You can have VS Code warn you when exiting if there active terminal sessions.

{
  "terminal.integrated.confirmOnExit": true
}

Currently this happens when any terminal shell is running (eg. bash), regardless of whether the shell itself is running something. The follow up item for this is Microsoft/vscode#23808.

Launch vscode at the terminal’s directory

Like most editors you can launch a new instance of vscode on a directory through the command line with:

code .

A little known trick though is that you can open the directory in the most recently used vscode window by passing in the -r command line argument:

code -r .

This even works in the integrated terminal!

Finding text within the terminal

Added in v1.14

You can bring up a find dialog the terminal using ctrl+f (+f on macOS). This works similar to find in the editor.

If you want ctrl+f to perform it’s regular move the cursor right 1 space action, you can unbind the find keybinding by adding this to your keybindings.json file:

[
  { "key": "ctrl+f", "command": "-workbench.action.terminal.focusFindWidget",
                      "when": "terminalFocus" }
]

Extensions

VS Code features an extension API that enables extensions to launch and communicate with terminals. Here are some useful ones:

  • PowerShell: PowerShell language and improved terminal support
  • Terminal Here: Exposes a command to launch a terminal in the directory of the current file
  • Shell Launcher: Easily launch multiple shell configurations in the terminal

Persistent sessions using tmux

João Moreno shared his tmux setup that allows reuse of terminal sessions between VS Code windows in this blog post.

External terminal

VS Code also features a convenient way to launch an external terminal as well via the workbench.action.terminal.openNativeConsole command (/ctrl+shift+c).

Like this article?
Subscribe for more!