diff --git a/CHANGELOG.develop b/CHANGELOG.develop index 10f56072f..5e5230f45 100644 --- a/CHANGELOG.develop +++ b/CHANGELOG.develop @@ -2430,6 +2430,8 @@ Other: - Evilify =ensime= search in insert/normal mode (thanks to Diego Alvarez) - Remove duplicated code (thanks to Tetsuro Takemoto) - Added ENSIME jump handlers (thanks to Joao Azevedo) +- Added scala-lsp and metals as an additional backend for scala + (thanks to Rodolfo Hansen) **** Scheme - Added missing =parinfer= package declaration (thanks to Kalle Lindqvist) - Update install docs for Chicken 5 changes (thanks to Grant Shangreaux) diff --git a/layers/+lang/scala/README.org b/layers/+lang/scala/README.org index d9c6c9e87..1ad890815 100644 --- a/layers/+lang/scala/README.org +++ b/layers/+lang/scala/README.org @@ -8,7 +8,9 @@ - [[#description][Description]] - [[#features][Features:]] - [[#layer-installation][Layer Installation]] -- [[#ensime][Ensime]] +- [[#backends][Backends]] + - [[#ensime][Ensime]] + - [[#metals][Metals]] - [[#scalastyle][Scalastyle]] - [[#use-java-doc-style][Use Java doc-style]] - [[#automatically-show-the-type-of-the-symbol-under-the-cursor][Automatically show the type of the symbol under the cursor]] @@ -22,6 +24,7 @@ This layer adds support for the Scala language to Spacemacs. ** Features: - Syntax highlighting +- Support for language backend. Either using [[https://ensime.github.io/][ENSIME]] or [[https://scalameta.org/metals/][Metals]] - Auto-completion - Syntax-checking - Refactoring @@ -31,7 +34,6 @@ This layer adds support for the Scala language to Spacemacs. - Eldoc integration - Test execution directly from Emacs - Automatic replacement of ASCII arrows with unicode ones -- Automatic starting/stopping of [[https://ensime.github.io/][ENSIME]] IDE server * Layer Installation To use this configuration layer, add it to your =~/.spacemacs=. You will need to @@ -46,7 +48,20 @@ version (Stable). Please add the following lines to =dotspacemacs/user-init=: (add-to-list 'package-pinned-packages '(ensime . "melpa-stable")) #+END_SRC -* Ensime +* Backends +The currently supported language backends are: +- scala-ensime (default) +- scala-metals + +To set your choice of backend, configure the layer variable =scala-backend=. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((scala :variables scala-backend 'scala-ensime))) ;or 'scala-metals +#+END_SRC + + +** Ensime [[https://ensime.github.io/][ENSIME]] provides IDE-like features, such as refactoring, incremental compilation and project-wide type-checking. @@ -57,6 +72,22 @@ list) to generate these files. Installation instructions and usage can be found in the =Java= layer [[https://github.com/syl20bnr/spacemacs/tree/develop/layers/%2Blang/java/README.org#ensime][README.org]]. +** Metals +Currently, you must manually install the metals server. It is possible to do so via coursier; the latest version can be built using the following commands: + +#+BEGIN_SRC bash +./coursier bootstrap \ + --java-opt -Xss4m \ + --java-opt -Xms100m \ + --java-opt -Dmetals.client=emacs \ + org.scalameta:metals_2.12:0.5.1 \ + -r bintray:scalacenter/releases \ + -r sonatype:snapshots \ + -o /usr/local/bin/metals-emacs -f +#+END_SRC + +You will then have the common LSP keybindings; see http://develop.spacemacs.org/layers/+tools/lsp/README.html#key-bindings for more details. + * Scalastyle [[http://www.scalastyle.org/][Scalastyle]] provides style-checking and linting. The Emacs functionality is provided by Flycheck. @@ -128,12 +159,12 @@ the ascii arrows back. #+END_SRC * Auto-start -If you prefer to have Ensime start when you load a scala file, you can enable it +If you prefer to have the backend start when you load a scala file, you can enable it with #+BEGIN_SRC emacs-lisp (setq-default dotspacemacs-configuration-layers '( - (scala :variables scala-auto-start-ensime t))) + (scala :variables scala-auto-start-backend t))) #+END_SRC * Key bindings diff --git a/layers/+lang/scala/config.el b/layers/+lang/scala/config.el index da1e38b52..e6d089ac7 100644 --- a/layers/+lang/scala/config.el +++ b/layers/+lang/scala/config.el @@ -20,5 +20,12 @@ (defvar scala-use-unicode-arrows nil "If non-nil then `->`, `=>` and `<-` are replaced with unicode arrows.") -(defvar scala-auto-start-ensime nil - "If non nil then ensime will be started when a scala file is opened.") +(defconst scala-backends '(scala-ensime scala-metals) + "Backend server implementation to enable advanced IDE language features") + +(defvar scala-backend 'scala-ensime + "Backend used to trigger IDE language features. +`scala-ensime' or `scala-metals' are currently supported") + +(defvar scala-auto-start-backend nil + "If non nil then ensime/metals will be started when a scala file is opened.") diff --git a/layers/+lang/scala/funcs.el b/layers/+lang/scala/funcs.el index e08a1aedc..914d56374 100644 --- a/layers/+lang/scala/funcs.el +++ b/layers/+lang/scala/funcs.el @@ -14,9 +14,21 @@ (spacemacs//java-setup-ensime) (add-to-list 'spacemacs-jump-handlers-scala-mode 'ensime-edit-definition)) +(defun spacemacs//scala-setup-metals () + "Setup LSP metals for Scala." + (setq-local lsp-prefer-flymake nil)) + (defun spacemacs//scala-disable-flycheck-scala () (push 'scala flycheck-disabled-checkers)) +(defun spacemacs//scala-backend-ensime-p () + "Return true if the selected backend is ensime" + (eq scala-backend 'scala-ensime)) + +(defun spacemacs//scala-backend-metals-p () + "Return true if the selected backend is metals" + (eq scala-backend 'scala-metals)) + (defun spacemacs/scala-join-line () "Adapt `scala-indent:join-line' to behave more like evil's line join. diff --git a/layers/+lang/scala/img/scalameta.png b/layers/+lang/scala/img/scalameta.png new file mode 100644 index 000000000..12842e8a2 Binary files /dev/null and b/layers/+lang/scala/img/scalameta.png differ diff --git a/layers/+lang/scala/layers.el b/layers/+lang/scala/layers.el index 575bf4b0f..0338e9c6d 100644 --- a/layers/+lang/scala/layers.el +++ b/layers/+lang/scala/layers.el @@ -10,4 +10,4 @@ ;;; License: GPLv3 -(configuration-layer/declare-layer 'java) +(configuration-layer/declare-layers '(lsp java)) diff --git a/layers/+lang/scala/packages.el b/layers/+lang/scala/packages.el index 935c916af..130942715 100644 --- a/layers/+lang/scala/packages.el +++ b/layers/+lang/scala/packages.el @@ -11,10 +11,8 @@ (setq scala-packages '( - eldoc ensime - flycheck - flyspell + (lsp-scala :requires lsp-mode) ggtags counsel-gtags helm-gtags @@ -25,7 +23,7 @@ )) (defun scala/post-init-eldoc () - (when scala-enable-eldoc + (when (and scala-enable-eldoc (spacemacs//scala-backend-ensime-p)) (add-hook 'scala-mode-hook #'spacemacs//java-setup-ensime-eldoc))) (defun scala/pre-init-ensime () @@ -35,10 +33,11 @@ (defun scala/post-init-ensime () (use-package ensime :defer t + :if (spacemacs//scala-backend-ensime-p) :init (progn (add-hook 'scala-mode-hook #'spacemacs//scala-setup-ensime) - (when scala-auto-start-ensime + (when scala-auto-start-backend (add-hook 'scala-mode-hook 'spacemacs//ensime-maybe-start))) :config (progn @@ -52,7 +51,8 @@ ;; Don't use scala checker if ensime mode is active, since it provides ;; better error checking. (with-eval-after-load 'flycheck - (add-hook 'ensime-mode-hook 'spacemacs//scala-disable-flycheck-scala))) + (add-hook 'ensime-mode-hook 'spacemacs//scala-disable-flycheck-scala) + (add-hook 'lsp-scala-))) (defun scala/post-init-flyspell () (spell-checking/add-flyspell-hook 'scala-mode) @@ -68,9 +68,20 @@ (defun scala/init-sbt-mode () (use-package sbt-mode :defer t - :init (spacemacs/set-leader-keys-for-major-mode 'scala-mode - "b." 'sbt-hydra - "bb" 'sbt-command))) + :config + ;; WORKAROUND: https://github.com/ensime/emacs-sbt-mode/issues/31 + ;; allows for using SPACE in the minibuffer + (substitute-key-definition + 'minibuffer-complete-word + 'self-insert-command + minibuffer-local-completion-map) + :init + (progn + (spacemacs/declare-prefix-for-mode 'scala-mode "mb" "sbt") + (spacemacs/declare-prefix-for-mode 'scala-mode "mg" "goto") + (spacemacs/set-leader-keys-for-major-mode 'scala-mode + "b." 'sbt-hydra + "bb" 'sbt-command)))) (defun scala/init-scala-mode () (use-package scala-mode @@ -81,6 +92,14 @@ (add-to-list 'completion-ignored-extensions ext))) :config (progn + ;; Ensure only one of metals and ensime is loaded + (unless (spacemacs//scala-backend-ensime-p) + (progn + (fmakunbound 'ensime) + (remove-hook 'after-change-functions 'ensime-after-change-function) + (remove-hook 'window-configuration-change-hook + 'ensime-show-left-margin-hook))) + ;; Automatically insert asterisk in a comment when enabled (defun scala/newline-and-indent-with-asterisk () (interactive) @@ -139,6 +158,15 @@ If it's part of a left arrow (`<-'),replace it with the unicode arrow." scala-indent:default-run-on-strategy scala-indent:operator-strategy)))) +(defun scala/init-lsp-scala () + (use-package lsp-scala + :after scala-mode + :demand t + :if (spacemacs//scala-backend-metals-p) + :config + (add-hook 'scala-mode-local-vars-hook #'spacemacs//scala-setup-metals) + :hook ((scala-mode) . lsp))) + (defun scala/post-init-ggtags () (add-hook 'scala-mode-local-vars-hook #'spacemacs/ggtags-mode-enable))