diff options
| author | Dave Love | 2000-07-24 13:39:05 +0000 |
|---|---|---|
| committer | Dave Love | 2000-07-24 13:39:05 +0000 |
| commit | bc66a9a99a20699cbdea4535df9daca5e0947283 (patch) | |
| tree | d43d9517374d67dc345e6abf97594cfcac76eeb6 | |
| parent | e024b10125c542b2b954ddb54ad455af9661547c (diff) | |
| download | emacs-bc66a9a99a20699cbdea4535df9daca5e0947283.tar.gz emacs-bc66a9a99a20699cbdea4535df9daca5e0947283.zip | |
Fix CRLF eols.
| -rw-r--r-- | lisp/recentf.el | 2120 |
1 files changed, 1060 insertions, 1060 deletions
diff --git a/lisp/recentf.el b/lisp/recentf.el index dc040be910b..82357dbe0b5 100644 --- a/lisp/recentf.el +++ b/lisp/recentf.el | |||
| @@ -1,1060 +1,1060 @@ | |||
| 1 | ;; recentf.el --- setup a menu of recently opened files | 1 | ;; recentf.el --- setup a menu of recently opened files |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1999, 2000 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1999, 2000 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: David Ponce <david@dponce.com> | 5 | ;; Author: David Ponce <david@dponce.com> |
| 6 | ;; Created: July 19 1999 | 6 | ;; Created: July 19 1999 |
| 7 | ;; Keywords: customization | 7 | ;; Keywords: customization |
| 8 | 8 | ||
| 9 | ;; This file is part of GNU Emacs. | 9 | ;; This file is part of GNU Emacs. |
| 10 | 10 | ||
| 11 | ;; GNU Emacs is free software; you can redistribute it and/or modify | 11 | ;; GNU Emacs is free software; you can redistribute it and/or modify |
| 12 | ;; it under the terms of the GNU General Public License as published by | 12 | ;; it under the terms of the GNU General Public License as published by |
| 13 | ;; the Free Software Foundation; either version 2, or (at your option) | 13 | ;; the Free Software Foundation; either version 2, or (at your option) |
| 14 | ;; any later version. | 14 | ;; any later version. |
| 15 | 15 | ||
| 16 | ;; GNU Emacs is distributed in the hope that it will be useful, | 16 | ;; GNU Emacs is distributed in the hope that it will be useful, |
| 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 19 | ;; GNU General Public License for more details. | 19 | ;; GNU General Public License for more details. |
| 20 | 20 | ||
| 21 | ;; You should have received a copy of the GNU General Public License | 21 | ;; You should have received a copy of the GNU General Public License |
| 22 | ;; along with GNU Emacs; see the file COPYING. If not, write to the | 22 | ;; along with GNU Emacs; see the file COPYING. If not, write to the |
| 23 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 23 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 24 | ;; Boston, MA 02111-1307, USA. | 24 | ;; Boston, MA 02111-1307, USA. |
| 25 | 25 | ||
| 26 | ;;; Commentary: | 26 | ;;; Commentary: |
| 27 | 27 | ||
| 28 | ;; This package maintains a menu for visiting files that were operated | 28 | ;; This package maintains a menu for visiting files that were operated |
| 29 | ;; on recently. When enabled a new "Open Recent" submenu is displayed | 29 | ;; on recently. When enabled a new "Open Recent" submenu is displayed |
| 30 | ;; in the "Files" menu. The recent files list is automatically saved | 30 | ;; in the "Files" menu. The recent files list is automatically saved |
| 31 | ;; across Emacs sessions. You can customize the number of recent | 31 | ;; across Emacs sessions. You can customize the number of recent |
| 32 | ;; files displayed, the location of the menu and others options (see | 32 | ;; files displayed, the location of the menu and others options (see |
| 33 | ;; the source code for details). To install and use, put the file on | 33 | ;; the source code for details). To install and use, put the file on |
| 34 | ;; your Emacs-Lisp load path and add the following into your ~/.emacs | 34 | ;; your Emacs-Lisp load path and add the following into your ~/.emacs |
| 35 | ;; startup file: | 35 | ;; startup file: |
| 36 | ;; | 36 | ;; |
| 37 | ;; (require 'recentf) | 37 | ;; (require 'recentf) |
| 38 | ;; (recentf-mode 1) | 38 | ;; (recentf-mode 1) |
| 39 | 39 | ||
| 40 | ;;; Code: | 40 | ;;; Code: |
| 41 | 41 | ||
| 42 | (require 'easymenu) | 42 | (require 'easymenu) |
| 43 | (require 'wid-edit) | 43 | (require 'wid-edit) |
| 44 | 44 | ||
| 45 | (defconst recentf-save-file-header | 45 | (defconst recentf-save-file-header |
| 46 | ";;; Automatically generated by `recentf' on %s.\n" | 46 | ";;; Automatically generated by `recentf' on %s.\n" |
| 47 | "Header to be written into the `recentf-save-file'.") | 47 | "Header to be written into the `recentf-save-file'.") |
| 48 | 48 | ||
| 49 | (defvar recentf-list nil | 49 | (defvar recentf-list nil |
| 50 | "List of recently opened files.") | 50 | "List of recently opened files.") |
| 51 | 51 | ||
| 52 | (defvar recentf-update-menu-p t | 52 | (defvar recentf-update-menu-p t |
| 53 | "Non-nil if the recentf menu must be updated.") | 53 | "Non-nil if the recentf menu must be updated.") |
| 54 | 54 | ||
| 55 | (defvar recentf-initialized-p nil | 55 | (defvar recentf-initialized-p nil |
| 56 | "Non-nil if recentf already initialized.") | 56 | "Non-nil if recentf already initialized.") |
| 57 | 57 | ||
| 58 | ;; IMPORTANT: This function must be defined before the following defcustoms | 58 | ;; IMPORTANT: This function must be defined before the following defcustoms |
| 59 | ;; because it is used in their :set clause. To avoid byte-compiler warnings | 59 | ;; because it is used in their :set clause. To avoid byte-compiler warnings |
| 60 | ;; the `symbol-value' function is used to access the `recentf-menu-path' | 60 | ;; the `symbol-value' function is used to access the `recentf-menu-path' |
| 61 | ;; and `recentf-menu-title' values. | 61 | ;; and `recentf-menu-title' values. |
| 62 | (defun recentf-menu-customization-changed (sym val) | 62 | (defun recentf-menu-customization-changed (sym val) |
| 63 | "Function called when menu customization has changed. | 63 | "Function called when menu customization has changed. |
| 64 | It removes the recentf menu and forces its complete redrawing." | 64 | It removes the recentf menu and forces its complete redrawing." |
| 65 | (when recentf-initialized-p | 65 | (when recentf-initialized-p |
| 66 | (easy-menu-remove-item nil | 66 | (easy-menu-remove-item nil |
| 67 | (symbol-value 'recentf-menu-path) | 67 | (symbol-value 'recentf-menu-path) |
| 68 | (symbol-value 'recentf-menu-title)) | 68 | (symbol-value 'recentf-menu-title)) |
| 69 | (setq recentf-update-menu-p t)) | 69 | (setq recentf-update-menu-p t)) |
| 70 | (custom-set-default sym val)) | 70 | (custom-set-default sym val)) |
| 71 | 71 | ||
| 72 | (defgroup recentf nil | 72 | (defgroup recentf nil |
| 73 | "Maintain a menu of recently opened files." | 73 | "Maintain a menu of recently opened files." |
| 74 | :version "21.1" | 74 | :version "21.1" |
| 75 | :group 'files) | 75 | :group 'files) |
| 76 | 76 | ||
| 77 | (defgroup recentf-filters nil | 77 | (defgroup recentf-filters nil |
| 78 | "Group to customize recentf menu filters. | 78 | "Group to customize recentf menu filters. |
| 79 | You should define the options of your own filters in this group." | 79 | You should define the options of your own filters in this group." |
| 80 | :group 'recentf) | 80 | :group 'recentf) |
| 81 | 81 | ||
| 82 | (defcustom recentf-max-saved-items 20 | 82 | (defcustom recentf-max-saved-items 20 |
| 83 | "*Maximum number of items saved to `recentf-save-file'." | 83 | "*Maximum number of items saved to `recentf-save-file'." |
| 84 | :group 'recentf | 84 | :group 'recentf |
| 85 | :type 'integer) | 85 | :type 'integer) |
| 86 | 86 | ||
| 87 | (defcustom recentf-save-file (expand-file-name "~/.recentf") | 87 | (defcustom recentf-save-file (expand-file-name "~/.recentf") |
| 88 | "*File to save `recentf-list' into." | 88 | "*File to save `recentf-list' into." |
| 89 | :group 'recentf | 89 | :group 'recentf |
| 90 | :type 'file) | 90 | :type 'file) |
| 91 | 91 | ||
| 92 | (defcustom recentf-exclude nil | 92 | (defcustom recentf-exclude nil |
| 93 | "*List of regexps for filenames excluded from `recentf-list'." | 93 | "*List of regexps for filenames excluded from `recentf-list'." |
| 94 | :group 'recentf | 94 | :group 'recentf |
| 95 | :type '(repeat regexp)) | 95 | :type '(repeat regexp)) |
| 96 | 96 | ||
| 97 | (defcustom recentf-menu-title "Open Recent" | 97 | (defcustom recentf-menu-title "Open Recent" |
| 98 | "*Name of the recentf menu." | 98 | "*Name of the recentf menu." |
| 99 | :group 'recentf | 99 | :group 'recentf |
| 100 | :type 'string | 100 | :type 'string |
| 101 | :set 'recentf-menu-customization-changed) | 101 | :set 'recentf-menu-customization-changed) |
| 102 | 102 | ||
| 103 | (defcustom recentf-menu-path '("files") | 103 | (defcustom recentf-menu-path '("files") |
| 104 | "*Path where to add the recentf menu. | 104 | "*Path where to add the recentf menu. |
| 105 | If nil add it at top-level (see also `easy-menu-change')." | 105 | If nil add it at top-level (see also `easy-menu-change')." |
| 106 | :group 'recentf | 106 | :group 'recentf |
| 107 | :type '(choice (const :tag "Top Level" nil) | 107 | :type '(choice (const :tag "Top Level" nil) |
| 108 | (sexp :tag "Menu Path")) | 108 | (sexp :tag "Menu Path")) |
| 109 | :set 'recentf-menu-customization-changed) | 109 | :set 'recentf-menu-customization-changed) |
| 110 | 110 | ||
| 111 | (defcustom recentf-menu-before "open-file" | 111 | (defcustom recentf-menu-before "open-file" |
| 112 | "*Name of the menu before which the recentf menu will be added. | 112 | "*Name of the menu before which the recentf menu will be added. |
| 113 | If nil add it at end of menu (see also `easy-menu-change')." | 113 | If nil add it at end of menu (see also `easy-menu-change')." |
| 114 | :group 'recentf | 114 | :group 'recentf |
| 115 | :type '(choice (string :tag "Name") | 115 | :type '(choice (string :tag "Name") |
| 116 | (const :tag "Last" nil)) | 116 | (const :tag "Last" nil)) |
| 117 | :set 'recentf-menu-customization-changed) | 117 | :set 'recentf-menu-customization-changed) |
| 118 | 118 | ||
| 119 | (defcustom recentf-menu-action 'recentf-find-file | 119 | (defcustom recentf-menu-action 'recentf-find-file |
| 120 | "*Function to invoke with a filename item of the recentf menu. | 120 | "*Function to invoke with a filename item of the recentf menu. |
| 121 | The default action `recentf-find-file' calls `find-file' to edit an | 121 | The default action `recentf-find-file' calls `find-file' to edit an |
| 122 | existing file. If the file does not exist or is not readable, it is | 122 | existing file. If the file does not exist or is not readable, it is |
| 123 | not edited and its name is removed from `recentf-list'. You can use | 123 | not edited and its name is removed from `recentf-list'. You can use |
| 124 | `find-file' instead to open non-existing files and keep them in the | 124 | `find-file' instead to open non-existing files and keep them in the |
| 125 | list of recently opened files." | 125 | list of recently opened files." |
| 126 | :group 'recentf | 126 | :group 'recentf |
| 127 | :type 'function | 127 | :type 'function |
| 128 | :set 'recentf-menu-customization-changed) | 128 | :set 'recentf-menu-customization-changed) |
| 129 | 129 | ||
| 130 | (defcustom recentf-max-menu-items 10 | 130 | (defcustom recentf-max-menu-items 10 |
| 131 | "*Maximum number of items in the recentf menu." | 131 | "*Maximum number of items in the recentf menu." |
| 132 | :group 'recentf | 132 | :group 'recentf |
| 133 | :type 'integer | 133 | :type 'integer |
| 134 | :set 'recentf-menu-customization-changed) | 134 | :set 'recentf-menu-customization-changed) |
| 135 | 135 | ||
| 136 | (defcustom recentf-menu-filter nil | 136 | (defcustom recentf-menu-filter nil |
| 137 | "*Function used to filter files displayed in the recentf menu. | 137 | "*Function used to filter files displayed in the recentf menu. |
| 138 | Nil means no filter. The following functions are predefined: | 138 | Nil means no filter. The following functions are predefined: |
| 139 | 139 | ||
| 140 | - - `recentf-sort-ascending' to sort menu items in ascending order. | 140 | - - `recentf-sort-ascending' to sort menu items in ascending order. |
| 141 | - - `recentf-sort-descending' to sort menu items in descending order. | 141 | - - `recentf-sort-descending' to sort menu items in descending order. |
| 142 | - - `recentf-sort-basenames-ascending' to sort file names in descending order. | 142 | - - `recentf-sort-basenames-ascending' to sort file names in descending order. |
| 143 | - - `recentf-sort-basenames-descending' to sort file names in descending order. | 143 | - - `recentf-sort-basenames-descending' to sort file names in descending order. |
| 144 | - - `recentf-sort-directories-ascending' to sort directories in ascending order. | 144 | - - `recentf-sort-directories-ascending' to sort directories in ascending order. |
| 145 | - - `recentf-sort-directories-descending' to sort directories in descending order. | 145 | - - `recentf-sort-directories-descending' to sort directories in descending order. |
| 146 | - - `recentf-show-basenames' to show file names (no directories) in menu items. | 146 | - - `recentf-show-basenames' to show file names (no directories) in menu items. |
| 147 | - - `recentf-show-basenames-ascending' to show file names in ascending order. | 147 | - - `recentf-show-basenames-ascending' to show file names in ascending order. |
| 148 | - - `recentf-show-basenames-descending' to show file names in descending order. | 148 | - - `recentf-show-basenames-descending' to show file names in descending order. |
| 149 | - - `recentf-relative-filter' to show file names relative to `default-directory'. | 149 | - - `recentf-relative-filter' to show file names relative to `default-directory'. |
| 150 | - - `recentf-arrange-by-rule' to show sub-menus following user defined rules. | 150 | - - `recentf-arrange-by-rule' to show sub-menus following user defined rules. |
| 151 | - - `recentf-arrange-by-mode' to show a sub-menu for each major mode. | 151 | - - `recentf-arrange-by-mode' to show a sub-menu for each major mode. |
| 152 | - - `recentf-arrange-by-dir' to show a sub-menu for each directory. | 152 | - - `recentf-arrange-by-dir' to show a sub-menu for each directory. |
| 153 | - - `recentf-filter-changer' to manage a ring of filters. | 153 | - - `recentf-filter-changer' to manage a ring of filters. |
| 154 | 154 | ||
| 155 | The filter function is called with one argument, the list of menu elements | 155 | The filter function is called with one argument, the list of menu elements |
| 156 | used to build the menu and must return a new list of menu elements (see | 156 | used to build the menu and must return a new list of menu elements (see |
| 157 | `recentf-make-menu-element' for menu element form)." | 157 | `recentf-make-menu-element' for menu element form)." |
| 158 | :group 'recentf | 158 | :group 'recentf |
| 159 | :type 'function | 159 | :type 'function |
| 160 | :set 'recentf-menu-customization-changed) | 160 | :set 'recentf-menu-customization-changed) |
| 161 | 161 | ||
| 162 | (defcustom recentf-menu-append-commands-p t | 162 | (defcustom recentf-menu-append-commands-p t |
| 163 | "*If not-nil command items are appended to the menu." | 163 | "*If not-nil command items are appended to the menu." |
| 164 | :group 'recentf | 164 | :group 'recentf |
| 165 | :type 'boolean | 165 | :type 'boolean |
| 166 | :set 'recentf-menu-customization-changed) | 166 | :set 'recentf-menu-customization-changed) |
| 167 | 167 | ||
| 168 | (defcustom recentf-keep-non-readable-files-p nil | 168 | (defcustom recentf-keep-non-readable-files-p nil |
| 169 | "*If nil (default), non-readable files are not kept in `recentf-list'." | 169 | "*If nil (default), non-readable files are not kept in `recentf-list'." |
| 170 | :group 'recentf | 170 | :group 'recentf |
| 171 | :type 'boolean | 171 | :type 'boolean |
| 172 | :require 'recentf | 172 | :require 'recentf |
| 173 | :initialize 'custom-initialize-default | 173 | :initialize 'custom-initialize-default |
| 174 | :set (lambda (sym val) | 174 | :set (lambda (sym val) |
| 175 | (if val | 175 | (if val |
| 176 | (remove-hook 'kill-buffer-hook 'recentf-remove-file-hook) | 176 | (remove-hook 'kill-buffer-hook 'recentf-remove-file-hook) |
| 177 | (add-hook 'kill-buffer-hook 'recentf-remove-file-hook)) | 177 | (add-hook 'kill-buffer-hook 'recentf-remove-file-hook)) |
| 178 | (custom-set-default sym val))) | 178 | (custom-set-default sym val))) |
| 179 | 179 | ||
| 180 | (defcustom recentf-mode nil | 180 | (defcustom recentf-mode nil |
| 181 | "Toggle recentf mode. | 181 | "Toggle recentf mode. |
| 182 | When recentf mode is enabled, it maintains a menu for visiting files that | 182 | When recentf mode is enabled, it maintains a menu for visiting files that |
| 183 | were operated on recently. | 183 | were operated on recently. |
| 184 | Setting this variable directly does not take effect; | 184 | Setting this variable directly does not take effect; |
| 185 | use either \\[customize] or the function `recentf-mode'." | 185 | use either \\[customize] or the function `recentf-mode'." |
| 186 | :set (lambda (symbol value) | 186 | :set (lambda (symbol value) |
| 187 | (recentf-mode (or value 0))) | 187 | (recentf-mode (or value 0))) |
| 188 | :initialize 'custom-initialize-default | 188 | :initialize 'custom-initialize-default |
| 189 | :type 'boolean | 189 | :type 'boolean |
| 190 | :group 'recentf | 190 | :group 'recentf |
| 191 | :require 'recentf) | 191 | :require 'recentf) |
| 192 | 192 | ||
| 193 | (defcustom recentf-load-hook nil | 193 | (defcustom recentf-load-hook nil |
| 194 | "*Normal hook run at end of loading the `recentf' package." | 194 | "*Normal hook run at end of loading the `recentf' package." |
| 195 | :group 'recentf | 195 | :group 'recentf |
| 196 | :type 'hook) | 196 | :type 'hook) |
| 197 | 197 | ||
| 198 | ;;; | 198 | ;;; |
| 199 | ;;; Common functions | 199 | ;;; Common functions |
| 200 | ;;; | 200 | ;;; |
| 201 | (defconst recentf-case-fold-search | 201 | (defconst recentf-case-fold-search |
| 202 | (memq system-type '(vax-vms windows-nt)) | 202 | (memq system-type '(vax-vms windows-nt)) |
| 203 | "Non-nil if recentf searches and matches should ignore case.") | 203 | "Non-nil if recentf searches and matches should ignore case.") |
| 204 | 204 | ||
| 205 | (defun recentf-include-p (filename) | 205 | (defun recentf-include-p (filename) |
| 206 | "Return t if FILENAME matches none of the `recentf-exclude' regexps." | 206 | "Return t if FILENAME matches none of the `recentf-exclude' regexps." |
| 207 | (let ((case-fold-search recentf-case-fold-search) | 207 | (let ((case-fold-search recentf-case-fold-search) |
| 208 | (rl recentf-exclude)) | 208 | (rl recentf-exclude)) |
| 209 | (while (and rl (not (string-match (car rl) filename))) | 209 | (while (and rl (not (string-match (car rl) filename))) |
| 210 | (setq rl (cdr rl))) | 210 | (setq rl (cdr rl))) |
| 211 | (null rl))) | 211 | (null rl))) |
| 212 | 212 | ||
| 213 | (defun recentf-add-file (filename) | 213 | (defun recentf-add-file (filename) |
| 214 | "Add or move FILENAME at the beginning of `recentf-list'. | 214 | "Add or move FILENAME at the beginning of `recentf-list'. |
| 215 | Does nothing if FILENAME matches one of the `recentf-exclude' regexps." | 215 | Does nothing if FILENAME matches one of the `recentf-exclude' regexps." |
| 216 | (let ((filename (expand-file-name filename))) | 216 | (let ((filename (expand-file-name filename))) |
| 217 | (when (recentf-include-p filename) | 217 | (when (recentf-include-p filename) |
| 218 | (setq recentf-list (cons filename (delete filename recentf-list))) | 218 | (setq recentf-list (cons filename (delete filename recentf-list))) |
| 219 | (setq recentf-update-menu-p t)))) | 219 | (setq recentf-update-menu-p t)))) |
| 220 | 220 | ||
| 221 | (defun recentf-remove-if-non-readable (filename) | 221 | (defun recentf-remove-if-non-readable (filename) |
| 222 | "Remove FILENAME from `recentf-list' if not readable." | 222 | "Remove FILENAME from `recentf-list' if not readable." |
| 223 | (unless (file-readable-p filename) | 223 | (unless (file-readable-p filename) |
| 224 | (setq recentf-list (delete filename recentf-list)) | 224 | (setq recentf-list (delete filename recentf-list)) |
| 225 | (setq recentf-update-menu-p t))) | 225 | (setq recentf-update-menu-p t))) |
| 226 | 226 | ||
| 227 | (defun recentf-find-file (filename) | 227 | (defun recentf-find-file (filename) |
| 228 | "Edit file FILENAME using `find-file'. | 228 | "Edit file FILENAME using `find-file'. |
| 229 | If FILENAME is not readable it is removed from `recentf-list'." | 229 | If FILENAME is not readable it is removed from `recentf-list'." |
| 230 | (if (file-readable-p filename) | 230 | (if (file-readable-p filename) |
| 231 | (find-file filename) | 231 | (find-file filename) |
| 232 | (progn | 232 | (progn |
| 233 | (message "File `%s' not found." filename) | 233 | (message "File `%s' not found." filename) |
| 234 | (setq recentf-list (delete filename recentf-list)) | 234 | (setq recentf-list (delete filename recentf-list)) |
| 235 | (setq recentf-update-menu-p t)))) | 235 | (setq recentf-update-menu-p t)))) |
| 236 | 236 | ||
| 237 | (defun recentf-trunc-list (l n) | 237 | (defun recentf-trunc-list (l n) |
| 238 | "Return a list of the first N elements of L." | 238 | "Return a list of the first N elements of L." |
| 239 | (let ((lh nil)) | 239 | (let ((lh nil)) |
| 240 | (while (and l (> n 0)) | 240 | (while (and l (> n 0)) |
| 241 | (setq lh (cons (car l) lh)) | 241 | (setq lh (cons (car l) lh)) |
| 242 | (setq n (1- n)) | 242 | (setq n (1- n)) |
| 243 | (setq l (cdr l))) | 243 | (setq l (cdr l))) |
| 244 | (nreverse lh))) | 244 | (nreverse lh))) |
| 245 | 245 | ||
| 246 | (defun recentf-elements (n) | 246 | (defun recentf-elements (n) |
| 247 | "Return a list of the first N elements of `recentf-list'." | 247 | "Return a list of the first N elements of `recentf-list'." |
| 248 | (recentf-trunc-list recentf-list n)) | 248 | (recentf-trunc-list recentf-list n)) |
| 249 | 249 | ||
| 250 | (defun recentf-make-menu-element (menu-item menu-value) | 250 | (defun recentf-make-menu-element (menu-item menu-value) |
| 251 | "Create a new menu-element. | 251 | "Create a new menu-element. |
| 252 | 252 | ||
| 253 | A menu element is a pair (MENU-ITEM . MENU-VALUE) where: | 253 | A menu element is a pair (MENU-ITEM . MENU-VALUE) where: |
| 254 | 254 | ||
| 255 | - - MENU-ITEM is the menu item string displayed. | 255 | - - MENU-ITEM is the menu item string displayed. |
| 256 | - - MENU-VALUE is the path used to open the file when the | 256 | - - MENU-VALUE is the path used to open the file when the |
| 257 | corresponding MENU-ITEM is selected. Or it is | 257 | corresponding MENU-ITEM is selected. Or it is |
| 258 | a pair (SUB-MENU-TITLE . MENU-ELEMENTS) where | 258 | a pair (SUB-MENU-TITLE . MENU-ELEMENTS) where |
| 259 | SUB-MENU-TITLE is a sub-menu title and | 259 | SUB-MENU-TITLE is a sub-menu title and |
| 260 | MENU-ELEMENTS is the list of menu elements in | 260 | MENU-ELEMENTS is the list of menu elements in |
| 261 | the sub-menu." | 261 | the sub-menu." |
| 262 | (cons menu-item menu-value)) | 262 | (cons menu-item menu-value)) |
| 263 | 263 | ||
| 264 | (defun recentf-menu-element-item (e) | 264 | (defun recentf-menu-element-item (e) |
| 265 | "Return the item part of the menu-element E." | 265 | "Return the item part of the menu-element E." |
| 266 | (car e)) | 266 | (car e)) |
| 267 | 267 | ||
| 268 | (defun recentf-menu-element-value (e) | 268 | (defun recentf-menu-element-value (e) |
| 269 | "Return the value part of the menu-element E." | 269 | "Return the value part of the menu-element E." |
| 270 | (cdr e)) | 270 | (cdr e)) |
| 271 | 271 | ||
| 272 | (defun recentf-set-menu-element-item (e item) | 272 | (defun recentf-set-menu-element-item (e item) |
| 273 | "Change the item part of menu-element E to ITEM." | 273 | "Change the item part of menu-element E to ITEM." |
| 274 | (setcar e item)) | 274 | (setcar e item)) |
| 275 | 275 | ||
| 276 | (defun recentf-set-menu-element-value (e value) | 276 | (defun recentf-set-menu-element-value (e value) |
| 277 | "Change the value part of menu-element E to VALUE." | 277 | "Change the value part of menu-element E to VALUE." |
| 278 | (setcdr e value)) | 278 | (setcdr e value)) |
| 279 | 279 | ||
| 280 | (defun recentf-sub-menu-element-p (e) | 280 | (defun recentf-sub-menu-element-p (e) |
| 281 | "Return non-nil if menu-element E defines a sub-menu." | 281 | "Return non-nil if menu-element E defines a sub-menu." |
| 282 | (consp (recentf-menu-element-value e))) | 282 | (consp (recentf-menu-element-value e))) |
| 283 | 283 | ||
| 284 | (defun recentf-make-default-menu-element (file-path) | 284 | (defun recentf-make-default-menu-element (file-path) |
| 285 | "Make a new default menu element (MENU-ITEM . MENU-VALUE) for the | 285 | "Make a new default menu element (MENU-ITEM . MENU-VALUE) for the |
| 286 | given recent file path FILE-PATH. MENU-ITEM and MENU-VALUE are set to | 286 | given recent file path FILE-PATH. MENU-ITEM and MENU-VALUE are set to |
| 287 | FILE-PATH. See also `recentf-make-menu-element'." | 287 | FILE-PATH. See also `recentf-make-menu-element'." |
| 288 | (recentf-make-menu-element file-path file-path)) | 288 | (recentf-make-menu-element file-path file-path)) |
| 289 | 289 | ||
| 290 | (defun recentf-menu-elements (n) | 290 | (defun recentf-menu-elements (n) |
| 291 | "Return a list of the first N default menu elements from | 291 | "Return a list of the first N default menu elements from |
| 292 | `recentf-list'. See also `recentf-make-default-menu-element'." | 292 | `recentf-list'. See also `recentf-make-default-menu-element'." |
| 293 | (mapcar 'recentf-make-default-menu-element | 293 | (mapcar 'recentf-make-default-menu-element |
| 294 | (recentf-elements n))) | 294 | (recentf-elements n))) |
| 295 | 295 | ||
| 296 | (defun recentf-apply-menu-filter (filter l) | 296 | (defun recentf-apply-menu-filter (filter l) |
| 297 | "Convenient funtion to apply the function FILTER to the list of | 297 | "Convenient funtion to apply the function FILTER to the list of |
| 298 | menu-elements L. It takes care of sub-menu elements in L and | 298 | menu-elements L. It takes care of sub-menu elements in L and |
| 299 | recursively apply FILTER to them. It is guarantee than FILTER receives | 299 | recursively apply FILTER to them. It is guarantee than FILTER receives |
| 300 | only a list of single menu-elements (no sub-menu)." | 300 | only a list of single menu-elements (no sub-menu)." |
| 301 | (if (and (functionp filter) l) | 301 | (if (and (functionp filter) l) |
| 302 | (let ((case-fold-search recentf-case-fold-search) | 302 | (let ((case-fold-search recentf-case-fold-search) |
| 303 | menu-element sub-menu-elements single-elements) | 303 | menu-element sub-menu-elements single-elements) |
| 304 | ;; split L in two sub-listes: | 304 | ;; split L in two sub-listes: |
| 305 | ;; one of sub-menus elements and | 305 | ;; one of sub-menus elements and |
| 306 | ;; one of single menu elements | 306 | ;; one of single menu elements |
| 307 | (while l | 307 | (while l |
| 308 | (setq menu-element (car l)) | 308 | (setq menu-element (car l)) |
| 309 | (if (recentf-sub-menu-element-p menu-element) | 309 | (if (recentf-sub-menu-element-p menu-element) |
| 310 | (setq sub-menu-elements | 310 | (setq sub-menu-elements |
| 311 | (cons menu-element sub-menu-elements)) | 311 | (cons menu-element sub-menu-elements)) |
| 312 | (setq single-elements | 312 | (setq single-elements |
| 313 | (cons menu-element single-elements))) | 313 | (cons menu-element single-elements))) |
| 314 | (setq l (cdr l))) | 314 | (setq l (cdr l))) |
| 315 | ;; apply FILTER to the list of single menu elements | 315 | ;; apply FILTER to the list of single menu elements |
| 316 | (if single-elements | 316 | (if single-elements |
| 317 | (setq single-elements (funcall filter | 317 | (setq single-elements (funcall filter |
| 318 | (nreverse single-elements)))) | 318 | (nreverse single-elements)))) |
| 319 | ;; apply FILTER to sub-menu menu element list | 319 | ;; apply FILTER to sub-menu menu element list |
| 320 | (setq l sub-menu-elements) | 320 | (setq l sub-menu-elements) |
| 321 | (setq sub-menu-elements nil) | 321 | (setq sub-menu-elements nil) |
| 322 | (while l | 322 | (while l |
| 323 | (setq menu-element (car l)) | 323 | (setq menu-element (car l)) |
| 324 | (recentf-set-menu-element-value | 324 | (recentf-set-menu-element-value |
| 325 | menu-element | 325 | menu-element |
| 326 | (recentf-apply-menu-filter | 326 | (recentf-apply-menu-filter |
| 327 | filter | 327 | filter |
| 328 | (recentf-menu-element-value menu-element))) | 328 | (recentf-menu-element-value menu-element))) |
| 329 | (setq sub-menu-elements (cons menu-element sub-menu-elements)) | 329 | (setq sub-menu-elements (cons menu-element sub-menu-elements)) |
| 330 | (setq l (cdr l))) | 330 | (setq l (cdr l))) |
| 331 | ;; build and return the new filtered menu element list | 331 | ;; build and return the new filtered menu element list |
| 332 | (nconc sub-menu-elements single-elements)) | 332 | (nconc sub-menu-elements single-elements)) |
| 333 | l)) | 333 | l)) |
| 334 | 334 | ||
| 335 | (defvar recentf-menu-items-for-commands | 335 | (defvar recentf-menu-items-for-commands |
| 336 | (list ["Cleanup list" recentf-cleanup t] | 336 | (list ["Cleanup list" recentf-cleanup t] |
| 337 | ["Edit list..." recentf-edit-list t] | 337 | ["Edit list..." recentf-edit-list t] |
| 338 | ["Save list now" recentf-save-list t] | 338 | ["Save list now" recentf-save-list t] |
| 339 | (vector "Recentf Options..." '(customize-group "recentf") t)) | 339 | (vector "Recentf Options..." '(customize-group "recentf") t)) |
| 340 | "List of menu items for recentf commands.") | 340 | "List of menu items for recentf commands.") |
| 341 | 341 | ||
| 342 | (defvar recentf-menu-filter-commands nil | 342 | (defvar recentf-menu-filter-commands nil |
| 343 | "This variable can be used by menu filters to setup their own command menu. | 343 | "This variable can be used by menu filters to setup their own command menu. |
| 344 | 344 | ||
| 345 | If non-nil it must contain a list of valid menu-items to be appended | 345 | If non-nil it must contain a list of valid menu-items to be appended |
| 346 | to the recent file list part of the menu. Before calling a menu | 346 | to the recent file list part of the menu. Before calling a menu |
| 347 | filter function this variable is reset to nil.") | 347 | filter function this variable is reset to nil.") |
| 348 | 348 | ||
| 349 | (defun recentf-make-menu-items () | 349 | (defun recentf-make-menu-items () |
| 350 | "Make menu items from `recentf-list'." | 350 | "Make menu items from `recentf-list'." |
| 351 | (setq recentf-menu-filter-commands nil) | 351 | (setq recentf-menu-filter-commands nil) |
| 352 | (let ((file-items | 352 | (let ((file-items |
| 353 | (mapcar 'recentf-make-menu-item | 353 | (mapcar 'recentf-make-menu-item |
| 354 | (recentf-apply-menu-filter | 354 | (recentf-apply-menu-filter |
| 355 | recentf-menu-filter | 355 | recentf-menu-filter |
| 356 | (recentf-menu-elements recentf-max-menu-items))))) | 356 | (recentf-menu-elements recentf-max-menu-items))))) |
| 357 | (append (or file-items (list ["No files" t nil])) | 357 | (append (or file-items (list ["No files" t nil])) |
| 358 | (and (< recentf-max-menu-items (length recentf-list)) | 358 | (and (< recentf-max-menu-items (length recentf-list)) |
| 359 | (list ["More..." recentf-open-more-files t])) | 359 | (list ["More..." recentf-open-more-files t])) |
| 360 | (and recentf-menu-filter-commands | 360 | (and recentf-menu-filter-commands |
| 361 | (cons "---" | 361 | (cons "---" |
| 362 | recentf-menu-filter-commands)) | 362 | recentf-menu-filter-commands)) |
| 363 | (and recentf-menu-append-commands-p | 363 | (and recentf-menu-append-commands-p |
| 364 | (cons "---" | 364 | (cons "---" |
| 365 | recentf-menu-items-for-commands))))) | 365 | recentf-menu-items-for-commands))))) |
| 366 | 366 | ||
| 367 | (defun recentf-make-menu-item (menu-element) | 367 | (defun recentf-make-menu-item (menu-element) |
| 368 | "Make a menu item from a menu element (see `recentf-make-menu-element')." | 368 | "Make a menu item from a menu element (see `recentf-make-menu-element')." |
| 369 | (let ((menu-item (recentf-menu-element-item menu-element)) | 369 | (let ((menu-item (recentf-menu-element-item menu-element)) |
| 370 | (menu-value (recentf-menu-element-value menu-element))) | 370 | (menu-value (recentf-menu-element-value menu-element))) |
| 371 | (if (recentf-sub-menu-element-p menu-element) | 371 | (if (recentf-sub-menu-element-p menu-element) |
| 372 | (cons menu-item (mapcar 'recentf-make-menu-item menu-value)) | 372 | (cons menu-item (mapcar 'recentf-make-menu-item menu-value)) |
| 373 | (vector menu-item | 373 | (vector menu-item |
| 374 | (list recentf-menu-action menu-value) | 374 | (list recentf-menu-action menu-value) |
| 375 | t)))) | 375 | t)))) |
| 376 | 376 | ||
| 377 | ;;; | 377 | ;;; |
| 378 | ;;; Predefined menu filter functions | 378 | ;;; Predefined menu filter functions |
| 379 | ;;; | 379 | ;;; |
| 380 | 380 | ||
| 381 | (defun recentf-sort-ascending (l) | 381 | (defun recentf-sort-ascending (l) |
| 382 | "Sort the list of menu elements L in ascending order. | 382 | "Sort the list of menu elements L in ascending order. |
| 383 | The MENU-ITEM part of each menu element is compared." | 383 | The MENU-ITEM part of each menu element is compared." |
| 384 | (sort (copy-sequence l) | 384 | (sort (copy-sequence l) |
| 385 | (function | 385 | (function |
| 386 | (lambda (e1 e2) | 386 | (lambda (e1 e2) |
| 387 | (string-lessp (recentf-menu-element-item e1) | 387 | (string-lessp (recentf-menu-element-item e1) |
| 388 | (recentf-menu-element-item e2)))))) | 388 | (recentf-menu-element-item e2)))))) |
| 389 | 389 | ||
| 390 | (defun recentf-sort-descending (l) | 390 | (defun recentf-sort-descending (l) |
| 391 | "Sort the list of menu elements L in descending order. | 391 | "Sort the list of menu elements L in descending order. |
| 392 | The MENU-ITEM part of each menu element is compared." | 392 | The MENU-ITEM part of each menu element is compared." |
| 393 | (sort (copy-sequence l) | 393 | (sort (copy-sequence l) |
| 394 | (function | 394 | (function |
| 395 | (lambda (e1 e2) | 395 | (lambda (e1 e2) |
| 396 | (string-lessp (recentf-menu-element-item e2) | 396 | (string-lessp (recentf-menu-element-item e2) |
| 397 | (recentf-menu-element-item e1)))))) | 397 | (recentf-menu-element-item e1)))))) |
| 398 | 398 | ||
| 399 | (defun recentf-sort-basenames-ascending (l) | 399 | (defun recentf-sort-basenames-ascending (l) |
| 400 | "Sort the list of menu elements L in ascending order. | 400 | "Sort the list of menu elements L in ascending order. |
| 401 | Only file names (without directories) are compared." | 401 | Only file names (without directories) are compared." |
| 402 | (sort (copy-sequence l) | 402 | (sort (copy-sequence l) |
| 403 | (function | 403 | (function |
| 404 | (lambda (e1 e2) | 404 | (lambda (e1 e2) |
| 405 | (string-lessp | 405 | (string-lessp |
| 406 | (file-name-nondirectory (recentf-menu-element-value e1)) | 406 | (file-name-nondirectory (recentf-menu-element-value e1)) |
| 407 | (file-name-nondirectory (recentf-menu-element-value e2))))))) | 407 | (file-name-nondirectory (recentf-menu-element-value e2))))))) |
| 408 | 408 | ||
| 409 | (defun recentf-sort-basenames-descending (l) | 409 | (defun recentf-sort-basenames-descending (l) |
| 410 | "Sort the list of menu elements L in descending order. | 410 | "Sort the list of menu elements L in descending order. |
| 411 | Only file names (without directories) are compared." | 411 | Only file names (without directories) are compared." |
| 412 | (sort (copy-sequence l) | 412 | (sort (copy-sequence l) |
| 413 | (function | 413 | (function |
| 414 | (lambda (e1 e2) | 414 | (lambda (e1 e2) |
| 415 | (string-lessp | 415 | (string-lessp |
| 416 | (file-name-nondirectory (recentf-menu-element-value e2)) | 416 | (file-name-nondirectory (recentf-menu-element-value e2)) |
| 417 | (file-name-nondirectory (recentf-menu-element-value e1))))))) | 417 | (file-name-nondirectory (recentf-menu-element-value e1))))))) |
| 418 | 418 | ||
| 419 | (defun recentf-directory-compare (p1 p2) | 419 | (defun recentf-directory-compare (p1 p2) |
| 420 | "Compare directories then filenames in pathes P1 and P2 and return | 420 | "Compare directories then filenames in pathes P1 and P2 and return |
| 421 | non-nil if P1 is less than P2." | 421 | non-nil if P1 is less than P2." |
| 422 | (let ((d1 (file-name-directory p1)) | 422 | (let ((d1 (file-name-directory p1)) |
| 423 | (f1 (file-name-nondirectory p1)) | 423 | (f1 (file-name-nondirectory p1)) |
| 424 | (d2 (file-name-directory p2)) | 424 | (d2 (file-name-directory p2)) |
| 425 | (f2 (file-name-nondirectory p2))) | 425 | (f2 (file-name-nondirectory p2))) |
| 426 | (if (string= d1 d2) | 426 | (if (string= d1 d2) |
| 427 | (string-lessp f1 f2) | 427 | (string-lessp f1 f2) |
| 428 | (string-lessp d1 d2)))) | 428 | (string-lessp d1 d2)))) |
| 429 | 429 | ||
| 430 | (defun recentf-sort-directories-ascending (l) | 430 | (defun recentf-sort-directories-ascending (l) |
| 431 | "Sort the list of menu elements L in ascending order. | 431 | "Sort the list of menu elements L in ascending order. |
| 432 | Compares directories then filenames to order the list." | 432 | Compares directories then filenames to order the list." |
| 433 | (sort (copy-sequence l) | 433 | (sort (copy-sequence l) |
| 434 | (function | 434 | (function |
| 435 | (lambda (e1 e2) | 435 | (lambda (e1 e2) |
| 436 | (recentf-directory-compare (recentf-menu-element-value e1) | 436 | (recentf-directory-compare (recentf-menu-element-value e1) |
| 437 | (recentf-menu-element-value e2)))))) | 437 | (recentf-menu-element-value e2)))))) |
| 438 | 438 | ||
| 439 | (defun recentf-sort-directories-descending (l) | 439 | (defun recentf-sort-directories-descending (l) |
| 440 | "Sort the list of menu elements L in descending order. | 440 | "Sort the list of menu elements L in descending order. |
| 441 | Compares directories then filenames to order the list." | 441 | Compares directories then filenames to order the list." |
| 442 | (sort (copy-sequence l) | 442 | (sort (copy-sequence l) |
| 443 | (function | 443 | (function |
| 444 | (lambda (e1 e2) | 444 | (lambda (e1 e2) |
| 445 | (recentf-directory-compare (recentf-menu-element-value e2) | 445 | (recentf-directory-compare (recentf-menu-element-value e2) |
| 446 | (recentf-menu-element-value e1)))))) | 446 | (recentf-menu-element-value e1)))))) |
| 447 | 447 | ||
| 448 | (defun recentf-show-basenames (l) | 448 | (defun recentf-show-basenames (l) |
| 449 | "Filter the list of menu elements L to show only file names (no directories) | 449 | "Filter the list of menu elements L to show only file names (no directories) |
| 450 | in the menu. When file names are duplicated their directory component is added." | 450 | in the menu. When file names are duplicated their directory component is added." |
| 451 | (let ((names (mapcar (function | 451 | (let ((names (mapcar (function |
| 452 | (lambda (item) | 452 | (lambda (item) |
| 453 | (file-name-nondirectory | 453 | (file-name-nondirectory |
| 454 | (recentf-menu-element-value item)))) | 454 | (recentf-menu-element-value item)))) |
| 455 | l)) | 455 | l)) |
| 456 | (dirs (mapcar (function | 456 | (dirs (mapcar (function |
| 457 | (lambda (item) | 457 | (lambda (item) |
| 458 | (file-name-directory | 458 | (file-name-directory |
| 459 | (recentf-menu-element-value item)))) | 459 | (recentf-menu-element-value item)))) |
| 460 | l)) | 460 | l)) |
| 461 | (pathes (mapcar 'recentf-menu-element-value l)) | 461 | (pathes (mapcar 'recentf-menu-element-value l)) |
| 462 | (pos -1) | 462 | (pos -1) |
| 463 | item filtered-items filtered-list) | 463 | item filtered-items filtered-list) |
| 464 | (while names | 464 | (while names |
| 465 | (setq item (car names)) | 465 | (setq item (car names)) |
| 466 | (setq names (cdr names)) | 466 | (setq names (cdr names)) |
| 467 | (setq pos (1+ pos)) | 467 | (setq pos (1+ pos)) |
| 468 | (setq filtered-list | 468 | (setq filtered-list |
| 469 | (cons (recentf-make-menu-element | 469 | (cons (recentf-make-menu-element |
| 470 | (if (or (member item names) (member item filtered-items)) | 470 | (if (or (member item names) (member item filtered-items)) |
| 471 | (concat item " (" (nth pos dirs) ")") | 471 | (concat item " (" (nth pos dirs) ")") |
| 472 | item) | 472 | item) |
| 473 | (nth pos pathes)) | 473 | (nth pos pathes)) |
| 474 | filtered-list)) | 474 | filtered-list)) |
| 475 | (setq filtered-items (cons item filtered-items))) | 475 | (setq filtered-items (cons item filtered-items))) |
| 476 | (nreverse filtered-list))) | 476 | (nreverse filtered-list))) |
| 477 | 477 | ||
| 478 | (defun recentf-show-basenames-ascending (l) | 478 | (defun recentf-show-basenames-ascending (l) |
| 479 | "Filter the list of menu elements L to show only file names in the menu, | 479 | "Filter the list of menu elements L to show only file names in the menu, |
| 480 | sorted in ascending order. This filter combines the `recentf-sort-basenames-ascending' | 480 | sorted in ascending order. This filter combines the `recentf-sort-basenames-ascending' |
| 481 | and `recentf-show-basenames' filters." | 481 | and `recentf-show-basenames' filters." |
| 482 | (recentf-show-basenames (recentf-sort-basenames-ascending l))) | 482 | (recentf-show-basenames (recentf-sort-basenames-ascending l))) |
| 483 | 483 | ||
| 484 | (defun recentf-show-basenames-descending (l) | 484 | (defun recentf-show-basenames-descending (l) |
| 485 | "Filter the list of menu elements L to show only file names in the menu, | 485 | "Filter the list of menu elements L to show only file names in the menu, |
| 486 | sorted in descending order. This filter combines the `recentf-sort-basenames-descending' | 486 | sorted in descending order. This filter combines the `recentf-sort-basenames-descending' |
| 487 | and `recentf-show-basenames' filters." | 487 | and `recentf-show-basenames' filters." |
| 488 | (recentf-show-basenames (recentf-sort-basenames-descending l))) | 488 | (recentf-show-basenames (recentf-sort-basenames-descending l))) |
| 489 | 489 | ||
| 490 | (defun recentf-relative-filter (l) | 490 | (defun recentf-relative-filter (l) |
| 491 | "Filter the list of `recentf-menu-elements' L to show filenames | 491 | "Filter the list of `recentf-menu-elements' L to show filenames |
| 492 | relative to `default-directory'." | 492 | relative to `default-directory'." |
| 493 | (setq recentf-update-menu-p t) ; force menu update | 493 | (setq recentf-update-menu-p t) ; force menu update |
| 494 | (mapcar (function | 494 | (mapcar (function |
| 495 | (lambda (menu-element) | 495 | (lambda (menu-element) |
| 496 | (let* ((ful-path (recentf-menu-element-value menu-element)) | 496 | (let* ((ful-path (recentf-menu-element-value menu-element)) |
| 497 | (rel-path (file-relative-name ful-path))) | 497 | (rel-path (file-relative-name ful-path))) |
| 498 | (if (string-match "^\\.\\." rel-path) | 498 | (if (string-match "^\\.\\." rel-path) |
| 499 | menu-element | 499 | menu-element |
| 500 | (recentf-make-menu-element rel-path ful-path))))) | 500 | (recentf-make-menu-element rel-path ful-path))))) |
| 501 | l)) | 501 | l)) |
| 502 | 502 | ||
| 503 | (defcustom recentf-arrange-rules | 503 | (defcustom recentf-arrange-rules |
| 504 | '( | 504 | '( |
| 505 | ("Elisp files (%d)" ".\\.el$") | 505 | ("Elisp files (%d)" ".\\.el$") |
| 506 | ("Java files (%d)" ".\\.java$") | 506 | ("Java files (%d)" ".\\.java$") |
| 507 | ("C/C++ files (%d)" "c\\(pp\\)?$") | 507 | ("C/C++ files (%d)" "c\\(pp\\)?$") |
| 508 | ) | 508 | ) |
| 509 | "*List of rules used by `recentf-arrange-by-rule' to build sub-menus. | 509 | "*List of rules used by `recentf-arrange-by-rule' to build sub-menus. |
| 510 | A rule is a pair (SUB-MENU-TITLE . MATCHER). SUB-MENU-TITLE is the | 510 | A rule is a pair (SUB-MENU-TITLE . MATCHER). SUB-MENU-TITLE is the |
| 511 | displayed title of the sub-menu where a '%d' `format' pattern is | 511 | displayed title of the sub-menu where a '%d' `format' pattern is |
| 512 | replaced by the number of items in the sub-menu. MATCHER is a regexp | 512 | replaced by the number of items in the sub-menu. MATCHER is a regexp |
| 513 | or a list of regexps. Items matching one of the regular expressions in | 513 | or a list of regexps. Items matching one of the regular expressions in |
| 514 | MATCHER are added to the corresponding sub-menu." | 514 | MATCHER are added to the corresponding sub-menu." |
| 515 | :group 'recentf-filters | 515 | :group 'recentf-filters |
| 516 | :type '(repeat (cons string (repeat regexp))) | 516 | :type '(repeat (cons string (repeat regexp))) |
| 517 | :set 'recentf-menu-customization-changed) | 517 | :set 'recentf-menu-customization-changed) |
| 518 | 518 | ||
| 519 | (defcustom recentf-arrange-by-rule-others "Other files (%d)" | 519 | (defcustom recentf-arrange-by-rule-others "Other files (%d)" |
| 520 | "*Title of the `recentf-arrange-by-rule' sub-menu where items that | 520 | "*Title of the `recentf-arrange-by-rule' sub-menu where items that |
| 521 | don't match any `recentf-arrange-rules' are displayed. If nil | 521 | don't match any `recentf-arrange-rules' are displayed. If nil |
| 522 | these items are displayed in the main recent files menu. A '%d' | 522 | these items are displayed in the main recent files menu. A '%d' |
| 523 | `format' pattern in the title is replaced by the number of items in | 523 | `format' pattern in the title is replaced by the number of items in |
| 524 | the sub-menu." | 524 | the sub-menu." |
| 525 | :group 'recentf-filters | 525 | :group 'recentf-filters |
| 526 | :type '(choice (const :tag "Main menu" nil) | 526 | :type '(choice (const :tag "Main menu" nil) |
| 527 | (string :tag "Title")) | 527 | (string :tag "Title")) |
| 528 | :set 'recentf-menu-customization-changed) | 528 | :set 'recentf-menu-customization-changed) |
| 529 | 529 | ||
| 530 | (defcustom recentf-arrange-by-rules-min-items 0 | 530 | (defcustom recentf-arrange-by-rules-min-items 0 |
| 531 | "*Minimum number of items in a `recentf-arrange-by-rule' sub-menu. | 531 | "*Minimum number of items in a `recentf-arrange-by-rule' sub-menu. |
| 532 | If the number of items in a sub-menu is less than this value the | 532 | If the number of items in a sub-menu is less than this value the |
| 533 | corresponding sub-menu items are displayed in the main recent files | 533 | corresponding sub-menu items are displayed in the main recent files |
| 534 | menu or in the `recentf-arrange-by-rule-others' sub-menu if | 534 | menu or in the `recentf-arrange-by-rule-others' sub-menu if |
| 535 | defined." | 535 | defined." |
| 536 | :group 'recentf-filters | 536 | :group 'recentf-filters |
| 537 | :type 'number | 537 | :type 'number |
| 538 | :set 'recentf-menu-customization-changed) | 538 | :set 'recentf-menu-customization-changed) |
| 539 | 539 | ||
| 540 | (defcustom recentf-arrange-by-rule-subfilter nil | 540 | (defcustom recentf-arrange-by-rule-subfilter nil |
| 541 | "*Function used by `recentf-arrange-by-rule' to filter sub-menu elements. | 541 | "*Function used by `recentf-arrange-by-rule' to filter sub-menu elements. |
| 542 | Nil means no filter. See also `recentf-menu-filter'. You can't use | 542 | Nil means no filter. See also `recentf-menu-filter'. You can't use |
| 543 | `recentf-arrange-by-rule' itself here!" | 543 | `recentf-arrange-by-rule' itself here!" |
| 544 | :group 'recentf-filters | 544 | :group 'recentf-filters |
| 545 | :type 'function | 545 | :type 'function |
| 546 | :set (lambda (sym val) | 546 | :set (lambda (sym val) |
| 547 | (if (eq val 'recentf-arrange-by-rule) | 547 | (if (eq val 'recentf-arrange-by-rule) |
| 548 | (error "Can't use `recentf-arrange-by-rule' itself here!") | 548 | (error "Can't use `recentf-arrange-by-rule' itself here!") |
| 549 | (recentf-menu-customization-changed sym val)))) | 549 | (recentf-menu-customization-changed sym val)))) |
| 550 | 550 | ||
| 551 | (defun recentf-match-rule-p (matcher file-path) | 551 | (defun recentf-match-rule-p (matcher file-path) |
| 552 | "Return non-nil if FILE-PATH match the rule specified by MATCHER. | 552 | "Return non-nil if FILE-PATH match the rule specified by MATCHER. |
| 553 | See `recentf-arrange-rules' for details on MATCHER." | 553 | See `recentf-arrange-rules' for details on MATCHER." |
| 554 | (if (stringp matcher) | 554 | (if (stringp matcher) |
| 555 | (string-match matcher file-path) | 555 | (string-match matcher file-path) |
| 556 | (while (and (consp matcher) | 556 | (while (and (consp matcher) |
| 557 | (not (string-match (car matcher) file-path))) | 557 | (not (string-match (car matcher) file-path))) |
| 558 | (setq matcher (cdr matcher))) | 558 | (setq matcher (cdr matcher))) |
| 559 | matcher)) | 559 | matcher)) |
| 560 | 560 | ||
| 561 | (defun recentf-arrange-by-rule (l) | 561 | (defun recentf-arrange-by-rule (l) |
| 562 | "Filter the list of menu-elements L to arrange them in sub-menus | 562 | "Filter the list of menu-elements L to arrange them in sub-menus |
| 563 | following rules in `recentf-arrange-rules'." | 563 | following rules in `recentf-arrange-rules'." |
| 564 | (let ((sub-menus-number (length recentf-arrange-rules))) | 564 | (let ((sub-menus-number (length recentf-arrange-rules))) |
| 565 | (if (> sub-menus-number 0) | 565 | (if (> sub-menus-number 0) |
| 566 | (let ((sub-menus (apply 'vector | 566 | (let ((sub-menus (apply 'vector |
| 567 | (mapcar (function | 567 | (mapcar (function |
| 568 | (lambda (pair) | 568 | (lambda (pair) |
| 569 | (list (car pair)))) | 569 | (list (car pair)))) |
| 570 | recentf-arrange-rules))) | 570 | recentf-arrange-rules))) |
| 571 | other-menu-elements index min-size) | 571 | other-menu-elements index min-size) |
| 572 | (while l | 572 | (while l |
| 573 | (let* ((menu-element (car l)) | 573 | (let* ((menu-element (car l)) |
| 574 | (file-path (recentf-menu-element-value menu-element)) | 574 | (file-path (recentf-menu-element-value menu-element)) |
| 575 | (rules recentf-arrange-rules) | 575 | (rules recentf-arrange-rules) |
| 576 | (found nil)) | 576 | (found nil)) |
| 577 | (setq index 0) | 577 | (setq index 0) |
| 578 | (while (and (not found) rules) | 578 | (while (and (not found) rules) |
| 579 | (if (recentf-match-rule-p (cdar rules) file-path) | 579 | (if (recentf-match-rule-p (cdar rules) file-path) |
| 580 | (let ((sub-menu (aref sub-menus index))) | 580 | (let ((sub-menu (aref sub-menus index))) |
| 581 | (setq found t) | 581 | (setq found t) |
| 582 | (recentf-set-menu-element-value | 582 | (recentf-set-menu-element-value |
| 583 | sub-menu | 583 | sub-menu |
| 584 | (cons menu-element (recentf-menu-element-value sub-menu))) | 584 | (cons menu-element (recentf-menu-element-value sub-menu))) |
| 585 | )) | 585 | )) |
| 586 | (setq index (1+ index)) | 586 | (setq index (1+ index)) |
| 587 | (setq rules (cdr rules))) | 587 | (setq rules (cdr rules))) |
| 588 | (or found | 588 | (or found |
| 589 | (setq other-menu-elements | 589 | (setq other-menu-elements |
| 590 | (cons menu-element other-menu-elements))) | 590 | (cons menu-element other-menu-elements))) |
| 591 | (setq l (cdr l)))) | 591 | (setq l (cdr l)))) |
| 592 | (setq index 0) | 592 | (setq index 0) |
| 593 | (setq l nil) | 593 | (setq l nil) |
| 594 | (setq min-size (if (integerp recentf-arrange-by-rules-min-items) | 594 | (setq min-size (if (integerp recentf-arrange-by-rules-min-items) |
| 595 | (max 0 recentf-arrange-by-rules-min-items) | 595 | (max 0 recentf-arrange-by-rules-min-items) |
| 596 | 0)) | 596 | 0)) |
| 597 | (while (< index sub-menus-number) | 597 | (while (< index sub-menus-number) |
| 598 | (let* ((sub-menu (aref sub-menus index)) | 598 | (let* ((sub-menu (aref sub-menus index)) |
| 599 | (sub-menu-title (recentf-menu-element-item sub-menu)) | 599 | (sub-menu-title (recentf-menu-element-item sub-menu)) |
| 600 | (sub-menu-elements (recentf-menu-element-value sub-menu)) | 600 | (sub-menu-elements (recentf-menu-element-value sub-menu)) |
| 601 | (sub-menu-length (length sub-menu-elements))) | 601 | (sub-menu-length (length sub-menu-elements))) |
| 602 | (if (> sub-menu-length 0) | 602 | (if (> sub-menu-length 0) |
| 603 | (cond | 603 | (cond |
| 604 | ((< sub-menu-length min-size) | 604 | ((< sub-menu-length min-size) |
| 605 | (setq other-menu-elements | 605 | (setq other-menu-elements |
| 606 | (nconc sub-menu-elements other-menu-elements))) | 606 | (nconc sub-menu-elements other-menu-elements))) |
| 607 | ((>= sub-menu-length min-size) | 607 | ((>= sub-menu-length min-size) |
| 608 | (recentf-set-menu-element-item | 608 | (recentf-set-menu-element-item |
| 609 | sub-menu | 609 | sub-menu |
| 610 | (format sub-menu-title sub-menu-length)) | 610 | (format sub-menu-title sub-menu-length)) |
| 611 | (recentf-set-menu-element-value | 611 | (recentf-set-menu-element-value |
| 612 | sub-menu | 612 | sub-menu |
| 613 | (recentf-apply-menu-filter | 613 | (recentf-apply-menu-filter |
| 614 | recentf-arrange-by-rule-subfilter | 614 | recentf-arrange-by-rule-subfilter |
| 615 | (nreverse sub-menu-elements))) | 615 | (nreverse sub-menu-elements))) |
| 616 | (setq l (cons sub-menu l))))) | 616 | (setq l (cons sub-menu l))))) |
| 617 | (setq index (1+ index)))) | 617 | (setq index (1+ index)))) |
| 618 | (if (and (stringp recentf-arrange-by-rule-others) | 618 | (if (and (stringp recentf-arrange-by-rule-others) |
| 619 | other-menu-elements) | 619 | other-menu-elements) |
| 620 | (setq l | 620 | (setq l |
| 621 | (nreverse | 621 | (nreverse |
| 622 | (cons (recentf-make-menu-element | 622 | (cons (recentf-make-menu-element |
| 623 | (format recentf-arrange-by-rule-others | 623 | (format recentf-arrange-by-rule-others |
| 624 | (length other-menu-elements)) | 624 | (length other-menu-elements)) |
| 625 | (recentf-apply-menu-filter | 625 | (recentf-apply-menu-filter |
| 626 | recentf-arrange-by-rule-subfilter | 626 | recentf-arrange-by-rule-subfilter |
| 627 | (nreverse other-menu-elements))) | 627 | (nreverse other-menu-elements))) |
| 628 | l))) | 628 | l))) |
| 629 | (setq l (nconc (nreverse l) | 629 | (setq l (nconc (nreverse l) |
| 630 | (recentf-apply-menu-filter | 630 | (recentf-apply-menu-filter |
| 631 | recentf-arrange-by-rule-subfilter | 631 | recentf-arrange-by-rule-subfilter |
| 632 | (nreverse other-menu-elements))))))) | 632 | (nreverse other-menu-elements))))))) |
| 633 | l)) | 633 | l)) |
| 634 | 634 | ||
| 635 | (defun recentf-build-mode-rules () | 635 | (defun recentf-build-mode-rules () |
| 636 | "Convert `auto-mode-alist' to `recentf-arrange-rules' format." | 636 | "Convert `auto-mode-alist' to `recentf-arrange-rules' format." |
| 637 | (let ((case-fold-search recentf-case-fold-search) | 637 | (let ((case-fold-search recentf-case-fold-search) |
| 638 | (modes auto-mode-alist) | 638 | (modes auto-mode-alist) |
| 639 | regexp mode rule-name rule rules) | 639 | regexp mode rule-name rule rules) |
| 640 | (while modes | 640 | (while modes |
| 641 | (setq regexp (caar modes)) | 641 | (setq regexp (caar modes)) |
| 642 | (setq mode (cdar modes)) | 642 | (setq mode (cdar modes)) |
| 643 | (when (symbolp mode) | 643 | (when (symbolp mode) |
| 644 | (setq rule-name (symbol-name mode)) | 644 | (setq rule-name (symbol-name mode)) |
| 645 | (if (string-match "\\(.*\\)-mode$" rule-name) | 645 | (if (string-match "\\(.*\\)-mode$" rule-name) |
| 646 | (setq rule-name (match-string 1 rule-name))) | 646 | (setq rule-name (match-string 1 rule-name))) |
| 647 | (setq rule-name (concat rule-name " (%d)")) | 647 | (setq rule-name (concat rule-name " (%d)")) |
| 648 | (setq rule (assoc rule-name rules)) | 648 | (setq rule (assoc rule-name rules)) |
| 649 | (if rule | 649 | (if rule |
| 650 | (setcdr rule (cons regexp (cdr rule))) | 650 | (setcdr rule (cons regexp (cdr rule))) |
| 651 | (setq rules (cons (list rule-name regexp) rules)))) | 651 | (setq rules (cons (list rule-name regexp) rules)))) |
| 652 | (setq modes (cdr modes))) | 652 | (setq modes (cdr modes))) |
| 653 | ;; It is important to preserve auto-mode-alist order | 653 | ;; It is important to preserve auto-mode-alist order |
| 654 | ;; to ensure the right file <-> mode association | 654 | ;; to ensure the right file <-> mode association |
| 655 | (nreverse rules))) | 655 | (nreverse rules))) |
| 656 | 656 | ||
| 657 | (defun recentf-arrange-by-mode (l) | 657 | (defun recentf-arrange-by-mode (l) |
| 658 | "Filter the list of menu-elements L to build sub-menus for each | 658 | "Filter the list of menu-elements L to build sub-menus for each |
| 659 | major mode." | 659 | major mode." |
| 660 | (let ((recentf-arrange-rules (recentf-build-mode-rules)) | 660 | (let ((recentf-arrange-rules (recentf-build-mode-rules)) |
| 661 | (recentf-arrange-by-rule-others "others (%d)")) | 661 | (recentf-arrange-by-rule-others "others (%d)")) |
| 662 | (recentf-arrange-by-rule l))) | 662 | (recentf-arrange-by-rule l))) |
| 663 | 663 | ||
| 664 | (defun recentf-build-dir-rules (l) | 664 | (defun recentf-build-dir-rules (l) |
| 665 | "Convert directories in the list of menu-elements L to rules in | 665 | "Convert directories in the list of menu-elements L to rules in |
| 666 | `recentf-arrange-rules' format." | 666 | `recentf-arrange-rules' format." |
| 667 | (let (dirs) | 667 | (let (dirs) |
| 668 | (mapcar (function | 668 | (mapcar (function |
| 669 | (lambda (e) | 669 | (lambda (e) |
| 670 | (let ((dir (file-name-directory | 670 | (let ((dir (file-name-directory |
| 671 | (recentf-menu-element-value e)))) | 671 | (recentf-menu-element-value e)))) |
| 672 | (or (member dir dirs) | 672 | (or (member dir dirs) |
| 673 | (setq dirs (cons dir dirs)))))) | 673 | (setq dirs (cons dir dirs)))))) |
| 674 | l) | 674 | l) |
| 675 | (mapcar (function | 675 | (mapcar (function |
| 676 | (lambda (d) | 676 | (lambda (d) |
| 677 | (cons (concat d " (%d)") | 677 | (cons (concat d " (%d)") |
| 678 | (concat "\\`" d)))) | 678 | (concat "\\`" d)))) |
| 679 | (nreverse (sort dirs 'string-lessp))))) | 679 | (nreverse (sort dirs 'string-lessp))))) |
| 680 | 680 | ||
| 681 | (defun recentf-file-name-nondir (l) | 681 | (defun recentf-file-name-nondir (l) |
| 682 | "Filter the list of menu-elements L to show only filenames. This | 682 | "Filter the list of menu-elements L to show only filenames. This |
| 683 | simplified version of `recentf-show-basenames' do not handle | 683 | simplified version of `recentf-show-basenames' do not handle |
| 684 | duplicates. It is used by `recentf-arrange-by-dir' as its | 684 | duplicates. It is used by `recentf-arrange-by-dir' as its |
| 685 | `recentf-arrange-by-rule-subfilter'." | 685 | `recentf-arrange-by-rule-subfilter'." |
| 686 | (mapcar (function | 686 | (mapcar (function |
| 687 | (lambda (e) | 687 | (lambda (e) |
| 688 | (recentf-make-menu-element | 688 | (recentf-make-menu-element |
| 689 | (file-name-nondirectory (recentf-menu-element-value e)) | 689 | (file-name-nondirectory (recentf-menu-element-value e)) |
| 690 | (recentf-menu-element-value e)))) | 690 | (recentf-menu-element-value e)))) |
| 691 | l)) | 691 | l)) |
| 692 | 692 | ||
| 693 | (defun recentf-arrange-by-dir (l) | 693 | (defun recentf-arrange-by-dir (l) |
| 694 | "Filter the list of menu-elements L to build sub-menus for each | 694 | "Filter the list of menu-elements L to build sub-menus for each |
| 695 | directory." | 695 | directory." |
| 696 | (let ((recentf-arrange-rules (recentf-build-dir-rules l)) | 696 | (let ((recentf-arrange-rules (recentf-build-dir-rules l)) |
| 697 | (recentf-arrange-by-rule-subfilter 'recentf-file-name-nondir) | 697 | (recentf-arrange-by-rule-subfilter 'recentf-file-name-nondir) |
| 698 | recentf-arrange-by-rule-others) | 698 | recentf-arrange-by-rule-others) |
| 699 | (nreverse (recentf-arrange-by-rule l)))) | 699 | (nreverse (recentf-arrange-by-rule l)))) |
| 700 | 700 | ||
| 701 | (defvar recentf-filter-changer-state nil | 701 | (defvar recentf-filter-changer-state nil |
| 702 | "Used by `recentf-filter-changer' to hold its state.") | 702 | "Used by `recentf-filter-changer' to hold its state.") |
| 703 | 703 | ||
| 704 | (defcustom recentf-filter-changer-alist | 704 | (defcustom recentf-filter-changer-alist |
| 705 | '( | 705 | '( |
| 706 | (recentf-arrange-by-mode . "*Files by Mode*") | 706 | (recentf-arrange-by-mode . "*Files by Mode*") |
| 707 | (recentf-arrange-by-dir . "*Files by Directory*") | 707 | (recentf-arrange-by-dir . "*Files by Directory*") |
| 708 | (recentf-arrange-by-rule . "*Files by User Rule*") | 708 | (recentf-arrange-by-rule . "*Files by User Rule*") |
| 709 | ) | 709 | ) |
| 710 | "*List of filters managed by `recentf-filter-changer'. | 710 | "*List of filters managed by `recentf-filter-changer'. |
| 711 | Each filter is defined by a pair (FILTER-FUN . FILTER-LBL) where: | 711 | Each filter is defined by a pair (FILTER-FUN . FILTER-LBL) where: |
| 712 | 712 | ||
| 713 | - - FILTER-FUN is the function that filters menu-elements | 713 | - - FILTER-FUN is the function that filters menu-elements |
| 714 | - - FILTER-LBL is the menu item used to activate the filter" | 714 | - - FILTER-LBL is the menu item used to activate the filter" |
| 715 | :group 'recentf-filters | 715 | :group 'recentf-filters |
| 716 | :type '(repeat (cons function string)) | 716 | :type '(repeat (cons function string)) |
| 717 | :set (lambda (sym val) | 717 | :set (lambda (sym val) |
| 718 | (setq recentf-filter-changer-state nil) | 718 | (setq recentf-filter-changer-state nil) |
| 719 | (recentf-menu-customization-changed sym val))) | 719 | (recentf-menu-customization-changed sym val))) |
| 720 | 720 | ||
| 721 | (defun recentf-filter-changer-goto-next () | 721 | (defun recentf-filter-changer-goto-next () |
| 722 | "Go to the next filter available (see `recentf-filter-changer')." | 722 | "Go to the next filter available (see `recentf-filter-changer')." |
| 723 | (and (consp recentf-filter-changer-state) | 723 | (and (consp recentf-filter-changer-state) |
| 724 | (setq recentf-filter-changer-state | 724 | (setq recentf-filter-changer-state |
| 725 | (cdr recentf-filter-changer-state))) | 725 | (cdr recentf-filter-changer-state))) |
| 726 | (setq recentf-update-menu-p t)) | 726 | (setq recentf-update-menu-p t)) |
| 727 | 727 | ||
| 728 | (defun recentf-filter-changer-get-current () | 728 | (defun recentf-filter-changer-get-current () |
| 729 | "Get the current filter available (see `recentf-filter-changer')." | 729 | "Get the current filter available (see `recentf-filter-changer')." |
| 730 | (if (null recentf-filter-changer-state) | 730 | (if (null recentf-filter-changer-state) |
| 731 | (setq recentf-filter-changer-state recentf-filter-changer-alist)) | 731 | (setq recentf-filter-changer-state recentf-filter-changer-alist)) |
| 732 | (and (consp recentf-filter-changer-state) | 732 | (and (consp recentf-filter-changer-state) |
| 733 | (car recentf-filter-changer-state))) | 733 | (car recentf-filter-changer-state))) |
| 734 | 734 | ||
| 735 | (defun recentf-filter-changer-get-next () | 735 | (defun recentf-filter-changer-get-next () |
| 736 | "Get the next filter available (see `recentf-filter-changer')." | 736 | "Get the next filter available (see `recentf-filter-changer')." |
| 737 | (let ((filters recentf-filter-changer-state)) | 737 | (let ((filters recentf-filter-changer-state)) |
| 738 | (cond ((consp filters) | 738 | (cond ((consp filters) |
| 739 | (setq filters (cdr filters)) | 739 | (setq filters (cdr filters)) |
| 740 | (if (null filters) | 740 | (if (null filters) |
| 741 | (setq filters recentf-filter-changer-alist))) | 741 | (setq filters recentf-filter-changer-alist))) |
| 742 | (t | 742 | (t |
| 743 | (setq filters recentf-filter-changer-alist) | 743 | (setq filters recentf-filter-changer-alist) |
| 744 | (if (consp filters) | 744 | (if (consp filters) |
| 745 | (setq filters (cdr filters))))) | 745 | (setq filters (cdr filters))))) |
| 746 | (if (consp filters) | 746 | (if (consp filters) |
| 747 | (car filters)))) | 747 | (car filters)))) |
| 748 | 748 | ||
| 749 | (defun recentf-filter-changer (l) | 749 | (defun recentf-filter-changer (l) |
| 750 | "Manage a ring of filters. `recentf-filter-changer-alist' defines | 750 | "Manage a ring of filters. `recentf-filter-changer-alist' defines |
| 751 | the filters in the ring. Actual filtering of L is delegated to the | 751 | the filters in the ring. Actual filtering of L is delegated to the |
| 752 | current filter in the ring. A filter menu item is displayed allowing | 752 | current filter in the ring. A filter menu item is displayed allowing |
| 753 | to dynamically activate the next filter in the ring. If the filter | 753 | to dynamically activate the next filter in the ring. If the filter |
| 754 | ring is empty L is left unchanged." | 754 | ring is empty L is left unchanged." |
| 755 | (let ((current-filter-item (recentf-filter-changer-get-current)) | 755 | (let ((current-filter-item (recentf-filter-changer-get-current)) |
| 756 | (next-filter-item (recentf-filter-changer-get-next))) | 756 | (next-filter-item (recentf-filter-changer-get-next))) |
| 757 | (when current-filter-item | 757 | (when current-filter-item |
| 758 | (setq l (recentf-apply-menu-filter (car current-filter-item) l)) | 758 | (setq l (recentf-apply-menu-filter (car current-filter-item) l)) |
| 759 | (if next-filter-item | 759 | (if next-filter-item |
| 760 | (setq recentf-menu-filter-commands | 760 | (setq recentf-menu-filter-commands |
| 761 | (list (vector (cdr next-filter-item) | 761 | (list (vector (cdr next-filter-item) |
| 762 | '(recentf-filter-changer-goto-next) | 762 | '(recentf-filter-changer-goto-next) |
| 763 | t))))) | 763 | t))))) |
| 764 | l)) | 764 | l)) |
| 765 | 765 | ||
| 766 | ;;; | 766 | ;;; |
| 767 | ;;; Dialogs stuff | 767 | ;;; Dialogs stuff |
| 768 | ;;; | 768 | ;;; |
| 769 | 769 | ||
| 770 | (defun recentf-cancel-dialog (&rest ignore) | 770 | (defun recentf-cancel-dialog (&rest ignore) |
| 771 | "Cancel the current dialog. Used by `recentf-edit-list' and | 771 | "Cancel the current dialog. Used by `recentf-edit-list' and |
| 772 | `recentf-open-files' dialogs." | 772 | `recentf-open-files' dialogs." |
| 773 | (interactive) | 773 | (interactive) |
| 774 | (kill-buffer (current-buffer)) | 774 | (kill-buffer (current-buffer)) |
| 775 | (message "Dialog canceled.")) | 775 | (message "Dialog canceled.")) |
| 776 | 776 | ||
| 777 | (defvar recentf-dialog-mode-map nil | 777 | (defvar recentf-dialog-mode-map nil |
| 778 | "`recentf-dialog-mode' keymap.") | 778 | "`recentf-dialog-mode' keymap.") |
| 779 | 779 | ||
| 780 | (if recentf-dialog-mode-map | 780 | (if recentf-dialog-mode-map |
| 781 | () | 781 | () |
| 782 | (setq recentf-dialog-mode-map (make-sparse-keymap)) | 782 | (setq recentf-dialog-mode-map (make-sparse-keymap)) |
| 783 | (define-key recentf-dialog-mode-map "q" 'recentf-cancel-dialog) | 783 | (define-key recentf-dialog-mode-map "q" 'recentf-cancel-dialog) |
| 784 | (set-keymap-parent recentf-dialog-mode-map widget-keymap)) | 784 | (set-keymap-parent recentf-dialog-mode-map widget-keymap)) |
| 785 | 785 | ||
| 786 | (defun recentf-dialog-mode () | 786 | (defun recentf-dialog-mode () |
| 787 | "Major mode used in recentf dialogs. | 787 | "Major mode used in recentf dialogs. |
| 788 | 788 | ||
| 789 | These are the special commands of recentf-dialog-mode mode: | 789 | These are the special commands of recentf-dialog-mode mode: |
| 790 | q -- cancel this dialog." | 790 | q -- cancel this dialog." |
| 791 | (interactive) | 791 | (interactive) |
| 792 | (setq major-mode 'recentf-dialog-mode) | 792 | (setq major-mode 'recentf-dialog-mode) |
| 793 | (setq mode-name "recentf-dialog") | 793 | (setq mode-name "recentf-dialog") |
| 794 | (use-local-map recentf-dialog-mode-map)) | 794 | (use-local-map recentf-dialog-mode-map)) |
| 795 | 795 | ||
| 796 | ;;; | 796 | ;;; |
| 797 | ;;; Hooks and Commands | 797 | ;;; Hooks and Commands |
| 798 | ;;; | 798 | ;;; |
| 799 | 799 | ||
| 800 | (defun recentf-add-file-hook () | 800 | (defun recentf-add-file-hook () |
| 801 | "Insert the name of the file just opened or written into `recentf-list'." | 801 | "Insert the name of the file just opened or written into `recentf-list'." |
| 802 | (and buffer-file-name (recentf-add-file buffer-file-name)) | 802 | (and buffer-file-name (recentf-add-file buffer-file-name)) |
| 803 | nil) | 803 | nil) |
| 804 | 804 | ||
| 805 | (defun recentf-remove-file-hook () | 805 | (defun recentf-remove-file-hook () |
| 806 | "When a buffer is killed remove a non readable file from `recentf-list'." | 806 | "When a buffer is killed remove a non readable file from `recentf-list'." |
| 807 | (and buffer-file-name (recentf-remove-if-non-readable buffer-file-name)) | 807 | (and buffer-file-name (recentf-remove-if-non-readable buffer-file-name)) |
| 808 | nil) | 808 | nil) |
| 809 | 809 | ||
| 810 | (defun recentf-update-menu-hook () | 810 | (defun recentf-update-menu-hook () |
| 811 | "Update the recentf menu from the current `recentf-list'." | 811 | "Update the recentf menu from the current `recentf-list'." |
| 812 | (when recentf-update-menu-p | 812 | (when recentf-update-menu-p |
| 813 | (condition-case nil | 813 | (condition-case nil |
| 814 | (progn | 814 | (progn |
| 815 | (setq recentf-update-menu-p nil) | 815 | (setq recentf-update-menu-p nil) |
| 816 | (easy-menu-change recentf-menu-path | 816 | (easy-menu-change recentf-menu-path |
| 817 | recentf-menu-title | 817 | recentf-menu-title |
| 818 | (recentf-make-menu-items) | 818 | (recentf-make-menu-items) |
| 819 | recentf-menu-before)) | 819 | recentf-menu-before)) |
| 820 | (error nil)))) | 820 | (error nil)))) |
| 821 | 821 | ||
| 822 | (defun recentf-dump-variable (variable &optional limit) | 822 | (defun recentf-dump-variable (variable &optional limit) |
| 823 | "Insert a \"(setq VARIABLE value)\" in the current buffer. Optional | 823 | "Insert a \"(setq VARIABLE value)\" in the current buffer. Optional |
| 824 | argument LIMIT specifies a maximum length when VARIABLE value is a | 824 | argument LIMIT specifies a maximum length when VARIABLE value is a |
| 825 | list (default to the full list)." | 825 | list (default to the full list)." |
| 826 | (let ((value (symbol-value variable))) | 826 | (let ((value (symbol-value variable))) |
| 827 | (insert (format "(setq %S\n '(\n" variable)) | 827 | (insert (format "(setq %S\n '(\n" variable)) |
| 828 | (cond ((consp value) | 828 | (cond ((consp value) |
| 829 | (if (and (integerp limit) (> limit 0)) | 829 | (if (and (integerp limit) (> limit 0)) |
| 830 | (setq value (recentf-trunc-list value limit))) | 830 | (setq value (recentf-trunc-list value limit))) |
| 831 | (mapcar (function | 831 | (mapcar (function |
| 832 | (lambda (e) | 832 | (lambda (e) |
| 833 | (insert (format " %S\n" e)))) | 833 | (insert (format " %S\n" e)))) |
| 834 | value)) | 834 | value)) |
| 835 | (t | 835 | (t |
| 836 | (insert (format " %S\n" value)))) | 836 | (insert (format " %S\n" value)))) |
| 837 | (insert " ))\n") | 837 | (insert " ))\n") |
| 838 | )) | 838 | )) |
| 839 | 839 | ||
| 840 | ;;;###autoload | 840 | ;;;###autoload |
| 841 | (defun recentf-save-list () | 841 | (defun recentf-save-list () |
| 842 | "Save the current `recentf-list' to the file `recentf-save-file'." | 842 | "Save the current `recentf-list' to the file `recentf-save-file'." |
| 843 | (interactive) | 843 | (interactive) |
| 844 | (with-temp-buffer | 844 | (with-temp-buffer |
| 845 | (erase-buffer) | 845 | (erase-buffer) |
| 846 | (insert (format recentf-save-file-header (current-time-string))) | 846 | (insert (format recentf-save-file-header (current-time-string))) |
| 847 | (recentf-dump-variable 'recentf-list recentf-max-saved-items) | 847 | (recentf-dump-variable 'recentf-list recentf-max-saved-items) |
| 848 | (recentf-dump-variable 'recentf-filter-changer-state) | 848 | (recentf-dump-variable 'recentf-filter-changer-state) |
| 849 | (if (file-writable-p recentf-save-file) | 849 | (if (file-writable-p recentf-save-file) |
| 850 | (write-region (point-min) (point-max) recentf-save-file)) | 850 | (write-region (point-min) (point-max) recentf-save-file)) |
| 851 | (kill-buffer (current-buffer))) | 851 | (kill-buffer (current-buffer))) |
| 852 | nil) | 852 | nil) |
| 853 | 853 | ||
| 854 | (defvar recentf-edit-selected-items nil | 854 | (defvar recentf-edit-selected-items nil |
| 855 | "Used by `recentf-edit-list' to hold the list of files to be deleted | 855 | "Used by `recentf-edit-list' to hold the list of files to be deleted |
| 856 | from `recentf-list'.") | 856 | from `recentf-list'.") |
| 857 | 857 | ||
| 858 | (defun recentf-edit-list-action (widget &rest ignore) | 858 | (defun recentf-edit-list-action (widget &rest ignore) |
| 859 | "Checkbox widget action used by `recentf-edit-list' to select/unselect a file." | 859 | "Checkbox widget action used by `recentf-edit-list' to select/unselect a file." |
| 860 | (let ((value (widget-get widget ':tag))) | 860 | (let ((value (widget-get widget ':tag))) |
| 861 | ;; if value is already in the selected items | 861 | ;; if value is already in the selected items |
| 862 | (if (memq value recentf-edit-selected-items) | 862 | (if (memq value recentf-edit-selected-items) |
| 863 | ;; then remove it | 863 | ;; then remove it |
| 864 | (progn | 864 | (progn |
| 865 | (setq recentf-edit-selected-items | 865 | (setq recentf-edit-selected-items |
| 866 | (delq value recentf-edit-selected-items)) | 866 | (delq value recentf-edit-selected-items)) |
| 867 | (message "%s removed from selection." value)) | 867 | (message "%s removed from selection." value)) |
| 868 | ;; else add it | 868 | ;; else add it |
| 869 | (progn | 869 | (progn |
| 870 | (setq recentf-edit-selected-items | 870 | (setq recentf-edit-selected-items |
| 871 | (nconc (list value) recentf-edit-selected-items)) | 871 | (nconc (list value) recentf-edit-selected-items)) |
| 872 | (message "%s added to selection." value))))) | 872 | (message "%s added to selection." value))))) |
| 873 | 873 | ||
| 874 | ;;;###autoload | 874 | ;;;###autoload |
| 875 | (defun recentf-edit-list () | 875 | (defun recentf-edit-list () |
| 876 | "Allow the user to edit the files that are kept in the recent list." | 876 | "Allow the user to edit the files that are kept in the recent list." |
| 877 | (interactive) | 877 | (interactive) |
| 878 | (with-current-buffer (get-buffer-create (concat "*" recentf-menu-title " - Edit list*")) | 878 | (with-current-buffer (get-buffer-create (concat "*" recentf-menu-title " - Edit list*")) |
| 879 | (switch-to-buffer (current-buffer)) | 879 | (switch-to-buffer (current-buffer)) |
| 880 | (kill-all-local-variables) | 880 | (kill-all-local-variables) |
| 881 | (let ((inhibit-read-only t)) | 881 | (let ((inhibit-read-only t)) |
| 882 | (erase-buffer)) | 882 | (erase-buffer)) |
| 883 | (let ((all (overlay-lists))) | 883 | (let ((all (overlay-lists))) |
| 884 | ;; Delete all the overlays. | 884 | ;; Delete all the overlays. |
| 885 | (mapcar 'delete-overlay (car all)) | 885 | (mapcar 'delete-overlay (car all)) |
| 886 | (mapcar 'delete-overlay (cdr all))) | 886 | (mapcar 'delete-overlay (cdr all))) |
| 887 | (setq recentf-edit-selected-items nil) | 887 | (setq recentf-edit-selected-items nil) |
| 888 | ;; Insert the dialog header | 888 | ;; Insert the dialog header |
| 889 | (widget-insert "Select the files to be deleted from the 'recentf-list'.\n\n") | 889 | (widget-insert "Select the files to be deleted from the 'recentf-list'.\n\n") |
| 890 | (widget-insert "Click on Ok to update the list. ") | 890 | (widget-insert "Click on Ok to update the list. ") |
| 891 | (widget-insert "Click on Cancel or type \"q\" to quit.\n") | 891 | (widget-insert "Click on Cancel or type \"q\" to quit.\n") |
| 892 | ;; Insert the list of files as checkboxes | 892 | ;; Insert the list of files as checkboxes |
| 893 | (mapcar (function | 893 | (mapcar (function |
| 894 | (lambda (item) | 894 | (lambda (item) |
| 895 | (widget-create 'checkbox | 895 | (widget-create 'checkbox |
| 896 | :value nil ; unselected checkbox | 896 | :value nil ; unselected checkbox |
| 897 | :format "\n %[%v%] %t" | 897 | :format "\n %[%v%] %t" |
| 898 | :tag item | 898 | :tag item |
| 899 | :notify 'recentf-edit-list-action))) | 899 | :notify 'recentf-edit-list-action))) |
| 900 | recentf-list) | 900 | recentf-list) |
| 901 | (widget-insert "\n\n") | 901 | (widget-insert "\n\n") |
| 902 | ;; Insert the Ok button | 902 | ;; Insert the Ok button |
| 903 | (widget-create 'push-button | 903 | (widget-create 'push-button |
| 904 | :notify (lambda (&rest ignore) | 904 | :notify (lambda (&rest ignore) |
| 905 | (if recentf-edit-selected-items | 905 | (if recentf-edit-selected-items |
| 906 | (progn (kill-buffer (current-buffer)) | 906 | (progn (kill-buffer (current-buffer)) |
| 907 | (mapcar (function | 907 | (mapcar (function |
| 908 | (lambda (item) | 908 | (lambda (item) |
| 909 | (setq recentf-list | 909 | (setq recentf-list |
| 910 | (delq item recentf-list)))) | 910 | (delq item recentf-list)))) |
| 911 | recentf-edit-selected-items) | 911 | recentf-edit-selected-items) |
| 912 | (message "%S file(s) removed from the list" | 912 | (message "%S file(s) removed from the list" |
| 913 | (length recentf-edit-selected-items)) | 913 | (length recentf-edit-selected-items)) |
| 914 | (setq recentf-update-menu-p t)) | 914 | (setq recentf-update-menu-p t)) |
| 915 | (message "No file selected."))) | 915 | (message "No file selected."))) |
| 916 | "Ok") | 916 | "Ok") |
| 917 | (widget-insert " ") | 917 | (widget-insert " ") |
| 918 | ;; Insert the Cancel button | 918 | ;; Insert the Cancel button |
| 919 | (widget-create 'push-button | 919 | (widget-create 'push-button |
| 920 | :notify 'recentf-cancel-dialog | 920 | :notify 'recentf-cancel-dialog |
| 921 | "Cancel") | 921 | "Cancel") |
| 922 | (recentf-dialog-mode) | 922 | (recentf-dialog-mode) |
| 923 | (widget-setup) | 923 | (widget-setup) |
| 924 | (goto-char (point-min)))) | 924 | (goto-char (point-min)))) |
| 925 | 925 | ||
| 926 | ;;;###autoload | 926 | ;;;###autoload |
| 927 | (defun recentf-cleanup () | 927 | (defun recentf-cleanup () |
| 928 | "Remove all non-readable and excluded files from `recentf-list'." | 928 | "Remove all non-readable and excluded files from `recentf-list'." |
| 929 | (interactive) | 929 | (interactive) |
| 930 | (let ((count (length recentf-list))) | 930 | (let ((count (length recentf-list))) |
| 931 | (setq recentf-list | 931 | (setq recentf-list |
| 932 | (delq nil | 932 | (delq nil |
| 933 | (mapcar (function | 933 | (mapcar (function |
| 934 | (lambda (filename) | 934 | (lambda (filename) |
| 935 | (and (file-readable-p filename) | 935 | (and (file-readable-p filename) |
| 936 | (recentf-include-p filename) | 936 | (recentf-include-p filename) |
| 937 | filename))) | 937 | filename))) |
| 938 | recentf-list))) | 938 | recentf-list))) |
| 939 | (setq count (- count (length recentf-list))) | 939 | (setq count (- count (length recentf-list))) |
| 940 | (message "%s removed from the list" | 940 | (message "%s removed from the list" |
| 941 | (cond ((= count 0) "No file") | 941 | (cond ((= count 0) "No file") |
| 942 | ((= count 1) "One file") | 942 | ((= count 1) "One file") |
| 943 | (t (format "%d files" count))))) | 943 | (t (format "%d files" count))))) |
| 944 | (setq recentf-update-menu-p t)) | 944 | (setq recentf-update-menu-p t)) |
| 945 | 945 | ||
| 946 | (defun recentf-open-files-action (widget &rest ignore) | 946 | (defun recentf-open-files-action (widget &rest ignore) |
| 947 | "Button widget action used by `recentf-open-files' to open a file." | 947 | "Button widget action used by `recentf-open-files' to open a file." |
| 948 | (kill-buffer (current-buffer)) | 948 | (kill-buffer (current-buffer)) |
| 949 | (funcall recentf-menu-action (widget-value widget))) | 949 | (funcall recentf-menu-action (widget-value widget))) |
| 950 | 950 | ||
| 951 | (defvar recentf-open-files-item-shift "" | 951 | (defvar recentf-open-files-item-shift "" |
| 952 | "String used by `recentf-open-files' to shift right sub-menu | 952 | "String used by `recentf-open-files' to shift right sub-menu |
| 953 | items.") | 953 | items.") |
| 954 | 954 | ||
| 955 | (defun recentf-open-files-item (menu-element) | 955 | (defun recentf-open-files-item (menu-element) |
| 956 | "Function called by `recentf-open-files' to insert a menu-element | 956 | "Function called by `recentf-open-files' to insert a menu-element |
| 957 | item in the current interaction buffer." | 957 | item in the current interaction buffer." |
| 958 | (let ((menu-item (car menu-element)) | 958 | (let ((menu-item (car menu-element)) |
| 959 | (file-path (cdr menu-element))) | 959 | (file-path (cdr menu-element))) |
| 960 | (if (consp file-path) ; This is a sub-menu | 960 | (if (consp file-path) ; This is a sub-menu |
| 961 | (let* ((shift recentf-open-files-item-shift) | 961 | (let* ((shift recentf-open-files-item-shift) |
| 962 | (recentf-open-files-item-shift (concat shift " "))) | 962 | (recentf-open-files-item-shift (concat shift " "))) |
| 963 | (widget-create 'item | 963 | (widget-create 'item |
| 964 | :tag menu-item | 964 | :tag menu-item |
| 965 | :sample-face 'bold | 965 | :sample-face 'bold |
| 966 | :format (concat shift "%{%t%}:\n")) | 966 | :format (concat shift "%{%t%}:\n")) |
| 967 | (mapcar 'recentf-open-files-item | 967 | (mapcar 'recentf-open-files-item |
| 968 | file-path) | 968 | file-path) |
| 969 | (widget-insert "\n")) | 969 | (widget-insert "\n")) |
| 970 | (widget-create 'push-button | 970 | (widget-create 'push-button |
| 971 | :button-face 'default | 971 | :button-face 'default |
| 972 | :tag menu-item | 972 | :tag menu-item |
| 973 | :help-echo (concat "Open " file-path) | 973 | :help-echo (concat "Open " file-path) |
| 974 | :format (concat recentf-open-files-item-shift "%[%t%]") | 974 | :format (concat recentf-open-files-item-shift "%[%t%]") |
| 975 | :notify 'recentf-open-files-action | 975 | :notify 'recentf-open-files-action |
| 976 | file-path) | 976 | file-path) |
| 977 | (widget-insert "\n")))) | 977 | (widget-insert "\n")))) |
| 978 | 978 | ||
| 979 | ;;;###autoload | 979 | ;;;###autoload |
| 980 | (defun recentf-open-files (&optional files buffer-name) | 980 | (defun recentf-open-files (&optional files buffer-name) |
| 981 | "Open a buffer that allows the user to choose a file to open from | 981 | "Open a buffer that allows the user to choose a file to open from |
| 982 | the list of recently opened files. The optional argument FILES may be | 982 | the list of recently opened files. The optional argument FILES may be |
| 983 | used to specify the list, otherwise recentf-list is used. The optional | 983 | used to specify the list, otherwise recentf-list is used. The optional |
| 984 | argument BUFFER-NAME specifies which buffer to use for the interaction." | 984 | argument BUFFER-NAME specifies which buffer to use for the interaction." |
| 985 | (interactive) | 985 | (interactive) |
| 986 | (if (null files) | 986 | (if (null files) |
| 987 | (setq files recentf-list)) | 987 | (setq files recentf-list)) |
| 988 | (if (null buffer-name) | 988 | (if (null buffer-name) |
| 989 | (setq buffer-name (concat "*" recentf-menu-title "*"))) | 989 | (setq buffer-name (concat "*" recentf-menu-title "*"))) |
| 990 | (with-current-buffer (get-buffer-create buffer-name) | 990 | (with-current-buffer (get-buffer-create buffer-name) |
| 991 | (switch-to-buffer (current-buffer)) | 991 | (switch-to-buffer (current-buffer)) |
| 992 | (kill-all-local-variables) | 992 | (kill-all-local-variables) |
| 993 | (let ((inhibit-read-only t)) | 993 | (let ((inhibit-read-only t)) |
| 994 | (erase-buffer)) | 994 | (erase-buffer)) |
| 995 | (let ((all (overlay-lists))) | 995 | (let ((all (overlay-lists))) |
| 996 | ;; Delete all the overlays. | 996 | ;; Delete all the overlays. |
| 997 | (mapcar 'delete-overlay (car all)) | 997 | (mapcar 'delete-overlay (car all)) |
| 998 | (mapcar 'delete-overlay (cdr all))) | 998 | (mapcar 'delete-overlay (cdr all))) |
| 999 | ;; Insert the dialog header | 999 | ;; Insert the dialog header |
| 1000 | (widget-insert "Click on a file to open it. ") | 1000 | (widget-insert "Click on a file to open it. ") |
| 1001 | (widget-insert "Click on Cancel or type \"q\" to quit.\n\n" ) | 1001 | (widget-insert "Click on Cancel or type \"q\" to quit.\n\n" ) |
| 1002 | ;; Insert the list of files as buttons | 1002 | ;; Insert the list of files as buttons |
| 1003 | (let ((recentf-open-files-item-shift "")) | 1003 | (let ((recentf-open-files-item-shift "")) |
| 1004 | (mapcar 'recentf-open-files-item | 1004 | (mapcar 'recentf-open-files-item |
| 1005 | (recentf-apply-menu-filter | 1005 | (recentf-apply-menu-filter |
| 1006 | recentf-menu-filter | 1006 | recentf-menu-filter |
| 1007 | (mapcar 'recentf-make-default-menu-element files)))) | 1007 | (mapcar 'recentf-make-default-menu-element files)))) |
| 1008 | (widget-insert "\n") | 1008 | (widget-insert "\n") |
| 1009 | ;; Insert the Cancel button | 1009 | ;; Insert the Cancel button |
| 1010 | (widget-create 'push-button | 1010 | (widget-create 'push-button |
| 1011 | :notify 'recentf-cancel-dialog | 1011 | :notify 'recentf-cancel-dialog |
| 1012 | "Cancel") | 1012 | "Cancel") |
| 1013 | (recentf-dialog-mode) | 1013 | (recentf-dialog-mode) |
| 1014 | (widget-setup) | 1014 | (widget-setup) |
| 1015 | (goto-char (point-min)))) | 1015 | (goto-char (point-min)))) |
| 1016 | 1016 | ||
| 1017 | ;;;###autoload | 1017 | ;;;###autoload |
| 1018 | (defun recentf-open-more-files () | 1018 | (defun recentf-open-more-files () |
| 1019 | "Allow the user to open files that are not in the menu." | 1019 | "Allow the user to open files that are not in the menu." |
| 1020 | (interactive) | 1020 | (interactive) |
| 1021 | (recentf-open-files (nthcdr recentf-max-menu-items recentf-list) | 1021 | (recentf-open-files (nthcdr recentf-max-menu-items recentf-list) |
| 1022 | (concat "*" recentf-menu-title " - More*"))) | 1022 | (concat "*" recentf-menu-title " - More*"))) |
| 1023 | 1023 | ||
| 1024 | ;;;###autoload | 1024 | ;;;###autoload |
| 1025 | (defun recentf-mode (&optional arg) | 1025 | (defun recentf-mode (&optional arg) |
| 1026 | "Toggle recentf mode. | 1026 | "Toggle recentf mode. |
| 1027 | With prefix ARG, turn recentf mode on if and only if ARG is positive. | 1027 | With prefix ARG, turn recentf mode on if and only if ARG is positive. |
| 1028 | Returns the new status of recentf mode (non-nil means on). | 1028 | Returns the new status of recentf mode (non-nil means on). |
| 1029 | 1029 | ||
| 1030 | When recentf mode is enabled, it maintains a menu for visiting files that | 1030 | When recentf mode is enabled, it maintains a menu for visiting files that |
| 1031 | were operated on recently." | 1031 | were operated on recently." |
| 1032 | (interactive "P") | 1032 | (interactive "P") |
| 1033 | (let ((on-p (if arg | 1033 | (let ((on-p (if arg |
| 1034 | (> (prefix-numeric-value arg) 0) | 1034 | (> (prefix-numeric-value arg) 0) |
| 1035 | (not recentf-mode)))) | 1035 | (not recentf-mode)))) |
| 1036 | (if on-p | 1036 | (if on-p |
| 1037 | (unless recentf-initialized-p | 1037 | (unless recentf-initialized-p |
| 1038 | (setq recentf-initialized-p t) | 1038 | (setq recentf-initialized-p t) |
| 1039 | (if (file-readable-p recentf-save-file) | 1039 | (if (file-readable-p recentf-save-file) |
| 1040 | (load-file recentf-save-file)) | 1040 | (load-file recentf-save-file)) |
| 1041 | (setq recentf-update-menu-p t) | 1041 | (setq recentf-update-menu-p t) |
| 1042 | (add-hook 'find-file-hooks 'recentf-add-file-hook) | 1042 | (add-hook 'find-file-hooks 'recentf-add-file-hook) |
| 1043 | (add-hook 'write-file-hooks 'recentf-add-file-hook) | 1043 | (add-hook 'write-file-hooks 'recentf-add-file-hook) |
| 1044 | (add-hook 'menu-bar-update-hook 'recentf-update-menu-hook) | 1044 | (add-hook 'menu-bar-update-hook 'recentf-update-menu-hook) |
| 1045 | (add-hook 'kill-emacs-hook 'recentf-save-list)) | 1045 | (add-hook 'kill-emacs-hook 'recentf-save-list)) |
| 1046 | (when recentf-initialized-p | 1046 | (when recentf-initialized-p |
| 1047 | (setq recentf-initialized-p nil) | 1047 | (setq recentf-initialized-p nil) |
| 1048 | (recentf-save-list) | 1048 | (recentf-save-list) |
| 1049 | (easy-menu-remove-item nil recentf-menu-path recentf-menu-title) | 1049 | (easy-menu-remove-item nil recentf-menu-path recentf-menu-title) |
| 1050 | (remove-hook 'find-file-hooks 'recentf-add-file-hook) | 1050 | (remove-hook 'find-file-hooks 'recentf-add-file-hook) |
| 1051 | (remove-hook 'write-file-hooks 'recentf-add-file-hook) | 1051 | (remove-hook 'write-file-hooks 'recentf-add-file-hook) |
| 1052 | (remove-hook 'menu-bar-update-hook 'recentf-update-menu-hook) | 1052 | (remove-hook 'menu-bar-update-hook 'recentf-update-menu-hook) |
| 1053 | (remove-hook 'kill-emacs-hook 'recentf-save-list))) | 1053 | (remove-hook 'kill-emacs-hook 'recentf-save-list))) |
| 1054 | (setq recentf-mode on-p))) | 1054 | (setq recentf-mode on-p))) |
| 1055 | 1055 | ||
| 1056 | (provide 'recentf) | 1056 | (provide 'recentf) |
| 1057 | 1057 | ||
| 1058 | (run-hooks 'recentf-load-hook) | 1058 | (run-hooks 'recentf-load-hook) |
| 1059 | 1059 | ||
| 1060 | ;;; recentf.el ends here. | 1060 | ;;; recentf.el ends here. |