Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork257
Vim mode for VSCode, powered by Neovim
License
vscode-neovim/vscode-neovim
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Neovim is a fork of Vim to allow greater extensibility and integration. This extension uses afully embedded Neovim instance, no more half-complete Vim emulation! VSCode's native functionality is used for insertmode and VSCode commands, making the best use of both editors.
- 🎉 Feature-complete Vim integration (except insert-mode and some Nvim UI plugins) by utilizing Nvim as a backend.
- 🔧 Supports custom
init.luaand most Nvim plugins. - 🥇 First-class and lag-free insert mode, letting VSCode do what it does best.
- 🤝 Complete integration with VSCode features (lsp/autocompletion/snippets/multi-cursor/etc).
Table of Contents
- 🧰 Getting Started
- 💡 Tips and Features
- ⚡️ API
- vscode.action(name, opts)
- vscode.call(name, opts, timeout)
- vscode.on(event, callback)
- vscode.has_config(name)
- vscode.get_config(name)
- vscode.update_config(name, value, target)
- vscode.notify(msg)
- vscode.eval(code[, opts, timeout])
- vscode.eval_async(code[, opts])
- vscode.with_insert(callback[, ms])
- Builtin module overrides
- VimScript
- ⌨️ Keybindings (shortcuts)
- 📟 Neovim Commands
- 🎨 Highlights
- 🧰 Developing
- ❤️ Credits & External Resources
Install thevscode-neovim extension.
InstallNeovim0.10.0 or greater.
Note: Though the extension strives to be as compatible as possible with older versions of Neovim, some olderversions may have quirks that are not present anymore. In light of this, certain configuration settings arerecommended in some older versions for the best experience. These can be foundon the wiki.
[Optional] Set the Neovim path in the extension settings under"vscode-neovim.neovimExecutablePaths.win32/linux/darwin", respective to your system. For example,"C:\Neovim\bin\nvim.exe" or "/usr/local/bin/nvim".
WSL Users: If you want to use Neovim from WSL, set the
useWSLconfiguration toggle and specify the Linux path tothe nvim binary.wsl.exeWindows binary andwslpathLinux binary are required for this.wslpathmust beavailable through$PATHLinux env setting. Usewsl --listto check for the correct default Linux distribution.Snap Users: If you want to use Neovim from Snap, the Neovim path must be resolved to the snap binary location. Onsome systems it might be "
/snap/nvim/current/usr/bin/nvim". To check if you're running as a snap package, see ifwhich nvimresolves to/usr/bin/snap.
Since many Vim plugins can cause issues in VSCode, it is recommended to start from an emptyinit.vim. For a guide forwhich types of plugins are supported, seetroubleshooting.
Before creating an issue on Github, make sure you can reproduce the problem with an emptyinit.vim and no VSCodeextensions.
To determine if Neovim is running in VSCode, add to yourinit.vim:
ifexists('g:vscode')" VSCode extensionelse" ordinary Neovimendif
In lua:
ifvim.g.vscodethen-- VSCode extensionelse-- ordinary Neovimend
To conditionally activate plugins, the best solution is to use theLazyVim VSCode extra. However,packer.nvim andlazy.nvim have built-insupport forcond = vim.g.vscode andvim-plug has afew solutions. Seeplugins in the wiki for tips on configuring Vim plugins.
You can view all availablesettings and commands by openingthe vscode-neovim extension details pane, and navigating to the featurestab.
- File and editor management commands such as
:e/:q/:vsplit/:tabnext/etc are mapped to corresponding VSCodecommands and behavior may be different (see below).- Do not use vim commands like
:ein scripts/keybindings, they won't work. If you're using them in some customcommands/mappings, you might need to rebind them to call VSCode commands from Neovim withrequire('vscode').call()(seeAPI). - Since version 1.18.0,
:w,:waand:savcommands are supported and no longer alias to VSCode commands. Youcan use them as you would in Neovim.
- Do not use vim commands like
- When you type some commands they may be substituted for another, checkAlterCommand for the listof substitutions.
- Scrolling is done by VSCode.C-d/C-u/etc are slightly different.
- Editor customization (relative line number, scrolloff, etc) is handled by VSCode.
- Dot-repeat (.) is slightly different - moving the cursor within a change range won't break the repeat.sequence. In Neovim, if you type
abc<cursor>in insert mode, then move the cursor toa<cursor>bcand type1herethe repeat sequence would be1. However, in VSCode, it would bea1bc. Another difference is that when you deletesome text in insert mode, dot repeat only works from right to left, meaning it will treatDel key asBS keys when running dot repeat.
- To fix intermittent problems, you can run the
Neovim: Restart Extensioncommand to restart the extension. - View the logs via
Output: Focus on Output Viewand selectvscode-neovim logs.- To enable debug logs, click the "gear" icon and select
Debug, then click it again and chooseSet As Default.
- To enable debug logs, click the "gear" icon and select
- Enable
vscode-neovim.neovimCleanin VSCode settings, which starts Nvimwithout your plugins (nvim --clean). Nvimplugins can doanything. Visual effects in particular can cause visual artifacts. vscode-neovim does its best tomerge the visual effects of Nvim and VSCode, but it's far from perfect. You may need to disable some Nvim plugins thatcause visual effects. - If you encounter rendering issues (visual artifacts), tryCTRL-L to force Nvim to redraw.
- If you get the
Unable to init vscode-neovim: command 'type' already existsmessage, uninstall other VSCodeextensions that useregisterTextEditorCommand("type", …)(likeVSCodeVim orOvertype). - On a Mac, theh,j,k andl movement keys may not repeat when held, to fixthis open Terminal and execute the following command:
defaults write com.microsoft.VSCode ApplePressAndHoldEnabled -bool false. - To fix the remapped escape key not working in Linux, set
"keyboard.dispatch": "keyCode". - Two VSCode developer commands are useful for keybindings debugging:
Developer: Toggle Keyboard Shortcuts Troubleshootingfor tracing VSCode emitted keypresses and their processingvia defined keybindings.Developer: Inspect Key Mappingfor getting the recognized mappings for the current keyboard layout insideVSCode.
If you have any performance problems (cursor jitter usually) make sure you're not using vim plugins that increaselatency and cause performance problems.
Make sure to disable unneeded plugins, as many of them don't make sense with VSCode. Specifically, you don't need anycode highlighting, completion, LSP plugins, or plugins that spawn windows/buffers (nerdtree , fuzzy-finders, etc). Mostnavigation/textobject/editing plugins should be fine.
For example, make sure you're not using anything that renders decorators very often:
- Line number extensions (VSCode has built-in support for normal/relative line numbers)
- Indent guide extensions (VSCode has built-in indent guides)
- Brackets highlighter extensions (VSCode has built-in feature)
If you're not sure, disable all other extensions,reload VSCode window, and see if the problem persists beforereporting it.
Set withcompositeKeys and tweak withcompositeTimeout.
Examples: add to yoursettings.json:
jj to escape
{"vscode-neovim.compositeKeys": {"jj": {"command":"vscode-neovim.escape", }, },}jk to escape and save
{"vscode-neovim.compositeKeys": {"jk": {// Use lua to execute any logic"command":"vscode-neovim.lua","args": [ ["local code = require('vscode')","code.action('vscode-neovim.escape')","code.action('workbench.action.files.save')", ], ], }, },}VSCode's jumplist is used instead of Neovim's. This is to make VSCode native navigation (mouse click, jump todefinition, etc) navigable through the jumplist.
Make sure to bind toworkbench.action.navigateBack /workbench.action.navigateForward if you're using custommappings. Marks (both upper & lowercased) should work fine.
Multiple cursors work in:
- Insert mode
- Visual line mode
- Visual block mode
To spawn multiple cursors from visual line/block modes typema/mA ormi/mI(by default). The effect differs:
- For visual line mode,mi will start insert mode on each selected line on the first non whitespace characterandma will on the end of line.
- For visual block mode,mi will start insert on each selected line before the cursor block andmaafter.
- mA/mI versions accounts for empty lines (only for visual line mode, for visual block modethey're same asma/mi).
See gif in action:
Note: The built-in multi-cursor support may not meet your needs. Please refer to the pluginvscode-multi-cursor.nvim for more multi-cursor features
We intend to use vscode-neovim as a UI extension, so when you're using remote development, vscode-neovim is enabled inthe Local Extension Host, and it should work out of the box.
If you prefer to use the remote environment's copy of Neovim, rather than the locally installed one, vscode-neovimshould be installed in the Remote Extension Host. You can set the following in your VSCodesettings.json:
{"remote.extensionKind": {"asvetliakov.vscode-neovim": ["workspace"] }}Note: You will need to install neovim in the remote environment.
For more information:
Load the module:
localvscode=require('vscode')
Tip
The previously used module named "vscode-neovim" is now deprecated, so don't be confused if "vscode-neovim" is used in old discussions or other resources.
vscode.action(): asynchronously executes a vscode command.vscode.call(): synchronously executes a vscode command.vscode.on(): defines a handler for some Nvim UI events.vscode.has_config(): checks if a vscode setting exists.vscode.get_config(): gets a vscode setting value.vscode.update_config(): sets a vscode setting.vscode.notify(): shows a vscode message (see also Nvim'svim.notify).vscode.to_op(): A helper formap-operator. Seecode_actions.lua for theusageg:vscode_clipboard: Clipboard provider using VSCode's clipboard API. Used by default when in WSL. See:h g:clipboardfor more details. Usage:vim.g.clipboard = vim.g.vscode_clipboardvscode.eval(): evaluate javascript synchronously in vscode and return the resultvscode.eval_async(): evaluate javascript asynchronously in vscodevscode.with_insert(): perform operations in insert mode.
Asynchronously executes a vscode command.
Parameters:
name(string): The name of the action, generally a vscode command.opts(table): Map of optional parameters:args(table): List of arguments passed to the vscode command. If the command only requires a single objectparameter, you can directly pass in a map-like table.- Examples:
action('foo', { args = { 'foo', 'bar', … } })action('foo', { args = { foo = bar, … } })
- Examples:
range(table): Specific range for the action. Implicitly passed in visual mode. Has three possible forms (allvalues are 0-indexed):[start_line, end_line][start_line, start_character, end_line, end_character]{start = { line = start_line, character = start_character}, end = { line = end_line, character = end_character}}
restore_selection(boolean): Whether to preserve the current selection. Only valid whenrangeis specified.Defaults totrue.callback: Function to handle the action result. Must have this signature:function(err: string|nil, ret: any):erris the error message, if anyretis the result- If no callback is provided, error will be shown as a VSCode notification.
Example: open definition aside (default binding):
nnoremap<C-w>gd<Cmd>lua require('vscode').action('editor.action.revealDefinitionAside')<CR>
Example: find in files for word under cursor (see thevscode command definitionfor the expected parameter format):
nnoremap?<Cmd>lua require('vscode').action('workbench.action.findInFiles', { args = { query = vim.fn.expand('<cword>') } })<CR>
Example: use in lua script:
-- Format current documentvscode.action("editor.action.formatDocument")do-- Comment the three lines below the cursorlocalcurr_line=vim.fn.line(".")-1-- 0-indexedvscode.action("editor.action.commentLine", {range= {curr_line+1,curr_line+3 }, })enddo-- Comment the previous linelocalcurr_line=vim.fn.line(".")-1-- 0-indexedlocalprev_line=curr_line-1ifprev_line>=0thenvscode.action("editor.action.commentLine", {range= {prev_line ,prev_line }, })endenddo-- Find in files for word under cursorvscode.action("workbench.action.findInFiles", {args= {query=vim.fn.expand('<cword>') } })end
Currently, two built-in actions are provided for testing purposes:
_pingreturns"pong"_waitwaits for the specified milliseconds and then returns"ok"
do-- Execute _ping asynchronously and print the resultvscode.action("_ping", {callback=function(err,res)iferr==nilthenprint(res)-- outputs: pongendend, })end
Synchronously executes a vscode command.
Parameters:
name(string): The name of the action, generally a vscode command.opts(table): Same asvscode.action().timeout(number): Timeout in milliseconds. The default value is -1, which means there is no timeout.
Returns: the result of the action
Example: format selection (default binding):
xnoremap=<Cmd>lua require('vscode').call('editor.action.formatSelection')<CR>nnoremap=<Cmd>lua require('vscode').call('editor.action.formatSelection')<CR><Esc>nnoremap==<Cmd>lua require('vscode').call('editor.action.formatSelection')<CR>
Example: use in lua script:
-- Execute _ping synchronously and print the resultprint(vscode.call("_ping"))-- outputs: pong-- Wait for 1 second and print the return value 'ok'print(vscode.call("_wait", {args= {1000 } }))-- outputs: ok-- Wait for 2 seconds with a timeout of 1 secondprint(vscode.call("_wait", {args= {2000 } }),1000)-- error: Call '_wait' timed out
Currently no available events for user use.
Check if configuration has a certain value.
Parameters:
name(string|string[]): The configuration name or an array of configuration names.
Returns:
boolean|boolean[]: Returnstrueif the configuration has a certain value,falseotherwise. Ifnameis anarray, returns an array of booleans indicating whether each configuration has a certain value or not.
Examples:
-- Check if the configuration "not.exist" existsprint(vscode.has_config("not.exist"))-- Should return: false-- Check multiple configurationsvim.print(vscode.has_config({"not.exist","existing.config"}))-- Should return: { false, true }
Get configuration value.
Parameters:
name(string|string[]): The configuration name or an array of configuration names.
Returns:
unknown|unknown[]: The value of the configuration. Ifnameis an array, returns an array of values correspondingto each configuration.
Examples:
-- Get the value of "editor.tabSize"print(vscode.get_config("editor.tabSize"))-- a number-- Get multiple configurationsvim.print(vscode.get_config({"editor.fontFamily","editor.tabSize"}))-- Should return: { "the font family", "the editor tabSizse" }
Update configuration value.
Parameters:
name(string|string[]): The configuration name or an array of configuration names.value(unknown|unknown[]): The new value for the configuration.target("global"|"workspace"|"workspace_folder"): The configuration target. Optional, defaults to"workspace_folder".
Examples:
-- Update the value of "editor.tabSize"vscode.update_config("editor.tabSize",16,"global")-- Update multiple configurationsvscode.update_config({"editor.fontFamily","editor.tabSize"}, {"Fira Code",14 })
Show a vscode notification
You can setvscode.notify as your default notify function.
vim.notify=vscode.notify
Evaluate javascript inside vscode and return the result. The code is executed in an async function context (soawaitcan be used). Use areturn statement to return a value back to lua. Arguments passed from lua are available as theargs variable. The evaluated code has access to theVSCode API through thevscode global.
Tips:
- Make sure to
awaiton asynchronous functions when accessing the API. - Use the global
logger(e.g.logger.info(...)) to log messages to the output of vscode-neovim. - JSON serializable values (primitives and simple objects) can be returned and will be automatically serialized thendeserialized to an equivalent lua value. If the return value is not JSON serializable then an error will be raised.
globalThis['some_name'] = ...can be used to persist values between calls.
Parameters:
code(string): The javascript to execute.opts(table): Map of optional parameters:args(any): a value to make available as theargsvariable in javascript. Can be a single value such as astring or a table of multiple values.
timeout(number): The number of milliseconds to wait for the evaluation to complete before cancelling. By defaultthere is no timeout.
Returns:
- The result of executing the provided code.
Examples:
localcurrent_file=vscode.eval("return vscode.window.activeTextEditor.document.fileName")localcurrent_tab_is_pinned=vscode.eval("return vscode.window.tabGroups.activeTabGroup.activeTab.isPinned")vscode.eval("await vscode.env.clipboard.writeText(args.text)", {args= {text="some text"} })
Likevscode.eval() but returns immediately and evaluates in the background instead.
Parameters:
code(string): The javascript to execute.opts(table): Map of optional parameters:args(any): a value to make available as theargsvariable in javascript. Can be a single value such as astring or a table of multiple values.callback: Function to handle the eval result. Must have this signature:function(err: string|nil, ret: any):erris the error message, if anyretis the result- If no callback is provided, error will be shown as a VSCode notification.
Perform operations in insert mode. If in visual mode, this function willpreserve the selection after switching toinsert mode.
Parameters:
callback(function): Callback function to run after switching to insert modems(number, optional): Milliseconds to defer the callback. Defaults to 30.
Example: makeeditor.action.addSelectionToNextFindMatch work correctly in any mode.
vim.keymap.set({"n","x","i"},"<C-d>",function()vscode.with_insert(function()vscode.action("editor.action.addSelectionToNextFindMatch")end)end)
Example: make "editor.action.refactor" work correctly on the selection and support snippet manipulation after enteringVSCode snippet mode.
vim.keymap.set({"n","x"},"<leader>r",function()vscode.with_insert(function()vscode.action("editor.action.refactor")end)end)
vim.ui: use VSCode's UI components.vim.lsp.buf: execute corresponding VSCode LSP commands.
Note: Since 1.0.0, vimscript functions are deprecated. Use theLua api instead.
VSCodeNotify()/VSCodeCall(): deprecated, useLuarequire('vscode').call()instead.VSCodeNotifyRange()/VSCodeCallRange(): deprecated, useLuarequire('vscode').call(…, {range:…})instead.VSCodeNotifyRangePos()/VSCodeCallRangePos(): deprecated, useLuarequire('vscode').call(…, {range:…})instead.
You can also usev:lua.require("vscode") to access the API from VimScript.
There are three types of default/user keybindings:
- Neovim keybindings: These are the keybindings that are defined in the extension's vimscript files or the user's
init.vimfile. These provide code navigation, buffer management, and other neovim-specific overrides. - VSCode keybindings: These are the keybindings that are defined in the extension's
package.jsonor the user'skeybindings.jsonfile. These provide the ability to interact with VSCode's built-in features, and are used to makeVSCode more Vim-like. - VSCode passthrough keybindings: These are the keybindings that are defined in the extension's
package.jsonorthe user'skeybindings.jsonfile, but simply pass the keypress through to Neovim. These are used to allow Neovim tohandle certain keypresses that would otherwise be handled by VSCode.
This document only mentions some special cases, it is not an exhaustive list of keybindings and commands. Use VSCode andNvim features to see documentation and all defined shortcuts:
- Run the
Preferences: Open Keyboard Shortcutsvscode command and search for "neovim" to see all vscode andpassthrough keybindings. - Use the Nvim
:helpcommand to see the documentation for a given neovim command or keybinding. For example try:help :splitor:help zo.- Note that
:helpfor<C-…>bindings is spelledCTRL-…. For example to see the help for<c-w>, run:help CTRL-W.
- Note that
- Search the online Nvim documentation:https://neovim.io/doc/user/
- Reference the VSCode docs:
Every special (control/alt/non-alphanumerical) keyboard shortcut must be explicitly defined in VSCode to send to neovim.By default, only bindings that are used by Neovim by default are sent.
Note: if you want to pass additional control keys without adding a custom passthrough, see below.
To add a custom passthrough, for exampleA-h in normal mode, add to yourkeybindings.json:
{"command":"vscode-neovim.send",// Invoke the binding with this key sequence."key":"alt+h",// Don't activate during insert mode.// Docs for "when": https://code.visualstudio.com/api/references/when-clause-contexts"when":"editorTextFocus && neovim.mode != insert",// Send this input to Neovim."args":"<A-h>",}Set byvscode-neovim.ctrlKeysForInsertMode.
Default:["a", "d", "h", "j", "m", "o", "r", "t", "u", "w"]
Set byctrlKeysForNormalMode.
Default:["a", "b", "d", "e", "f", "h", "i", "j", "k", "l", "m", "o", "r", "t", "u", "v", "w", "x", "y", "z", "/", "]"]
Always enabled.
- Tab, Up, Down
- Ctrl keys:
<C-h><C-w><C-u><C-n><C-p><C-l><C-g><C-t> - All
<C-r>prefixed keys
Set byeditorLangIdExclusions.
Disable keybindings defined by this extension in certain filetypes. Please note that this will not affect allkeybindings.
If the above configuration flags do not provide enough control, you can remove the keybindings by editing yourkeybindings.json or using the VSCode keybindings editor:
| Key | VSCode Command |
|---|---|
| = /== | editor.action.formatSelection |
| gh /K | editor.action.showHover |
| gd /C-] | editor.action.revealDefinitionAlso works in vim help. |
| gf | editor.action.revealDeclaration |
| gH | editor.action.referenceSearch.trigger |
| gO | workbench.action.gotoSymbol |
| C-wgd /C-wgf | editor.action.revealDefinitionAside |
| gD | editor.action.peekDefinition |
| gF | editor.action.peekDeclaration |
| Tab | togglePeekWidgetFocusSwitch between peek editor and reference list. |
| C-n /C-p | Navigate lists, parameter hints, suggestions, quick-open, cmdline history, peek reference list |
💡 To specify the default peek mode, modify
editor.peekWidgetDefaultFocusin your settings.
| Key | VSCode Command |
|---|---|
| j ork | list.focusDown/Up |
| h orl | list.collapse/select |
| Enter | list.select |
| gg | list.focusFirst |
| G | list.focusLast |
| o | list.toggleExpand |
| C-u orC-d | list.focusPageUp/Down |
| zo orzO | list.expand |
| zc | list.collapse |
| zC | list.collapseAllToFocus |
| za orzA | list.toggleExpand |
| zm orzM | list.collapseAll |
| / orEscape | list.toggleKeyboardNavigation |
| Key | VSCode Command |
|---|---|
| r | renameFile |
| d | deleteFile |
| y | filesExplorer.copy |
| x | filesExplorer.cut |
| p | filesExplorer.paste |
| v | explorer.openToSide |
| a | explorer.newFile |
| A | explorer.newFolder |
| R | workbench.files.action.refreshFilesExplorer |
| Key | VSCode Command |
|---|---|
| K | editor.action.showHover |
| h | editor.action.scrollLeftHover |
| j | editor.action.scrollDownHover |
| k | editor.action.scrollUpHover |
| l | editor.action.scrollRightHover |
| gg | editor.action.goToTopHover |
| G | editor.action.goToBottomHover |
| C-f | editor.action.pageDownHover |
| C-b | editor.action.pageUpHover |
Default commands and bindings are available for file/scroll/window/tab management.
Seevscode-file-commands.vim for file commands reference.
The extension aliases various Nvim commands (:edit,:enew,:find,:quit, etc.) to equivalent vscode commands.Also their normal-mode equivalents (where applicable) such asC-w q, etc.
Seevscode-tab-commands.vim for tab commands reference.
The extension aliases various Nvim tab commands (:tabedit,:tabnew,:tabfind,:tabclose,:tabnext,:tabprevious,:tabfirst,:tablast) to equivalent vscode commands. Also their normal-mode equivalents (whereapplicable) such asgt, etc.
Seevscode-window-commands.vim for file commands reference.
The extension aliases various Nvim buffer/window commands (:split,:vsplit,:new,:vnew,:only) to equivalentvscode commands. Also their normal-mode equivalents (where applicable) such asC-w s, etc.
💡 Split size distribution is controlled by
workbench.editor.splitSizingsetting. By default, it'sdistribute,which is equal to vim'sequalalwaysandeadirection = 'both'(default).
To use VSCode command 'Increase/decrease current view size' instead of separate bindings for width and height:
workbench.action.increaseViewSizeworkbench.action.decreaseViewSize
Copy this into init.vim
function!s:manageEditorSize(...)letcount=a:1letto=a:2foriinrange(1,count ?count :1)callVSCodeNotify(to==#'increase' ?'workbench.action.increaseViewSize' :'workbench.action.decreaseViewSize')endforendfunction" Sample keybindings. Note these override default keybindings mentioned above.nnoremap<C-w>><Cmd>call<SID>manageEditorSize(v:count, 'increase')<CR>xnoremap<C-w>><Cmd>call<SID>manageEditorSize(v:count, 'increase')<CR>nnoremap<C-w>+<Cmd>call<SID>manageEditorSize(v:count, 'increase')<CR>xnoremap<C-w>+<Cmd>call<SID>manageEditorSize(v:count, 'increase')<CR>nnoremap<C-w><<Cmd>call<SID>manageEditorSize(v:count, 'decrease')<CR>xnoremap<C-w><<Cmd>call<SID>manageEditorSize(v:count, 'decrease')<CR>nnoremap<C-w>-<Cmd>call<SID>manageEditorSize(v:count, 'decrease')<CR>xnoremap<C-w>-<Cmd>call<SID>manageEditorSize(v:count, 'decrease')<CR>
There are two ways to customize highlight colors:
Set colors in nvim
Note: Due to the support for the
syntaxoption requiring processing of syntax highlights, all built-inhighlight groups may be overridden or cleared. Therefore, please do not link any highlights to the built-inhighlight groups.Set colors in vscode
Please seeCONTRIBUTING.md for details on how to contribute to this project.
- vim-altercmd - Used for rebinding default commands to call VSCode command.
- neovim nodejs client - NodeJS library for communicating with Neovim.
- VSCodeVim - Used for various inspiration.
About
Vim mode for VSCode, powered by Neovim
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Packages0
Uh oh!
There was an error while loading.Please reload this page.



