changeset 29492:94fe67994fcb

Fixed recentf-edit-list and recentf-open-more-files commands. Require `wid-edit' at run-time. Added some "Commentary". (recentf-open-more-files, recentf-edit-list): Minor changes to move the point at the top of the file list. This behaviour is consistent with the menu one when the list contains a lot of files. (recentf-cleanup): Now displays the number of items removed from the list. (recentf-relative-filter) New menu filter to show filenames relative to `default-directory'.
author Gerd Moellmann <gerd@gnu.org>
date Wed, 07 Jun 2000 15:33:22 +0000
parents bbf5694aae6a
children 0345c6ffb8b4
files lisp/recentf.el
diffstat 1 files changed, 138 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/recentf.el	Wed Jun 07 13:33:25 2000 +0000
+++ b/lisp/recentf.el	Wed Jun 07 15:33:22 2000 +0000
@@ -1,6 +1,6 @@
 ;; recentf.el --- setup a menu of recently opened files
 
-;; Copyright (C) 1999 Free Software Foundation, Inc.
+;; Copyright (C) 1999, 2000 Free Software Foundation, Inc.
 
 ;; Author: David Ponce <david.ponce@wanadoo.fr>
 ;; Created: July 19 1999
@@ -25,12 +25,22 @@
 
 ;;; Commentary:
 
+;; This package maintains a menu for visiting files that were operated
+;; on recently. When enabled a new "Open Recent" submenu is displayed
+;; in the "Files" menu. The recent files list is automatically saved
+;; across Emacs sessions.  You can customize the number of recent
+;; files displayed, the location of the menu and others options (see
+;; the source code for details).  To install and use, put the file on
+;; your Emacs-Lisp load path and add the following into your ~/.emacs
+;; startup file:
+;;
+;;  (require 'recentf)
+;;  (recentf-mode 1) 
+
 ;;; Code:
 
 (require 'easymenu)
-(require 'widget)
-(eval-when-compile
-  (require 'wid-edit))
+(require 'wid-edit)
 
 (defconst recentf-save-file-header
   ";;; Automatically generated by `recentf' on %s.\n"
@@ -124,9 +134,16 @@
 
 - - `recentf-sort-ascending' to sort menu items in ascending order.
 - - `recentf-sort-descending' to sort menu items in descending order.
+- - `recentf-sort-basenames-ascending' to sort file names in descending order.
+- - `recentf-sort-basenames-descending' to sort file names in descending order.
+- - `recentf-show-basenames' to show file names (no directories) in menu items.
+- - `recentf-show-basenames-ascending' to show file names in ascending order.
+- - `recentf-show-basenames-descending' to show file names in descending order.
+- - `recentf-relative-filter' to show file names relative to `default-directory'.
 
-The filter function is called with one argument, the list of filenames to be
-displayed in the menu and must return a new list of filenames."
+The filter function is called with one argument, the list of menu elements
+used to build the menu and must return a new list of menu elements (see
+`recentf-menu-elements' for menu element form)."
   :group 'recentf
   :type 'function
   :set 'recentf-menu-customization-changed)
@@ -143,11 +160,11 @@
   :type 'boolean
   :require 'recentf
   :initialize 'custom-initialize-default
-  :set  (lambda (sym val)
-	  (if val
-	      (remove-hook 'kill-buffer-hook 'recentf-remove-file-hook)
-	    (add-hook 'kill-buffer-hook 'recentf-remove-file-hook))
-	  (custom-set-default sym val)))
+  :set (lambda (sym val)
+         (if val
+             (remove-hook 'kill-buffer-hook 'recentf-remove-file-hook)
+           (add-hook 'kill-buffer-hook 'recentf-remove-file-hook))
+         (custom-set-default sym val)))
 
 (defcustom recentf-mode nil
   "Toggle recentf mode.
@@ -216,11 +233,11 @@
   (when recentf-update-menu-p
     (condition-case nil
         (progn
+          (setq recentf-update-menu-p nil)
           (easy-menu-change recentf-menu-path
                             recentf-menu-title
                             (recentf-make-menu-items)
-                            recentf-menu-before)
-          (setq recentf-update-menu-p nil))
+                            recentf-menu-before))
       (error nil))))
 
 ;;;###autoload
@@ -309,19 +326,26 @@
                              (message "Command canceled."))
                    "Cancel")
     (use-local-map widget-keymap)
-    (widget-setup)))
+    (widget-setup)
+    (goto-char (point-min))))
 
 ;;;###autoload
 (defun recentf-cleanup ()
   "Remove all non-readable and excluded files from `recentf-list'."
   (interactive)
-  (setq recentf-list
-        (delq nil
-              (mapcar '(lambda (filename)
-                         (and (file-readable-p filename)
-                              (recentf-include-p filename)
-                              filename))
-                      recentf-list)))
+  (let ((count (length recentf-list)))
+    (setq recentf-list
+          (delq nil
+                (mapcar '(lambda (filename)
+                           (and (file-readable-p filename)
+                                (recentf-include-p filename)
+                                filename))
+                        recentf-list)))
+    (setq count (- count (length recentf-list)))
+    (message "%s removed from the list"
+             (cond ((= count 0) "No file")
+                   ((= count 1) "One file")
+                   (t (format "%d files" count)))))
   (setq recentf-update-menu-p t))
 
 (defun recentf-open-more-files-action (widget &rest ignore)
@@ -367,7 +391,8 @@
                              (message "Command canceled."))
                    "Cancel")
     (use-local-map widget-keymap)
-    (widget-setup)))
+    (widget-setup)
+    (goto-char (point-min))))
 
 (defvar recentf-menu-items-for-commands
   (list ["Cleanup list" recentf-cleanup t]
@@ -379,10 +404,9 @@
 (defun recentf-make-menu-items ()
   "Make menu items from `recentf-list'."
   (let ((file-items
-	 (mapcar '(lambda (entry)
-		    (vector entry (list recentf-menu-action entry) t))
-		 (funcall (or recentf-menu-filter 'identity)
-			  (recentf-elements recentf-max-menu-items)))))
+         (mapcar 'recentf-make-menu-item
+                 (funcall (or recentf-menu-filter 'identity)
+                          (recentf-menu-elements recentf-max-menu-items)))))
     (append (or file-items (list ["No files" t nil]))
             (and (< recentf-max-menu-items (length recentf-list))
                  (list ["More..." recentf-open-more-files t]))
@@ -390,6 +414,10 @@
                  (cons ["---" nil nil]
                        recentf-menu-items-for-commands)))))
 
+(defun recentf-make-menu-item (menu-element)
+  "Make a menu item from a menu element (see `recentf-menu-elements')."
+  (vector (car menu-element) (list recentf-menu-action (cdr menu-element)) t))
+
 (defun recentf-add-file (filename)
   "Add or move FILENAME at the beginning of `recentf-list'.
 Does nothing if FILENAME matches one of the `recentf-exclude' regexps."
@@ -429,13 +457,93 @@
       (setq l (cdr l)))
     (nreverse lh)))
 
+(defun recentf-menu-elements (n)
+  "Return a list of the first N menu elements from `recentf-list'.
+Each menu element has this form:
+
+ (MENU-ITEM . FILE-PATH)
+
+MENU-ITEM is the menu item string displayed.
+
+FILE-PATH is the path used to open the file when the corresponding MENU-ITEM
+is selected.
+
+At the start each MENU-ITEM is set to its corresponding FILE-PATH."
+  (mapcar '(lambda (item) (cons item item)) (recentf-elements n)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Predefined menu filter functions ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 (defun recentf-sort-ascending (l)
-  "Sort the list of strings L in ascending order."
-  (sort l '(lambda (e1 e2) (string-lessp e1 e2))))
+  "Sort the list of menu elements L in ascending order.
+The MENU-ITEM part of each menu element is compared."
+  (sort l '(lambda (e1 e2) (string-lessp (car e1) (car e2)))))
 
 (defun recentf-sort-descending (l)
-  "Sort the list of strings L in descending order."
-  (sort l '(lambda (e1 e2) (string-lessp e2 e1))))
+  "Sort the list of menu elements L in descending order.
+The MENU-ITEM part of each menu element is compared."
+  (sort l '(lambda (e1 e2) (string-lessp (car e2) (car e1)))))
+
+(defun recentf-sort-basenames-ascending (l)
+  "Sort the list of menu elements L in ascending order.
+Only file names (without directories) are compared."
+  (sort l '(lambda (e1 e2) (string-lessp
+                            (file-name-nondirectory (cdr e1))
+                            (file-name-nondirectory (cdr e2))))))
+
+(defun recentf-sort-basenames-descending (l)
+  "Sort the list of menu elements L in descending order.
+Only file names (without directories) are compared."
+  (sort l '(lambda (e1 e2) (string-lessp
+                            (file-name-nondirectory (cdr e2))
+                            (file-name-nondirectory (cdr e1))))))
+
+(defun recentf-show-basenames (l)
+  "Filter the list of menu elements L to show only file names (no directories)
+in the menu. When file names are duplicated their directory component is added."
+  (let ((names  (mapcar '(lambda (item) (file-name-nondirectory (cdr item))) l))
+        (dirs   (mapcar '(lambda (item) (file-name-directory (cdr item))) l))
+        (pathes (mapcar 'cdr l))
+        (pos    -1)
+        item filtered-items filtered-list)
+    (while names
+      (setq item  (car names))
+      (setq names (cdr names))
+      (setq pos   (1+ pos))
+      (setq filtered-list
+            (cons (cons (if (or (member item names) (member item filtered-items))
+                            (concat item " (" (nth pos dirs) ")")
+                          item)
+                        (nth pos pathes))
+                  filtered-list))
+      (setq filtered-items (cons item filtered-items)))
+    (nreverse filtered-list)))
+
+(defun recentf-show-basenames-ascending (l)
+  "Filter the list of menu elements L to show only file names in the menu,
+sorted in ascending order. This filter combines the `recentf-sort-basenames-ascending'
+and `recentf-show-basenames' filters."
+  (recentf-show-basenames (recentf-sort-basenames-ascending l)))
+
+(defun recentf-show-basenames-descending (l)
+  "Filter the list of menu elements L to show only file names in the menu,
+sorted in descending order. This filter combines the `recentf-sort-basenames-descending'
+and `recentf-show-basenames' filters."
+  (recentf-show-basenames (recentf-sort-basenames-descending l)))
+
+(defun recentf-relative-filter (l)
+  "Filter the list of `recentf-menu-elements' L to show filenames
+relative to `default-directory'."
+  (setq recentf-update-menu-p t)        ; force menu update
+  (mapcar '(lambda (menu-element)
+             (let* ((ful-path (cdr menu-element))
+                    (rel-path (file-relative-name ful-path)))
+               (if (string-match "^\\.\\." rel-path)
+                   menu-element
+                 (cons rel-path ful-path))))
+          l))
 
 (provide 'recentf)