Probably about a year ago, I used eclim to create a Java development environment with NeoVim.
This eclim is quite high performance because it starts Eclipse in the background and provides a Java development environment, but it requires a workspace like Eclipse, and Eclipse starts up in the background, so it is heavy even though it is Vim, installation is There were many painful parts such as annoying and difficult to automate, so I erased them with almost no use.
So, after all, I used the IDE when writing Java, but recently there is a Java LSP called eclipse.jdt.ls. I found it.
For me during the campaign to replace the development environment with LSP
"It looks like the official eclipse plugin, and it seems that the environment construction can be automated, and this won (idiot)"
I tried to build an environment with a similar feeling.
After all, I couldn't beat the IDE, but I was quite satisfied with it, so I'll introduce it.
I'm using NeoVim, but I should be able to build an environment with normal Vim in the same way.
LSP is an abbreviation for Language Server Protocel
, which is a specification released by Microsoft in June 2016.
What exactly is this? It defines common specifications for providing functions such as code completion and error analysis required for the IDE as a service.
By standardizing the specifications in this way, the IDE function can be used in any environment as long as there is an LSP language implementation and the editor used has an LSP client.
LSP is described in detail in this article, and the specifications are published on the official website and GitHub, so if you are interested, please have a look.
In addition, the implementation for each language and the client for each editor are summarized below.
In this environment construction, I tried to create a Java development environment using ʻeclipse.jdt.ls, which is a Java implementation of this LSP, and
LanguageClient-neovim`, which is NeoVim's LSP client.
dein.vim The one who doesn't know this person is said to be Moguri (self-examination). A plug-in management tool developed by Mr. Shougo, also known as Dark Minou. It is introduced in various places and the explanation is omitted.
Please refer to here for details.
deoplete.nvim A code completion plugin also developed by Shougo. I don't need to talk about it now either. (suitable)
I will throw the details in another article.
eclipse.jdt.ls
Java implementation of LSP mentioned above. The leading role of this time, part 1.
When NeoVim starts up, it starts up automatically, and by exchanging messages with LanguageClient-neovim
, which will be described later, it is a hateful guy who blows the wind of IDE into NeoVim.
The startup speed and memory usage are much better than eclim, and the installation is easy enough to automate for the time being.
LanguageClient-neovim The LSP NeoVim client mentioned above. The leading role of this time, part 2.
Code completion, code format, syntax check, document display, definition source jump, etc., which seems to be the minimum necessary for coding can be done by preparing this guy and LSP for each language, the best squid guy ..
In my case, I don't use syntax check and code format because I have another plugin do it.
There is also vim-lsp developed by an MS employee (I think I heard it somewhere), but it supports deoplete. I'm using this. Many of the stars on GitHub are Language Client-neovim.
By the way, the name says neovim
, but it seems that it can be used with ordinary vim.
I haven't tried it.
ale.vim A plugin that performs syntax checking asynchronously during coding.
** Image Image **
LanguageClient-neovim
has a similar function, but I'm using a language that doesn't support LSP, so I'm using this plugin for the purpose of unifying.
You can also customize the check tool to your liking.
In the case of Java, it seems that syntax check is performed using javac
andgoogle-java-format (described later)
[^ 1] as standard.
[^ 1]: The check with google-java-format
is executed only when the tool is installed.
vim-autoformat A plug-in that allows you to specify the formatter tool and format the code. Some default formatters are set depending on the file type, and they will be executed unless the formatter is specified.
There is a similar feature in ʻale.vim`, but I've been using this plugin for quite some time and it's still in use.
When saving the code, set it so that it will be formatted with google-java-format
described later.
google-java-format A CLI tool that can format code according to Google Java Style.
By default, it is formatted with 2-space indentation, which many Java uncles may not be familiar with.
Please be assured that you can make it 4 space indent by specifying the --aosp
option (Android Open Source Project).
That's why the explanation of plug-in settings and so on.
The settings for dein.vim
and deoplete.nvim
are not relevant this time, so they are omitted.
By the way, the directory structure looks like this.
$XDG_CONFIG_HOME/nvim
├── autoload
│ └── hook
│ ├── add
│ │ ├── ale.vim
│ │ ├── language_client_neovim.vim
│ │ └── vim_autoformat.vim
│ ├── post_update
│ │ ├── ale.vim
│ │ ├── language_client_neovim.vim
│ │ └── vim_autoformat.vim
│ └── source
│ └── deoplete.vim
├── dein
│ ├── dein.toml
│ └── dein_lazy.toml
└── init.vim
The first is the setting of the main feature, LanguageClient-neovim
.
It is defined in dein.toml
as follows.
dein/dein.toml
[[plugins]]
repo = 'autozimu/LanguageClient-neovim'
rev = 'next'
#Callback called when updating plugin
hook_post_update = 'call hook#post_update#language_client_neovim#load()'
#Callback called when the plugin is loaded
hook_add = 'call hook#add#language_client_neovim#load()'
Two functions are called at the time of update and at the time of loading to set.
When updating the plug-in, it is determined whether ʻeclipse.jdt.ls` is installed and if it is not installed, the installation process is started.
autoload/hook/post_update/language_client_neovim.vim
function! hook#post_update#language_client_neovim#load() abort
!./install.sh
" g:outher_package_path is`eclipse.jdt.ls`The directory where external tools such as are installed.
"Although omitted,`init.vim`It is set in.
let l:jdt_lsp_path = expand(g:outher_package_path) . "/jdt-lsp"
"In the specified directory`eclipse.jdt.ls`Check if exists
if !executable(l:jdt_lsp_path . "/plugins/org.eclipse.equinox.launcher_1.5.0.v20180207-1446.jar")
" `eclipse.jdt.ls`Download
!curl -o /tmp/tmp_jdt_lsp.tar.gz http://download.eclipse.org/jdtls/snapshots/jdt-language-server-0.16.0-201803280253.tar.gz
" `eclipse.jdt.ls`Create a destination directory for
call mkdir(l:jdt_lsp_path, "p")
"Unzip the downloaded file to the save destination directory
execute "!tar xf /tmp/tmp_jdt_lsp.tar.gz -C " . l:jdt_lsp_path
" tar.Delete gz file
!rm /tmp/tmp_jdt_lsp.tar.gz
endif
endfunction
Next is the setting at the time of reading. The LSP startup settings are set, and it is called every time NeoVim is started.
autoload/hook/add/language_client_neovim.vim
function! hook#add#language_client_neovim#load() abort
let g:LanguageClient_autoStart = 1 "Automatically start LSP when NeoVim starts
let g:LanguageClient_diagnosticsEnable = 0 "Syntax check OFF
let g:LanguageClient_serverCommands = {}
" `eclipse.jdt.ls`Confirmation of the existence of the data storage destination directory used in
"Create the directory if it does not exist
let l:jdt_lsp_data_dir = expand(g:outher_package_path) . "/jdt-data"
if !isdirectory(l:jdt_lsp_data_dir)
call mkdir(l:jdt_lsp_data_dir, "p")
endif
"LSP startup settings
" `configuration`Options need to be set differently for each OS.
" `eclipse.jdt.ls`In the installation directory`config_linux`, `config_mac`, `config_win`Since there is a directory called, specify the setting file path according to each OS.
let g:LanguageClient_serverCommands["java"] = [
\ 'java',
\ '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1044',
\ '-Declipse.application=org.eclipse.jdt.ls.core.id1',
\ '-Dosgi.bundles.defaultStartLevel=4',
\ '-Declipse.product=org.eclipse.jdt.ls.core.product',
\ '-Dlog.protocol=true',
\ '-Dlog.level=ALL',
\ '-noverify',
\ '-Xmx1G',
\ '-jar',
\ expand(g:outher_package_path) . '/jdt-lsp/plugins/org.eclipse.equinox.launcher_1.5.0.v20180207-1446.jar',
\ '-configuration',
\ expand(g:outher_package_path) . '/jdt-lsp/config_mac',
\ '-data',
\ l:jdt_lsp_data_dir]
"Key mapping
nnoremap <silent> K :call LanguageClient_textDocument_hover()<CR>
nnoremap <silent> gd :call LanguageClient_textDocument_definition()<CR>
nnoremap <silent> <F2> :call LanguageClient_textDocument_rename()<CR>
nnoremap <silent> <F3> :call LanguageClient_textDocument_references()<CR>
endfunction
ale.vim For Java, ale.vim uses the default settings. Since the symbol at the time of syntax check is changed, I will introduce it for the time being
dein/dein.toml
[[plugins]]
repo = 'w0rp/ale'
#Callback when loading plugin
hook_add = 'call hook#add#ale#load()'
autoload/hook/add/ale.vim
function! hook#add#ale#load() abort
let g:ale_sign_error = '✖' "Error symbol
let g:ale_sign_warning = '⚠' "Warning symbol
endfunction
vim-autoformat Similar to LanguageClient-neovim, the formatter is installed at the time of update and the plugin is set at the time of loading.
dein/dein.toml
[[plugins]]
repo = 'Chiel92/vim-autoformat'
#Callback when loading plugin
hook_add = 'call hook#add#vim_autoformat#load()'
#Callback when updating plugins
hook_post_update = 'call hook#post_update#vim_autoformat#load()'
Callback processing at the time of update looks like this
autoload/hook/post_update/vim_autoformat.vim
function! hook#post_update#vim_autoformat#load() abort
" `google_java_formatter`Check if is installed
let l:google_java_formatter = expand(g:outher_package_path) . "/google-java-format-1.5-all-deps.jar"
if !executable(l:google_java_formatter)
"Download jar if not installed
execute "!wget https://github.com/google/google-java-format/releases/download/google-java-format-1.5/google-java-format-1.5-all-deps.jar -P " . expand(g:outher_package_path)
endif
endfunction
The settings at the time of reading are like this. The formatter settings and the automatic format when saving are set.
autoload/hook/add/vim_autoformat.vim
function! hook#add#vim_autoformat#load() abort
let g:autoformat_remove_trailing_spaces = 1 "Removal of trailing spaces
" google_java_formatter startup command settings
let g:formatdef_google_java_formatter = '"java -jar ' . g:outher_package_path . '/' . g:google_java_formatter . ' - --aosp"'
"Java formatter settings
let g:formatters_java = ['google_java_formatter']
"Set for automatic code formatting when saving
call s:set_autoformat("java")
endfunction
function! s:set_autoformat(...) abort
augroup AutoIndentPreWrite
autocmd!
augroup End
for var in a:000
let l:cmd = 'autocmd AutoIndentPreWrite BufWrite *.' . var . ' :Autoformat'
execute l:cmd
endfor
endfunction
If you set it for the above, it will work like that.
** Code completion and auto-formatting **
Like this, the Lambda expression also completes the code firmly.
** Document reference and definition source jump **
It was not possible to jump the definition source to a standard package or an external library.
Mainly here. I didn't feel like Go for 1 and 2, so I thought I could go to Java, but it was unexpectedly painful.
Regarding ~~ 3, in the Maven project, the code completion of the external package and the document reference are working properly, so there may be some mistakes in the settings ...? ~~ [Addition-It worked fine in the Gradle project](It worked fine in the #gradle project)
build.gradle
plugins {
id 'java'
id 'application'
id 'eclipse'
}
mainClassName = 'App'
dependencies {
compile 'com.google.guava:guava:23.0'
testCompile 'junit:junit:4.12'
}
repositories {
jcenter()
}
After applying the ʻeclipse plugin, execute the ʻeclipseJdt
task in the project root.
$ gradle eclipseJdt
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
Now you can use the LSP function in your Gradle project.
That's why I couldn't beat the IDE ... However, it's easier to edit the code than the IDE, and the code completion is also quite nice, so it seems unlikely that you will delete it without using it at all like eclim.
Even if you think it's hard right now, it may be easier to get used to it, and maybe there is a useful tool just because you don't know it, so I'll review the environment again even in my spare time.
Recommended Posts