vimtricks.wiki Concise Vim tricks, one at a time.

How do I create a Neovim namespace for grouping extmarks and virtual text to avoid conflicts with other plugins?

Answer

vim.api.nvim_create_namespace('my_plugin')

Explanation

Neovim's extmark system (for highlights, virtual text, and diagnostics) uses namespaces to group related marks. Creating a named namespace lets your plugin add and remove its own marks independently without disturbing other plugins' extmarks or diagnostics.

How it works

  • vim.api.nvim_create_namespace(name) returns a numeric namespace ID
  • The same name always returns the same ID (idempotent), so it's safe to call at startup
  • Use the namespace ID when adding extmarks with nvim_buf_set_extmark()
  • Use nvim_buf_clear_namespace() to remove only your plugin's marks

Example

-- Create once at plugin startup
local ns = vim.api.nvim_create_namespace('my_plugin_highlights')

-- Add virtual text at end of line 0, column 0
vim.api.nvim_buf_set_extmark(0, ns, 0, 0, {
  virt_text = { { '  needs review', 'WarningMsg' } },
  virt_text_pos = 'eol',
})

-- Add inline highlight
vim.api.nvim_buf_set_extmark(0, ns, 2, 0, {
  end_col = 10,
  hl_group = 'Search',
})

-- Clear only your marks (LSP diagnostics stay intact)
vim.api.nvim_buf_clear_namespace(0, ns, 0, -1)

Tips

  • Pass 0 as the buffer ID to use the current buffer
  • Use vim.api.nvim_get_namespaces() to list all registered namespaces by name
  • vim.api.nvim_buf_get_extmarks(0, ns, 0, -1, {}) retrieves all marks in your namespace
  • Neovim's built-in diagnostics use their own namespace — never clear namespace 0 (global)

Next

How do I enable matchit so % jumps between if/else/end style pairs?