Skip to content

Embedded terminal in VSCode and variants

RedBearAK edited this page Feb 18, 2025 · 6 revisions

Fixing shortcuts in VSCode terminal pane

In Linux, the keymapper is unable to tell which portion of a window has the focus, only the app class and title (name) of the window. Since the way the keymapper config works in terminal apps is by treating terminals as a group and changing its modifier remaps compared to "GUI" apps, the shortcuts you would expect to work in terminals won't work the same way in a terminal view that is embedded inside a "GUI" app like Visual Studio Code or any of its variants (e.g., VSCodium, Code - OSS).

But the VSCode window knows which pane you are in, and you can remap some shortcuts with an internal VSCode method so that things work a little more the way you would expect. The remaps need to be targeted to only be active in the embedded terminal, with the terminalFocus conditional test in the when part of each remap.

Here are some that I came up with or copied from other comments. Feel free to open an issue and submit more fixes if you come up with some. This needs to be entered into the keybindings.json file that you open from the Command Palette with "open keyboard shortcuts json". (Don't choose the one that says "Default Keyboard Settings".)

Saving the changes to the file should make them immediately active in the terminal pane.

Some of the fixes will not work as expected unless you override one of the default VSCode-related keymaps. See further below for more information on that.

Caution

Doing this will also cause these shortcuts to behave differently when Toshy or Kinto are disabled, and that behavior may not make much sense after the modifier keys move back to their original positions. These remaps for the embedded terminal won't go away when the keymapper is not running, unless you open the keybindings.json file again and comment them all out and save the file. This could potentially cause some major confusion unless you remember what is going on. This could also mess with using a terminal app like nano.

// Place your key bindings in this file to override the defaults
[

    //////////////////////////////////////////////////////////
    // Fixes for embedded terminal for use with Toshy/Kinto //
    //////////////////////////////////////////////////////////

    {
        // Send the Ctrl+C/SIGINT interrupt sequence in terminal with Ctrl+C
        "key": "meta+c",
        "command": "workbench.action.terminal.sendSequence",
        "args": { "text": "\u0003" },
        "when": "terminalFocus"
    },
    {
        // Send the Ctrl+C/SIGINT interrupt sequence in terminal with Cmd+Dot
        "key": "ctrl+.",
        "command": "workbench.action.terminal.sendSequence",
        "args": { "text": "\u0003" },
        "when": "terminalFocus"
    },
    {
        // Reverse search history with Ctrl+R
        "key": "meta+r",
        "command": "workbench.action.terminal.sendSequence",
        "args": { "text": "\u0012" },
        "when": "terminalFocus"
    },
    {
        // Clear screen in terminal with Cmd+L
        "key": "ctrl+l",
        "command": "workbench.action.terminal.clear",
        "when": "terminalFocus"
    },
    {
        // Copy selected text in terminal with Cmd+C
        "key": "ctrl+c",
        "command": "workbench.action.terminal.copySelection",
        "when": "terminalFocus"
    },    
    {
        // Paste text in terminal with Cmd+V
        "key": "ctrl+v",
        "command": "workbench.action.terminal.paste",
        "when": "terminalFocus"
    },
    {
        // Delete all text left of cursor in terminal (Ctrl+U sequence)
        // For Kinto (Cmd+Backspace)
        "key": "ctrl+backspace",
        "command": "workbench.action.terminal.sendSequence",
        "args": { "text": "\u0015" },
        "when": "terminalFocus"
    },
    {
        // Delete all text left of cursor in terminal (Ctrl+U sequence)
        // Alternate for Toshy (Shift+Cmd+Backspace)
        "key": "shift+ctrl+backspace",
        "command": "workbench.action.terminal.sendSequence",
        "args": { "text": "\u0015" },
        "when": "terminalFocus"
    },
    {
        // Delete word left of cursor in terminal (Ctrl+W sequence)
        "key": "alt+backspace",
        "command": "workbench.action.terminal.sendSequence",
        "args": { "text": "\u0017" },
        "when": "terminalFocus"
    },

]

Some shortcuts are protected and can't be changed this way. For instance, you can't remap Ctrl+B from this file, so Cmd+B will move the cursor one character to the left in the embedded terminal. If you want to instead have Cmd+B toggle the sidebar visibility the same way it does outside of the terminal pane, you have to add this to your "User Settings JSON" file:

    "terminal.integrated.commandsToSkipShell": [
        "workbench.action.toggleSidebarVisibility"
    ]

This keeps the shell from consuming the Ctrl+B key combo that is emitted by the physical equivalent of Cmd+B.

Override keymap to fix some fixes

It has come to my attention that I used a custom override keymap while developing these fixes, to overcome a deficiency caused by a default VSCode keymap. Namely, the Meta+C and Ctrl+C fixes will be affected by this. Placing a custom keymap in your user_apps editable slice should make those shortcuts work as intended in the embedded terminal pane.

####################################  USER APPS  #####################################
###                                                                                ###
###                                                                                ###
###      ██    ██ ███████ ███████ ██████       █████  ██████  ██████  ███████      ###
###      ██    ██ ██      ██      ██   ██     ██   ██ ██   ██ ██   ██ ██           ###
###      ██    ██ ███████ █████   ██████      ███████ ██████  ██████  ███████      ###
###      ██    ██      ██ ██      ██   ██     ██   ██ ██      ██           ██      ###
###       ██████  ███████ ███████ ██   ██     ██   ██ ██      ██      ███████      ###
###                                                                                ###
###                                                                                ###
######################################################################################
### This is a good location in the config file for adding new custom keymaps for 
### user applications and custom function keys. Watch out that you don't override 
### any "general" shortcuts like Cmd+Z/X/C/V that may be defined below this section. 
### Changes made between the "slice" marks will be retained by the Toshy installer 
### if you reinstall and it finds matching start/end markers for each section. 

###################################################################################################
###  SLICE_MARK_START: user_apps  ###  EDITS OUTSIDE THESE MARKS WILL BE LOST ON UPGRADE

# A "User hardware keys" empty keymap is typically in this slice as an example.

keymap("User overrides: VSCodes overrides for not Chromebook/IBM", {
    C("Super-c"):               C("Super-c"),                   # Default - Terminal - Sigint
    C("Super-x"):               C("Super-x"),                   # Default - Terminal - Exit nano
}, when = lambda ctx:
    cnfg.screen_has_focus and
    not (   isKBtype('Chromebook', map="vscodes ovr not cbook")(ctx) or 
            isKBtype('IBM', map="vscodes ovr not ibm")(ctx) ) and
    matchProps(clas=vscodeStr)(ctx)
)

###  SLICE_MARK_END: user_apps  ###  EDITS OUTSIDE THESE MARKS WILL BE LOST ON UPGRADE
###################################################################################################

This will override this default VSCode supplementary keymap that tries to make Ctrl+C work in the embedded terminal without these special keybindings.json fixes:

keymap("VSCodes overrides for not Chromebook/IBM", {
    C("Super-c"):               C("C-c"),                       # Default - Terminal - Sigint
    C("Super-x"):               C("C-x"),                       # Default - Terminal - Exit nano
}, when = lambda ctx:
    not (   isKBtype('Chromebook', map="vscodes ovr not cbook")(ctx) or
            isKBtype('IBM', map="vscodes ovr not ibm")(ctx) ) and
    matchProps(clas=vscodeStr)(ctx)
)