Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Neovim MarksNew to Visual Studio Code? Get it now.
Neovim Marks

Neovim Marks

xbghc

|
3 installs
| (0) | Free
Show Neovim marks in the VS Code gutter when using vscode-neovim. Marks stay native to Neovim; this extension only renders them.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Neovim Marks for VS Code

Shows your Neovim marks in the VS Code gutter when you use vscode-neovim.

vscode-neovim forces signcolumn=no, so plugins that draw marks in the sign column render nothing inside VS Code. This project fills that gap without moving marks out of Neovim: ma, 'a, `a, d'a, :'a,'bs/…/…/, :marks and :delmarks keep their native behaviour, and the VS Code side only draws what Neovim reports.

The repository contains two halves that are installed separately:

  • a Neovim plugin (lua/nvim-marks/) that snapshots marks and pushes them to VS Code through require("vscode").action(...);
  • a VS Code extension (src/) that receives the snapshot and renders gutter icons, end-of-line labels and overview-ruler markers, plus a QuickPick to jump.

Installation

1. VS Code extension

Install the .vsix from the releases page or build it yourself:

npm install
npm run package          # produces nvim-marks-<version>.vsix
code --install-extension nvim-marks-<version>.vsix

2. Neovim plugin

With lazy.nvim:

{
  "xbghc/vscode-nvim-marks",
  cond = vim.g.vscode ~= nil,
  opts = {},
}

Outside VS Code setup() is a no-op, so the plugin is safe to keep in a shared config; the cond just avoids loading it at all in terminal Neovim.

Usage

Set marks as usual. They appear in the gutter within a few milliseconds: lowercase marks as a plain letter, uppercase (global) marks as a letter inside a rounded frame. When several marks sit on one line the icon shows the first two letters, or one letter and +.

Commands (Command Palette):

  • Neovim Marks: List marks — QuickPick of all known marks, grouped into the current file and other files; accepting jumps to the mark.
  • Neovim Marks: Toggle mark decorations — hide or show the decorations without touching Neovim.
  • Neovim Marks: Show status — print the versions of both halves, the number of marks received and the active settings to the "Neovim Marks" output channel. Start here when marks do not show up.

The two halves are updated separately. The Neovim plugin sends its version with every payload, and the extension warns once when the plugin is older than it expects or when the two speak different protocol versions.

Neovim side:

  • :NvimMarksRefresh — resend all marks, e.g. after reloading the VS Code window.
  • require("nvim-marks").sync(true) — same thing from Lua.

Settings

Setting Default Meaning
nvimMarks.enabled true Render marks at all.
nvimMarks.style "gutter" gutter, eol (text after the line) or both.
nvimMarks.overviewRuler true Also mark lines in the scrollbar.
nvimMarks.showLocalMarks true Show a–z.
nvimMarks.showGlobalMarks true Show A–Z.
nvimMarks.localColor { light: "#4d4d4d", dark: "#bdbdbd" } Letter colour for lowercase marks, per theme kind.
nvimMarks.globalColor { light: "#1a1a1a", dark: "#f2f2f2" } Letter colour for uppercase marks, per theme kind.

Neovim setup() options:

require("nvim-marks").setup({
  map_m = true,          -- wrap `m` so a new mark shows up immediately
  debounce_ms = 60,      -- coalesce bursts of events into one push
  extra_events = {},     -- additional autocmd events that trigger a sync
  command = "nvimMarks.update",
})

With map_m = false marks still sync, but only on the next CursorHold, BufEnter, TextChanged, InsertLeave, BufWritePost or command-line event.

How it works

  1. On the triggers above, Lua collects a–z marks of every loaded buffer via getmarklist(buf) and A–Z marks via getmarklist(), with absolute file paths and 1-based positions.
  2. If the snapshot differs from the last one it is sent with vscode.action("nvimMarks.update", { args = { payload } }).
  3. The extension normalizes paths, converts to 0-based positions and groups marks per line. Each distinct label (a, aB, c+, …) gets its own TextEditorDecorationType whose gutter icon is an inline SVG data URI, so the extension ships no image files and can colour icons per theme.
  4. Decorations are re-applied whenever the set of visible editors changes, so split views and newly opened tabs pick up their marks from the stored snapshot without another round trip.

Between pushes VS Code shifts decoration ranges with edits on its own; the next push from Neovim corrects any drift.

Limitations

  • VS Code draws one gutter icon per line. Multiple marks on a line are combined into one icon (ab, a+).
  • The gutter is shared with breakpoints and git decorations; there is no dedicated column as in Neovim.
  • Marks are only visible, not editable, from the VS Code side. Use Neovim to set and delete them.
  • Payload path: vim.g.vscode must be set, i.e. Neovim must run inside vscode-neovim.

Development

npm install
npm test             # typecheck + unit tests (node:test)
npm run test:vscode  # integration tests in a real VS Code (xvfb-run -a on Linux)
npm run test:lua     # headless Neovim test of the Lua plugin (needs nvim)
npm run package      # build the .vsix

License

MIT

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft