DEV Community

Karl N. Redman
Karl N. Redman

Posted on • Edited on • Originally published at github.com

11 3 1 1

Navigate your vscode like it's 1999 (the vim way)

If you are a vim person it can be frustraiting to work in vscode without vim keystrokes. The fantastic plugin vscodevim only goes so far. If you, like me, are used to M-h,M-j,M-k,M-l (where M == 'Alt key') and vim-like tab movements things get freaking nuts. Note that these keys in default vim are the same as pressing escape [I HATE ever having to hit the esc key -ever].

This configuration demonstrates how to switch to vscode easily from vim. In addition a method for you to switch tabs in a vim-like way.Lastly, these settings allow you to navigate vscode with bookmarks in a way you would use marks in regular vim.

Wait there's more! Read though the code (below) and find many vim-like jems that will make vscode feel a bit closer to home.

  • Tested with:
    • vscode v1.32.1
    • vim 8.1 how to compile
    • MX Linux 18.1
    • Debian Stretch 9.8

Vim configuration (at your discretion)

Open you current vim document in vcode

  • Add this following line to your ~/.vimrc
  • This (default) means \ov will open the current file in vscode from vim
nnoremap <leader>ov :exe ':silent !code %'<CR>:redraw!<CR>

Use ctrl+j and ctrl+k to change tabs in vim (I prefer up/down -adjust as needed)

" switch tabs (same as gt & gT)
nnoremap <C-j> :tabprevious<CR>
nnoremap <C-k> :tabnext<CR>
"
" (bonus) move tabls right or left
map <C-h> :execute "tabmove" tabpagenr() - 2 <CR>
map <C-l> :execute "tabmove" tabpagenr() + 1 <CR>

VS Code changes

This get's really complicated to explain. I'm going to list the functions with examples here and then the code -edit as needed. I had to configure keybindings.json and settings.json -I haven't tried combining the configurations.

features from keybindings.json (+noted settings.json)

  • focus active editor (vim windows)

    • i.e. (similar to vim C-w shortcuts)
    {
        "key": "ctrl+w j",
        "command": "workbench.action.focusBelowGroup",
    },
  • focus window groups

    • (similar to tmux panes)
{
    "key": "ctrl+w down",
    "command": "workbench.action.moveActiveEditorGroupDown",
},
  • do nothing for <ALT>+h,j,k,l

    • be sure to disable menu keys in vscode settings: Uncheck "Settings->Window->Enable Menubar Mneumonics"
    • Same as default vim behavior
   {
    "key": "alt+h",
    "command": "extension.vim_escape",
    "when": "editorTextFocus && vim.active && vim.mode == 'Insert'"
},
  • create mark

    • see file (/.conf/Code/User/settings.json)
     "vim.normalModeKeyBindingsNonRecursive": [
        {
            "before": ["m","a"],
            "commands": [
                "numberedBookmarks.toggleBookmark1"
            ]
        }
    ]
  • jump to mark

    • i.e. jump to mark a
{
    "key": "' a",
    "command": "numberedBookmarks.jumpToBookmark1",
    "when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
},

The files / configs

