我们一路走来,真正的 0.5 是我们交的朋友
期待已久的 Neovim v0.5.0 版本终于在 2021 年 7 月 2 日发布。发布过程比大家预期的要长,但这都是值得的:它包含了超过 4000 次提交,规模之大甚至导致了一些发布工具的故障。因此,本篇笔记无法涵盖开发过程中所做的所有变更,只会关注对用户来说最显着的改进,其中最大的改进包括
Neovim 0.5 在将 Lua 打造成 Neovim 的一等公民脚本语言方面取得了长足的进步,无论是在插件开发还是用户配置方面都是如此。
需要提醒的是,Lua 是一种小型脚本语言,专为嵌入式设计,通常用于游戏开发等领域。此外,它还配备了一个即时编译器(LuaJIT,Neovim 在可用的平台上使用它),可以在相关任务中提供令人印象深刻的性能。本质上,Lua 被选中替代其他语言是因为它
有关此选择的更多详细信息,请参见 Justin M Keyes 在 2019 年 Vim Conf 上的演讲,以及 TJ DeVries 在 Vimconf.live 上的演讲。
让我们看看这对插件作者和用户意味着什么。
Neovim 通过例如 vim.api.nvim_open_win()
将 API 本地暴露给 Lua。它还提供方法通过例如 vim.cmd("echo 'foo'")
和 vim.g.syntax_on
分别访问 vimscript (ex) 命令和变量。这样可以编写与 Vimscript 编写的插件具有相同功能的插件,同时在核心编程语言任务(例如循环)中利用 Lua(JIT) 的性能。也可以使用 Lua 自己的 luarocks
插件生态系统。
相应地,在 0.5 的开发周期中,Lua 插件的数量呈爆炸式增长,从流行的 Vimscript 插件的重写到完全无法用 Vimscript 实现的新插件,这些插件通常来自以前从未参与过 (neo)vim 插件开发、并且不愿为了这项任务而学习 Vimscript 的贡献者。作为漫长开发周期的积极副作用,许多插件在 0.5 发布时就已经功能齐全且稳定了!
以下列出了一些非代表性的 Lua 插件
可以在用户贡献的 Awesome Neovim 集合中找到更全面的 Neovim 插件列表。
并非所有这些插件都是用 Lua 编写的:还有许多其他语言(其中一些是类型化的)可以编译成 Lua,例如
也可以用 Lua 编写用户配置:如果存在 init.lua
,则会读取它而不是 init.vim
(它们不能共存,在您的配置文件目录中同时存在这两个文件会导致错误),并且运行时目录(plugin/
、colorscheme/
、after/
等)中的 .lua
文件将与 Vimscript 文件一起(之后)被来源。请注意,这完全是可选的,并非享受 Neovim 0.5 中引入的新功能所必需;此外,并非所有 Vimscript 配置选项都具有完全原生的 Lua 等效项。将原生 API 扩展以涵盖这些选项也是 Neovim 0.6 的目标之一。
有关使用 Lua 进行 Neovim 脚本和配置的全面且最新的指南,请参见 在 Neovim 中开始使用 Lua 。一个使用 init.lua
的 Lua 配置的好例子是 Defaults.nvim 。
语言服务器协议 (LSP) 是一种开放的基于 JSON-RPC 的协议,用于代码编辑器和语言服务器之间的通信,语言服务器提供特定于编程语言的功能,例如
等等。
其理念是将这些功能分离到一个与编辑器无关但与语言相关的服务器和一个与语言无关但与编辑器相关的客户端,它们通过 RPC 使用语言服务器协议进行通信。(需要注意的是,并非所有服务器都实现了所有功能,并且响应的质量可能千差万别。“参考实现”在 VS Code 中也经常添加 LSP 本身未涵盖的非标准功能。)
Neovim 0.5 提供一个用 Lua(大部分)编写的 LSP 客户端,它提供了一种高度可配置且可扩展的方式来访问这些功能。它并不旨在与 CoC.nvim 等功能更丰富、开箱即用的插件竞争,而是旨在根据您的偏好进行定制(同时仍然可以正常使用默认值)。有关概述,请参见 TJ DeVries 的 Vimconf.live 演示 以及他的短视频 。
对于许多语言服务器,Nvim-lspconfig 已经提供了必要的配置,可以轻松地设置所有内容。或者,某些语言还具有特定的 LSP 插件,可以提供更加集成的设置,例如用于 Java 和 Scala 。
要详细了解 LSP 以及如何在 Neovim 中使用它,请访问 Nvim-lspconfig (包括它的Wiki ),并阅读:h lsp
。
在 0.5.x 的开发周期中,预计将对 LSP 进行更多工作,以提供改进的配置选项和对最新 LSP 规范(截至编写本文时为 3.16 版本)的更好支持,包括语义突出显示。
Neovim 0.5 添加了对 tree-sitter 的实验性 支持,tree-sitter 是一个库,它以增量和容错的方式将一段代码解析成语法树;这意味着在编辑后重新解析代码非常快,并且由于例如打字错误导致的解析错误会保持局部化,不会中断后续的解析。然后可以有效地查询此树,以获取有关代码的语法信息。这可以提高和/或加速
等等。Tree-sitter 还使得轻松地以不同的方式突出显示文件中的不同部分成为可能,如果这些部分包含不同语言的代码。要详细了解 tree-sitter,请观看 Tree-sitter - A new parsing system for programming tools - Max Brunsfield 。
目标是使用 tree-sitter 替换当前基于 vim 正则表达式的语法,这不仅是为了获得更好、更快的语法高亮,也是为了提供新的、改进的结构化文本编辑方法。但是,0.5 中的 tree-sitter 支持仍然应该被视为“抢先体验”:它工作得很好,足以进行测试并查看可能性,但由于存在一些严重的错误和性能回归,因此不应在生产环境中依赖它,这些问题需要在 Neovim 中的 tree-sitter 宣布稳定之前得到解决。另外请注意,为某种语言启用基于 tree-sitter 的高亮会完全禁用这种文件类型的内部基于正则表达式的语法引擎,这可能会破坏依赖它的其他功能。修复这些问题并改进 API 将是通往 0.6 版本发布的开发周期的主要目标。
此外,Neovim 本身只提供(Lua)API,用于使用捆绑的 tree-sitter 库生成和查询语法树;请参见:h treesitter
。面向用户的功能(如上面提到的功能)是在插件中实现的,例如
有关使用这些功能的更多信息,请参阅Nvim-treesitter README 或观看 Thomas Vigouroux 的 Vimconf.live 演示 。
这是一个常见问题,尤其是因为 LSP 从 3.16 版本开始提供“语义突出显示”。简而言之,tree-sitter 作用于单个文件,将文件解析成语法树,然后使用它来支持各种增强的代码导航和操作功能。另一方面,语言服务器作用于多个文件和项目库,使用各种不同的服务器依赖方法来解析每个文件的语法树。(当然,tree-sitter 是其中一种可行的选择,事实上它被例如 bash-language-server 和 wasm-language-server 使用。)
具体来说,这意味着语言服务器可以使用来自不同文件的语义 信息来注释当前文件的树:例如,在一个文件中声明为 const
的变量可以在另一个文件中被突出显示为红色——这是 tree-sitter 无法做到的,因为它在突出显示时只能访问后一个文件。
有关更多详细信息,请观看 TJ DeVries 的关于此主题的演示 。
当然,这些并不是 0.5 版本中唯一的重大变化。以下是代表性新功能的简要概述。
有一个改进的装饰提供程序 API,允许设置和交互 extmarks(不可见的锚定文本标记,在周围文本被编辑时移动)、虚拟文本(可以在屏幕上的任何位置绘制的文本叠加层)和高亮显示(被 nvim-treesitter 大量利用)。
来自帖子的这个模型,由@sunjon展示了可以通过这个 API 实现什么。
浮动窗口的 API 现在包括一个“z 轴”(允许控制浮动窗口的堆叠顺序)和对边框的支持。
Neovim 现在有一个内置函数,可以短暂地高亮显示粘贴区域(类似于 https://github.com/machakann/vim-highlightedyank),可以在 Lua 中配置。要使用它,您可以在您的 init.vim
中添加以下内容。
au TextYankPost * lua vim.highlight.on_yank {higroup="IncSearch", timeout=150, on_visual=true}
查看 :h vim.highlight.on_yank()
以获取更多配置选项。
在这个版本中超过 4000 个提交中,大约 1000 个是来自 Vim 的移植补丁和运行时更新——几乎所有这些都是由很棒的 @janlazo 编写或在他们的帮助下完成的。特别是,运行时文件(语法文件、文档等)与 Vim 的同步时间直到 2021 年 5 月,其中许多较新的更改也已包含在内。
为了与本通讯的格言保持一致,最显着积极的变化之一是社区的增长以及与之互动的新方式。
以前,支持请求和讨论分散在 Reddit、Gitter 和 GitHub Discussions 上,并且要么是短暂的,要么是难以搜索的。我们现在已经围绕一个新的 Neovim Discourse 进行了整合,这是一个免费的开源论坛平台,除了一个不错的网络界面之外,还具有邮件列表和 RSS 功能。Neovim Discourse 是一个官方的核心项目,由核心团队成员管理。
Neovim 的官方聊天室位于 Gitter 上。在 Matrix(一个联合聊天协议)收购 Gitter 之后,现在也可以从 Matrix 访问此房间;它还与 IRC 网络 Libera.chat 相连。由于用户数量不断增加,现在有额外的、更具体的房间用于 neovim 的开发及其周围、GUI 和 非主题聊天。
(上面的链接指向通过 Element 访问的房间,Element 是一个基于 Web 的 Matrix 客户端;您也可以通过许多其他 Matrix 客户端 访问它。)
由于全球 COVID-19 大流行,VimConf 2020 不幸地不得不取消。取而代之的是,举办了一个虚拟的 Vimconf.live 会议,有 16 位演讲者和来自 12 个国家的 1000 多名注册参与者。如果您错过了它,您可以在 Youtube 播放列表 上观看讲座。
大流行的另一个影响是对 Twitch 上开源开发的直播流的兴趣上升。许多 Vimconf.live 的演讲者都是活跃的流媒体;特别是,TJ DeVries 定期直播他在 Neovim 上的工作作为“开放开源”,Neovim 0.5 的发布是在 他的频道上直播的。(**更新:**发布流的编辑播放列表现在在 YouTube 上。)
积极参与 Neovim 开发的人数也在增长。在 0.4.4 和 0.5.0 之间,有 301 个独特的提交作者,而在 0.3.8 和 0.4.4 之间(一个类似的时间范围)则有 112 个。
您现在可以通过 Github Sponsors 或 OpenCollective 赞助 Neovim。(BountySource 开始在他们的服务条款协议中引入令人担忧的更改,因此不再推荐。)
如前所述,对 0.5 中引入的 headlight 功能的进一步改进将在 0.5.x 版本周期中进行。
使 tree-sitter 成为语法高亮显示(以及更多)的稳定且更快的替代方案是 0.6.0 版本的主要目标。这包括对装饰 API 的基础工作,以允许进行诸如内联折叠或插入虚拟行和列(“反隐藏”)之类的操作。
除此之外,值得注意的目标是 更好的文件更改检测,以及进一步将 TUI(终端 UI)与 Neovim 核心分离,目的是允许远程 TUI 实例。
最后,我们的目标是发布更多定期和频繁的版本(至少对于补丁版本),这将有望消除对“neovim 0.6 什么时候发布?”这个梗的需求。
感谢所有参与该项目并帮助 Neovim 0.5 成为现实的人——无论是贡献者、赞助商、错误报告者还是支持者。代替完整的致谢,这里列出了一些您可以感谢他们在本文中列出的功能的人。
:smile
。Neovim 是一个基于 Vim 的文本编辑器,专为 可扩展性 和 可用性 而设计,以鼓励新的应用程序和 贡献。
访问 #neovim:matrix.org 或 irc.libera.chat 上的 #neovim 与团队聊天。