Skip to content

Fill in the content to the right margin (or semantically) when printing Lisp forms

I'm using CL built-in facilities for printing in my structural editor. And I want the code I print with it to be pretty. SBCL does that with its printer:

(print '(loop repeat (min n (- (length %page-buffer)
                                    %page-index))
                   when %page-index
                   do (format t "~&~d: ~a~%" %page-index (elt %page-buffer %page-index))
                   unless (= 1 n)
                     do (incf %page-index)))

;; (LOOP REPEAT (MIN N (- (LENGTH %PAGE-BUFFER) %PAGE-INDEX))
;;       WHEN %PAGE-INDEX
;;       DO (FORMAT T "~&~d: ~a~%" %PAGE-INDEX (ELT %PAGE-BUFFER %PAGE-INDEX))
;;       UNLESS (= 1 N)
;;       DO (INCF %PAGE-INDEX))

While ECL is printing less human-readable code

(print '(loop repeat (min n (- (length %page-buffer)
                                    %page-index))
                   when %page-index
                   do (format t "~&~d: ~a~%" %page-index (elt %page-buffer %page-index))
                   unless (= 1 n)
                     do (incf %page-index)))
;; (LOOP REPEAT
;;       (MIN N (- (LENGTH %PAGE-BUFFER) %PAGE-INDEX))
;;       WHEN
;;       %PAGE-INDEX
;;       DO
;;       (FORMAT T "~&~d: ~a~%" %PAGE-INDEX (ELT %PAGE-BUFFER %PAGE-INDEX))
;;       UNLESS
;;       (= 1 N)
;;       DO
;;       (INCF %PAGE-INDEX))

What I'm expecting is an output that is either

  • Filled up to the *print-right-margin*
  • Filled up semantically (like SBCL does).
  • Or filled up per keywords, because keywords conventionally are written on the same line as their arguments. I.e.
;; (LOOP :REPEAT (MIN N (- (LENGTH %PAGE-BUFFER) %PAGE-INDEX))
;;       :WHEN %PAGE-INDEX
;;       :DO (FORMAT T "~&~d: ~a~%" %PAGE-INDEX (ELT %PAGE-BUFFER %PAGE-INDEX))
;;       :UNLESS (= 1 N)
;;       :DO (INCF %PAGE-INDEX))

Provide details regarding ECL version (or preferably commit), operating system and if revelant the build options and versions of the build tools.

(format t "~&~@{~12@A ~S~%~}"
        :version (lisp-implementation-version)
        :vcs-id (ext:lisp-implementation-vcs-id)
        :os (software-type)
        :os-version (software-version)
        :machine-type (machine-type)
        :features *features*)
;;      VERSION "23.9.9"
;;       VCS-ID "UNKNOWN"
;;           OS "Linux"
;;   OS-VERSION "6.8.6"
;; MACHINE-TYPE "x86_64"
;;     FEATURES (:PACKAGE-LOCKS :QUICKLISP :ASDF3.3 :ASDF3.2 :ASDF3.1 :ASDF3
;;               :ASDF2 :ASDF :OS-UNIX :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE
;;               :WALKER :CDR-6 :CDR-1 :CDR-5 :LINUX :FORMATTER :CDR-7
;;               :ECL-WEAK-HASH :LITTLE-ENDIAN :ECL-READ-WRITE-LOCK :LONG-LONG
;;               :UINT64-T :UINT32-T :UINT16-T :COMPLEX-FLOAT :LONG-FLOAT :UNICODE
;;               :DFFI :CLOS-STREAMS :CMU-FORMAT :UNIX :ECL-PDE :DLOPEN :CLOS
;;               :THREADS :BOEHM-GC :ANSI-CL :COMMON-LISP
;;               :FLOATING-POINT-EXCEPTIONS :IEEE-FLOATING-POINT
;;               :PACKAGE-LOCAL-NICKNAMES :CDR-14 :PREFIXED-API :FFI :X86_64
;;               :COMMON :ECL)

Some additional notes.