跳过正文
  1. 文章/

Neovim 工作流

·468 字·3 分钟
作者
Yang Hu

与 Vim 相比,Neovim 内置了许多实用插件和功能,Lua 配置也更易读、更强大。以下是一些在 Nvim 中编写代码的实用技巧。

搜索(文件、文本、诊断、帮助)
#

search-in-vim 中介绍的技巧类似,我们可以在文件中搜索文本,或通过过滤文件名来查找文件。在 Neovim 中,我们使用 fzf-lua,与 fzf.vim 非常相似。

使用 FZF 选择器

FZF 的界面由一个选择器(对条目列表进行模糊搜索)和一个预览窗口组成。在选择器中,使用 c-j/k/n/p(或 c-u/d移动Tab/S-Tab 用于选择文件。默认操作(Enter)是编辑文件或发送到 qflist,具体取决于选中数量。若要编辑多个文件,使用 c-e

另一个实用命令是"恢复"(<Leader>sr),可以继续上次的 FZF 搜索。

模糊匹配查找文件
#

用途快捷键说明
当前目录 中的文件<Leader>fPWD
最近文件(MRU)<Leader>o非常适合搜索之前打开过的文件
缓冲区 的同级文件<Leader>s.也包含子目录中的文件
项目范围的文件(git<Leader>gf只显示 git 跟踪的文件
缓冲区目录 为起点的任意路径<Leader>sfEnter 前可以修改路径

搜索文本
#

在文件中 Grep
#

用途快捷键说明
当前目录中的文件<leader>/使用 keyword -- glob 过滤文件(! 表示排除模式)
Git 根目录<leader>g/同上
当前 word/WORD<leader>w/Ww 在可视模式下也有效

实时 grep:两个快捷键都使用"实时 grep",即每次按键都会运行一条新的 ripgrep 命令并更新结果,可以即时测试 grep 表达式。

glob:在实时 grep 中,可以在关键词后加 -- 来添加 glob。例如:-- *.lua !*.md lib/**/*.c

  • * 表示任意字符
  • ** 表示任意文件夹(递归)
  • ! 表示排除匹配

模糊搜索缓冲区行
#

用途快捷键说明
搜索当前缓冲区的行<leader>sb[S]earch [B]uffer lines
搜索所有已打开缓冲区<leader>so[S]earch [O]pen buffer lines

搜索 Git 仓库内容
#

用途快捷键说明
搜索包含当前缓冲区的提交<leader>gb[G]it [B]uffer commits
搜索所有提交<leader>gc[G]it [C]ommits

搜索 Vim 帮助
#

FZF 也非常适合搜索帮助标签和快捷键(通过 <leader> 后接 shsk)。还有一个用于查看 Man 手册的快捷键 <leader>sm

Treesitter
#

Treesitter 将文件解析为代码对象,不仅能提供更好的_高亮_,还带来了一套全新的动作对象,可在操作待定模式和可视模式中使用,使文本操作更加轻松和精确。

Treesitter 对象
#

定义了以下字母对应的文本对象:

  • c:类(Classes)
  • m:方法/函数定义
  • f:函数调用
  • i:条件(if)语句
  • l:循环
  • a:参数
  • =:赋值

所有对象都支持通过 [] 跳转到上一个/下一个。大写字母跳转到末尾,小写字母跳转到开头:

  • [c:跳转到上一个类的开头
  • ]L:跳转到下一个循环的末尾
  • [f:跳转到上一个函数调用的开头

在操作待定模式下的示例:

  • cr=:修改赋值右侧
  • caa:修改一个参数
  • cii:修改 if 内部(根据光标位置选中条件或条件体)
  • daf:删除一个函数调用

Flash 插件快速选择代码块,通过 SR 触发:

  • S:从当前光标位置选择一个代码块
  • R:远程选择代码块

[x 跳转到上层作用域的开头。

大纲
#

安装了 aerial.nvim 来显示 Treesitter 提供的精确文档大纲:

  • 切换侧边大纲窗口:<leader>a<leader>A 停留在大纲窗口)
  • 跳转到上一个/下一个大纲条目:<leader>{<leader>}

LSP 与诊断
#

Neovim 原生支持 LSP,提供_诊断_、签名帮助文档、_代码操作_和_格式化_等功能。

诊断
#

用途快捷键说明
上一个诊断[d
下一个诊断]d
切换诊断显示<leader>dt切换虚拟文本显示
显示浮动框<leader>df显示包含详细信息的浮动框
Fzf 搜索诊断<leader>sd搜索当前文档的诊断
发送到 quickfix 列表<leader>dq之后可使用 :cdo:cfdo 处理
发送到 location 列表<leader>dl

使用 trouble.nvim
#

用途快捷键
缓冲区诊断<leader>xX
工作区诊断<leader>xx
Quickfix 列表<leader>xq

重命名与代码操作
#

用途快捷键
重命名<leader>rn
代码操作<leader>ca

自动补全
#

快捷键
#

用途快捷键说明
上一个/下一个<C-j> / <C-k>
关闭<C-c>
滚动<C-b> / <C-f>
确认<C-y>不是 CRTAB
移动到上一个/下一个位置<C-h> / <C-l>INSERT 模式下有效,适用于代码片段
下一个选项<C-e>用于代码片段中的选项节点

代码片段
#

Luasnip 提供代码片段。我的代码片段位于 dotfiles/nvim/lua/snippets/,文件名需要与文件类型匹配。

辅助代码片段(在 lua 中触发):

  • snipf:用于带有 i 节点等的复杂代码片段
  • snipt:用于简单文本代码片段

Markdown 代码片段:sc 用于 Hugo 短代码。

格式化
#

自动格式化
#

使用 conform.nvim 格式化文件:

用途快捷键说明
手动触发格式化,f调用 Conform
格式化_嵌入_代码,mf如 Markdown 中的代码块
  • Prettierd 配置以 80 列宽格式化 markdown(需在 .config/nvim/utils/linter-config/.prettierd.toml 中设置 proseWrap = "always"

使用 leapgrapple 进行跳转
#

Leap 跳转
#

s 开头,然后输入两个字母即可跳转到可视范围内的任意位置。gs 跳转到另一个窗口。

特殊字符:<space> 行尾,<space><space> 空行,所有括号类型视为等价。

远程操作
#

操作待定模式下按 r 触发远程操作,无需移动光标即可对远程位置执行操作:

  1. y,再按 r 进入远程模式
  2. 输入远程位置的字母,按下标签键
  3. 输入动作,操作在远程文本上完成,光标回到原处

语法选择(flash
#

功能快捷键
选择包含当前光标的代码块S
远程选择代码块R

文件间跳转(Grapple
#

用途快捷键说明
添加标签<Leader>ma可以输入可选名称
删除标签<Leader>md取消标记当前文件
移动到下一个标签<Leader>n
显示所有标签并选择<Leader>mk

文件管理
#

oil.nvim 允许像编辑 vim 缓冲区一样编辑文件系统,保存时应用到文件系统。通过 nvim .:e . 触发。

使用 Git
#

  • gitsigns:行号栏差异标记,提供暂存/取消暂存辅助,以及内联差异、blame 等
  • Fugitive:经典插件

内联差异与暂存
#

用途快捷键说明
在变更/块之间移动[h / ]h
预览块差异<Leader>hp
对比差异(并排)<Leader>hd / <Leader>hDd:与已暂存版本;D:与最后一次提交
退出差异视图<Leader>hq
暂存缓冲区/块<Leader>hS/hs大写对应缓冲区,小写对应块
重置缓冲区/块<Leader>hR/hr
取消暂存块<Leader>hu
Blame 行<Leader>hb
切换 blame 内嵌显示<Leader>htb
切换已删除块的显示<Leader>htd

暂存文件与创建提交
#

通过 Fugitive 的 status 视图:

  1. <leader>gs 打开 git status
  2. () 在文件之间移动
  3. = 切换光标所在文件的差异显示
  4. - 切换暂存状态
  5. X 硬重置文件
  6. cc 创建提交

杂项
#

预览 Markdown 文件
#