Vim 中 Java 代码自动完成 - vim-javacomplete2

用 Java 进行编码基本还是离不开 IntelliJ IDEA 或 Eclipse, 看别人完全用 Vim 进行 Javascript 项目编程很是眼红,估摸着能不能把 Vim 打造成一个更强的 Java IDE。语法高亮是不在话下,最主要是给它加上自动完成功能,不光对当前类,项目中的方法或变能能提示,而且必须像 Java IDE 那样理解所有的项目依赖。这就是今天试用的一个 Vim 插件 vim-javacomplete2,另种可能更好的方案 YouCompleteMe + Eclim 还会再研究。

提到 Vim 的自动完成功能,有必要了解 Vim 自带的提示功能

  1. ctrl - n/p:  Vim 根据当前缓冲区的关键字来提示,像 Sublime 或 Visual Studio Code 中的关键字提示
  2. ctrl - x 进行自动自动完成模式,接着一些操作如 ctrl - l/n/t/i 完成类似于 ctrl - n/p 的操作; ctrl - k 能基于字典自动完成,完整按键是 ctrl - x ctrl -k
  3. ctrl - x ctrl - o, 这个单独拉出来,是使用 Vim 的 Omni Completion 功能来自动完成,因为将要用到的 vim-javacomplete2 就依赖于这个功能

除 YouCompleteMe 插件外,另外还两个 Vim 下的自动完成插件是 NeoCompleteVimCompleteMe

摘要部分算是说完了,现在开始体验 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 的依赖

再次启动 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 文件是自动解析的,也可以用

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 来弹出提示, 需要两次组合按键, 为了简化操作还能利用其他两个插件 AutoComplPopSuperTab. 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 管理插件,打开了语法加亮。

用 vim -u autocomplete.vim +PluginInstall +qallvim -u autocomplete.vim 进行 Vim 执行命令以 :PluginInstall 安装好了所有插件后,以后启动 Vim 带上参数 -u autocomplete.vim 就可以使用 Java 代码的提示功能。

 

类别: Vim. 标签: . 阅读(2,658). 订阅评论. TrackBack.

2
Leave a Reply

avatar
1 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Yanbinyiran Recent comment authors
yiran
Guest
yiran

您好,我想问一个问题:我刚刚按照您写的文章安装且配置了javacomplete2,实现了代码提示、也实现了针对自己添加的类库中某个类自动地添加import语句,,可是插件语法纠错却报package xxx.xxx.xxx does not existimport xxx.xxx.xxx.xxx,然而又能编译通过,这是怎么回事呢?

Yanbin
Guest
Yanbin

没碰过这个问题,现在基本上还是在 IntelliJ IDEA 中写 Java.