At this point I think you get the idea. There are several other vim-like settins I've added into the config files but, like Vim, you'll have to read the code to find the gems.

  • ~/.config/Code/User/keybindings.json
{
    "vim.easymotion": true,
    "vim.sneak": true,
    "vim.incsearch": true,
    "vim.useSystemClipboard": true,
    "vim.useCtrlKeys": true,
    "vim.hlsearch": true,
    "vim.leader": "\\",
    "vim.handleKeys": {
        "<C-a>": false,
        "<C-f>": false
    },
    "vim.normalModeKeyBindingsNonRecursive": [
        {
            "before": ["<C-n>"],
            "commands": [":nohl"]
        },
        {
            "before": ["m","a"],
            "commands": [
                "numberedBookmarks.toggleBookmark1"
            ]
        },
        {
            "before": ["m","b"],
            "commands": [
                "numberedBookmarks.toggleBookmark2"
            ]
        },
        {
            "before": ["m","c"],
            "commands": [
                "numberedBookmarks.toggleBookmark3"
            ]
        },
        {
            "before": ["m","d"],
            "commands": [
                "numberedBookmarks.toggleBookmark4"
            ]
        },
        {
            "before": ["m","e"],
            "commands": [
                "numberedBookmarks.toggleBookmark5"
            ]
        },
        {
            "before": ["m","f"],
            "commands": [
                "numberedBookmarks.toggleBookmark6"
            ]
        },
        {
            "before": ["m","g"],
            "commands": [
                "numberedBookmarks.toggleBookmark7"
            ]
        },
        {
            "before": ["m","h"],
            "commands": [
                "numberedBookmarks.toggleBookmark8"
            ]
        },
        {
            "before": ["m","i"],
            "commands": [
                "numberedBookmarks.toggleBookmark9"
            ]
        },
        {
            "before": ["m","j"],
            "commands": [
                "numberedBookmarks.toggleBookmark0"
            ]
        },
    ],
    "breadcrumbs.enabled": true,
    "workbench.activityBar.visible": true,
    "workbench.statusBar.visible": true,
    "workbench.sideBar.location": "left",
    "zenMode.hideStatusBar": false,
    "zenMode.hideTabs": false,
    "window.enableMenuBarMnemonics": false,
    "window.menuBarVisibility": "default",
    "window.zoomLevel": 1,
    "telemetry.enableTelemetry": false,
    "telemetry.enableCrashReporter": false
}

  • ~/.config/Code/User/settings.json
