0

I want to print an alist with a title consisting of a key title keytl and a value title valtl before printing the values using tabulated-list-print.

(defun tlprint-alist (alist &optional outbufr keytl valtl)
  "Print an associated list via `tabulated-list-print'."

  (let*
      ( (bufr (or outbufr (get-buffer-create "*Alist*")))
        (keytl (or keytl "Key Title"))
        (valtl (or valtl "Value Title")) )

    (with-current-buffer bufr
      (setq tabulated-list-format [(keytl 20 t) (valtl 20 t)])
      (setq tabulated-list-sort-key (cons keytl nil))
      (setq tabulated-list-entries
            (cons (list keytl valtl)
                  (mapcar (lambda (pair)
                            (list (car pair) (cdr pair)))
                          alist)))
      (tabulated-list-print) )))

Running

(setq foo '((a . ["a1" "a2"]) (b . ["b1" "b2"]) (c . ["c1" "c2"])))
(tlprint-alist foo)

gives

Debugger entered--Lisp error: (error "No column named Key Title")
  signal(error ("No column named Key Title"))
  error("No column named %s" "Key Title")
  tabulated-list--column-number("Key Title")
  tabulated-list--get-sorter()
  tabulated-list-print()
Dilna
  • 1,173
  • 3
  • 10
  • 1
    What is the problem that is stopping you from doing this? Is it a question of getting the values of some variable into `tabulated-list-format`? If so, please say so in the question! – Fran Burstall Jun 13 '23 at 21:26
  • 1
    What @FranBurstall said. A guess is that you're looking for this: https://emacs.stackexchange.com/q/7481. – Drew Jun 13 '23 at 21:39

1 Answers1

0

This seems to do what you want:

(defun tlprint-alist (alist &optional outbufr keytl valtl)
  "Print an associated list via `tabulated-list-print'."

  (let*
      ((bufr (or outbufr (get-buffer-create "*Alist*")))
       (keytl (or keytl "Key Title"))
       (valtl (or valtl "Value Title")))

    (with-current-buffer bufr
      (tabulated-list-mode)
      (setq tabulated-list-format (vector (list keytl 20 t) (list valtl 20 t)))
      (setq tabulated-list-sort-key (cons keytl nil))
      (setq tabulated-list-entries
        (mapcar (lambda (pair)
              (list (car pair) (cdr pair)))
            alist))
      (tabulated-list-init-header)
      (tabulated-list-print))))

Four issues arise in your code:

  1. You need to ensure that keytl and valtl get evaluated when setting tabulated-list-format.
  2. (list keytl valtl) is not of the right format to go into tabulated-list-entries and is not the way to get a header-line.
  3. You should put the target buffer in tabulated-list-mode.
  4. Most important: you need to call tabulated-list-init-header to get the header.

Commentary: I found out what was missing from your code by experimenting with it in the scratch buffer and reading the manual section on tabulated-list-mode (24.2.7). I urge you to adopt the same strategy before posting here.

Fran Burstall
  • 3,665
  • 10
  • 18
  • I do not get the header though, just the values. – Dilna Jun 16 '23 at 09:50
  • That is very strange because I get the header and values. Try this in a fresh emacs session to make sure that you are using the right version of the function (I have just now copy/pasted the function from my answer along with the data and function call from your question into the scratch buffer, evaluated the lot and got the desired table). – Fran Burstall Jun 16 '23 at 09:57
  • I am using GNU Emacs 29.0.50 – Dilna Jun 16 '23 at 10:04
  • Have added `(insert "TEST")` just before `(tabulated-list-mode)`. But that is not getting printed either. – Dilna Jun 16 '23 at 10:06
  • Another thing I noticed is that calling `(tlprint-alist foo)` twice gives `Debugger entered--Lisp error: (buffer-read-only #) insert("TEST")` – Dilna Jun 16 '23 at 10:40
  • I am using GNU Emacs 29.0.91 but also tested this on 28.2. – Fran Burstall Jun 16 '23 at 10:46