Search code examples
elisp

How to pass member from a list as string to another function?


This is my first ever elisp program. I'm trying to make a dashboard of sorts to display when Emacs starts up. I'm following code from the elisp startup page startup.el:

(defun dashboard ()
  "Display a custom dashboard on startup"
  (let ((dash-buffer (get-buffer-create "*dashboard*")))
    (with-current-buffer dash-buffer
      (let ((inhibit-read-only t))
        (erase-buffer)

        (fancy-splash-insert
         :face 'variable-pitch "Recent Files:"
         :face 'variable-pitch "\n")

        (dolist (recent recentf-list)
          (defconst file-text
            `((:link ((with-output-to-string (princ recent)),
                      (lambda (_button) (browse-url "https://www.gnu.org/software/emacs/"))
                      ))))

          (apply #'fancy-splash-insert (car file-text))
          (insert "\n")))

      (display-buffer dash-buffer))))

I want to ultimately display the recently used files, so I walk over the list with (dolist (recent recentf-list), so recent in theory holds a recently used file. I would like to then make a link out of the variable recent. Yes I realize that a link to gnu.org is not exactly what I want, but I have not made it to the link part yet. I think something with find-file is what I want there, but I'll get to that later. At any rate, try as I might, the only thing I can make work is a hard coded string:

--works

`((:link ("foo",

--does not work

`((:link (recent,

`((:link ((format "%s" recent),

`((:link ((with-output-to-string (princ recent)),

I've tried everything I can think of to get this thing to take a variable and it is defeating me...any ideas?

I'm getting errors similar to the following:

fancy-splash-insert: Wrong type argument: char-or-string-p, (with-output-to-string (princ recent))

Solution

  • You need to use the special marker , to tell the backquote that recent is not a constant. You also don't need princ nor with output to string. This should work:

    (defun dashboard ()
      "Display a custom dashboard on startup"
      (let ((dash-buffer (get-buffer-create "*dashboard*")))
        (with-current-buffer dash-buffer
          (let ((inhibit-read-only t))
            (erase-buffer)
    
            (fancy-splash-insert
             :face 'variable-pitch "Recent Files:"
             :face 'variable-pitch "\n")
    
            (dolist (recent recentf-list)
              (defconst file-text
                `((:link (,recent
                          (lambda (_button) (browse-url "https://www.gnu.org/software/emacs/"))
                          ))))
    
              (apply #'fancy-splash-insert (car file-text))
              (insert "\n")))
    
          (display-buffer dash-buffer))))
    

    See more info about the backquote in the documentation.