emacs + scala
For a bit more than a year I have been working mainly with Scala in Emacs. While it's not like working with a LISP, there are a few tweaks that make life a bit easier. I'll describe my setup and the small additions that work for me. There's only very little Emacs Lisp, but you can always find more details on fgeller/emacs.d.
As a caveat, while I used aemoncannon/ensime heavily in the beginning, I rarely switch it on nowadays, mostly due to the overhead with sub projects in SBT. Instead I use other tools to get similar functionality. These tools are not as tightly integrated with Scala, but that also means many are applicable for other scenarios as well. Also, none of this is meant as a reference, but more as pointers -- I'm always curious to learn about other techniques :)
Entry point is usually the project root via an alias in eshell
to set the
default-directory
. Then I'll start a SBT session via compile
in comint-mode
to
run tests and drive compilation (e.g., via an alias for (compile "sbt" t)
in
eshell
).
I use magit/magit for getting a basic overview
of where I left off or to create a new branch. Then there are multiple options
to find a file to edit. Either jump to a specific line in a file with
uncommitted changes via the hunk in magit-status
, or browse the log and jump
via a commit, or browse current files under version control via
emacs-helm/helm-ls-git.
I use hvesalai/scala-mode2 for basic syntax highlighting plus drothlis/pretty-symbols for two more unicode glyphs ;)
In the background, there is usually a process running for formatting files via
mdr/scalariform that I connect to by
adding to the after-save-hook
. It's a small
fgeller/scalariform-daemon that
waits for HTTP requests and formats files in place. This means that I lose undo
history but that hasn't been an issue for me. I tried magit's integration with
bartman/git-wip, but very rarely used
it. Most importantly, it saves time to start up the JVM for each format request
and combined with a low value for auto-revert-interval
you get quick formats
on save.
magnars/expand-region.el and Fuco1/smartparens enable a light version of structured editing, but mostly there is little special configuration for editing Scala code versus general text editing. There are tons of cool resources out there that do a much better job at describing snippets, auto-completion or quick in buffer jumping and more :)
SBT's triggered execution via the tilde operator is usually my main driver during development for red-green-refactor. Using compile-mode to run the SBT session enables jumping to specific lines on compilation or test failure.
For other navigation I use a combination of tags and basic text search. For tags, I configure Exuberant ctags as a plug-in parser for GNU global. ctags allows me to simply add a basic regex-based configuration for Scala files and global allows for incremental updates on save. I also add other sources to my projects to enable jumping to tags in other libraries or the Scala distribution for reference. helm-gtags allows for convenient selection between multiple candidates by matching on the source line or file name. I also copied helm-gtags functionality for a crude helper to create import statements based on indexed tags.
Finally, for in-buffer search there is the excellent built-in isearch but for text searches across files I use Wilfred/ag.el as a front-end for ggreer/the_silver_searcher. As a bonus, you get easy text changes across files via mhayashi1120/Emacs-wgrep.