Programming in scala with a custom sbt with ensime
Having a project that needs a custom sbt executable requires a bit of setup to make Scala development more pleasing in these occasions.
Imagine you work in Scala and you build your project with sbt. It may
occur that your client has some special environment, and the simple
way to hide the configuration complexity is to use a slightly
configured sbt. Say that you come up with an executable called
sbt.sh like the following:
#!/bin/bash SBT_OPTS="someCoolOptions" java $SBT_OPTS -jar `dirname $0`/sbt-launch.jar "$@"
Note that the shebang is necessary, otherwise sbt-mode will not run your custom sbt.
Now: how do we make ensime consider this executable the one to use for this project?
We are lucky (and grateful) that the maintainers of ensime and
sbt-mode provided two variables that allow to define the executable to
The idea is to reassign those variables if a custom sbt executable
exists in the project. For simplicity I assumed that the executable is
not present in any parent directory of the project root directory.
Given that the
dir directory in the following function is the
directory from where we start ensime, we can find the file through:
(defun get-to-parent-until (fn dir) "Returns the first directory from DIR that satisfies FN or NIL." (let ((current dir)) (while (not (or (equalp current "/") (funcall fn current))) (setq current (expand-file-name (concat current "/..")))) (if (funcall fn current) current nil)))
This function returns the first directory that satisfies the
With this we can obtain the executable path and assign the variables:
(defun set-sbt-program () "Sets ensime ans sbt program name to local if it exists" (interactive) (let* ((sbt-dir (get-to-parent-until #'(lambda (d) (file-exists-p (concat d "/sbt"))) default-directory)) (exec (if sbt-dir (concat sbt-dir "/sbt") "sbt"))) (setq ensime-sbt-command exec sbt:program-name exec)))
Finally we can set a hook to run this function every time we use ensime:
(add-hook 'ensime-mode-hook #'set-sbt-program)
I have shown how to automate some boring configuration for ensime. I added this to the sbt-mode repository for users reference: https://github.com/ensime/emacs-sbt-mode/issues/129.