LSP Java backend for the Java layer

Fixes #10654

Added new backend for the Java.
This commit is contained in:
kyoncho 2018-08-21 21:47:48 +03:00 committed by Codruț Constantin Gușoi
parent 25be8ecb62
commit 862d873fa8
5 changed files with 152 additions and 6 deletions

2
.gitignore vendored
View File

@ -48,6 +48,8 @@ python-*-docs-html
/recentf
.mc-lists.el
nov-places
workspace
eclipse.jdt.ls
# Private directory
private/

View File

@ -24,6 +24,9 @@
- [[#configuration-1][Configuration]]
- [[#usage-1][Usage]]
- [[#issues][Issues]]
- [[#lsp-java][LSP Java]]
- [[#instalation][Instalation]]
- [[#configuration-2][Configuration]]
- [[#key-bindings][Key bindings]]
- [[#meghanada-1][Meghanada]]
- [[#server][Server]]
@ -58,6 +61,7 @@
- [[#refactoring-2][Refactoring]]
- [[#tests-1][Tests]]
- [[#repl][REPL]]
- [[#lsp-java-1][LSP Java]]
- [[#maven][Maven]]
- [[#gradle][Gradle]]
@ -69,6 +73,7 @@ This layer adds support for the Java language.
- [[https://github.com/mopemope/meghanada-emacs][Meghanada]] client/server (default),
- [[http://eclim.org][Eclim]] client/server,
- [[https://ensime.github.io/][ENSIME]] client/server.
- [[https://github.com/emacs-lsp/lsp-java][LSP Java]] client/server.
- Each provides:
- Auto-completion using company
- Linting using flycheck integration
@ -231,6 +236,40 @@ will suffice do the trick.
ENSIME is originally built for Scala, so support for java is not complete, in
particular refactoring doesn't work.
** LSP Java
LSP Java is the Java adapter for [[https://github.com/emacs-lsp/lsp-mode][LSP Mode]] which is the Emacs client for [[https://github.com/Microsoft/language-server-protocol][Language
Server Protocol]].
*** Instalation
Download either [[http://download.eclipse.org/jdtls/snapshots/jdt-language-server-latest.tar.gz][latest]] or [[http://download.eclipse.org/jdtls/snapshots/?d][a specific version]] of Eclipse JDT Language Server
distribution to =~/.emacs.d/eclipse.jdt.ls/server/=
If you choose to have the server installed in a different directory, set
=lsp-java-server-install-dir=
If you choose to have the server installed in a different directory, set
=lsp-java-server-install-dir=
On Linux/MacOS you could install/update Eclipse JDT Language Server via running the following commands:
#+BEGIN_SRC bash
rm -rf ~/.emacs.d/eclipse.jdt.ls/server/
mkdir -p ~/.emacs.d/eclipse.jdt.ls/server/
wget http://download.eclipse.org/jdtls/snapshots/jdt-language-server-latest.tar.gz -O /tmp/jdt-latest.tar
tar xf /tmp/jdt-latest.tar -C ~/.emacs.d/eclipse.jdt.ls/server/
#+END_SRC
*** Configuration
Specify the list of projects which will be imported in the LSP server. Note that
if project is not imported JDT server will provide only basic java support due
to lack of classpath information.
#+BEGIN_SRC emacs-lisp
(java :variables java-backend 'lsp
lsp-java--workspace-folders '(list "/path/to/project1"
"/path/to/project2"
...))
#+END_SRC
* Key bindings
** Meghanada
*** Server
@ -243,7 +282,7 @@ particular refactoring doesn't work.
| ~SPC m D k~ | Kill server |
| ~SPC m D l~ | Clear server cache |
| ~SPC m D p~ | Ping server |
| ~SPC m D r~ | Restarrt server |
| ~SPC m D r~ | Restart server |
| ~SPC m D s~ | Start server |
| ~SPC m D u~ | Update server |
| ~SPC m D v~ | Print version of the server |
@ -522,6 +561,34 @@ particular refactoring doesn't work.
| ~SPC m s r~ | send region to the REPL |
| ~SPC m s R~ | send region to the REPL and focus the REPL buffer in =insert state= |
** LSP Java
| Key Binding | Description |
|---------------+---------------------------------------|
| ~SPC m g g~ | Go to definition |
| ~SPC m g r~ | Find references |
| ~SPC m g R~ | Peek references using ~lsp-ui~ |
| ~SPC m g d~ | Goto type definition |
| ~SPC m g a~ | Search type in project |
| ~SPC m g A~ | Search type in project using ~lsp-ui~ |
| ~SPC m h h~ | Describe thing at point |
| ~SPC m e l~ | List project errors/warnings |
| ~SPC m p u~ | Refresh user settings |
| ~SPC m e a~ | Execute code action |
| ~SPC m q r~ | Restart workspace |
| ~SPC m r o i~ | Organize imports |
| ~SPC m r r~ | Rename symbol |
| ~SPC m r a i~ | Add import |
| ~SPC m r a m~ | Add unimplemented methods |
| ~SPC m r c p~ | Create parameter |
| ~SPC m r c f~ | Create field |
| ~SPC m r e c~ | Extract constant |
| ~SPC m r e l~ | Extract local |
| ~SPC m r e m~ | Extract method |
| ~SPC m c c~ | Build project |
| ~SPC m a n~ | Actionable notifications |
| ~SPC m =~ | Format code |
** Maven
| Key Binding | Description |

View File

@ -14,8 +14,8 @@
(spacemacs|define-jump-handlers java-mode)
(defvar java-backend 'meghanada
"The backend to use for IDE features. Possible values are `eclim', `ensime'
and `meghanada'.")
"The backend to use for IDE features. Possible values are `eclim', `ensime',
`meghanada' and `lsp'.")
(defvar java--ensime-modes '(java-mode)
"Modes using ensime. Mainly used to define ENSIME key bindings.")

View File

@ -29,21 +29,24 @@
(pcase java-backend
(`meghanada (spacemacs//java-setup-meghanada))
(`eclim (spacemacs//java-setup-eclim))
(`ensime (spacemacs//java-setup-ensime))))
(`ensime (spacemacs//java-setup-ensime))
(`lsp (spacemacs//java-setup-lsp))))
(defun spacemacs//java-setup-company ()
"Conditionally setup company based on backend."
(pcase java-backend
(`meghanada (spacemacs//java-setup-meghanada-company))
(`eclim (spacemacs//java-setup-eclim-company))
(`ensime (spacemacs//java-setup-ensime-company))))
(`ensime (spacemacs//java-setup-ensime-company))
(`lsp (spacemacs//java-setup-lsp-company))))
(defun spacemacs//java-setup-flycheck ()
"Conditionally setup flycheck based on backend."
(pcase java-backend
(`meghanada (spacemacs//java-setup-meghanada-flycheck))
(`eclim (spacemacs//java-setup-eclim-flycheck))
(`ensime (spacemacs//java-setup-ensime-flycheck))))
(`ensime (spacemacs//java-setup-ensime-flycheck))
(`lsp (spacemacs//java-setup-lsp-flycheck))))
(defun spacemacs//java-setup-flyspell ()
"Conditionally setup flyspell based on backend."
@ -288,3 +291,36 @@
(when (s-matches? (rx (+ (not space)))
(buffer-substring (line-beginning-position) (point)))
(delete-horizontal-space t)))
;; LSP Java
(defun spacemacs//java-setup-lsp ()
"Setup LSP Java."
(if (configuration-layer/layer-used-p 'lsp)
(progn
(require 'lsp-java)
(require 'company-lsp)
(lsp-java-enable))
(message "`lsp' layer is not installed, please add `lsp' layer to your dotfile.")))
(defun spacemacs//java-setup-lsp-company ()
"Setup lsp auto-completion."
(if (configuration-layer/layer-used-p 'lsp)
(progn
(spacemacs|add-company-backends
:backends company-lsp
:modes java-mode
:append-hooks nil
:call-hooks t)
(company-mode))
(message "`lsp' layer is not installed, please add `lsp' layer to your dotfile.")))
(defun spacemacs//java-setup-lsp-flycheck ()
"Setup LSP Java syntax checking."
(if (configuration-layer/layer-used-p 'lsp)
(when (spacemacs/enable-flycheck 'java-mode)
(require 'lsp-ui-flycheck)
(lsp-ui-flycheck-enable nil)
(flycheck-mode))
(message "`lsp' layer is not installed, please add `lsp' layer to your dotfile.")))

View File

@ -29,6 +29,7 @@
maven-test-mode
(meghanada :toggle (not (version< emacs-version "25.1")))
mvn
(lsp-java :requires lsp-mode lsp-ui company-lsp)
org
))
@ -428,6 +429,46 @@
"x:" 'meghanada-run-task))))
(defun java/init-lsp-java ()
(use-package lsp-java
:defer t
:config
(progn
;; key bindings
(dolist (prefix '(("mc" . "compile")
("mg" . "goto")
("mr" . "refactor")
("mq" . "lsp")))
(spacemacs/set-leader-keys-for-major-mode 'java-mode
"gg" 'xref-find-definitions
"gr" 'xref-find-references
"gR" 'lsp-ui-peek-find-references
"ga" 'xref-find-apropos
"gA" 'lsp-ui-peek-find-workspace-symbol
"gd" 'lsp-goto-type-definition
"hh" 'lsp-describe-thing-at-point
"el" 'lsp-ui-flycheck-list
"pu" 'lsp-java-update-user-settings
"ea" 'lsp-execute-code-action
"qr" 'lsp-restart-workspace
"roi" 'lsp-java-organize-imports
"rr" 'lsp-rename
"rai" 'lsp-java-add-import
"ram" 'lsp-java-add-unimplemented-methods
"rcp" 'lsp-java-create-parameter
"rcf" 'lsp-java-create-field
"rec" 'lsp-java-extract-to-constant
"rel" 'lsp-java-extract-to-local-variable
"rem" 'lsp-java-extract-method
"cc" 'lsp-java-build-project
"an" 'lsp-java-actionable-notifications
"=" 'lsp-format-buffer)
(setq lsp-highlight-symbol-at-point nil
lsp-ui-sideline-update-mode 'point
lsp-eldoc-render-all nil
lsp-java-completion-guess-arguments t)))))
(defun java/init-mvn ()
(use-package mvn
:defer t