Hi all,

I manage my business affairs using accounting software I whipped up in TXR.

Most of the operations are done in the interactive listener.

The reports like a full ledger and whatnot run for many pages, so I scroll through them using the less utility.

Here is how:

(defmacro page (expr)
  (with-gensyms (saved-int-var)
    ^(let ((,saved-int-var (get-sig-handler sig-int)))
       (unwind-protect
         (with-stream (*stdout* (open-process "less" "w"))
           (unwind-protect ,expr (set-sig-handler sig-int nil)))
         (set-sig-handler sig-int ,saved-int-var)))))

you simply wrap this macro around an expression and whatever output it produces is piped to less. Example:

;; page through the numbers from 1 to 200
(page (tprint (range 1 200)))

It wasn't this complicated in the beginning, but I ran into issues with Ctrl-C. What happens is that the with-stream macro ensures that the pipe stream is closed, and so when expr finishes executing, TXR is sitting in a pclose call which is internally doing a waitpid.  If Ctrl-C is issued, the TTY sends a SIGINT signal which aborts this waitpid.  However, the less utility doesn't respond to Ctrl-C; it keeps running and reading from the TTY. The result is a mess.

The above page macro tries to ensure that SIGINT is ignored after expr is finished, while still allowing expr itself to be interrupted before that. During the pclose call, and the waitpid that it is doing, SIGINT is blocked. When less terminates, pclose finishes and SIGINT is restored.

Cheers ...