Java Development in emacs with lsp-mode

4. June 2018

Our team recently took ownership of a Java service, an occasion that had my team betting how long it would take me to leave the Church of emacs and return to the JetBrains fold. Thanks to Microsoft’s Language Server Protocol and the emacs-lsp project, that never happened.

For those unfamiliar with the idea of LSP clients and servers, it makes it far simpler for language developers to provide common features of an IDE, such as finding references, managing imports, jumping to symbol definitions, or providing type signatures without having to create a custom implementation for each editor.

As a Spacemacs user, there were a few modifications I had to make to the installation instructions to get lsp-mode working with company, lsp-ui, and lsp-java. Here’s the relevant portion from my init.el:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  (use-package lsp-mode
    :defer t
    :commands lsp-mode
    :init (setq lsp-before-save-edits t
                lsp-inhibit-message t)
    :config (add-to-list 'spacemacs-default-company-backends 'company-lsp))
  (use-package lsp-ui
    :commands lsp-ui-mode
    :hook (lsp-mode . lsp-ui-mode)
    :config (add-hook 'lsp-mode-hook 'lsp-ui-mode))
  (use-package company-lsp
    :hook (lsp-mode . company-mode)
    :init (setq company-lsp-cache-candidates 'auto
                company-lsp-enable-snippet t)
    :config (progn
              (spacemacs|defvar-company-backends java-mode)
              (push 'company-lsp company-backends-java-mode)
              (spacemacs|add-company-hook java-mode)))
  (use-package lsp-java
    :commands lsp-java-enable
    :init (progn (defun my/java-mode-jump-handler ()
                   (let ((xref-prompt-for-identifier nil))
                     (call-interactively #'xref-find-definitions)))
                 (setq lsp-java-server-install-dir "~/bin/jdt/"
                       lsp-java-trace-server 'off
                       lsp-java--workspace-folders (list "~/projects/nike/marketing-segment-dm-poc"))
                 (spacemacs|define-jump-handlers java-mode my/java-mode-jump-handler))
    :hook ((java-mode . lsp-java-enable)
           (java-mode . flycheck-mode)))