Vim: Key mapping does not support ctrl key

Please thumbs-up 👍 this issue if it personally affects you! You can do this by clicking on the emoji-face on the top right of this post. Issues with more thumbs-up will be prioritized.


What did you do?

Attempted to map <kbd>Ctrl +h</kbd> to <kbd>Ctrl-w h</kbd>.

In settings.json:

    "vim.otherModesKeyBindings": [
        {
            "before": ["<C-h>"],
            "after": ["<C-w>", "h"]
        }
    ],

Saved config, then tried <kbd>Ctrl + h</kbd>

What did you expect to happen?

Expected to map <kbd>Ctrl +h</kbd> to <kbd>Ctrl-w h</kbd>

What happened instead?

Character under cursor was deleted. (Escape sequence Ctrl+h ??)

Technical details:

  • VSCode Version: Version 1.10.1 (1.10.1)
  • VsCodeVim Version: 0.6.11
  • OS: OS X

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 25
  • Comments: 23 (8 by maintainers)

Most upvoted comments

Hi Is it possible to bind Ctrl+; to this action somehow? I’ve got used to this combo so much already…

{
            "before": ["<C-;>"],
            "after": ["A", ";", "<Esc>"]
}

Not sure if I should expect the plugin to manage custom key bindings for VScode, other than maybe providing a vim-like configuration. In the meantime, I used VSCode’s user-defined keymappings to accomplish mapping ctrl+ keys to editor actions.

Code -> Preferences -> Keyboard Shortcuts (or ⌘K ⌘S)

[
  {
    "key": "ctrl+alt+h",
    "command": "workbench.action.focusPreviousGroup",
    "when": "editorTextFocus"
  },
  {
     "key": "ctrl+alt+l",
    "command": "workbench.action.focusNextGroup",
    "when": "editorTextFocus"
  },
  {
    "key": "ctrl+h",
    "command": "workbench.action.previousEditor",
    "when": "editorTextFocus"
  },
  {
    "key": "ctrl+l",
    "command": "workbench.action.nextEditor",
    "when": "editorTextFocus"
  }
]

We bind to a couple of <ctrl>+<key> commands (https://github.com/VSCodeVim/Vim/blob/master/package.json#L140). Pertaining to the original issue, <C-h>works on v0.13.1:

    "vim.normalModeKeyBindings": [
        {
            "before": [
                "<C-h>"
            ],
            "after": [
                "<C-w>",
                "h"
            ]
        }
    ],

For keycombos that involve CTRL, the full list is in our package.json, for others we have a bug tracking this here https://github.com/VSCodeVim/Vim/issues/757.

I had a similar issue remapping emacs-like text motion in insert mode (trying to get ctrl-{a,e,p,n,d,h,f,b} to work in insert mode like other mac text boxes). Either the vscodevim keymappings would have preference over my vim.*KeyBindings or they’d be disabled if I used handleKeys to exclude them. I ended up getting a good result by just using keybindings.json like others here, gating on vim.mode (note ctrl-{h,b,p} already worked without an explicit mapping so I left them be):

    {
        "key": "ctrl+d",
        "command": "deleteRight",
        "when": "editorTextFocus && vim.active && !inDebugRepl && vim.mode == 'Insert'"
    },
    {
        "key": "ctrl+n",
        "command": "cursorDown",
        "when": "editorTextFocus && vim.active && !inDebugRepl && vim.mode == 'Insert'"
    },
    {
        "key": "ctrl+f",
        "command": "cursorRight",
        "when": "editorTextFocus && vim.active && !inDebugRepl && vim.mode == 'Insert'"
    },
    {
        "key": "ctrl+a",
        "command": "cursorLineStart",
        "when": "editorTextFocus && vim.active && !inDebugRepl && vim.mode == 'Insert'"
    },
    {
        "key": "ctrl+e",
        "command": "cursorLineEnd",
        "when": "editorTextFocus && vim.active && !inDebugRepl && vim.mode == 'Insert'"
    },

I also added the ctrl-p similar to @eysi09, but gated to only be in non-insert mode:

    {
        "key": "ctrl+p",
        "command": "workbench.action.quickOpen",
        "when": "editorTextFocus && vim.active && !inDebugRepl && vim.mode != 'Insert'"
    },

I also added C-{h,l,j,k} to do vim navigation (the original question here) similar to @jpotterm but filtering to only non-insert mode (so I can still have delete backward & join line & kill line in insert mode):

    {
        "key": "ctrl+h",
        "command": "extension.vim_navigateLeft",
        "when": "editorTextFocus && vim.active && vim.use<C-w> && !inDebugRepl && vim.mode != 'Insert'"
    },
    {
        "key": "ctrl+l",
        "command": "extension.vim_navigateRight",
        "when": "editorTextFocus && vim.active && vim.use<C-w> && !inDebugRepl && vim.mode != 'Insert'"
    },
    {
        "key": "ctrl+j",
        "command": "extension.vim_navigateDown",
        "when": "editorTextFocus && vim.active && vim.use<C-w> && !inDebugRepl && vim.mode != 'Insert'"
    },
    {
        "key": "ctrl+k",
        "command": "extension.vim_navigateUp",
        "when": "editorTextFocus && vim.active && vim.use<C-w> && !inDebugRepl && vim.mode != 'Insert'"
    },

I bet it’d be good to call some of this out in the readme (namely that most C-* bindings that are already handled by vscodevim aren’t user-configurable via the vim.KeyBindings user setting, but only by keybindings.json). It took me a bit to find this issue

For the original question of mapping ctrl+h to ctrl+w h you can add the following to keybindings.json:

{
    "key": "ctrl+h",
    "command": "extension.vim_navigateLeft",
    "when": "vim.active && vim.use<C-w>",
}

I think this works better than mapping to the command workbench.action.focusPreviousGroup because this lets you navigate into the file explorer sidebar.

Actually it does work if I just set the keybindings directly in keybindings.json, regardless of whether or not I use the "vim.handleKeys" option. Originally I was trying to set the behaviour using the "vim.otherModesKeyBindingsNonRecursive" option. So, the following just works:

// In keybindings.json
  {
    "key": "ctrl+p",
    "command": "workbench.action.quickOpen",
  }