用 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 的依赖
1 2 3 4 5 |
<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
来弹出提示, 需要两次组合按键, 为了简化操作还能利用其他两个插件 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 管理插件,打开了语法加亮。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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 +qall
或 vim -u autocomplete.vim
进行 Vim 执行命令以 :PluginInstall
安装好了所有插件后,以后启动 Vim 带上参数 -u autocomplete.vim
就可以使用 Java 代码的提示功能。
[…] 在编译过程中始终觉得手打代码过于复杂,没有当时使用的C语言编译器中类似的自动补全功能。我搜索了vim使用手册发现一些固定短语可以通过ctrl+N或ctrl+P补全,但是还是有很多语法不能补全。搜索到了vim插件YouCompleteMe+Eclim以及JavaComplete有java语言补全功能。但是下载及配置还需要再尝试学习。链接:1.YCM:https://www.cnblogs.com/luhouxiang/p/5809133.html2.Javacomplete2:https://yanbin.blog/vim-java-autocomplete-with-vim-javacomplete2/ […]
您好,我想问一个问题:我刚刚按照您写的文章安装且配置了javacomplete2,实现了代码提示、也实现了针对自己添加的类库中某个类自动地添加import语句,,可是插件语法纠错却报package xxx.xxx.xxx does not existimport xxx.xxx.xxx.xxx,然而又能编译通过,这是怎么回事呢?
没碰过这个问题,现在基本上还是在 IntelliJ IDEA 中写 Java.