3
10
2017
6

在 Vim 8 里用 git subrepo 安装 vim-go

本文来自依云'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 的处理),但至少能用。

Category: Vim | Tags: vim go Git | Read Count: 4799
SpicyCat 说:
Mar 10, 2017 06:32:54 PM

用插件管理器也不一定要联网,用优盘把插件内容拷贝到目标机器上也行。
而且现在的插件管理器都支持并发,下载也不慢。除非你是用优盘拷贝插件,不然自己不也得手动下载。
插件来源方面,github 和 官方的 http://www.vim.org/scripts/ 都支持,自定义第三方来源也支持。

我也试过手动管理插件,实在繁琐,尤其是更新插件。
用插件管理器的话,一份 vimrc 文件就走天下了。

laixintao 说:
Mar 10, 2017 06:41:24 PM

我觉得插件管理器方便一些,如果有一个新的环境,先配置一下翻墙的环境,然后就可以进入vim一键安装所有插件了。插件一些都不大,clone速度感觉可以接受。好处是可以只管理vimrc文件,不用关心其他的东西。

Avatar_small
依云 说:
Mar 10, 2017 08:58:13 PM

不考虑更新的话,我之前的方式只需要 clone 约 7M 的数据。如果没有 git 直接下载 tar 包解压也能用。

Avatar_small
依云 说:
Mar 10, 2017 09:03:06 PM

我的 dotvim 目前只有 7M 左右,因为它不包含其它插件的历史。而且并发并不快,会受限于带宽,而且来来回回的沟通很费时间的。

更新确实是个令人头疼的问题,所以我也在尝试着用 subrepo 来管理了(不过这样就不能支持 vim <= 7.4,所以我目前只会把非关键、常用的插件放到 subrepo 里去)。

不过还好,因为我不常更新插件。更新之后行为变了,break 掉自己的使用习惯或者需要重新配置是很烦的。

我可不想一份 vimrc 依赖整个天下。有 http://left-pad.io/ 这个前车之鉴呢。我依旧会把所有我用到的文件全部放在自己的仓库里,然后向多个上游推送。

jiazhoulvke 说:
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']

TaoBeier 说:
Mar 13, 2017 11:06:17 AM

我现在的配置文件目前还只是一份vimrc, 通过Vundle来管理插件。 配置新环境是慢了些, 毕竟是clone所有仓库~ (你也开始写go啦~ 赞赞赞


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

部分静态文件存储由又拍云存储提供。 | Theme: Aeros 2.0 by TheBuckmaker.com