最近滚了以下系统(arch),可能是go升级了,导致原本的go开发环境没有补全了(也可能是因为我把YCM重新编译了一次,把--go-completer也加上了)。我本地维护了两个GOPATH,一个自己平时用,一个给公司的项目用,两个环境都没有补全了。

google了一下发现负责golang补全的服务nsf/gocode似乎自1.10以后不维护了,转到了一个叫做mdempsky/gocode的项目。

YCM本身支持go的补全,但是用的gocode是那个不维护的版本,网上有个方法是手动修改,使用mdempsky/gocode,见这里. 实际上,ycmd已经修复了这个问题,迁移到了mdempsky/gocode,只是ycm还没有更新ycmd这个submodule而已。因此,可以通过以下的方法单独更新ycmd:

cd YouCompleteMe/third_party/ycmd
git checkout master
git pull
git submodule update --init --recursive
./build.py --go-completer

ycmd虽然使用了最新的gocode,但是gocode本身还有一个问题,其表现为如果将GOPATH改为一个新的值以后,gocode就只有对标准库的补全而没有对第三方包的补全了。这个在这个gocode的issue中有提到,其中说到了要在gocode启动服务和客户端请求的时候加入-source选项,但是这个选项会极大的降低补全速度,因此gocode的开发者拉了一条cache分支,意图提高性能。ycmd用的还是gocodemaster分支,因此如果有必要,可以手动的修改ycmd/completers/go/go_completer.py,在两个地方都加入-source选项即可(当然,性能很低)。

2018-11-07更新

现在好像gocodecache分支已经合并到master,我重新安装了YCM并且编译,但是go的自动补全还是无法工作。我干脆在YCM编译的时候不添加go的选项,直接使用vim-go提供的gocode,结果竟然OK了。但是,补全速度很慢。。。

2018-11-08更新

上边“不能工作”是发生在我的某个go workspace里的,具体现象是不能补全外部包。我使用这个workspace是通过改变GOPATH来设置的。但是,我设置GOPATH的时候在最后加了一个/,是这个/导致了YCM的go completer无法补全外部包。因此,现在我的配置是使用YCM的go补全。

2018-12-06更新

最近在用go1.11的go module功能,然后我把我的$GOPATH/pkg/linux_amd64都清了,只剩下$GOPATH/pkg/mod

然后,我更新了最新的YCM,然后我就再一次无法补全外部包了。。。

经过一番google,我在mdempsky/gocode的issue: Problem with completion for external/vendores packages since 1.11 找到了原因。这个大姐说现在ycmd使用的mdempsky/gocode是不支持go modules,她自己fork了一个新的项目叫做stamblerre/gocode却支持。

所以,问题就变成了怎么样让ycmd使用这个stamblerre/gocde来替代以前的那个mdempsky/gocode.

整个过程如下:

$ cd /home/magodo/.vim/plugged/YouCompleteMe/third_party/ycmd/third_party/go/src/github.com/
$ git clone git@github.com:stamblerre/gocode.git
$ export GOPATH=$HOME/.vim/plugged/YouCompleteMe/third_party/ycmd/third_party/go
$ cd /home/magodo/.vim/plugged/YouCompleteMe/third_party/ycmd/third_party/go/src/github.com/stamblerre/gocode

# 下载新版本的gocode的依赖
$ go get golang.org/x/tools/go/packages

# 修改: /home/magodo/.vim/plugged/YouCompleteMe/third_party/ycmd/build.py
# 只要将mdempsky改成stamblerre即可

# 修改:/home/magodo/.vim/plugged/YouCompleteMe/third_party/ycmd/ycmd/completers/go/go_completer.py
# 1. 将mdempsky改成stamblerre
# 2. 将启动参数和ComputeCandidatesInner中加上`-source`选项

遇到的问题:

  1. 前几次补全的会报: No completions found. 重试几次就可以了 issue

2019-2-19更新

2019-04-25更新

貌似vim-go现在支持使用gopls进行自动补全和跳转了,gopls的性能比gocode好多了(我本地的使用gocode经常莫名其妙跑满cpu),所以我准备完全使用vim-go,ycm仅做自动弹出联想的功能。

更新到最新的vim-go,然后更新Go的二进制文件(GoUpdateBinaries)。最后,在~/.vimrc中加入:

let g:go_def_mode = 'gopls'

因为,vim-go默认使用guru做跳转。