接 入门 与 实战:本篇面向「配置已能干活、想掌控扩展点」的读者——读懂 Lua API、写可靠 autocmd / keymap、搭最小插件、会 profiling,并把 nvim 嵌进 iTerm2 + tmux / 远程场景。
Lua API 速览
Neovim 把编辑器状态暴露给 Lua。最常用:
| API | 用途 |
|---|---|
vim.opt / vim.o / vim.bo / vim.wo | 选项(全局 / buffer / window) |
vim.g / vim.b / vim.w / vim.t | 全局与作用域变量 |
vim.keymap.set | 键位(替代 nvim_set_keymap) |
vim.api.nvim_* | 底层 API:缓冲、窗口、命令、autocmd |
vim.fn.* | 调用 Vimscript 函数 |
vim.cmd() | 执行 Ex 命令字符串 |
vim.uv / vim.loop | libuv 异步(文件、定时器、进程) |
vim.schedule | 把回调排回主循环(API 安全) |
示例:读当前文件与改一行选项:
local buf = vim.api.nvim_get_current_buf()
local name = vim.api.nvim_buf_get_name(buf)
vim.bo[buf].filetype = 'python'
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
print(#lines, name)
创建用户命令:
vim.api.nvim_create_user_command('WdDate', function()
local s = os.date('%Y-%m-%d %H:%M')
vim.api.nvim_put({ s }, 'c', true, true)
end, { desc = 'Insert local datetime' })
通知:
vim.notify('LSP ready', vim.log.levels.INFO)
autocmd:事件驱动
用 nvim_create_augroup + nvim_create_autocmd,避免散落的 Vimscript au。
local aug = vim.api.nvim_create_augroup('WdTweaks', { clear = true })
-- 离开插入时取消搜索高亮可按需
vim.api.nvim_create_autocmd('TextYankPost', {
group = aug,
callback = function()
vim.highlight.on_yank({ higroup = 'IncSearch', timeout = 120 })
end,
})
-- 按文件类型缩进
vim.api.nvim_create_autocmd('FileType', {
group = aug,
pattern = { 'python', 'rust' },
callback = function()
vim.opt_local.shiftwidth = 4
vim.opt_local.tabstop = 4
end,
})
-- 终端 buffer 自动 insert
vim.api.nvim_create_autocmd('TermOpen', {
group = aug,
callback = function()
vim.opt_local.number = false
vim.opt_local.relativenumber = false
vim.cmd.startinsert()
end,
})
-- 保存时自动创建无尾空白(谨慎用于有意义空白的格式)
vim.api.nvim_create_autocmd('BufWritePre', {
group = aug,
pattern = '*',
callback = function()
local view = vim.fn.winsaveview()
vim.cmd([[%s/\s\+$//e]])
vim.fn.winrestview(view)
end,
})
常用事件:BufWritePre、BufEnter、LspAttach、UIEnter、VimResized、FileType。
调试::autocmd / :autocmd TextYankPost 查看;clear = true 保证重载不重复注册。
Keymap 设计原则
- Leader 语义分层:
<leader>f找、<leader>ggit、<leader>llsp、<leader>x诊断/列表。 - buffer-local 优先:LSP 映射放
LspAttach,避免全局污染。 - desc 必填:配合 which-key,也方便自己
:map。 - 少用递归:
vim.keymap.set默认noremap语义更安全。 - 插入模式映射克制:容易与输入法、补全冲突;
jk→Esc 可留。 - 终端模式:
vim.keymap.set('t', '<Esc><Esc>', [[<C-\><C-n>]])跳出。
模式化封装:
local M = {}
function M.map(mode, lhs, rhs, opts)
opts = opts or {}
opts.silent = opts.silent ~= false
vim.keymap.set(mode, lhs, rhs, opts)
end
function M.nmap(lhs, rhs, desc)
M.map('n', lhs, rhs, { desc = desc })
end
return M
冲突排查::verbose nmap <leader>ff 看最后定义位置。
自定义 plugin 骨架
最小插件不必发布;本地 ~/projects/wd.nvim 或配置内 lua/wd/ 即可。
作为 runtimepath 插件
~/code/wd.nvim/
lua/
wd/
init.lua
health.lua
plugin/
wd.lua -- 可选:自动加载入口
doc/
wd.txt
lua/wd/init.lua:
local M = {}
M.config = {
cheer = true,
}
function M.setup(opts)
M.config = vim.tbl_deep_extend('force', M.config, opts or {})
vim.api.nvim_create_user_command('WdHello', function()
local msg = M.config.cheer and '🍷 Cabernet ready' or 'ok'
vim.notify(msg)
end, {})
end
return M
在 lazy 里:
{
dir = vim.fn.expand('~/code/wd.nvim'),
name = 'wd.nvim',
opts = { cheer = true },
config = function(_, opts)
require('wd').setup(opts)
end,
},
plugin/wd.lua(Vim 启动时自动 source):
-- 仅注册极轻逻辑;重逻辑放 setup
vim.api.nvim_create_user_command('WdPing', function()
print('pong')
end, {})
健康检查 :checkhealth wd:
-- lua/wd/health.lua
local M = {}
function M.check()
vim.health.start('wd.nvim')
if vim.fn.has('nvim-0.9') == 1 then
vim.health.ok('Neovim >= 0.9')
else
vim.health.error('Need Neovim 0.9+')
end
end
return M
要点:setup() 幂等;默认值与用户 opts 合并;避免在 import 时创建 autocmd(放到 setup)。
性能 profiling
启动
:profile start /tmp/nvim-profile.log
:profile func *
:profile file *
" 再执行可疑操作或重启后加载
:profile stop
或启动参数:
nvim --startuptime /tmp/startup.log
看谁最慢:大插件、同步 require、过早加载的 UI。
lazy 视角
:Lazy profile
把不碍事的插件设 event = 'VeryLazy'、cmd = ...、ft = 'python'、keys = ...。
运行时卡顿
- Treesitter:大 minified JSON 可
vim.bo.syntax = 'off'或禁用 highlight。 - LSP:
:LspStop对比;pyright 对巨型 monorepo 要限root_dir/ exclude。 - 状态栏轮询、git blame 实时刷新:降频或按需。
-- 大文件保护
vim.api.nvim_create_autocmd('BufReadPre', {
callback = function(args)
local ok, stat = pcall(vim.loop.fs_stat, args.file)
if ok and stat and stat.size > 1024 * 1024 * 1.5 then
vim.b.large_file = true
vim.cmd.syntax('off')
vim.opt_local.foldmethod = 'manual'
end
end,
})
远程编辑
方案 A:SSH 上直接跑 nvim
最稳。本地 tmux → ssh host → nvim。配置用 GNU stow / git bare / Ansible 同步 ~/.config/nvim。
方案 B:netrw / scp
nvim scp://user@host//var/www/app/main.py
可用但体验一般,延迟高时痛苦。
方案 C:SSHFS / mutagen / rclone mount
把远端目录挂到本地,再用本地 nvim + LSP。注意:LSP 在本地跑、文件在远端时,解释器路径与索引要想清楚;有时不如远端 nvim + 远端 pyright。
方案 D:neovim 远程 UI(进阶)
nvim --headless --listen 0.0.0.0:6666 与 nvim --server / 第三方 UI。公司网络需 SSH 隧道:
ssh -L 6666:127.0.0.1:6666 user@host
安全:勿对公网裸奔 listen。
与 iTerm2 / tmux 配合
iTerm2
- Profiles → Colors:真彩色;Font 用等宽(JetBrains Mono / Maple Mono)。
- Keys:把 Option 设为
Esc+,方便 Meta 映射。 - 滚动与鼠标:
set mouse=a后,可在 nvim 里用鼠标调窗(tmux 需同步设置)。 - 分裂窗:习惯上 tmux 管会话,nvim 管 buffer,避免两边都狂分屏。
tmux 最小友好配置
# ~/.tmux.conf
set -g mouse on
set -g default-terminal "tmux-256color"
set -as terminal-overrides ",xterm-256color:RGB"
set -s escape-time 0
set -g focus-events on
setw -g mode-keys vi
# 窗格移动与 nvim 一致的心智
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
escape-time 0 减少 Esc 延迟;focus-events 利于「自动保存 / git gutter」类插件。
剪贴板三角
iTerm2 ↔ tmux ↔ nvim:优先让 nvim unnamedplus 对接系统;tmux 可装 OSC52 或 set -g set-clipboard on。SSH 远程时 OSC52 常比抢 X11 转发更省事。
会话脚本示例
#!/usr/bin/env bash
# wd-session.sh — 数据项目一键
SESSION=analysis
PROJECT=~/work/report-q3
tmux has-session -t "$SESSION" 2>/dev/null && tmux attach -t "$SESSION" && exit
tmux new-session -d -s "$SESSION" -c "$PROJECT"
tmux send-keys -t "$SESSION":0 'source .venv/bin/activate && nvim' C-m
tmux split-window -h -t "$SESSION":0 -c "$PROJECT"
tmux send-keys -t "$SESSION":0.1 'source .venv/bin/activate && python' C-m
tmux attach -t "$SESSION"
配置维护建议
- 配置进 git:
~/.config/nvim单独 repo,机器间 pull。 lazy-lock.json提交,保证同事/另一台电脑版本一致。- 用
git bisect或临时nvim --clean对比「是不是配置害的」。 - 文档化自己的 leader 表(可放在本博客或
CHEATSHEET.md)。
三部曲收束
| 篇 | 焦点 |
|---|---|
| 入门 | 安装、模式、buffer、最小 init.lua |
| 实战 | lazy、LSP、telescope、git、Python 流 |
| 精通(本篇) | Lua API、autocmd、插件、性能、远程、tmux |
下一步不是「更多插件」,而是:把常用操作练到不必想,并删掉一个月没用的映射。
精通是减法:知道能加什么,更知道不该加什么。
评论