本文来自依云's Blog,转载请注明。
我一直没有使用 Vim 插件管理插件。我没数过,但是三四个实现肯定是有的。我不喜欢它们的原因,一是迁移成本,二是依赖太巨大:我在一个新环境上配置 Vim 时,我不希望必须访问 GitHub,而且是几十个 clone,这得多慢啊……而且这还意味着它需要有 git,能够联网,DNS 解析正常,等等。这些在各种奇怪的环境里都不容易实现啊。
后来,Vim 8 出来了,内建 packages 管理功能。不愧是官方出品,没有奇怪的依赖。插件来源用户随意,把文件放对位置就可以了。
然后,我又遇见了 git-subrepo,给了 submodule 以外的选择。简单来说它有点 vendoring 的感觉,把第三方仓库放自己里边了。如果目标没有安装 git-subrepo,也没有关系,所有文件都在这儿了,只是没有与第三方仓库同步的能力了而已。
而且,git-subrepo 和 git-notes 类似,它使用额外的 ref 来存储第三方仓库的数据。但与 notes 不同的是,subrepo 已经存在于第三方仓库了,所以我不必把 subrepo 的 ref 推得到处都是,还在每个地方 fetch 下来浪费空间。万一第三方仓库没了或者搬家了,关系也不大,反正我用的代码还在我的仓库里呀。
git-subrepo 是很棒的「pay as you go」设计呢。
有了这两个东西,我就可以尝试一下新的 Vim 插件管理方案了。刚好我需要安装 vim-go,所以就开始尝试啦~
于是开始安装:
cd ~/.vim git subrepo clone git@github.com:fatih/vim-go.git pack/go/start/vim-go
Vim 8 会自动加载pack/*/start/*
下的东西(它下边的目录跟原来的 ~/.vim 布局和用法一样),:packadd
命令会加载pack/*/opt/*
下的东西。
然后记得设置环境变量。首先是 GOPATH,这是放所有 Go 的源码和编译出来的库和二进制文件的地方。Go 1.8 开始默认 ~/go,但是也需要设置 GOPATH,不然 vim-go 不认。然后得把 $GOPATH/bin 加到 PATH 里去。
确认环境变量设置好之后,打开一个新的 Vim,执行:GoInstallBinaries
命令安装依赖。如果中途有神秘失败的,可以把地址拷出来,在命令行里手动调用 go install xxx 安装。部分软件需要访问 Google 的服务器,国内用户注意自行配置一下国际互联网的访问。
安装好之后就有补全、自动格式化、自动加 imports、重命名什么的啦。具体看 vim-go 的文档吧。不过有几点我稍微调整了一下。
我使用 syntastic 来进行代码检查。它默认不启用针对 Go 的检查,需要配置一下:
let g:syntastic_go_checkers = ['go', 'golint']
syntastic 的显示效果比 :GoMetaLinter 命令使用 quickfix 窗口的要好很多哦。
另外不要使用 :GoLint 这个命令,它连非常简单的未定义变量都检查不出来。
而且 vim-go 好 chatty,连跳转到定义都要用显眼的颜色来报告一下成功了……安静真的很珍贵的说。
:GoDoc 我还不会用,因为它报错了:
vim-go: gogetdoc: couldn't get package for .../t.go: can't find package containing .../t.go^@
写 Go 的时候,特别是调试的时候,加句fmt.Printf
得记得修改 import,不需要了还得再去删掉才能通过编译……Go 编译是快了,但是处理未使用变量比等待编译结束更令人心烦啊。
有了 goimports 这个命令之后,不需要在开发过程中反复手动修改导入的包列表了。它可以自动添加和删除 import。不过 vim-go 并没有提供在保存时自动调用的支持,所以我就自己动手了。
首先禁用掉它自己的自动格式化:
let g:go_fmt_autosave = 0
然后,是我自己设置的自动命令:
if !exists('#GoImports') && executable("goimports") augroup GoImports au! autocmd BufWrite *.go silent call s:GoImports() augroup END endif function! s:GoImports() let pos = getpos('.') let na = line('$') %!goimports if v:shell_error undo endif let nb = line('$') let pos[1] = pos[1] + nb - na call setpos('.', pos) endfunction
还有待提高(比如 undo 的处理),但至少能用。
Mar 10, 2017 06:32:54 PM
用插件管理器也不一定要联网,用优盘把插件内容拷贝到目标机器上也行。
而且现在的插件管理器都支持并发,下载也不慢。除非你是用优盘拷贝插件,不然自己不也得手动下载。
插件来源方面,github 和 官方的 http://www.vim.org/scripts/ 都支持,自定义第三方来源也支持。
我也试过手动管理插件,实在繁琐,尤其是更新插件。
用插件管理器的话,一份 vimrc 文件就走天下了。
Mar 10, 2017 06:41:24 PM
我觉得插件管理器方便一些,如果有一个新的环境,先配置一下翻墙的环境,然后就可以进入vim一键安装所有插件了。插件一些都不大,clone速度感觉可以接受。好处是可以只管理vimrc文件,不用关心其他的东西。
Mar 10, 2017 08:58:13 PM
不考虑更新的话,我之前的方式只需要 clone 约 7M 的数据。如果没有 git 直接下载 tar 包解压也能用。
Mar 10, 2017 09:03:06 PM
我的 dotvim 目前只有 7M 左右,因为它不包含其它插件的历史。而且并发并不快,会受限于带宽,而且来来回回的沟通很费时间的。
更新确实是个令人头疼的问题,所以我也在尝试着用 subrepo 来管理了(不过这样就不能支持 vim <= 7.4,所以我目前只会把非关键、常用的插件放到 subrepo 里去)。
不过还好,因为我不常更新插件。更新之后行为变了,break 掉自己的使用习惯或者需要重新配置是很烦的。
我可不想一份 vimrc 依赖整个天下。有 http://left-pad.io/ 这个前车之鉴呢。我依旧会把所有我用到的文件全部放在自己的仓库里,然后向多个上游推送。
Mar 11, 2017 06:01:26 AM
依云也开始写go了呀
我也喜欢用syntastic,不过我是用gometalinter做checker:
let g:syntastic_go_checkers=['gometalinter']
let g:syntastic_go_gometalinter_args=['--fast','--disable=gocyclo','--disable=gas','--disable=goconst']
Mar 13, 2017 11:06:17 AM
我现在的配置文件目前还只是一份vimrc, 通过Vundle来管理插件。 配置新环境是慢了些, 毕竟是clone所有仓库~ (你也开始写go啦~ 赞赞赞
Oct 24, 2018 02:59:11 PM
packadd用起来也比较麻烦啊。我先从vim-plug用用看。
```
A package directory contains two sub-directories:
start/ - contains plugins that will be automatically loaded
opt/ - contains plugins that are loaded on demand with :packadd
It may seem a bit complicated, but in practice all you have to do is add your plugin here:
↓ package name
~/ .vim / pack / bundle / start / some-plugin
↑ packages dir ↑ plugin dir
```
Oct 24, 2018 03:22:42 PM
再补充一下,vim-plug等插件来管理插件用起来比较方便。我之前除了配置文件外不用任何插件,现在由于需要对plantuml语法高亮支持安装龙个插件管理,packadd好像要把文件拷贝到.vim下的目录,这个操作后续如果频繁的化会比较机械。而且功能上不如插件管理的顺手吧。
P.S我最近打算从VSCODE等编辑器转到VIm+插件上,开发继续用重型IDE如 jetbrain全家桶等。觉得VSCODe用起来不如IDEA好用,编辑也不如VIM好,VScode插件对VIM支持的不是很好,用起来挺变扭,经常VIM光标前后置。卸载之。
Oct 24, 2018 03:36:36 PM
我主要是想把文件放同一仓库中,同时不带第三方插件的历史。省时间和空间,同时不任何特定的第三方,提高可用性。