gocode——VIM 和 Emacs 的 golang 代码自动补全
虽然 golang 自身提供了 VIM 的语法高亮之类的脚本,但 autocompletion 并没有官方解决方案。无意之中发现 gocode 这个支持 VIM 和 Emacs 的 autocompletion daemon。
这里有个Flash 动画演示,展示了 gocode 的强大。我得说,用过之后,感觉速度确实够快。
下面是来自官方的部分介绍:
用于 Go 编程语言的自动补全守护进程
Gocode 是可以整合在如 vim 和 emacs 这样的代码编辑器中的辅助工具。它提供了一系列的高级功能,包括:
- 上下文敏感的自动补全
(译注:残念,还真是“一”系列啊!好吧,但是说实话单就这一个功能就很好用了。)
由于使用 client/server 架构的缓存形式,所以被称为守护进程。这使得自动补全非常快。通常,在缓存生效的情况下自动补全时间在 30ms,一般不会察觉这个延迟。
gocode 的文档对安装说得很是详细,我这里仅对 VIM 做个简单的说明。另外,由于 golang 的 pkg 还不够稳定,不同版本可能会出现编译错误。实际上在我安装过程中,还是 fix 了 gocode 的兼容问题,才顺利安装的。下面会做详细说明。
首先,我假设你已经安装好了 go,设置好了 $GOBIN,并将其加入了 $PATH中。使用 8g -V 查看 go 版本,确保版本是【8g version weekly.2011-03-15 7807】。版本不同,在一些 go 的 pkg 的命名、方法等都会有不同。这可能会引起你在编译 gocode 时报错。
从 github 上获取 gocode 代码:
git clone git://github.com/nsf/gocode.git
进入 gocode 目录,编译并安装:
cd gocode&make install
在我的编译过程中,出现如下错误:
mikespook@mikespook-desktop:~/Desktop/gocode$ make install 8g -o _go_.8 gocode.go autocompletefile.go package.go autocompletecontext.go server.go rpc.go decl.go apropos.go scope.go ripper.go config.go declcache.go os_posix.go autocompletefile.go:230: undefined: ast.TypeCaseClause autocompletefile.go:232: undefined: ast.TypeCaseClause autocompletefile.go:246: typechecking loop make: *** [_go_.8] 错误 1
这是由于 go/ast 中的 TypeCaseClause 已经改名为 CaseClause。用下面的 patch 即可解决这个问题:
diff --git a/autocompletefile.go b/autocompletefile.go index e08e161..c0c83c4 100644 --- a/autocompletefile.go +++ b/autocompletefile.go @@ -227,17 +227,17 @@ func (f *AutoCompleteFile) processTypeSwitchStmt(a *ast.TypeSwitchStmt) { } } - var lastCursorAfter *ast.TypeCaseClause + var lastCursorAfter *ast.CaseClause for _, s := range a.Body.List { - if cc := s.(*ast.TypeCaseClause); f.cursor > f.fset.Position(cc.Colon).Offset { + if cc := s.(*ast.CaseClause); f.cursor > f.fset.Position(cc.Colon).Offset { lastCursorAfter = cc } } if lastCursorAfter != nil { if tv != nil { - if lastCursorAfter.Types != nil && len(lastCursorAfter.Types) == 1 { - tv.Type = lastCursorAfter.Types[0] + if lastCursorAfter.List != nil && len(lastCursorAfter.List) == 1 { + tv.Type = lastCursorAfter.List[0] tv.Value = nil } f.scope.addNamedDecl(tv)
完成后,安装程序会自动将编译好的 gocode 可执行文件复制到 $GOBIN 目录中。所以请务必确保 $GOBIN 设置正确。
对于 VIM 来说:
首先确保 $GOROOT/misc/vim 中的 Go VIM 脚本正确安装配置。可参考我的 vim 配置:https://bitbucket.org/mikespook/foobar/src/b7dbcbdbf3dd/vim/
然后安装 gocode 的 vim 脚本,可以简单执行 gocode 提供的 shell 脚本:
cd gocode/vim && ./update.bash
实际上,这个脚本做了以下工作:
#!/usr/bin/env bash mkdir -p ~/.vim/{autoload,ftplugin} cp autoload/gocomplete.vim ~/.vim/autoload cp ftplugin/go.vim ~/.vim/ftplugin
确保 vim 启用了 filetype 插件,.vimrc 中应当有:
filetype plugin on
好了,用 现在可以呼出 go 语言的自动补全了。
我为了方便,将 Ctrl+Space 映射为自动补全快捷键:
imap <C-Space> <C-x><C-o>
由于我不用 Emacs,所以 Emacs 党请绕道官方文档吧……;)
【最新更新】
根据作者提供的线索,使用 golang 的 weekly 版本是不需要打补丁的。所以,正确的 golang 安装版本是【3b4e9c85b643 weekly/weekly.2011-03-15】
hg up -r weekly hg id
在 7787 版本 CaseClause 才与 TypeCaseClause 合并到一起,成为 CaseClause。