// Place your key bindings in this file to override the defaults
[
    {
        "key": "ctrl+w j",
        "command": "workbench.action.focusBelowGroup",
    },
    {
        "key": "ctrl+w k",
        "command": "workbench.action.focusAboveGroup",
    },
    {
        "key": "ctrl+w h",
        "command": "workbench.action.focusLeftGroup",
    },
    {
        "key": "ctrl+w l",
        "command": "workbench.action.focusRightGroup",
    },
    {
        "key": "ctrl+w down",
        "command": "workbench.action.moveActiveEditorGroupDown",
    },
    {
        "key": "ctrl+w up",
        "command": "workbench.action.moveActiveEditorGroupUp",
    },
    {
        "key": "ctrl+w left",
        "command": "workbench.action.moveActiveEditorGroupLeft",
    },
    {
        "key": "ctrl+w right",
        "command": "workbench.action.moveActiveEditorGroupRight",
    },
    {
        "key": "alt+h",
        "command": "extension.vim_escape",
        "when": "editorTextFocus && vim.active && vim.mode == 'Insert'"
    },
    {
        "key": "alt+j",
        "command": "extension.vim_escape",
        "when": "editorTextFocus && vim.active && vim.mode == 'Insert'"
    },
    {
        "key": "alt+k",
        "command": "extension.vim_escape",
        "when": "editorTextFocus && vim.active && vim.mode == 'Insert'"
    },
    {
        "key": "alt+l",
        "command": "extension.vim_escape",
        "when": "editorTextFocus && vim.active && vim.mode == 'Insert'"
    },
    {
        "key": "' a",
        "command": "numberedBookmarks.jumpToBookmark1",
        "when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
    },
    {
        "key": "' b",
        "command": "numberedBookmarks.jumpToBookmark2",
        "when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
    },
    {
        "key": "' c",
        "command": "numberedBookmarks.jumpToBookmark3",
        "when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
    },
    {
        "key": "' d",
        "command": "numberedBookmarks.jumpToBookmark4",
        "when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
    },
    {
        "key": "' e",
        "command": "numberedBookmarks.jumpToBookmark5",
        "when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
    },
    {
        "key": "' f",
        "command": "numberedBookmarks.jumpToBookmark6",
        "when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
    },
    {
        "key": "' g",
        "command": "numberedBookmarks.jumpToBookmark7",
        "when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
    },
    {
        "key": "' h",
        "command": "numberedBookmarks.jumpToBookmark8",
        "when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
    },
    {
        "key": "' i",
        "command": "numberedBookmarks.jumpToBookmark9",
        "when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
    },
    {
        "key": "' j",
        "command": "numberedBookmarks.jumpToBookmark0",
        "when": "editorTextFocus && vim.active && vim.mode == 'Normal'"
    },
    {
        "key": "ctrl+1",
        "command": "-numberedBookmarks.jumpToBookmark1",
        "when": "editorTextFocus"
    },
    {
        "key": "ctrl+2",
        "command": "-numberedBookmarks.jumpToBookmark2",
        "when": "editorTextFocus"
    },
    {
        "key": "ctrl+3",
        "command": "-numberedBookmarks.jumpToBookmark3",
        "when": "editorTextFocus"
    },
    {
        "key": "ctrl+4",
        "command": "-numberedBookmarks.jumpToBookmark4",
        "when": "editorTextFocus"
    },
    {
        "key": "ctrl+5",
        "command": "-numberedBookmarks.jumpToBookmark5",
        "when": "editorTextFocus"
    },
    {
        "key": "ctrl+6",
        "command": "-numberedBookmarks.jumpToBookmark6",
        "when": "editorTextFocus"
    },
    {
        "key": "ctrl+7",
        "command": "-numberedBookmarks.jumpToBookmark7",
        "when": "editorTextFocus"
    },
    {
        "key": "ctrl+8",
        "command": "-numberedBookmarks.jumpToBookmark8",
        "when": "editorTextFocus"
    },
    {
        "key": "ctrl+9",
        "command": "-numberedBookmarks.jumpToBookmark9",
        "when": "editorTextFocus"
    },
    {
        "key": "ctrl+shift+tab",
        "command": "workbench.action.focusNextGroup"
    },
    {
        "key": "ctrl+j",
        "command": "workbench.action.previousEditorInGroup"
    },
    {
        "key": "ctrl+pagedown",
        "command": "workbench.action.nextEditorInGroup"
    },
    {
        "key": "ctrl+w shift+-",
        "command": "workbench.action.minimizeOtherEditors"
    },
    {
        "key": "ctrl+w =",
        "command": "workbench.action.evenEditorWidths"
    },
    {
        "key": "ctrl+w v",
        "command": "workbench.action.splitEditorRight"
    },
    {
        "key": "ctrl+w s",
        "command": "workbench.action.splitEditorDown"
    },
    {
        "key": "ctrl+w c",
        "command": "workbench.action.closeActiveEditor"
    },
    {
        "key": "ctrl+w shift+k",
        "command": "workbench.action.moveEditorToAboveGroup"
    },
    {
        "key": "ctrl+w shift+j",
        "command": "workbench.action.moveEditorToBelowGroup"
    },
    {
        "key": "ctrl+w shift+h",
        "command": "workbench.action.moveEditorToLeftGroup"
    },
    {
        "key": "ctrl+w shift+l",
        "command": "workbench.action.moveEditorToRightGroup"
    },
    {
        "key": "ctrl+b",
        "command": "-extension.vim_ctrl+b",
        "when": "editorTextFocus && vim.active && vim.use<C-b> && !inDebugRepl && vim.mode != 'Insert'"
    },
    {
        "key": "ctrl+k",
        "command": "-extension.vim_ctrl+k",
        "when": "editorTextFocus && vim.active && vim.use<C-k> && !inDebugRepl"
    },
    {
        "key": "ctrl+b b",
        "command": "workbench.action.toggleSidebarVisibility"
    },
    {
        "key": "ctrl+b",
        "command": "-workbench.action.toggleSidebarVisibility"
    },
    {
        "key": "ctrl+b a",
        "command": "workbench.action.toggleActivityBarVisibility"
    },
    {
        "key": "ctrl+b f",
        "command": "workbench.files.action.showActiveFileInExplorer"
    },
    {
        "key": "ctrl+b n",
        "command": "workbench.action.nextSideBarView"
    },
    {
        "key": "ctrl+b p",
        "command": "workbench.action.previousSideBarView"
    },
    {
        "key": "ctrl+b m",
        "command": "workbench.action.toggleMenuBar"
    },
    {
        "key": "ctrl+b s",
        "command": "workbench.action.toggleStatusbarVisibility"
    },
    {
        "key": "ctrl+b l",
        "command": "workbench.action.toggleSidebarPosition"
    },
    {
        "key": "ctrl+b o",
        "command": "outline.focus"
    },
    {
        "key": "ctrl+b e",
        "command": "workbench.files.action.focusFilesExplorer"
    },
    {
        "key": "ctrl+b r",
        "command": "search.action.focusSearchList"
    },
    {
        "key": "ctrl+' l",
        "command": "workbench.action.togglePanelPosition"
    },
    {
        "key": "ctrl+' '",
        "command": "workbench.action.togglePanel"
    },
    {
        "key": "ctrl+j",
        "command": "-workbench.action.togglePanel"
    },
    {
        "key": "ctrl+' c",
        "command": "workbench.debug.panel.action.clearReplAction",
        "when": "inDebugRepl"
    },
    {
        "key": "meta+l",
        "command": "-workbench.debug.panel.action.clearReplAction",
        "when": "inDebugRepl"
    },
    {
        "key": "ctrl+' c",
        "command": "workbench.action.closePanel"
    },
    {
        "key": "ctrl+' space",
        "command": "workbench.action.focusPanel"
    },
    {
        "key": "ctrl+' n",
        "command": "workbench.action.nextPanelView"
    },
    {
        "key": "ctrl+' p",
        "command": "workbench.action.previousPanelView"
    },
    {
        "key": "ctrl+' shift+-",
        "command": "workbench.action.toggleMaximizedPanel"
    }
]

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (6)

