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 的依赖

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

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 管理插件,打开了语法加亮。

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

 

类别: Vim. 标签: . 阅读(191). 订阅评论. TrackBack.

Leave a Reply

Be the First to Comment!

avatar
wpDiscuz