MCPcopy
hub / github.com/vscode-neovim/vscode-neovim

github.com/vscode-neovim/vscode-neovim @v1.19.0 sqlite

repository ↗ · DeepWiki ↗ · release v1.19.0 ↗
446 symbols 1,292 edges 82 files 36 documented · 8%
README

VSCode Neovim

VSCode Neovim Integration

Neovim is a fork of Vim to allow greater extensibility and integration. This extension uses a fully embedded Neovim instance, no more half-complete Vim emulation! VSCode's native functionality is used for insert mode 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.lua and 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

Installation

Install the vscode-neovim extension.

Install Neovim 0.10.0 or greater.

Note: Though the extension strives to be as compatible as possible with older versions of Neovim, some older versions may have quirks that are not present anymore. In light of this, certain configuration settings are recommended in some older versions for the best experience. These can be found on 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 useWSL configuration toggle and specify the Linux path to the nvim binary. wsl.exe Windows binary and wslpath Linux binary are required for this. wslpath must be available through $PATH Linux env setting. Use wsl --list to 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. On some systems it might be "/snap/nvim/current/usr/bin/nvim". To check if you're running as a snap package, see if which nvim resolves to /usr/bin/snap.

Neovim configuration

Since many Vim plugins can cause issues in VSCode, it is recommended to start from an empty init.vim. For a guide for which types of plugins are supported, see troubleshooting.

Before creating an issue on Github, make sure you can reproduce the problem with an empty init.vim and no VSCode extensions.

To determine if Neovim is running in VSCode, add to your init.vim:

if exists('g:vscode')
    " VSCode extension
else
    " ordinary Neovim
endif

In lua:

if vim.g.vscode then
    -- VSCode extension
else
    -- ordinary Neovim
end

To conditionally activate plugins, the best solution is to use the LazyVim VSCode extra. However, packer.nvim and lazy.nvim have built-in support for cond = vim.g.vscode and vim-plug has a few solutions. See plugins in the wiki for tips on configuring Vim plugins.

VSCode Settings & Commands

You can view all available settings and commands by opening the vscode-neovim extension details pane, and navigating to the features tab.

💡 Tips and Features

VSCode specific differences

  • File and editor management commands such as :e/:q/:vsplit/:tabnext/etc are mapped to corresponding VSCode commands and behavior may be different (see below).
    • Do not use vim commands like :e in scripts/keybindings, they won't work. If you're using them in some custom commands/mappings, you might need to rebind them to call VSCode commands from Neovim with require('vscode').call() (see API).
    • Since version 1.18.0, :w, :wa and :sav commands are supported and no longer alias to VSCode commands. You can use them as you would in Neovim.
  • When you type some commands they may be substituted for another, check AlterCommand for the list of 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 to a<cursor>bc and type 1 here the repeat sequence would be 1. However, in VSCode, it would be a1bc. Another difference is that when you delete some text in insert mode, dot repeat only works from right to left, meaning it will treat Del key as BS keys when running dot repeat.

Troubleshooting

  • To fix intermittent problems, you can run the Neovim: Restart Extension command to restart the extension.
  • View the logs via Output: Focus on Output View and select vscode-neovim logs.
    • To enable debug logs, click the "gear" icon and select Debug, then click it again and choose Set As Default.
  • Enable vscode-neovim.neovimClean in VSCode settings, which starts Nvim without your plugins (nvim --clean). Nvim plugins can do anything. Visual effects in particular can cause visual artifacts. vscode-neovim does its best to merge the visual effects of Nvim and VSCode, but it's far from perfect. You may need to disable some Nvim plugins that cause visual effects.
  • If you encounter rendering issues (visual artifacts), try CTRL-L to force Nvim to redraw.
  • If you get the Unable to init vscode-neovim: command 'type' already exists message, uninstall other VSCode extensions that use registerTextEditorCommand("type", …) (like VSCodeVim or Overtype).
  • On a Mac, the h, j, k and l movement keys may not repeat when held, to fix this 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 Troubleshooting for tracing VSCode emitted keypresses and their processing via defined keybindings.
    • Developer: Inspect Key Mapping for getting the recognized mappings for the current keyboard layout inside VSCode.

Performance

