06 Sep 2026

Emacs salmagundi, 2026-09-06

Compilation commands by project type

I while ago I added a minor mode, haskell-ng-project-mode, to my Haskell mode. The idea I had was that I could use it to add keybindings for running various tools (via compile), e.g. I bound cabal build and cabal test , p b and , p t respectively. Then I hooked in the minor mode in my haskell-ng-mode. Soon I realised it'd be nice to have those shortcuts available in dired too, so I hooked it in there as well. When I later wanted to re-run the tests after modifying a JSON file that was part of a golden test I realised that this wasn't a very nice solution at all.

After looking around a bit I found emacs-multi-compile. I removed the minor mode and add this configuration instead

(add-to-list 'multi-compile-alist
             '((haskell-ng-is-project) . (("cabal build" "cabal build -j --semaphore" (project-root (project-current)))
                                          ("cabal test" "cabal test" (project-root (project-current)))
                                          ("fourmolu" "fourmolu -i $(fd .hs$)" (project-root (project-current))))))

I've had some vague thoughts that it'd be rather easy to write something slightly more custom, but emacs-multi-compile works very well for me so I'm very happy with it.

Jumping between implementation and test, again

I wrote about this a while ago. At the time I came up with a way of bending ff-find-other-file to my will, but soon after that I ran into a case where there may be 2 "other files" – one of the Haskell projects at work put unit tests in files ending in Spec.hs and property tests in filed ending with Prop.hs. Unfortunately this is a situation that ff-find-other-file can't handle.

I ended up hacking together consult-kith to deal with it. The configuration to handle two kinds of test files looks like this

(setq-local consult-kith-alist `((,(rx (seq "Spec.hs" eol)) (".hs"))
                                 (,(rx (seq "Prop.hs" eol)) (".hs"))
                                 (,(rx (seq ".hs" eol)) ("Prop.hs" "Spec.hs")))
            consult-kith-search-directories '("src" "test"))

The project has since settled on only using Spec.hs for tests, but I'm sticking to consult-kith for now.

Tags: emacs
Comment here.