> 该博客翻译自: https://rsvim.github.io/blog/2024/08/29/motivation
Vim 和 Neovim 编辑器在世界各地广受开发人员和文字编辑者的欢迎和喜爱,我也一样。
## 历史
在由 [Bram Moolenaar]( https://en.wikipedia.org/wiki/Bram_Moolenaar) 领导 Vim 开发的过程中,一直存在一种趋势,即用户希望通过提供各种插件的方式将 Vim 变成一个 IDE:文件资源管理器、UI 组件和图标、代码补全、诊断、代码格式化等等。Vim 使用了 [vimscript]( https://en.wikipedia.org/wiki/Vim_(text_editor)#Vim_script) 作为其一等公民来进行支持,但这其实是非常小众的,并且阻碍了人们创建自己的插件、或给 Vim 项目本身提交代码(当然也和 vimscript 自己的文档和语法设计有关)。Vim 的可扩展性和用户需求之间的冲突一直在增加。
随后 Neovim 于 [2014]( https://en.wikipedia.org/wiki/Vim_(text_editor)#Neovim) 年问世。为了提供更丰富友好的功能,以及更接近 IDE 的编辑体验,它引入了 [lua]( https://www.lua.org/) 作为脚本语言, [LuaJIT]( https://luajit.org/) 作为运行时解析器。这在一开始引起了很大争议,因为 lua 既带来了不兼容 vimscript 的破坏性更新( vimscript 作为专门为 Vim 设计的脚本语言,确实更能融入编辑器中),又不像 [python]( https://www.python.org/) 或 [javascript]( https://en.wikipedia.org/wiki/JavaScript)/[typescript]( https://www.typescriptlang.org/) 那么受开发者欢迎。在 Neovim 和 lua 出现之前,Vim 社区通常利用这些外部语言来实现复杂的插件,例如自动补全、文件资源管理器等。但是,编辑器本身和语言解释器/运行时之间的 [IPC]( https://en.wikipedia.org/wiki/Inter-process_communication) 开销无法消除,额外增加一个语言也无法开箱即用。
事实证明 Neovim 的选择是成功的,luajit 大大提高了性能,而 lua 提供了更好的语法(与 vimscript 相比)来处理用户自己的逻辑。这鼓励了更多用户创建自己的插件(包括我自己),以及给 Neovim 项目提交代码。与此同时,Vim 带来了 [vimscript9]( https://www.vim.org/vim90.php) 作为替换原 vimscript 的更好的脚本语言,但这仍需要付出很多努力,包括开发/维护以及时间和用户反馈。显然,嵌入一个现成的脚本语言要容易得多,也快得多。
## 脚本
脚本在 (Neo)Vim 编辑器中[扮演着一个最为重要的角色:它驱动着编辑器的外观和行为、调度着后台任务、负责与远程进程通信、等等。与此同时,它也将编辑器变成一个语言解释器/运行时/虚拟机]( https://github.com/rsvim/rfc/blob/873cf96ca2ea256c0694e9396816b2ded827d08a/2-JavascriptEngine.md?plain=1#L9)。当我们将 (Neo)Vim 编辑器看作一个语言解释器时,我们会开始思考更多的方面:
* 现代的编程语言特性:函数式( Functional Programming )编程:迭代、闭包、无副作用、等等特性,内置的异步( Async/Await ),静态类型( Static Type ),以及很多其他特性。
* 包的管理、升级和分发。比如:lua 的 [luarocks]( https://luarocks.org/),js/ts 的 [npm]( https://www.npmjs.com/),python 的 [pip]( https://packaging.python.org/en/latest/tutorials/installing-packages/)。
选择 lua 的劣势逐渐显现出来,毕竟它受限于自己糟糕的语法设计,也缺乏庞大的社区支持,远远落后于上述这些真正流行的脚本语言。
这就是为什么在审视( Neo ) Vim 编辑器时,突然会冒出用 Rust+Javascript 重写(重新发明)它的想法。与 c/c++相比,rust 提供了如此多强大而高效的语言特性,更别提它的工具链和活跃的社区。至于脚本,我们希望有一个包含以下特点的脚本语言:
* 包括上述这些脚本语言的现代化功能、包管理系统。
* 流行且广受欢迎和使用,拥有活跃的开发社区。
* 性能出色,不会让编辑器卡顿。
其实我们没有太多选择:
* Python 太慢了
* 其他脚本语言如 lua/vimscript/lisp 并不那么流行,一些新的脚本语言仍然太年轻,尚未被广泛使用。
Javascript 满足了大部分的要求,谷歌在 [V8]( https://v8.dev/) 引擎上花费了数百万美元和不计其数的开发时间,社区也出现了 [QuickJS]( https://bellard.org/quickjs/),两者都是非常好的内置入编辑器的解决方案。但是等等,js 的语法糟糕且混乱,它的成功实际上属于浏览器和网络行业,并非 js 本身。所以最终的目标是[用 typescript 编写脚本,js 则可以扮演一个中间层的角色]( https://github.com/rsvim/rfc/blob/873cf96ca2ea256c0694e9396816b2ded827d08a/2-JavascriptEngine.md?plain=1#L25)。ts 弥补了 js 的一些缺点:
* 更优雅和漂亮的语法设计
* 静态类型
* 完全兼容 js 和社区
## TUI
另一个强劲趋势是:越来越多的 (Neo)Vim 插件通过定制 [floating window]( https://neovim.io/doc/user/api.html#_floating-windows) 和 [buffers]( https://vimhelp.org/windows.txt.html#buffers) 来提供复杂的 UI 部件。甚至还出现了一些 TUI 库/框架,它们将 (Neo)Vim 视作一个包含着 UI 部件的屏幕。这个想法引导我们看向一些现代的 GUI 框架甚至 Web UI 组件,例如 [Qt]( https://www.qt.io/)、[Tk]( https://www.tcl.tk/)/[Tkinter]( https://docs.python.org/3/library/tkinter.html)、[Material UI]( https://mui.com/material-ui/)、[Iced]( https://iced.rs/)。
大多数 GUI 框架都支持以下功能:
* 坐标系统:管理 UI 在二维坐标系上的形状、位置和大小,以及在三维坐标系上的碰撞和叠加(通过引入第三个维度的坐标,即 Z-index )。
* 事件处理:根据位置和形状,可以定位用户发出的键盘/鼠标事件,将其分派到绑定在 UI 部件上的相应处理函数(回调函数),从而简化用户逻辑的处理。
* 布局:UI 的形状可以是固定尺寸的或灵活可变的,甚至是可以由 [css flexbox]( https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox) 这类机制进行管理,如按行排布、按列排布和按网格排布。
* 特制化的 UI 部件:按钮、弹出窗口、对话框、内容预览器、文本编辑窗口等。
通过引入具有此类概念的 TUI 引擎,可以改善视觉效果、标准化小部件行为并减少插件开发工作量。 |
|