nvim从零单排(三)

3 阅读5分钟

像喝水一样简单,想你所想

快捷键映射和对外暴露的实用且高频的 API,这些 API 是定制 Neovim 配置、开发插件的核心

  • 自备lua基础,简单上头,一学就会
  • 所有的伟大源自一个简单的开始
  • 衣来伸手饭来张口

一、编辑器基础操作之映射篇

1. 全局配置:vim.opt/vim.g/vim.wo/vim.bo/vim.bo

..... 上篇已经讲了就不重复了,这篇主要讲映射

2. 快捷键映射:vim.keymap.set()

  • 作用:定义快捷键(替代 Vimscript 的 map 命令,更灵活);
  • 核心参数:模式(n/i/v 等)、按键、映射目标、可选配置(desc/buffer/silent);
-- 普通模式:<leader>e 打开文件树
vim.keymap.set("n", "<leader>e", "<CMD>NvimTreeToggle<CR>", {
  desc = "Open file tree", -- 描述(WhichKey 可识别)
  silent = true,           -- 不显示命令输出
  noremap = true           -- 禁用递归映射(推荐)
})
-- 仅当前缓冲区生效的快捷键
vim.keymap.set("n", "K", vim.lsp.buf.hover, { buffer = 0, desc = "LSP hover" })
  • 使用场景:自定义所有快捷键,区分全局 / 缓冲区、不同模式。

3. 命令执行:vim.cmd()/vim.api.nvim_command()

  • 作用:执行 Vim 命令(兼容老逻辑,必要时使用);
vim.cmd("colorscheme catppuccin") -- 设置配色
vim.cmd("w")                      -- 保存文件
-- 带参数执行
vim.cmd(string.format("tabedit %s", "/tmp/test.lua"))
  • 注意:优先用 Lua 原生 API(如 vim.api.nvim_buf_set_lines),仅当无 Lua 替代时用 vim.cmd。

4. 自动命令:vim.api.nvim_create_autocmd()

  • 作用:监听编辑器事件(如打开文件、LSP 附着)并执行逻辑;
-- 打开文件时自动禁用换行
vim.api.nvim_create_autocmd("BufReadPost", {
  pattern = { "*.lua", "*.go", "*.py" }, -- 匹配文件类型
  callback = function()
    vim.wo.wrap = false
  end,
  desc = "Disable wrap for code files"
})
-- LSP 附着时绑定快捷键
vim.api.nvim_create_autocmd("LspAttach", {
  group = vim.api.nvim_create_augroup("UserLspConfig", {}),
  callback = function(ev)
    vim.keymap.set("n", "gd", vim.lsp.buf.definition, { buffer = ev.buf })
  end
})
  • 使用场景:动态调整配置、LSP 快捷键绑定、文件类型专属逻辑。

二、缓冲区 / 窗口操作 API,插件开发高频

1. 缓冲区操作:vim.api.nvim_buf_*

API 方法作用示例
nvim_buf_get_lines()获取缓冲区指定行内容local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)(获取当前文件所有行)
nvim_buf_set_lines()修改缓冲区内容vim.api.nvim_buf_set_lines(0, 1, 3, false, { "new line 1", "new line 2" })(替换 2-3 行为新内容)
nvim_buf_get_name()获取缓冲区文件名local filename = vim.api.nvim_buf_get_name(0)
nvim_buf_delete()删除缓冲区vim.api.nvim_buf_delete(123, { force = true })(强制删除编号 123 的缓冲区)
  • 核心参数:第一个参数为缓冲区编号(0 代表当前缓冲区)。

2. 窗口操作:vim.api.nvim_win_*

API 方法作用示例
nvim_win_get_cursor()获取当前光标位置local pos = vim.api.nvim_win_get_cursor(0)(返回 {行号, 列号})
nvim_win_set_cursor()设置光标位置vim.api.nvim_win_set_cursor(0, {10, 5})(跳到第 10 行第 5 列)
nvim_open_win()打开新窗口(支持浮动窗口)见下方「浮动窗口」示例
nvim_win_close()关闭窗口vim.api.nvim_win_close(123, true)

3. 浮动窗口(Neovim 特色):vim.api.nvim_open_win()

  • 作用:创建悬浮窗口(LSP 悬浮文档、弹窗菜单的核心);
-- 创建一个简单的浮动窗口
local buf = vim.api.nvim_create_buf(false, true) -- 创建临时缓冲区
vim.api.nvim_buf_set_lines(buf, 0, -1, false, { "Hello Neovim!", "This is a float window" })
local win = vim.api.nvim_open_win(buf, true, {
  relative = "cursor", -- 相对于光标位置
  row = 1,             -- 光标下方 1 行
  col = 0,             -- 光标同列
  width = 30,          -- 窗口宽度
  height = 2,          -- 窗口高度
  border = "rounded"   -- 圆角边框
})

  • 使用场景:自定义弹窗、悬浮提示、快捷菜单。

三、LSP 相关 API(开发必备):vim.lsp.*

Neovim 原生 LSP API 是其碾压 Vim 的核心,常用接口:

