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

How do I use Neovim's built-in native snippet support to expand snippets without a plugin?

Answer

vim.snippet.expand()

Explanation

Neovim 0.10 introduced vim.snippet, a built-in snippet engine that lets you expand LSP-style snippets without installing a plugin. It handles tabstops, placeholders, and jumping between fields — the same snippet format used by language servers via completion.

How it works

  • vim.snippet.expand(body) expands a snippet string with tabstops and placeholders
  • Snippet syntax follows the LSP specification: $1, $2 for tabstops; ${1:default} for tabstops with defaults; $0 for the final cursor position
  • vim.snippet.jumpable(direction) checks whether you can jump to the next (1) or previous (-1) tabstop
  • vim.snippet.jump(direction) moves to the next or previous tabstop

A minimal insert-mode mapping to expand a snippet and jump with <Tab>:

vim.keymap.set('i', '<Tab>', function()
  if vim.snippet.jumpable(1) then
    vim.snippet.jump(1)
  else
    -- fallback
  end
end)

Example

Expanding a function snippet manually:

vim.snippet.expand('function ${1:name}($2)\n  $0\nend')

After calling this, the cursor lands on name. Pressing <Tab> (with the mapping above) moves to $2, then $0.

Tips

  • LSP servers send snippets as completion items — Neovim 0.10 automatically uses vim.snippet to expand them when you accept a completion
  • Use vim.snippet.active() to check if a snippet session is currently active before triggering jumps
  • This pairs naturally with vim.lsp without requiring nvim-cmp or other completion plugins
  • For complex snippet authoring, dedicated plugins like LuaSnip still offer more features (transforms, conditionals, etc.)

Next

What is the difference between the inner word (iw) and inner WORD (iW) text objects in Vim?