(ispell-local-dictionary-alist): Add
[bpt/emacs.git] / lisp / recentf.el
index 76c2999..efe4ebc 100644 (file)
@@ -8,8 +8,6 @@
 ;; Maintainer: FSF
 ;; Keywords: files
 
-(defconst recentf-version "$Revision: 1.25 $")
-
 ;; This file is part of GNU Emacs.
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
@@ -78,9 +76,13 @@ See the command `recentf-save-list'."
   :type 'file)
 
 (defcustom recentf-exclude nil
-  "*List of regexps for filenames excluded from the recent list."
+"*List of regexps and predicates for filenames excluded from the recent list.
+When a filename matches any of the regexps or satisfies any of the
+predicates it is excluded from the recent list.
+A predicate is a function that is passed a filename to check and that
+must return non-nil to exclude it."
   :group 'recentf
-  :type '(repeat regexp))
+  :type '(repeat (choice regexp function)))
 
 (defun recentf-menu-customization-changed (variable value)
   "Function called when the recentf menu customization has changed.
@@ -236,6 +238,12 @@ cleanup the list."
            ;; Unavailable until recentf has been loaded.
            (recentf-auto-cleanup))))
 
+(defcustom recentf-initialize-file-name-history t
+  "*non-nil means to initialize `file-name-history' with the recent list.
+If `file-name-history' is not empty, do nothing."
+  :group 'recentf
+  :type  'boolean)
+
 (defcustom recentf-load-hook nil
    "*Normal hook run at end of loading the `recentf' package."
   :group 'recentf
@@ -343,17 +351,34 @@ process the canonical name."
              (funcall recentf-filename-handler filename))
         filename)))
 
+(defsubst recentf-file-readable-p (filename)
+  "Return t if file FILENAME exists and you can read it.
+Like the function `file-readable-p' but return nil on error."
+  (condition-case nil
+      (file-readable-p filename)
+    (error nil)))
+
 (defun recentf-include-p (filename)
-  "Return t if FILENAME match none of the `recentf-exclude' regexps."
+  "Return non-nil if FILENAME should be included in the recent list.
+That is, if it doesn't match any of the `recentf-exclude' checks."
   (let ((case-fold-search recentf-case-fold-search)
-        (rl recentf-exclude))
-    (while (and rl (not (string-match (car rl) filename)))
-      (setq rl (cdr rl)))
-    (null rl)))
+        (checks recentf-exclude)
+        (keepit t)
+        check)
+    (while (and checks keepit)
+      (setq check  (car checks)
+            checks (cdr checks)
+            keepit (not (if (stringp check)
+                            ;; A regexp
+                            (string-match check filename)
+                          ;; A predicate
+                          (funcall check filename)))))
+    keepit))
 
 (defsubst recentf-add-file (filename)
   "Add or move FILENAME at the beginning of the recent list.
-Does nothing it if it matches any of the `recentf-exclude' regexps."
+Does nothing if the name satisfies any of the `recentf-exclude' regexps or
+predicates."
   (setq filename (recentf-expand-file-name filename))
   (when (recentf-include-p filename)
     (recentf-push filename)))
@@ -361,7 +386,7 @@ Does nothing it if it matches any of the `recentf-exclude' regexps."
 (defsubst recentf-remove-if-non-readable (filename)
   "Remove FILENAME from the recent list, if file is not readable.
 Return non-nil if FILENAME has been removed."
-  (unless (file-readable-p filename)
+  (unless (recentf-file-readable-p filename)
     (let ((m (recentf-string-member
               (recentf-expand-file-name filename) recentf-list)))
       (and m (setq recentf-list (delq (car m) recentf-list))))))
@@ -1112,28 +1137,38 @@ default."
   "Save the recent list.
 Write data into the file specified by `recentf-save-file'."
   (interactive)
-  (with-temp-file (expand-file-name recentf-save-file)
-    (erase-buffer)
-    (insert (format recentf-save-file-header (current-time-string)))
-    (recentf-dump-variable 'recentf-list recentf-max-saved-items)
-    (recentf-dump-variable 'recentf-filter-changer-state)
-    nil))
+  (condition-case error
+      (with-temp-buffer
+       (erase-buffer)
+       (insert (format recentf-save-file-header (current-time-string)))
+       (recentf-dump-variable 'recentf-list recentf-max-saved-items)
+       (recentf-dump-variable 'recentf-filter-changer-state)
+       (write-file (expand-file-name recentf-save-file))
+       nil)
+    (error
+     (warn "recentf mode: %s" (error-message-string error)))))
 
 (defun recentf-load-list ()
   "Load a previously saved recent list.
-Read data from the file specified by `recentf-save-file'."
+Read data from the file specified by `recentf-save-file'.
+When `recentf-initialize-file-name-history' is non-nil, initialize an
+empty `file-name-history' with the recent list."
   (interactive)
   (let ((file (expand-file-name recentf-save-file)))
     (when (file-readable-p file)
-      (load-file file))))
+      (load-file file)
+      (and recentf-initialize-file-name-history
+           (not file-name-history)
+           (setq file-name-history (mapcar 'abbreviate-file-name
+                                           recentf-list))))))
 
 (defun recentf-cleanup ()
-  "Remove all non-readable and excluded files from the recent list."
+  "Remove all excluded or non-readable files from the recent list."
   (interactive)
   (message "Cleaning up the recentf list...")
   (let (newlist)
     (dolist (f recentf-list)
-      (if (and (recentf-include-p f) (file-readable-p f))
+      (if (and (recentf-include-p f) (recentf-file-readable-p f))
           (push f newlist)
         (message "File %s removed from the recentf list" f)))
     (setq recentf-list (nreverse newlist))