Quick scala experimenting in emacs

Sometimes it is very handy to do a quick coding session in some scripting language - when experimenting with new language feature, trying out some idea or just throwing together some math. Until recently, there was no way to use Scala for this. While it had script execution feature, it was very slow - could take several seconds on each script restart. This happened because you had to load and initialize scala compiler every time - and it's not a small beast.
Somewhere between 2.9 and 2.11, situation changed to better - now, instead of tearing compiler up and down, "scala script.scala" silently starts a compile server in the background, and subsequent scripts are sent to it, cutting down script execution time to less than a second.
It would get even better if there was a way to run the script directly from my emacs session, without going to terminal. Turns out, it's easy to do. Just place the following function in your init.el:
(defun run-current-file ()
  "Execute the current file.
File suffix is used to determine what program to run.
If the file is modified, ask if you want to save first."
  (let* (
          ;; ("extension" . "shell program name")
            ("scala" . "scala")
            ("rb" . "ruby")
         (fName (buffer-file-name))
         (fSuffix (file-name-extension fName))
         (progName (cdr (assoc fSuffix suffixMap)))
         (cmdStr (concat progName " \""   fName "\"")))

    (when (buffer-modified-p)
      (when (y-or-n-p "Buffer modified. Do you want to save first?")

    (if (string-equal fSuffix "el") ; special case for emacs lisp
        (load fName)
      (if progName
            (message "Running…")
            (shell-command cmdStr "*run-current-file output*" ))
        (message "No recognized program file suffix for this file.")))))
Use "M-x run-current-file" or bind it to key combination of your choice.
This function runs the current buffer, using file extension to determine what program to use as a script engine - scala, elisp or ruby here, but it should be easy to extend this to any other script runner.


  1. Good to see you again!

    Note that you can also test scripts in REPL -- a somewhat cheaper solution. It would need copy-pasting around though, closer to the point when you thing the script is alomost ready (or you're editing it).

    -- vasya novikov

    1. Hi! Good to hear from you!
      Essentially, this is almost the same - background compile server acts as a "hidden REPL", but without extra actions to select-copy-paste the script each time and without consuming valuable screen space.
      On the other hand, REPL also has :load - also eliminating problem with copy-paste, but still taking screen space.


Post a Comment

Popular posts from this blog

How to create your own simple 3D render engine in pure Java

Solving quadruple dependency injection problem in Angular

Better CLI option parsing in Scala