[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Access recent files menu from minibuffer

From: Stephen Berman
Subject: Access recent files menu from minibuffer
Date: Wed, 15 Mar 2006 16:15:40 +0100
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

As pointed out in the Emacs wiki, recentf.el lacks a minibuffer
interface, and several ways of accessing recent files from the
minibuffer are presented there (see  These all use
just the unstructured recentf-list.  But one of the features of
recentf.el that I find most useful is the possibility of filtering
recentf-list and structuring the recent file menu in accordance with
the filter.  So I wrote some code that makes the filtering and
structuring of the recent file menu accessible from the minibuffer,
with standard tabbed completion.  Here it is.  (I find it convenient
to globally bind `C-c r' to the command recentf-minibuffer-dialog.)

Steve Berman

(defun recentf-filtered-list (arg)
  "Return a filtered list of ARG recentf items."
     (mapcar 'recentf-make-default-menu-element
             (butlast recentf-list (- (length recentf-list) arg)))))

(defun recentf-list-submenus (arg)
  "Return a list of the recentf submenu names."
  (if (listp (cdar (recentf-filtered-list arg))) ; submenues exist
      (delq nil (mapcar 'car (recentf-filtered-list arg)))))

(defmacro recentf-list-entries (fn arg)
  "Return a list of ARG recentf menu entries as determined by FN.
When FN is `'car' return the menu entry names, when FN is `'cdr'
return the absolute file names."
  `(mapcar (lambda (x) (mapcar ,fn x))
           (if (recentf-list-submenus ,arg)
               (mapcar 'cdr (recentf-filtered-list ,arg))
             (list (recentf-filtered-list ,arg)))))

;; This function is not specific to recentf mode but is needed by
;; `recentf-minibuffer-dialog'.  I've also made enough use of it in
;; other contexts that I'm surprised it's not part of Emacs, and the
;; fact that it isn't makes me wonder if there's a preferred way of
;; doing what I use this function for.
(defun recentf-memindex (mem l)
  "Return the index of MEM in list L."
  (let ((mempos -1) ret)
    (while (eq ret nil)
      (setq mempos (1+ mempos))
      (when (equal (car l) mem) (setq ret mempos))
      (setq l (cdr l)))

(defun recentf-minibuffer-dialog (arg)
  "Open the recentf menu via the minubuffer, with completion.
With positive prefix ARG, show the ARG most recent items.
Otherwise, show the default maximum number of recent items."
  (interactive "P")
  (let* ((num (prog1 (if (and (not (null arg))
                              (> arg 0))
                         (min arg (length recentf-list))
                (and (not (null arg))
                     (> arg (length recentf-list))
                     (message "There are only %d recent items."
                              (length recentf-list))
                     (sit-for 2))))
         (menu (if (recentf-list-submenus num)
                   (completing-read "Open recent: "
                                    (recentf-list-submenus num))))
         (i (recentf-memindex menu (recentf-list-submenus num)))
         (items (nth i (recentf-list-entries 'car num)))
         (files (nth i (recentf-list-entries 'cdr num)))
         (item (completing-read "Open recent: " items))
         (j (recentf-memindex item items))
         (file (nth j files)))
    (funcall recentf-menu-action file))) ; find-file by default

reply via email to

[Prev in Thread] Current Thread [Next in Thread]