Neovim 中文周刊 第 9 期

点击查看原文

欢迎收看第 9 期 Neovim 中文周刊!

本期周刊包含以下版块:

  • Neovim 开发近况:摘录近期合并的 PR,以新功能为主
  • 社区资讯:摘录近期更新的 Issue 讨论以及 Reddit 等论坛的热门话题
  • 插件推荐

Neovim 开发近况

feat(checkhealth): trigger FileType event after showing report (#33677)

:checkhealth 的报告生成完毕后再将 buffer 的 'filetype' 设置成 checkhealth

#33172 引入后会使用 Emoji 展示 checkhealth 状态,charbelnicolas 表示不希望使用 Emoji,justinmk 指出可以使用 FileType checkhealth 将 Emoji 替换掉,但是原先在 :checkhealth 的内容生成之前就将 buffer 的 'filetype' 设置成 checkhealth,导致用户没有机会替换 Emoji,现在可以通过下列命令来替换掉 Emoji

autocmd FileType checkhealth :set modifiable | silent! %s/\v( ?[^\x00-\x7F])//g

docs: make it more beginner-friendly (#33524)

现在 Neovim 提供了一个可供新手参考的 init.lua 示例,位置在 $VIMRUNTIME/example_init.lua,参见 :h nvim-quickstart

perf(lsp): include previousResultId in DocumentDiagnosticParams (#32887)

现在 Neovim 在请求 textDocument/diagnostic 时会携带 previousResultId 参数,以提高该请求的性能。#31454 报告在使用 Roslyn LSP 解析较大文档时 diagnostic 很慢,但是 VSCode 能秒开,mparq 指出 VSCode 在请求时附带了 previousResultId 等参数。

feat(ui): use builtin completion popupmenu with ext_cmdline (#31269)

:h nvim_open_winconfig 参数新增字段 _cmdline_offset,注意:该字段被标记为 EXPERIMENTAL

UI 在实现 ext_cmdline 时,由于当 'wildoptions' 包含 pum 时需要能够使用 popup menu 来展示补全项,因此必须同时实现 ext_popupmenu。该 PR 引入后,通过使用 _cmdline_offset 字段,可以将 window 标记为 cmdline 窗口,这样内置的 cmdline popup menu 将锚定在该 window,从而直接复用内置的 cmdline popup menu。

feat(ui): no delay for errors with ext_messages (#33693)

Neovim 在发生某些错误的时候会在打印错误消息之后卡一下,目的是确保用户确实看到了消息并仔细思考自己的操作,比如在编辑只读文件的时候,第一次修改的时候会卡 1 秒。该 PR 合并后,当 UI 实现了 ext_messages 时将不再停顿,理由是开发者很可能并不希望要停这么一下,而且这完全可以由开发者自己实现。

justinmk 表示在改良 Neovim 的消息架构之后,可以考虑移除这些消息停顿的部分或者全部。

Shada saving improvements (#33542)

:h shada-' 现在支持设置成 '0 的时候禁止保存 jumplistchangelist

PR 作者不希望 jumplist 保存到 :h shada 中,此前 'shada' 添加了 shada-' 之后必定会保存 jumplist,但是 Neovim 又规定当 'shada' 选项不为空时必须添加 shada-',导致 jumplist 一定会保存。

vim-patch: 9.1.{1341,1344} (#33667)

新增选项 'isexpand' 和内置 API complete_match()'isexpand' 用于指定 Insert 模式下补全的触发词或 pattern,如 ->/* 等,而 complete_match() 将根据 'isexpand' 返回一张列表,每个列表项包括触发补全的起始位置 start_col 和触发补全的关键词 trigger_text

此前不少补全插件作者使用 'iskeyword' 选项来获取补全触发位置,这导致如果用户希望自定义触发词的话就必须修改 'iskeyword',这可能会导致意想不到的副作用。

feat(lsp): root_markers can control priority (#33485)

vim.lsp.Configroot_markers 字段现在支持传入 (string|string[])[],并支持优先级,由列表项在列表中的顺序决定优先级,相同优先级的 marker 可放入同一个列表中,例如

{
    -- `.stylua.toml` 和 `.luarc.json` 的优先级相同,并且比 `.git` 高
    root_markers = { { ".stylua.toml", ".luarc.json" }, { ".git "} }
}

此前的实现直接使用 vim.fs.root(..., root_markers) 来计算 root_dir,这导致所有的 marker 优先级相同,将返回第一个包含任一 marker 的目录。该 PR 引入后,会挨个对 root_markers 的每个项调用一次 vim.fs.root,确保完整找一圈高优先级的 marker 没找到之后再开始找低优先级的。

Start and stop LSPs as necessary during vim.lsp.enable (#33702)

此前 vim.lsp.enable 的实现基本上就是设置一个 autocmd FileType 来为启用的 LSP 调用 vim.lsp.start,然而这样无法影响在调用前已经存在的 buffer。该 PR 合并后,调用 vim.lsp.enable 将立刻执行一次 doautoall nvim.lsp.enable FileType 或者关闭所有被禁用的 LSP 客户端。

然而这也引入了副作用,由于在 Neovim 启动时使用 vim.lsp.enable 启用 LSP 是惯用法,这将导致 Neovim 在启动时就会尝试启动 LSP,这在使用 SchemaStore.nvim 等插件时可能会出错(#33761 报告了这一问题),并在 #33762 中通过判断 vim.v.vim_did_enter 修复。

feat(terminal): parse current buffer contents in nvim_open_term() (#33720)

vim.api.nvim_open_termbuffer 参数支持传入一个非空的 buffer,buffer 中的内容将被解析并 pipe 到 PTY,并在该 API 打开的 terminal 中输出。justinmk 指出该功能有助于解决 #28297,该提案请求 :mksession 支持保存 :terminal

fix(trust): better support for trusting directories (#33617)

该 PR 正确地实现了 vim.secure.{read,trust} 以支持目录。vim.secure.read 的返回值类型由 string? 变更为 boolean|string?,当用户信任参数指定的目录时,该调用将返回 true。此前 vim.secure.read 在接受目录时将永远返回 nil,导致调用者无法得知用户是否信任该目录。

fix(diagnostic): allow virtual_{lines,text} cursor exclusivity (#33517)

:h vim.diagnostic.Opts.VirtualTextcurrent_line 字段现在支持三种行为,该字段的类型为 boolean?。当值为 nil (默认)时,显示所有 diagnostic;当值为 true 时,只显示当前行的 diagnostic;当值为 false 时,显示除当前行外的所有 diagnostic

#33092 报告如果同时用 virtual_linesvirtual_text,这俩会各自渲染同一条 diagnostic 导致重复。该 PR 合并后,可以通过

vim.diagnostic.config({
  virtual_text = { current_line = false },
  virtual_lines = { current_line = true },
})

这样当前行的 diagnostic 用 virtual_lines 来渲染,其他行的用 virtual_text,完美互补。

feat(build): build.zig MVP: build and run functionaltests on linux (#28344)

感谢 jinzhongjia 协助测评!

支持使用 Zig 构建 Neovim!目前仅支持 Linux,您可以使用

zig build -Dtarget=x86_64-linux-gnu nvim_bin

为 x86_64 Linux 构建,注意默认使用的是 Lua 5.1,您可以添加构建参数 -Dluajit=true 来使用 LuaJIT。

使用

# 将 $VIMRUNTIME 设置成 Neovim 仓库的 runtime 目录
VIMRUNTIME=./runtime ./zig-out/bin/nvim

来试玩这个使用 Zig 构建的 Neovim。我在简单的试用中发现 blink.cmp 不能工作,此外

但是 vim.uri 这些没有

feat(ui): ext_cmdline/messages for the TUI (#27855)

新增实验性模块 :h vim._extui,这是一个非常振奋人心的 UI 改进,包括

  • 使用 tree-sitter 和 :h matchparen 高亮命令行

cmdline highlight

  • 当消息显示位置设置为 cmd (默认)时,消息将像以往一样显示在 cmdline 处,但多行消息将被截断(No more Hit-Enter!);当 'cmdheight' 为 0 或设置显示位置为 box 时,消息将显示在右下角,类似于 fidget.nvim

floating message

  • :messages 将打开一个常规的窗口来展示,这意味着您可以自由移动光标、选择和复制消息内容!(Tips:上述的多行消息被截断时,按 g< 可以直接打开这个 :messages 窗口)

messages window

您需要执行 require("vim._extui").enable({}) 来启用这些实验性的 UI 功能。

feat(messages): add hl-StderrMsg and hl-StdoutMsg (#33429)

添加了两个标准高亮组 :h hl-StdoutMsg:h hl-StderrMsg,分别用于高亮 :! 命令行程序的 stdoutstderr 消息。

#33405 报告在 #32013 合并之后 :!stderr 输出被高亮为 :h hl-ErrorMsg,问题是有不少软件也用 stderr 输出错误消息以外的内容,这些全部被高亮成 hl-ErrorMsg 看起来很让人火大,而且容易让用户视觉疲劳而忽视真正的错误。

值得注意的是 hl-StderrMsg 默认还是 :h :highlight-linkhl-ErrorMsg,引入这两个高亮组的目的主要是为用户和 Colorscheme 作者提供自定义的手段。

社区资讯

Released Nvim 0.11.1 with 50+ fixes

Talk with Gorilla Moe and Yaro (Kulala Maintainers) | Kulala, a Postman Alternative in Neovim

采访了 kulala.nvim 的两位维护者,访谈中详细介绍了 kulala.nvim ——一个为 Neovim 实现 REST 客户端的插件。

插件推荐

ui.nvim

ui.nvim 是一个使用 Lua 自定义 Neovim 的用户界面的示例插件。它的主要目标是演示如何处理不同的 UI 事件,并为用户提供一个可自由定制的模板,便于进行个性化开发。

  • 完全可定制的命令行实现。支持 Block 模式、prompt、confirm()、语法高亮等
  • 基础的消息支持。支持动态地更改消息显示时长,修改消息内容,以及保留消息中的高亮等
  • 支持 'showcmd'
  • 支持 :h ins-completion 和命令行的 Popup menu
  • 自定义的 :messages UI
  • 更多的实用工具 API

ui-nvim demo

鸣谢

关于

本周我们将《Neovim 中文周刊》由个人项目迁移至 nvim-weekly-cn 组织的项目,请大家留意 Github 地址的变化。

同时,jinzhongjia 为本周刊搭建了 Github Pages,并提供了一个非常棒的域名 weekly.nvimer.org,非常感谢 jinzhongjia 大佬的支持和贡献!

我们计划继续改进 Github Pages 的阅读体验,并希望能逐步弃用原先使用的 Github Release Notes。我们在 #5 追踪 Github Pages 的相关事务,欢迎各位读者提供建议,感谢各位的支持。

那么,一如既往,希望本期周刊能对您有所裨益,感谢您的阅读。

  • 周刊网站 | 周刊项目地址 | RSS 订阅
  • 我不是 Neovim 贡献者,也不是任何有影响力的插件贡献者,甚至算不上一个 (Neo)vim 老手,我的观点很可能错漏百出。如果您希望贡献本周刊,请收下我的感谢并查看贡献指南
  • 发布日期:2025-05-03 修订日期:2025-05-03