Vim 中的多语言编程(或如何在 Vim 中获得任何语言的良好开发体验)
本文最初发表于Barbarian Meets Coding。
Vim 开箱即用地支持大量语言,例如语法高亮和合理的缩进规则。然而,即使是像 JavaScript 这样的热门语言,你也无法获得出色的自动补全、语义导航、诊断等等功能,而这些功能在当今时代或许已经是你所期待的了。而对于 Svelte、JSX 或 TSX 等更现代或小众的语言,语法高亮功能甚至都不存在。
在本文中,您将学习如何设置 Vim,以便使用 JavaScript 等流行编程语言和 TypeScript、Svelte 和 JSX 等现代语言获得更好的开发人员体验。
如何在 Vim 中获得任何语言的良好开发体验
每当您想要在 Vim 中添加对新语言的支持时,理想情况下您的目标应该是至少设置以下两件事:
- 适合新语言的语法高亮和缩进
- 类似 IDE 的功能,如自动完成、语义导航、诊断等......可以让你使用该语言时更加轻松
在 Vim 中实现这两个目标的最简单方法是利用丰富的 Vim 插件生态系统。
1. 语法高亮
为了在 Vim 中为新语言添加语法高亮显示,您可以遵循以下任一方法:
- 为您选择的语言安装一个语法高亮插件(例如,Svelte 的vim-svelte , TypeScript 的yats.vim )。
- 安装vim-polyglot插件。vim -polyglot是 Vim 的一个语言包,它为多种编程语言提供语法高亮和缩进功能。这个插件的编写方式是延迟加载,因此不会增加 vim 启动初始化的时间。
- 编写您自己的语法高亮插件或覆盖现有插件的部分内容。
你可以自由选择以上任何一种,但我个人更喜欢确切地了解我的 vim 配置,并对其进行一定程度的控制。这也是我选择为每种要使用的语言分别安装插件的主要原因。
VimAwesome.com是寻找新语言插件的好地方。它是一个 Vim 插件目录,你可以在其中搜索关键词(例如 TypeScript),并查看该关键词最热门插件的排名。例如,这里列出了所有可用的 TypeScript 插件,涵盖语法插件、自动补全、格式化、代码检查等。
不知道如何在 Vim 中安装插件?
请参阅本文以了解如何配置 vim并使用插件扩展它。
我尝试过vim-polyglot,但发现它有太多缺点,不太好用:
- 从试用情况来看,该插件仅包含从其他语言插件中抽取的语法高亮和缩进功能。也就是说,像映射和命令这样通常非常有用的附加功能并未包含在内。这意味着,如果您想使用这些附加功能,就需要在 vim 配置中同时安装 vim-polyglot 和原有的插件(这多少违背了语言包的初衷)。
- 如果您发现针对某种语言的另一个插件比 vim-polyglot 附带的插件更有用,则需要停用该插件并安装您选择的插件。
最后,编写我自己的自定义语法突出显示不是我的第一选择,但它在以下情况下很有用:
- 当没有针对特定语言的可用插件时(我还没有遇到过这种情况)
- 当某种语言的语法高亮显示不够好时
- 当您编写一个提供其自己特殊 UI 的插件时,您希望它看起来很漂亮(例如,想象一下在 Vim 中编写一个音乐播放器,并且您想要突出显示专辑)。
太棒了!现在,我们已经为想要尝试的新语言提供了语法高亮和合适的缩进。这为你提供了一个基本的开发环境,你可以在这里获得语言语法各个组成部分的可视化反馈,以及所有让 Vim 成为优秀编辑器的强大功能。
下一步是什么?添加类似 IDE 的功能!
2.类似IDE的功能
我的职业生涯始于 .NET 生态系统中的软件开发,使用 C# 编写并使用 Visual Studio 和 ReSharper 等工具,因此我一直对强大的功能非常着迷,例如编辑器内诊断、语句完成、智能重构、语义代码导航、自动代码修复、项目范围重命名等...几年前,将所有这些功能都融入 Vim 是非常困难的,但今天,随着支持 LSP 1 的语言服务器数量的不断增加, 我们可以在 Vim 中享受所有这些功能。
市面上有很多插件可以提供这类功能,但在我尝试过的所有插件中,我发现coc.nvim(或称Conquer of Completion)提供了最佳的支持,并且在设置简便性和功能丰富性之间取得了良好的平衡。为了针对特定语言设置 coc.nvim,您需要遵循以下两个步骤:
- 使用你最喜欢的插件管理器在 Vim 中安装coc.nvim插件。你只需安装一次。
- 安装特定语言的扩展(例如,您可以运行
:CocInstall coc-tsserver
命令为 JavaScript 和 TypeScript 提供类似 IDE 的支持)。许多流行的编程语言都提供丰富的扩展。安装新语言的扩展时,建议查看该扩展的文档,了解是否需要进行一些额外的配置(例如,coc-tsserver开箱即用,但文档提供了有关如何进一步配置的更多信息)。
安装 coc.vim 后,只要您打开与扩展程序匹配的文件,它就会立即激活。例如,如果您安装了 coc-tsserver,那么每次打开 TypeScript 文件时,coc.nvim 都会自动激活。将 coc.nvim 的状态信息添加到 Vim 的状态栏中会很有用。这样,每当您打开文件时,您都能立即收到 coc.nvim 是否正常工作的反馈。或者,您可以使用以下:CocInfo
命令获取有关 coc.nvim 当前状态的详细信息:
## versions
vim version: NVIM v0.4.2
node version: v12.6.0
coc.nvim version: 0.0.74-3712edf331
term: iTerm.app
platform: darwin
## Messages
## Output channel: tsserver
[Info - 12:55:23 PM] Started TSServer
{
"path": ".../.config/coc/extensions/node_modules/coc-tsserver/node_modules/typescript/lib",
"_pathLabel": "",
"_api": {
"versionString": "3.7.3",
"version": "3.7.3"
}
}
每个扩展都充当功能源,您可以使用不同的 coc.nvim 命令访问这些功能源。例如:
- 您可以使用
:CocInstall {extension}
安装扩展 :CocList
允许您访问来自不同来源的列表。例如::CocList extensions
列出已安装的扩展:CocList outline
为您提供当前文件的概要(类似于您在 VSCode 或 Visual Studio 等编辑器中获得的概要):CocList snippets
为您提供可用片段的列表:CocList diagnostics
为您提供错误和警告列表
:CocCommand {command}
允许你运行源提供的命令。例如::CocCommand snippets.editSnippets
将您发送到当前文件语言的片段文件:CocCommand tsserver.executeAutoFix
修复当前存在的所有可自动修复的错误(例如缺少导入和错误实现的接口)
:CocAction
允许您对光标下或当前选定的代码执行操作。一些非常有用的操作,例如重命名、添加缺失的导入、重构(例如提取函数或常量)、提取代码片段等。:CocFix
允许您应用语言服务器推荐的修复程序
你可以在 GitHub 上找到更多关于如何设置 coc.nvim、如何安装扩展、如何配置以及如何提供合理映射的最小化配置的信息。强烈推荐后者,它包含一些实用的绑定,例如:
" Use `[g` and `]g` to navigate diagnostics
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)
" Remap keys for gotos
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)
coc.nvim 还附带了全面的文档,您可以使用始终方便的帮助命令 :h coc-nvim
直接在 vim 中找到它。
其他非常成熟的 coc.nvim 替代品包括YouCompleteMe、Ale、Deoplete和vim-lsp 。你还可以在vimawesome.org上找到完整的类 IDE 插件列表。
无论你最终选择哪个插件,我都希望你下次配置 Vim 使用新语言时,都能获得绝佳的开发体验。保重,祝你拥有美好的一天。
如果您采用不同的方法或使用不同的插件集,请随时发表评论!:D
-
LSP 代表语言服务器协议 (Language Server Protocol)。(摘自维基百科)它是一个基于 JSON-RPC 的开放协议,用于文本编辑器或 IDE 与提供特定编程语言功能的服务器之间。该协议的目标是允许独立于任何编辑器或 IDE 实现和分发编程语言支持 。↩