1. 核心 LSP 操作

API 方法作用示例
vim.lsp.buf.hover()悬浮显示符号文档(函数 / 变量说明)vim.keymap.set("n", "K", vim.lsp.buf.hover)
vim.lsp.buf.definition()跳转到定义vim.keymap.set("n", "gd", vim.lsp.buf.definition)
vim.lsp.buf.rename()重命名符号vim.keymap.set("n", "rn", vim.lsp.buf.rename)
vim.lsp.buf.format()格式化代码vim.keymap.set("n", "f", vim.lsp.buf.format)
vim.diagnostic.open_float()显示诊断信息(错误 / 警告)vim.keymap.set("n", "d", vim.diagnostic.open_float)

2. LSP 配置:vim.lsp.start()/vim.lsp.config

  • 作用:手动启动 LSP 客户端(nvim-lspconfig 底层基于此);
  • 简化示例
-- 启动 gopls LSP
vim.lsp.start({
  name = "gopls",
  cmd = { "gopls" },
  root_dir = vim.fs.dirname(vim.fs.find({ "go.mod" }, { upward = true })[1]),
  settings = { gopls = { staticcheck = true } }
})

四、Treesitter 相关 API:vim.treesitter.*

基于语法解析的高亮 / 操作 API,比正则更精准:

1. 核心接口

API 方法作用示例
vim.treesitter.get_parser()获取当前缓冲区的 Treesitter 解析器local parser = vim.treesitter.get_parser(0, "lua")
vim.treesitter.query.parse()解析 Treesitter 查询(提取语法节点)见下方示例

2.提取当前文件的所有函数名(Lua)

local parser = vim.treesitter.get_parser(0, "lua")
local tree = parser:parse()[1]
local query = vim.treesitter.query.parse("lua", [[
  (function_declaration name: (identifier) @func_name)
  (local_function_definition name: (identifier) @func_name)
]])
-- 遍历所有匹配的函数名
for id, node in query:iter_captures(tree:root(), 0) do
  local func_name = vim.treesitter.get_node_text(node, 0)
  print("Found function:", func_name)
end
  • 使用场景:语法高亮定制、代码导航、代码提取。

五、实用工具 API:vim.fn/vim.fs/vim.tbl_*

1. 文件系统操作:vim.fs(Neovim 0.9+)

  • 作用:现代文件系统 API(替代 vim.fn.glob);
-- 向上查找 go.mod 文件(LSP 根目录检测)
local mod_file = vim.fs.find({ "go.mod" }, { upward = true, type = "file" })[1]
-- 遍历目录下的所有 .lua 文件
for _, file in ipairs(vim.fs.find("*.lua", { path = "~/.config/nvim", type = "file" })) do
  print(file)
end

2. 表操作工具:vim.tbl_*

  • 作用:Lua 表的便捷操作(替代手动写循环);
local t1 = { a = 1, b = 2 }
local t2 = { b = 3, c = 4 }
local merged = vim.tbl_deep_extend("force", t1, t2) -- 深度合并表
print(vim.inspect(merged)) -- { a = 1, b = 3, c = 4 }
local filtered = vim.tbl_filter(function(v) return v > 2 end, { 1, 2, 3, 4 })
print(vim.inspect(filtered)) -- { 3, 4 }

3. 延迟执行:vim.defer_fn()

  • 作用:延迟执行函数(避免阻塞主线程);
-- 延迟 1 秒打印信息
vim.defer_fn(function()
  print("Delayed message")
end, 1000)

六、调试 / 日志 API:vim.notify()/vim.log

1. 通知弹窗:vim.notify()

  • 作用:替代 print,支持不同级别(info/warn/error),可被 nvim-notify 美化;
vim.notify("Config loaded successfully", vim.log.levels.INFO)
vim.notify("LSP startup failed", vim.log.levels.ERROR)

总结

功能分类核心 API 命名空间 / 方法核心场景
基础配置vim.opt/vim.g/vim.keymap.set编辑器基础配置、快捷键
缓冲区 / 窗口vim.api.nvim_buf_/nvim_win_编辑内容、窗口管理、浮动窗口
LSP 开发vim.lsp.buf./vim.diagnostic.代码导航、诊断、格式化
语法解析vim.treesitter.*精准语法操作、代码提取
工具函数vim.fs/vim.tbl_*/vim.defer_fn文件操作、表处理、异步执行
调试 / 通知vim.notify/vim.log日志、用户提示

关键使用建议

  1. 优先用 Lua API:避免 vim.cmd/vim.fn,性能更高、类型更安全;
  1. 查文档技巧:在 Neovim 中执行 :h vim.keymap.set/:h vim.lsp.buf.hover 可查看对应 API 详细说明;
  1. 复用成熟库:无需重复造轮子 —— 如文件操作用 vim.fs,表操作用 vim.tbl_*,异步用 vim.defer_fn;
  1. 插件开发参考:热门插件(如 Lazy.nvim、nvim-tree)的源码是学习 API 最佳实践的素材。