读《Modern Vim》
上半年技术书看得比较少,也比较慢,这本百来页的书断断续续看了一个月。
毫不夸张的说,Vim 是我用的时间最多的软件,工作以来至少90%的代码是用 Vim 写的,不过相关的技能差不多一直停留在两三年前的水平,毕竟是一个快三十岁的编辑器,本身已趋于成熟稳定,很难再有大惊喜,插件也尝试过很多,留下的也都是精挑细选过,能最大程度地提高我的效率。
不过看到有 Vim 的新书出来,还是要看看,毕竟天天在用,可能还要再用三四十年,一个个小技巧节约下来的时间,累计起来也是非常可观的。
先说个总体评价:有用。
虽然部分章节的知识目前用不上,但也带给我很多新思路。
再说个附加评价:我遇到的第二本附录对我超级有帮助的书,花一本书的钱,只买两页附录也值得。另一本是《jQuery in Action》,用一页附录让我弄懂了闭包的概念。
Morden Vim
下面按章节顺序概述一些本书内容,章节标题就用原文了。
1. Get Morden Vim
一句话概括:为了更好的用户体验,请选择使用最新的 Vim 8 或 Neovim。
我选择 Vim 8 。
2. Installing Plugins
介绍了 Vim 8 的插件机制和利用新机制的插件管理器 minpac ,新机制可同时安装、更新多个插件。
但个人认为实际意义不大,毕竟插件的安装和更新频率没那么高,提升的效率有限,没有足够的动机取代我正在使用的 VimPlug,后者的功能更加成熟,使用上的便利性足以抵消前者性能上的优势。新用户倒是可以考虑新机制。
3. Opening Files
可以模糊查找文件的 fzf 和它的 Vim 插件,fzf 单独使用也不错,一定程度上可以代替 find 命令,fzf 的效果类似搜索引擎的即时搜索功能,边输入边提示匹配的文件,或者和 everything 也可以类比一下,只是 fzf 是在每次使用的时候,针对当前目录以下的内容即时建立索引,而不是全局。
通过插件 Projectionist 语意化查找文件。使用前需要先建立配置文件,适合重名文件多、而常用文件的目录层级又很深的项目,不同命令对应不同项目可以有不同语意。
依旧是 Projectionist ,可以在配置文件中通过 alternate 规则建立不同文件间的联系,然后通过 :A 命令快速切换。这个对于 MVC 结构的项目特别直观和有效,比如在相关的 Controller 、Model 和 View 文件间切换。
4. Working with the Quickfix List
Tip 10. Running a Build and Navigating Failures
Vim 8.1 开始可以通过 :terminal 打开内置的终端模拟器,vim-dispatch 插件通过调用 Vim 内部或借助 tmux 等工具,另开一个终端执行命令,达到后台执行命令,前端继续编辑的效果。
通过配置 makeprg 和 errorformat 改变 :make 执行的命令以及处理返回结果的方式,dispatch 提供的 :Make 是 :make 的异步版本。
但我现在走的是通过外置脚本 watch 文件变化再自动编译的路子。
而上述功能中最有吸引力的 :make 结果结合 quickfix 快速定位编译异常的功能,暂时没有找到和 watch 脚本结合的方案。
Tip 11. Switching Compilers
在多个编译脚本间切换,目前用不到。
5. Neovim's Built-in Terminal Emulator
我选择 Vim 8,跳过了这一章。
6. Sessions
通过 :mksession 和 source 的结合,保存编辑器的当前环境:比如打开的文件、编辑的位置、临时录制的宏等,这样下次打开编辑器就可以直接回到上次的状态继续展开工作。
这个好久以前就学会了,但是已经基本不再使用。因为本地编辑用的是苹果笔记本 ,除了系统更新从来不关机或者重启。远程用的是 tmux,断开连接时,所有环境都仍由其维持,加上服务器重启的次数更少,mksession 渐渐地就淡出了我的视线。
这一章还介绍了一个把编辑记录也保存到 session 中的方法(重新打开后还能撤销上一次打开时的操作),确实很实用,但没仔细看如何实现。
7. Configuring Vim
Tip 26. Using Autocommands to Respond to Events
这一节是离 Vim 内部机制最近的一节,介绍如何通过 Vim 丰富的事件机制来做一些小脚本,实现自动化操作。
Tip 27. Respecting Project Convertions
通过 EditorConfig 插件,实现针对不同项目独立配置缩进、编码、换行等编码规范。
EditorConfig 本身也是一个致力于使编码规范的配置独立于编辑器的项目,已被大量编辑器原生或者通过插件支持,解决了项目组成员使用不同编辑器带来的部分问题
Tip 28. Setting Buffer-Local Configuration Per Project
结合 Projectionist 和 AutoCommand 为不同项目下不同类型的文件设置局部变量,从而改变其他插件针对这些文件的行为。
展示了 Projectionist 的无限潜能,非常期待 .projections.json 能和 .editorconfig 一样成为一种跨编辑器的标准配置。
Appendix 1. What's Next for Morden Vim?
Integrating with the Language Server Protocol
早期的编辑器插件,用编辑器自带的脚本来处理和解析特定的语言,比如用 viml 解析 javascript, 这样针对每种语言都至少需要一个插件,其他编辑器也同样面临这个问题,所以这语言插件的数量大体上等于编辑器数量乘以语言数量,而且对开发人员的要求也高,需要同时了解特定编辑器的插件开发技术和特定语言的语法规则。
新的概念中,将语言相关的插件,分拆成两部分,一部分针对编辑器,一部分针对语言本身,两部分互相独立,这样针对语言本身的部分(Language Server)可以持续独立进化,编辑器插件开发者,只要正确调用语言服务就可以。
LSP 是微软提出的一个协议,旨在让不同语言服务提供一致的接口,这样每个编辑器只要一个符合协议插件就能对接各种语言,每种语言也只需要一个优秀的语言服务,这样总数就变成了编辑器数量加上语言服务数量。正所谓集中精力办大事。
这个生态一旦建立起来,将彻底改变语言类插件的存在形式,本文作者非常看好这种模式,但目前这个概念的实现仍然有一定实验性质,各种实现也尚未完善,因此没有在正文中介绍,而选择在附录中推荐相关的插件让读者体验。
What’s Next for Neovim
这一章最有趣的就是将 Neovim 嵌入其他编辑器,一改以往通过插件模拟 vim 按键的方式,直接将一个 vim 实例嵌入到另一个编辑器里,实现 100% 的 vim 功能,连插件都能用上,但是两个编辑器的完美结合还是面临非常多的问题,个人认为是不可能的任务。