I’ve been playing around in common lisp lately, and one feature I particularly
like is the trace macro.
trace is a macro which lets you easily log the
arguments and result of all calls to a function. It’s particularly handy for
visualising recursive function calls.
As you might expect Emacs has an equivalent macro. It’s called
and is used like this:
(defun fact (n) (if (= n 0) 1 (* n (fact (1- n))))) (trace-function #'fact) (fact 3)
which pops up a
*trace-output* buffer containing
====================================================================== 1 -> (fact 3) | 2 -> (fact 2) | | 3 -> (fact 1) | | | 4 -> (fact 0) | | | 4 <- fact: 1 | | 3 <- fact: 1 | 2 <- fact: 2 1 <- fact: 6
This is great if you’re working interactively, but I want to use it for debugging unit tests too. I run typically tests in batch mode using ert-runner, so the challenge is to get the trace macro to print to stdout instead of writing to a buffer.
Unfortunately Emacs doesn’t have a simple way of redirecting a buffer to stdout.
My somewhat hacky solution is to add the following code to my ert-runner
(defun log-trace-buffer (&rest _) (when (get-buffer trace-buffer) (with-current-buffer trace-buffer (message (buffer-substring-no-properties (point-min) (point-max)))))) (add-to-list 'ert-runner-reporter-run-ended-functions #'log-trace-buffer)
which just dumps the entire contents of the trace output buffer to stdout when the tests finish. It’s not perfect but it’s enough for me to fix my tests!