Collapse
 
danielcodex profile image
Daniel Codex

but there is one problem: when you are in insert mode and you want to delete a word, normally the command is crtl+w. but right now is not working.
i am not good with vscode setting if you have a solution for that, really like to know

Collapse
 
karlredman profile image
Karl N. Redman • Edited

Daniel,

Yea, I replaced ctrl+w with the slew of window controlling combinations within the configuration -all using ctrl+w+<something>. The Vim way of deleting a word works though dw if you are using the plugins that I've specified.

Basically I wanted something that operated like Vim and ditches any wysiwyg editor methods.

I think I probably should have emphasized that my goal was to make VsCode work/feel like Vim over other editor experiences.

Something that might be good to add here is a Vim Cheat Sheet -hope this helps

Collapse
 
danielcodex profile image
Daniel Codex

thanks for the answer.
actually you can delete the word in insert mode with ctrl+w, but when I use your setting I couldn't (because when you press ctrl+w vscode is waiting for the next word/command). so I change that to alt+u for now.
and just another question which I don't get about vim, when we split the window horizontal/vertical, why in vim (or vscodevim I don't know) it split the file we are in it.
here is the picture:
dev-to-uploads.s3.amazonaws.com/i/...
shouldn't it actually split another file in the right??
for example, shouldn't be like ctrl+w v {filename}??

(and sorry for my English and my lack of knowledge in vim in general)

Thread Thread
 
karlredman profile image
Karl N. Redman • Edited

Daniel, I completely glossed over that you were talking about insert mode and not normal mode. Sorry about that and I'm glad you found a solution that works for you.

Nonetheless, in Vim proper the way to delete the word under the cursor while in insert mode would be (ctrl+o)dw. I have not found a solution to do insert mode operations in VsCode.

I should also mention that I almost never do any commands in insert mode -not even in Vim. Also, and this might be useful(?), I never use the Esc key to toggle back to normal mode -I have Alt+[hjkl] mapped for that (i.e. hitting Alt+k while in insert mode puts me back in normal mode). This way I don't move my hands around as much :D

As far as the split goes, yes, (ctrl+w)v is emulating normal Vim behavior. However, if you want to create a new split with a new file in both Vim and VsCode you can use the command :vnew. So you may want to replace the normal vsplit command with vnew instead.

Also note: vsplit is really for editing/reviewing long files in different places at the same time. In VsCode splits have a different context because a split also opens a new tab within a "view". Vim's concept of window vs. tab vs. view is not a 1:1 match with VsCode.

Thread Thread
 
danielcodex profile image
Daniel Codex

thanks for the answer.
actually what I want to open an existing file, vertically.
so around that, I usually, used ctrl+w v to open a file vertically, and when I open file with ctrl+p (go to file... which is for vscode), and when i open the file, i will close the previous file.
just watch this:
dev-to-uploads.s3.amazonaws.com/i/...
as you can see, the only thing i wanted in that video is to open all the flag.txt vertically.

Collapse
 
danielcodex profile image
Daniel Codex • Edited

I just love it, thanks
I just start using all of this setting, and it makes a lot of stuff easier in vscode 😎(❁´◡`❁)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more