Skip to content
Development
Skill

/neovim

Interact with the user's running Neovim instance via RPC. Use this skill when you need to execute Lua or Vimscript inside Neovim, query buffer state, send commands, or interact with the Neovim runtime in any way. Triggers when the user asks about their current Neovim session,

BOOST
From plugin
fredrikaverpil-dotfiles
25913 skills1 MCP
Install
$ npx -y skills add fredrikaverpil/dotfiles --skill neovim --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/neovim

Context preview

The summary Claude sees to decide when to auto-load this skill.

Interact with the user's running Neovim instance via RPC. Use this skill when you need to execute Lua or Vimscript inside Neovim, query buffer state, send commands, or interact with the Neovim runtime in any way. Triggers when the user asks about their current Neovim session,

SKILL.md

neovim.SKILL.md
name: neovim
description: Interact with the user's running Neovim instance via RPC. Use this skill when you need to execute Lua or Vimscript inside Neovim, query buffer state, send commands, or interact with the Neovim runtime in any way. Triggers when the user asks about their current Neovim session, wants to run something inside Neovim, or when you need to inspect Neovim state (buffers, windows, options, LSP, etc.). Also use when running inside a Neovim terminal and needing to communicate with the parent editor.

Neovim RPC

When Claude Code runs inside a Neovim terminal, the `$NVIM` environment variable points to the parent Neovim's Unix socket. This gives full access to Neovim's msgpack-RPC API without any plugins or HTTP servers.

Prerequisites

Before sending any commands, verify the socket is available:

echo "$NVIM"

If `$NVIM` is empty, you are not running inside a Neovim terminal and cannot communicate with a Neovim instance.

**Important:** When `NVIM_APPNAME` is set, all `nvim --server` commands emit a `Warning: Using NVIM_APPNAME=...` message on **stdout** (not stderr). This corrupts parsed output (especially JSON). To suppress it, capture the output first, then filter:

result=$(nvim --server "$NVIM" --remote-expr 'EXPR') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

**Note:** Piping `nvim` directly (e.g. `nvim --server "$NVIM" ... | grep ...`) can fail because `$NVIM` may not expand correctly in pipe contexts. Always use command substitution (`$(...)`) as shown above.

Evaluating expressions

All examples below use the command substitution pattern from Prerequisites to filter the `NVIM_APPNAME` warning. The shorthand `nvimx EXPR` means:

result=$(nvim --server "$NVIM" --remote-expr 'EXPR') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

Use `--remote-expr` to evaluate a Vimscript expression and get the result back:

result=$(nvim --server "$NVIM" --remote-expr 'v:version') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

For Lua expressions, wrap them in `luaeval()`:

result=$(nvim --server "$NVIM" --remote-expr 'luaeval("vim.api.nvim_buf_get_name(0)")') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

For multi-statement Lua that returns a value, use an IIFE:

result=$(nvim --server "$NVIM" --remote-expr 'luaeval("(function() local x = vim.api.nvim_get_current_win(); return vim.api.nvim_win_get_number(x) end)()")') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

Returning tables/lists

`luaeval()` returns Lua tables as Vimscript values. For complex data, encode as JSON:

result=$(nvim --server "$NVIM" --remote-expr 'luaeval("vim.json.encode(vim.api.nvim_list_bufs())")') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

Sending commands

Use `--remote-send` to send keystrokes (as if the user typed them):

nvim --server "$NVIM" --remote-send ':echo "hello"<CR>'

Note: `--remote-send` does not return output and does not need the warning filter. Use `--remote-expr` when you need a return value.

Opening files remotely

Use `--remote` to open files in the running Neovim instance:

nvim --server "$NVIM" --remote file.txt

Use `--remote-tab` to open files in new tabs:

nvim --server "$NVIM" --remote-tab file1.txt file2.txt

Executing Lua without a return value

To run Lua that performs side effects (no return value needed):

result=$(nvim --server "$NVIM" --remote-expr 'execute("lua vim.notify(\"Hello from Claude\")")') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

The `execute()` Vimscript function runs an Ex command and returns its output as a string (empty if the command produces no output).

Common patterns

# Current buffer path
result=$(nvim --server "$NVIM" --remote-expr 'luaeval("vim.api.nvim_buf_get_name(0)")') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

# List all buffer paths (JSON)
result=$(nvim --server "$NVIM" --remote-expr 'luaeval("vim.json.encode(vim.tbl_map(function(b) return vim.api.nvim_buf_get_name(b) end, vim.api.nvim_list_bufs()))")') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

# Current working directory
result=$(nvim --server "$NVIM" --remote-expr 'luaeval("vim.fn.getcwd()")') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

# Current cursor position [row, col] (1-indexed row)
result=$(nvim --server "$NVIM" --remote-expr 'luaeval("vim.json.encode(vim.api.nvim_win_get_cursor(0))")') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

# Get a Neovim option value
result=$(nvim --server "$NVIM" --remote-expr 'luaeval("vim.o.filetype")') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

# Check if an LSP client is attached
result=$(nvim --server "$NVIM" --remote-expr 'luaeval("vim.json.encode(vim.tbl_map(function(c) return c.name end, vim.lsp.get_clients({bufnr = 0})))")') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

Reading help documentation

Do **not** use `execute("help ...")` — that opens help inside the editor as a side effect instead of returning content.

First, get the key paths via RPC (do this once per session):

# Neovim data directory (plugin install root is <data>/lazy/ for lazy.nvim)
result=$(nvim --server "$NVIM" --remote-expr 'luaeval("vim.fn.stdpath(\"data\")")') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

# Built-in Neovim docs
result=$(nvim --server "$NVIM" --remote-expr 'luaeval("vim.fn.expand(\"$VIMRUNTIME\")")') && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

Then use standard tools (`fd`, `rg`, `Glob`, `Grep`) to search and `Read` to view the files. Search `<data>/lazy/*/doc/` for plugin docs and `<runtime>/doc/` for built-in docs.

**Search help tags** (equivalent to `:h query<Tab>` completion):

result=$(nvim --server "$NVIM" --remote-expr
Read more
Ships withfredrikaverpil-dotfiles

Personal dotfiles, managed in three layers: Nix (nix/): system configuration and packages, pinned by flake.lock and applied with a rebuild. Fully reproducible. Stow (stow/): dotfiles symlinked into $HOME with GNU Stow (not Nix).

Get the whole plugin
Stats
259
Stars
7
Forks
Active
Maintenance
QML
Language
MIT
License
21h ago
Last commit
10y ago
Created
6h ago
Added

Repo: fredrikaverpil/dotfiles

Other skills on fredrikaverpil-dotfiles.