If you have any performance problems (cursor jitter usually) make sure you're not using vim plugins that increase latency 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 any code highlighting, completion, LSP plugins, or plugins that spawn windows/buffers (nerdtree , fuzzy-finders, etc). Most navigation/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 before reporting it.

Composite escape keys

Set with compositeKeys and tweak with compositeTimeout.

Examples: add to your settings.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')",
                ],
            ],
        },
    },
}

Jumplist

VSCode's jumplist is used instead of Neovim's. This is to make VSCode native navigation (mouse click, jump to definition, etc) navigable through the jumplist.

Make sure to bind to workbench.action.navigateBack / workbench.action.navigateForward if you're using custom mappings. Marks (both upper & lowercased) should work fine.

Multiple cursors

Multiple cursors work in:

  1. Insert mode
  2. Visual line mode
  3. Visual block mode

To spawn multiple cursors from visual line/block modes type ma/mA or mi/mI (by default). The effect differs:

  • For visual line mode, mi will start insert mode on each selected line on the first non whitespace character and ma will on the end of line.
  • For visual block mode, mi will start insert on each selected line before the cursor block and ma after.
  • mA/mI versions accounts for empty lines (only for visual line mode, for visual block mode they're same as ma/mi).

See gif in action:

multicursor

Note: The built-in multi-cursor support may not meet your needs. Please refer to the plugin vscode-multi-cursor.nvim for more multi-cursor features

Remote development

We intend to use vscode-neovim as a UI extension, so when you're using remote development, vscode-neovim is enabled in the 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-neovim should be installed in the Remote Extension Host. You can set the following in your VSCode settings.json:

{
    "remote.extensionKind": {
        "asvetliakov.vscode-neovim": ["workspace"]
    }
}

Note: You will need to install neovim in the remote environment.

For more information:

  • [Remote Development](https:

Extension points exported contracts — how you extend this code

IDocumentContent (Interface)
* The document content in neovim.
src/document_change_manager.ts
VimHighlightUIAttributes (Interface)
(no doc)
src/eventBus.ts
RequestResponse (Interface)
(no doc)
src/main_controller.ts
ILogger (Interface)
(no doc)
src/logger.ts
CursorInfo (Interface)
(no doc)
src/cursor_manager.ts
DotRepeatChange (Interface)
(no doc)
src/utils/vscode.ts
HighlightConfiguration (Interface)
(no doc)
src/highlights/highlight_group_store.ts
TextEndChange (Interface)
(no doc)
src/cmdline/cmdline_text.ts

Core symbols most depended-on inside this repo

sendVSCodeKeys
called by 385
src/test/integ/integrationUtils.ts
assertContent
called by 283
src/test/integ/integrationUtils.ts
openTextDocument
called by 146
src/test/integ/integrationUtils.ts
sendEscapeKey
called by 129
src/test/integ/integrationUtils.ts
wait
called by 115
src/test/integ/integrationUtils.ts
sendVSCodeCommand
called by 93
src/test/integ/integrationUtils.ts
debug
called by 74
src/logger.ts
sendInsertKey
called by 72
src/test/integ/integrationUtils.ts

Shape

Method 262
Function 100
Class 63
Interface 19
Enum 2

Languages

TypeScript100%

Modules by API surface

src/buffer_manager.ts40 symbols
src/config.ts32 symbols
src/utils/vscode.ts25 symbols
src/test/integ/integrationUtils.ts25 symbols
src/mode_manager.ts22 symbols
src/logger.ts17 symbols
src/viewport_manager.ts15 symbols
src/test/integ/highlights.test.ts15 symbols
src/main_controller.ts15 symbols
src/status_line_manager.ts14 symbols
src/highlights/highlight_grid.ts14 symbols
src/document_change_manager.ts14 symbols

Dependencies from manifests, versioned

@johnnymorganz/stylua-bin2.0.2 · 1×
@jpwilliams/waitgroup2.1.1 · 1×
@sinonjs/fake-timers14.0.0 · 1×
@types/lodash4.17.16 · 1×
@types/mocha10.0.7 · 1×
@types/node22.13.13 · 1×
@types/sinonjs__fake-timers8.1.5 · 1×
@types/vscode1.90.0 · 1×
@vscode/test-electron2.4.1 · 1×
@vscode/vsce3.3.0 · 1×
async-mutex0.5.0 · 1×
eslint8.57.0 · 1×

For agents

$ claude mcp add vscode-neovim \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact