Hi Karl, > Here is a patch that adds shortcut keys and corresponding labels > to recentf-dialog-mode (the mode that `recentf-open-files' uses). > > The variable `recentf-dialog-show-labels-p' controls whether labels > are displayed, and could default to nil. > > I've been using this functionality for a long time and find it > indispensable. However, defadvice is brittle and I had to rewrite > it every time recentf changed. > > I hope this feature is suitable for installing.
This is a good idea! However your implementation fails when items are grouped into sub-menus in the `recentf-open-files' dialog. Attached is a reworked patch which fixes that bug, plus some minor cleanups. Could you try it please. If it works as you expect I could commit it if there is no objection from the other developers. Thanks! David Index: lisp/recentf.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/recentf.el,v retrieving revision 1.42 diff -c -r1.42 recentf.el *** lisp/recentf.el 6 Aug 2005 22:13:43 -0000 1.42 --- lisp/recentf.el 2 Sep 2005 08:16:10 -0000 *************** *** 259,264 **** --- 259,272 ---- :group 'recentf :type '(choice (const :tag "None" nil) function)) + + (defcustom recentf-show-file-shortcuts-flag t + "Whether to show ``[N]'' for the Nth item up to 10. + If non-nil, `recentf-open-files' will show labels for keys that can be + used as shortcuts to open the Nth file." + :group 'recentf + :type 'boolean) + ;;; Utilities ;; *************** *** 349,355 **** "Convert filename NAME to absolute, and canonicalize it. See also the function `expand-file-name'. If defined, call the function `recentf-filename-handler' ! to postprocess the canonical name." (let* ((filename (expand-file-name name))) (or (and recentf-filename-handler (funcall recentf-filename-handler filename)) --- 357,363 ---- "Convert filename NAME to absolute, and canonicalize it. See also the function `expand-file-name'. If defined, call the function `recentf-filename-handler' ! to post process the canonical name." (let* ((filename (expand-file-name name))) (or (and recentf-filename-handler (funcall recentf-filename-handler filename)) *************** *** 926,931 **** --- 934,942 ---- (set-keymap-parent km widget-keymap) (define-key km "q" 'recentf-cancel-dialog) (define-key km [down-mouse-1] 'widget-button-click) + ;; Keys in reverse order of appearence in help. + (dolist (k '("O" "9" "8" "7" "6" "5" "4" "3" "2" "1")) + (define-key km k 'recentf-open-file-with-key)) km) "Keymap used in recentf dialogs.") *************** *** 1063,1068 **** --- 1074,1084 ---- (kill-buffer (current-buffer)) (funcall recentf-menu-action (widget-value widget))) + ;; File counter while building the `recentf-open-files' dialog. + (defvar recentf--file-count nil) + ;; List of files associated to a digit shortcut key. + (defvar recentf--files-with-key nil) + (defun recentf-open-files-item (menu-element) "Return a widget to display MENU-ELEMENT in a dialog buffer." (if (consp (cdr menu-element)) *************** *** 1076,1083 **** ,@(mapcar 'recentf-open-files-item (cdr menu-element))) ;; Represent a single file with a link widget `(link :tag ,(car menu-element) ! :button-prefix "" :button-suffix "" :button-face default :format "%[%t%]\n" --- 1092,1108 ---- ,@(mapcar 'recentf-open-files-item (cdr menu-element))) ;; Represent a single file with a link widget + ;; Use digit shortcuts for the first ten files. + (setq recentf--file-count (+ 1 recentf--file-count)) + (unless (> recentf--file-count 10) + (push (cdr menu-element) recentf--files-with-key)) `(link :tag ,(car menu-element) ! :button-prefix ,(if recentf-show-file-shortcuts-flag ! (if (> recentf--file-count 10) ! " " ! (format "[%d] " ! (% recentf--file-count 10))) ! "") :button-suffix "" :button-face default :format "%[%t%]\n" *************** *** 1093,1116 **** use for the dialog. It defaults to \"*`recentf-menu-title'*\"." (interactive) (recentf-dialog (or buffer-name (format "*%s*" recentf-menu-title)) ! (widget-insert "Click on a file to open it. Click on Cancel or type `q' to cancel.\n" ) ;; Use a L&F that looks like the recentf menu. (tree-widget-set-theme "folder") (apply 'widget-create `(group :indent 2 :format "\n%v\n" ! ,@(mapcar 'recentf-open-files-item ! (recentf-apply-menu-filter ! recentf-menu-filter ! (mapcar 'recentf-make-default-menu-element ! (or files recentf-list)))))) (widget-create 'push-button :notify 'recentf-cancel-dialog "Cancel") (recentf-dialog-goto-first 'link))) (defun recentf-open-more-files () "Show a dialog to open a recent file that is not in the menu." --- 1118,1162 ---- use for the dialog. It defaults to \"*`recentf-menu-title'*\"." (interactive) (recentf-dialog (or buffer-name (format "*%s*" recentf-menu-title)) ! (widget-insert ! "Click on a file or type the corresponding digit key to open it. Click on Cancel or type `q' to cancel.\n" ) ;; Use a L&F that looks like the recentf menu. (tree-widget-set-theme "folder") + (make-local-variable 'recentf--files-with-key) (apply 'widget-create `(group :indent 2 :format "\n%v\n" ! ,@(let ((recentf--file-count 0)) ! (mapcar 'recentf-open-files-item ! (recentf-apply-menu-filter ! recentf-menu-filter ! (mapcar 'recentf-make-default-menu-element ! (or files recentf-list))))))) ! (setq recentf--files-with-key ! (nreverse recentf--files-with-key)) (widget-create 'push-button :notify 'recentf-cancel-dialog "Cancel") (recentf-dialog-goto-first 'link))) + + (defun recentf-open-file-with-key (n) + "Open the recent file with the shortcut numeric key N. + `1' opens the first file, `2' the second file, ... `9' the ninth file. + `0' opens the tenth file." + (interactive + (list + (let ((char (string-to-char (this-command-keys)))) + (cond + ((= char ?0) 10) + ((and (>= char ?1) (<= char ?9)) (- char ?0)) + (t (error "Invalid digit key")))))) + (let ((file (nth (- n 1) recentf--files-with-key))) + (unless file (error "Not that many recent files")) + (kill-buffer (current-buffer)) + (funcall recentf-menu-action file))) (defun recentf-open-more-files () "Show a dialog to open a recent file that is not in the menu." _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel