smithery.ai

neovim

Expert guidance on Neovim configuration, plugin management, lazy.nvim, LSP setup, and editor workflow optimization

First seen Mar 10, 2026

Installation

$ npx skills add https://smithery.ai

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery.ai · top by installs.

npx skills add https://smithery.ai

Browse all from smithery.ai

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 8,827 B
  • docs SUMMARY.md 128 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 2 installs

SKILL.md

Neovim Expertise

Comprehensive guidance on Neovim configuration, plugin ecosystem, and workflow optimization.

Configuration Architecture

Directory Structure

~/.config/nvim/
├── init.lua                 # Entry point
├── lua/
│   ├── config/             # Core configuration
│   │   ├── options.lua     # vim.opt settings
│   │   ├── keymaps.lua     # Key mappings
│   │   ├── autocmds.lua    # Autocommands
│   │   └── lazy.lua        # Plugin manager setup
│   ├── plugins/            # Plugin specifications
│   └── utils/              # Utility functions
├── after/                  # After-directory scripts
│   └── ftplugin/          # Filetype-specific settings
└── snippets/              # Custom snippets

Modular Configuration

-- init.lua
require("config.options")
require("config.keymaps")
require("config.autocmds")
require("config.lazy")

-- config/options.lua
vim.g.mapleader = " "
vim.g.maplocalleader = ","

local opt = vim.opt
opt.number = true
opt.relativenumber = true
opt.termguicolors = true
opt.signcolumn = "yes"
opt.wrap = false
opt.scrolloff = 8

Plugin Management with lazy.nvim

Bootstrap and Setup

local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    "git", "clone", "--filter=blob:none",
    "https://github.com/folke/lazy.nvim.git",
    "--branch=stable", lazypath,
  })
end
vim.opt.rtp:prepend(lazypath)

require("lazy").setup({
  spec = {
    { import = "plugins" },
    { import = "plugins.lsp" },
  },
  defaults = { lazy = true },
  performance = {
    rtp = {
      disabled_plugins = {
        "gzip", "tarPlugin", "tohtml",
        "tutor", "zipPlugin",
      },
    },
  },
})

Plugin Specification Pattern

return {
  "plugin/name",
  event = { "BufReadPre", "BufNewFile" },  -- Lazy load on these events
  dependencies = { "required/plugin" },
  opts = {
    -- Plugin options
  },
  config = function()
    -- Custom setup
  end,
}

LSP Configuration

LSP Setup Pattern

-- plugins/lsp/init.lua
return {
  {
    "neovim/nvim-lspconfig",
    event = { "BufReadPre", "BufNewFile" },
    dependencies = {
      "williamboman/mason.nvim",
      "williamboman/mason-lspconfig.nvim",
      "folke/neodev.nvim",
    },
    config = function()
      require("mason").setup()
      require("mason-lspconfig").setup({
        ensure_installed = { "lua_ls", "rust_analyzer", "tsserver" },
      })

      local lspconfig = require("lspconfig")
      local capabilities = require("cmp_nvim_lsp").default_capabilities()

      lspconfig.lua_ls.setup({
        capabilities = capabilities,
        settings = {
          Lua = {
            workspace = { checkThirdParty = false },
            telemetry = { enable = false },
          },
        },
      })
    end,
  },
}

Treesitter Integration

return {
  "nvim-treesitter/nvim-treesitter",
  build = ":TSUpdate",
  event = { "BufReadPost", "BufNewFile" },
  opts = {
    ensure_installed = {
      "lua", "vim", "vimdoc", "query",
      "javascript", "typescript", "rust",
    },
    highlight = { enable = true },
    indent = { enable = true },
    incremental_selection = {
      enable = true,
      keymaps = {
        init_selection = "<C-space>",
        node_incremental = "<C-space>",
        scope_incremental = "<C-s>",
        node_decremental = "<C-backspace>",
      },
    },
  },
}

Performance Optimization

Startup Optimization

-- Defer shada loading
vim.opt.shadafile = "NONE"
vim.api.nvim_create_autocmd("CmdlineEnter", {
  once = true,
  callback = function()
    vim.opt.shadafile = ""
    vim.cmd.rshada({ bang = true })
  end,
})

-- Lazy load providers
vim.g.loaded_node_provider = 0
vim.g.loaded_perl_provider = 0
vim.g.loaded_python3_provider = 0
vim.g.loaded_ruby_provider = 0

Lazy Loading Strategies

-- Load after startup
vim.api.nvim_create_autocmd("User", {
  pattern = "VeryLazy",
  callback = function()
    require("config.commands")
    require("config.abbreviations")
  end,
})

Common Patterns

Filetype-Specific Settings

-- after/ftplugin/python.lua
vim.opt_local.expandtab = true
vim.opt_local.shiftwidth = 4
vim.opt_local.tabstop = 4

-- Python-specific keymaps
vim.keymap.set("n", "<leader>r", ":!python %<CR>", { buffer = true })

Custom Commands

vim.api.nvim_create_user_command("Config", function()
  vim.cmd("edit " .. vim.fn.stdpath("config") .. "/init.lua")
end, { desc = "Edit config" })

vim.api.nvim_create_user_command("Plugins", function()
  vim.cmd("edit " .. vim.fn.stdpath("config") .. "/lua/plugins/init.lua")
end, { desc = "Edit plugins" })

Floating Windows

local function create_float()
  local buf = vim.api.nvim_create_buf(false, true)
  local win = vim.api.nvim_open_win(buf, true, {
    relative = "editor",
    width = math.floor(vim.o.columns * 0.8),
    height = math.floor(vim.o.lines * 0.8),
    col = math.floor(vim.o.columns * 0.1),
    row = math.floor(vim.o.lines * 0.1),
    border = "rounded",
    style = "minimal",
  })
  return buf, win
end

Custom Operators

-- Custom operator for surrounding
vim.keymap.set("n", "s", function()
  vim.o.operatorfunc = "v:lua.require'utils'.surround_operator"
  return "g@"
end, { expr = true })

Best Practices

Configuration Organization

  • Separate concerns (options, keymaps, plugins)
  • Use lazy loading for better startup time
  • Prefer Lua over Vimscript for new configs
  • Document complex configurations

Plugin Selection

  • Choose actively maintained plugins
  • Prefer plugins with lazy loading support
  • Avoid plugin overlap/conflicts
  • Regular plugin updates and cleanup

Performance

  • Profile startup with :Lazy profile
  • Lazy load language-specific plugins
  • Minimize synchronous operations
  • Use built-in features when possible

Common Keybinding Patterns

-- Leader key patterns
vim.g.mapleader = " "
vim.g.maplocalleader = ","

-- Common keymaps
vim.keymap.set("n", "<leader>w", ":w<CR>", { desc = "Save file" })
vim.keymap.set("n", "<leader>q", ":q<CR>", { desc = "Quit" })
vim.keymap.set("n", "<Esc>", ":nohlsearch<CR>", { silent = true })

-- Window navigation
vim.keymap.set("n", "<C-h>", "<C-w>h")
vim.keymap.set("n", "<C-j>", "<C-w>j")
vim.keymap.set("n", "<C-k>", "<C-w>k")
vim.keymap.set("n", "<C-l>", "<C-w>l")

Autocommands

-- Auto-format on save
vim.api.nvim_create_autocmd("BufWritePre", {
  pattern = "*.lua",
  callback = function()
    vim.lsp.buf.format()
  end,
})

-- Highlight on yank
vim.api.nvim_create_autocmd("TextYankPost", {
  callback = function()
    vim.highlight.on_yank({ timeout = 200 })
  end,
})

Testing Neovim Configuration

Use nvim --headless to test config changes without a running editor.

Config Location

The chezmoi source config is at: /home/joba/.local/share/chezmoi/privatedotconfig/nvim/

Basic Config Load Test

nvim --headless -u /home/joba/.local/share/chezmoi/private_dot_config/nvim/init.lua \
  -c "lua print('ok')" -c "qa!" 2>&1

Test Lua Code in Context

Open a file, move the cursor, and run lua:

nvim --headless -u /home/joba/.local/share/chezmoi/private_dot_config/nvim/init.lua \
  -c "edit /path/to/file.lua" \
  -c "normal! 10G" \
  -c "lua local result = some_function(); print(result)" \
  -c "qa!" 2>&1

Test Plugin APIs

nvim --headless -u /home/joba/.local/share/chezmoi/private_dot_config/nvim/init.lua \
  -c "edit /path/to/file" \
  -c "lua local ok, mod = pcall(require, 'plugin.module'); print(ok, mod)" \
  -c "qa!" 2>&1

Test Visual Mode / Selection

nvim --headless -u /home/joba/.local/share/chezmoi/private_dot_config/nvim/init.lua \
  -c "edit /path/to/file" \
  -c 'normal! 5GVjj"zy' \
  -c "lua print(vim.fn.getreg('z'))" \
  -c "qa!" 2>&1

Guidelines

  • Always use -u to point at the chezmoi source config, not ~/.config/nvim
  • Use 2>&1 to capture both stdout and stderr
  • Use pcall when testing plugin requires that may not be installed
  • Set a timeout (10-15s) on Bash calls — headless nvim can hang if a plugin

blocks

  • Chain -c commands for multi-step tests
  • Use qa! as the final command to exit cleanly

Error Prevention

Common Issues:

  1. Startup Errors: Use pcall() for optional features
  2. Plugin Conflicts: Check for keybinding overlaps
  3. Performance: Profile with :Lazy profile
  4. Compatibility: Check Neovim version requirements