用 Java 进行编码基本还是离不开 IntelliJ IDEA 或 Eclipse, 看别人完全用 Vim 进行 javascript 项目编程很是眼红,估摸着能不能把 Vim 打造成一个更强的 Java IDE。语法高亮是不在话下,最主要是给它加上自动完成功能,不光对当前类,项目中的方法或变能能提示,而且必须像 Java IDE 那样理解所有的项目依赖。这就是今天试用的一个 Vim 插件 vim-javacomplete2 ,另种可能更好的方案 YouCompleteMe + Eclim 还会再研究。
提到 Vim 的自动完成功能,有必要了解 Vim 自带的提示功能
ctrl - n/p: Vim 根据当前缓冲区的关键字来提示,像 Sublime 或 Visual Studio Code 中的关键字提示 ctrl - x 进行自动自动完成模式,接着一些操作如 ctrl - l/n/t/i 完成类似于 ctrl - n/p 的操作; ctrl - k 能基于字典自动完成,完整按键是 ctrl - x ctrl -k ctrl - x ctrl - o, 这个单独拉出来,是使用 Vim 的 Omni Completion 功能来自动完成,因为将要用到的 vim-javacomplete2 就依赖于这个功能除 YouCompleteMe 插件外,另外还两个 Vim 下的自动完成插件是 NeoComplete 和 VimCompleteMe 。
摘要部分算是说完了,现在开始体验 vim-javacomplete2 对 Java 项目的自动完成功能。它所有完成的代码提示不仅要支持基本的 Java 类库, 当前项目的类, 手动添加的 jar 包 ,还能支持 maven , gradle 和 Eclipse 的 .classpath 文件中定义的 classpath, 这完全能应付我们实际中的项目了。实际运作也是一个 C/S 结构,这个插件会启动一个 javavi server, 用 javaparser 来解析依赖, 然后 Vim 中用 omnifunc 经 socket 连接到 javavi server 获得提示列表的。
vim-javacomplete2 的安装我是通过 Vundle 来安装这个插件的,假定你已安装好 Vundle, 那么只要在 ~/.vimrc 中加上一行
Plugin 'artur-shaik/vim-javacomplete2'
然后启动 Vim 时使用命令 vim +PluginInstall +qall 或者进入到 Vim 中执行 :PluginInstall 也行
再回到 .vimrc 文件中,指定 omnifunc 连接到该插件
autocmd FileType java setlocal omnifunc=javacomplete#Complete
体验一下简单的 Java 提示输入完 list ., 然后按下 ctrl -x ctrl -o 就得到下图中的提示,列出 list 的所有方法,以及原型

如果本插件只是对 JDK 类库有自动完成也没什么卵用,它需要真正派上用场就要能够理解像 Maven, Gradle 那些工具管理的依赖,如果你的项目是 SBT 就无法直接用了,办法还是有的, 在项目中同时放一个相同依赖的 pom.xml 文件。
对 Maven pom.xml 中依赖的自动完成假设我们在当前目录下创建了一个 pom.xml 文件,并且在依赖部分添加了一个 Google Guava 的依赖
<dependency><groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
再次启动 Vim, 然后我们试着去使用 Maven 给我们添加的依赖库,我喜欢 ImmutableMap 了,请看图

没错,这个 ImmutableMap 只能是当前项目中的 pom.xml 给我们带来的。还请注意第一行
import com.google.common.collection.ImmutableMap
还是由 Vim 自动添加上去的,所以在 Vim 中只需直接输入 ImmutableMap. , 再按下 ctrl - x ctrl - o , 不光提示方法,还自动加上 import 语句,真有点像是在 IDEA 中写代码,从此可以在 Vim 中进行快乐的 Java 编程了。
前面说过,当前目录下的 pom.xml 文件是自动解析的,也可以用
本文原始链接 http://unmi.cc/vim-java-autocomplete-with-vim-javacomplete2/ , 来自隔叶黄莺 Unmi Blog
let g:JavaComplete_PomPath = "your_path/to/pom.xml"
来自由的指定 pom.xml 文件,或者 g:JavaComplete_LibsPath 指定多个 jar 包文件, g:JavaComplete_SourcesPath 指定源代码路径,由此可知这个插件不仅仅会解析依赖,还懂编译代码。更多配置请参见 https://github.com/artur-shaik/vim-javacomplete2 。
遇到的一个坑安装好插件后,启动 Vim 时遇到过这样一个错误
No Javavi library classes found, it means that we couldn't compile it. Do you have JDK8+ installed?
Failed to compile javavi server
这是一个 Bug, https://github.com/artur-shaik/vim-javacomplete2/issues/220
进到插件安装目录 .vim/bundle/vim-javacomplete2/libs/javavi , 看到它里面的 target 目录所有者是 root, 所以把这个 target 目录删除,并在此处运行 maven compile 命令下载了该插件用到的第三方依赖, 并重新生成了 target 目录
javavi git:(master) pwd
/Users/Yanbin/.vim/bundle/vim-javacomplete2/libs/javavi
javavi git:(master) mvn compile
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Building javavi 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------Downloading: https://repo.maven.apache.org/maven2/com/github/javaparser/javaparser-core/2.5.1/javaparser-core-2.5.1.pom
..........
Downloading: https://repo.maven.apache.org/maven2/org/json/json/20150729/json-20150729.pom
..........
Downloading: https://repo.maven.apache.org/maven2/org/jmockit/jmockit/1.20/jmockit-1.20.pom
.........
[INFO] Compiling 57 source files to /Users/Yanbin/.vim/bundle/vim-javacomplete2/libs/javavi/target/classes 更好的弹出提示到目前为止我们使用 Vim 默认的 ctrl - x ctrl -o 来弹出提示, 需要两次组合按键, 为了简化操作还能利用其他两个插件 AutoComplPop 或 SuperTab . AutoComplPop 可以配置成关键字符弹出提示, 如点号, 或输入两个字符号匹配到列表时弹出。我在使用 AutoComplPop 配置时有些问题, 所以最终选择了 SuperTab.
安装 SuperTab: Vundle 管理插件的话在 ~/.vimrc 中加上
Plugin 'ervandew/supertab'
并在其中加上配置
let g:SuperTabDefaultCompletionType = '<C-x><C-o>'
记得 PlugInstall , 然后在 Vim 中就可以按一下 Tab 键实现 ctrl - x ctrl -o 的功能, 这符一些 IDE 的习惯。
一个最简单的 Vim 配置Vim 在启动的时候能够通过参数 -u autocomplete.vim 来使用 autocomplete.vim 中的配置,而不应用 ~/.vimrc 配置文件。下面是一个达到本文 Java 自动提示的最简的 Vim 配置文件 autocomplete.vim -- 应用 Vundle 管理插件,打开了语法加亮。
set nocompatiblefiletype plugin indent on
syntax on
set shell=/bin/bash
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
Plugin 'ervandew/supertab'
Plugin 'artur-shaik/vim-javacomplete2'
call vundle#end()
autocmd FileType java setlocal omnifunc=javacomplete#Complete
let g:SuperTabDefaultCompletionType = '<C-x><C-o>'
用 vim -u autocomplete.vim +PluginInstall +qall 或 vim -u autocomplete.vim 进行 Vim 执行命令以 :PluginInstall 安装好了所有插件后,以后启动 Vim 带上参数 -u autocomplete.vim 就可以使用 Java 代码的提示功能。