Set-popup-rules! breaks `sbt-do-run`

What happened?

I wanted sbt-mode's buffer to be on the bottom of my window, so I followed the example in the docstring for sbt:display-buffer-action, setting this in my config.el:

(defun display-sbt-at-bottom (buffer args)
  (display-buffer-at-bottom buffer (cons '(window-height . 8) args)))

(setq sbt:display-buffer-action '(display-sbt-at-bottom))

So if I call M-x sbt-do-run from an sbt project, that pops up an *sbt*<~/repos/helloworld/> buffer and runs sbt in it. That works well, and is visually what I want, but behaves like a normal buffer instead of a popup. One particular issue I’ve had with it is that it resizes if I call balance-windows.

So I removed those lines and tried doing

(set-popup-rules!
  '(("\\*sbt :ttl nil :quit nil :select nil)))

To get a nicely-behaved buffer like I would expect. The sbt buffer opens correctly, but it fails to actually run the code in the project, even though the sbt server starts correctly. I can go to the *sbt* buffer and type run to compile and run the code, so I know sbt is still running.

I see this in *Messages*:

Starting sbt in buffer *sbt*<~/repos/helloworld/> 
sbt-do-run: Symbol’s value as variable is void: sbt:submode

I poked around in sbt-mode.el and saw this:

(eval-when-compile
  (defvar sbt:submode)
  (defun scala-mode:set-scala-syntax-mode ()))

but I’m not sure why using a popup makes it so that variable is void. Is this a problem with sbt-mode or have I done something wrong?

What did you expect to happen?

I would expect that setting a popup rule not affect the functionality of sbt-do-run.

Steps to reproduce

  1. If you don’t have a scala environment locally, you can set up coursier to install one. Install coursier and then
coursier setup
coursier install metals
coursier install metals-emacs
  1. Uncomment the scala line in init.el and add +lsp.
  2. Create a simple Scala project:
mkdir foo-build
cd foo-build
touch build.sbt
mkdir -p src/main/scala/example
touch src/main/scala/example/Hello.scala

Then add this to Hello.scala:

object Main extends App {
  println("Hello, World!")
}

Once LSP starts, select Import Build when prompted to. Then, M-x sbt-do-run. This will open the sbt pop-up but won’t perform the run action.

*Messages* will contain the sbt-do-run: Symbol’s value as variable is void: sbt:submode error message indicated previously.

Removing the call to set-popup-rules! in config.el and restarting emacs allows me to run sbt-do-run and see Hello, World! in the *sbt* buffer as expected.

No other errors besides the void variable are reported in *Messages*:

Doom loaded 289 packages across 51 modules in 0.501s
org-super-agenda-mode enabled.
Loading /home/luciano/.emacs.d/.local/cache/recentf...done
Note: scala-indent:step, tab-width, evil-shift-width adjusted to 2
Starting new Ispell process aspell with default dictionary...done
LSP :: Guessed project root is ~/foo-build
LSP :: Connected to [metals:297498/starting].
LSP :: metals:297498 initialized successfully in folders: (/home/luciano/foo-build)
Starting sbt in buffer *sbt*<~/foo-build/> 
sbt-do-run: Symbol’s value as variable is void: sbt:submode

System information


Loading data dump...