The mode provides basic functionality required for successfully interacting with sbt inside emacs. The core functionality includes:
- interacting with sbt shell and scala console
- compiling code and navigating to errors
See also (emacs-scala-mode)[https://github.com/hvesalai/emacs-scala-mode].
The preferred mechanism is via MELPA and
use-package as per our
Learning Emacs guide:
(use-package sbt-mode :commands sbt-start sbt-command :config ;; WORKAROUND: allows using SPACE when in the minibuffer (substitute-key-definition 'minibuffer-complete-word 'self-insert-command minibuffer-local-completion-map))
Start an sbt session with
M-x sbt-start or send a command to the current sbt process with
You might also want to customize some
sbt-mode variables (run
M-x customize-mode RET sbt-mode).
For example you can play with variable
sbt:scroll-to-bottom-on-output. If set to
t (which is a default
value) sbt output buffer scrolls automatically to the last line if
there is some new output. Setting this variable to
nil will cause
point remain on it's current position in a buffer when there is some
new output. If set to
nil and point is on the last line, it scrolls
automaticaly with new output, but if there is compilation error (line
[error] - ...) it will stop on that line.
Although sbt 1.0 is supported, there are some niggles. Pull requests are always welcome to enhance the mode.
To work efficiently with
sbt-mode, you may wish to customise your
workflow with the built-in Emacs compile support:
- locally bind a key to
- locally bind a key to
- locally bind a key to
A more daring customisation is to use
replace long repetitive strings with symbols. For example
(add-hook 'sbt-mode-hook (lambda () (setq prettify-symbols-alist `((,(expand-file-name (directory-file-name default-directory)) . ?⌂) (,(expand-file-name "~") . ?~))) (prettify-symbols-mode t)))
will replace occurrences of the project's root directory with the UTF-8 symbol for "house" and any long-form occurrences of your home directory with tilde.
Most users may prefer to use
projectile for these
sbt-mode provides also
grep-based commands for
A special version of the
rgrep command is available with
M-x sbt-grepgreps files in the sbt project
M-x sbt-find-definitionswill search for the definition of the thing at point from the project
M-x sbt-find-usageswill search for occurrences of the id at point from the project
It is also possible to drop into an sbt
console session using
It is advised when typing multi-line code snippets, use
comint-accumulate instead of
RET for newlines. This way, if you
need to modify the code, you can use
M-p to recall the whole snippet
You can also send a region of code from an other buffer in the same
project. First set the mark to the other end of the region to send and
the point (cursor) the other. Then run the
sbt-paste-region will enter
:paste mode of Scala REPL, so
that multiline statement/expression will work as expected.
The simplest way to compile the code you are working on in emacs by
sbt-run-previous-command to a key. For example
(local-set-key (kbd "C-x '") 'sbt-run-previous-command). By default,
this will run
Triggered execution in sbt, the
~test commands (when
sbt is waiting with the message "press enter to interrupt"), can be
interrupted by typing
C-c C-j in
C-c C-b C-j
anywhere else). Hitting just
RET in an sbt buffer doesn't interrupt
sbt because there isn't a recognized sbt prompt in
RET in an
sbt-mode buffer will cause Emacs to
complain that "Text is read-only".
sbt-mode also offers hydra to
speed up sbt interaction. This is focused mainly on running usual sbt
run etc. on multiproject
build. Hydra allows to execute these commands on per project basis.
M-x sbt-hydra command. This will start new sbt process in
sbt buffer (if there is already sbt process running it will switch to
You will see message:
Please wait! sbt projects are loading. sbt Hydra will be ready soon.
while sbt is launching.
To generate hydra we need to get information about available projects.
This is done by running
projects command in sbt (this is done
automatically as soon as sbt is ready). After this is done, you will
Success hydra for projects (projectA, projectB, ...) created.
After you will see this message run
M-x sbt-hydra command again and
you will see hydra appearing at the bottom of the screen. By pressing
h you can invoke help where you can learn more detais about Hydra
We recommend to bind
sbt-hydra command to some convenient shortcut.
Hydra remembers last command which was executed and it can run this
command automatically again on a save of an edited file. Of course it
would be undesirable to run 10 commands when saving 10 edited files by
save-some-buffers command so for this reason last sbt command will
be run again only on a save of last edited file.
To enable this feature add
before-save-hook. For example:
(add-hook 'sbt-mode-hook (lambda () (add-hook 'before-save-hook 'sbt-hydra:check-modified-buffers)))
To eliminate undesirable execution of last sbt command, there is
allowed-files-regexp containing regular
expressions to detect files which when edited will cause executing
last sbt command again. By default this variable contains two records:
There exists 3 Directory Local
which provides more customization for Hydra. They must be specified in
.dir-locals.el file in the root of your sbt project.
This variable allows to specify list of projects to include in the Hydra. By default Hydra includes all sbt projects, which in case there is lots of them make working with Hydra cumbersome. This variable, when set, allows to specify subset of all projects.
((sbt-mode (sbt-hydra:projects "api" "core" "foo" "jerky" "server" "swanky" "util")))
run sbt command we usually want to provide some command
line arguments to the main method. This variable allows us to specify
these arguments. We can provide different arguments for every
projects. Example configuration looks like this:
((sbt-mode (sbt-hydra:command-line-arguments . ( ("restApi" . "myconf.conf development") ("jobs" . "delivery_flag") ("identityManager" . "myconf.conf 9001")))))
Here we have 3 sbt projects
For example when we execute
run command through
r hydra key we
myconf.conf development arguments to
restApi project main
run sbt command we may to set system variables for our
program to use while running. This variable allows us to specify
system variables without need to manipule environment variables. When
set they will be provided to our main method by forking JVM and
putting them into
javaOptions before executing
((sbt-mode (sbt-hydra:system-properties . ( ("macwire" . ("-Dconf.file=myconf.conf" "-Xmx1G")) ("reader" . ("-Dconf.file=myconf.conf" "-Xmx1G"))))))
Here we have 2 sbt projects
reader. For example for
macwire project there will be set two system variables