diff options
| author | Gerd Moellmann | 2000-06-07 15:33:22 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-06-07 15:33:22 +0000 |
| commit | f56e2e8e6da3485655c6262d50deca760cf36629 (patch) | |
| tree | 7a85cc77cbeb4596002a53fa88bb6381467d3da6 | |
| parent | c14dcd22403c451b0d2dcd1f5ef8e08b2de47acd (diff) | |
| download | emacs-f56e2e8e6da3485655c6262d50deca760cf36629.tar.gz emacs-f56e2e8e6da3485655c6262d50deca760cf36629.zip | |
Fixed recentf-edit-list and recentf-open-more-files
commands. Require `wid-edit' at run-time.
Added some "Commentary".
(recentf-open-more-files, recentf-edit-list): Minor changes to
move the point at the top of the file list. This behaviour is
consistent with the menu one when the list contains a lot of
files.
(recentf-cleanup): Now displays the number of items removed from
the list.
(recentf-relative-filter) New menu filter to show filenames
relative to `default-directory'.
| -rw-r--r-- | lisp/recentf.el | 170 |
1 files changed, 139 insertions, 31 deletions
diff --git a/lisp/recentf.el b/lisp/recentf.el index 16be807c73c..375c8c890cc 100644 --- a/lisp/recentf.el +++ b/lisp/recentf.el | |||
| @@ -1,6 +1,6 @@ | |||
| 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 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1999, 2000 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: David Ponce <david.ponce@wanadoo.fr> | 5 | ;; Author: David Ponce <david.ponce@wanadoo.fr> |
| 6 | ;; Created: July 19 1999 | 6 | ;; Created: July 19 1999 |
| @@ -25,12 +25,22 @@ | |||
| 25 | 25 | ||
| 26 | ;;; Commentary: | 26 | ;;; Commentary: |
| 27 | 27 | ||
| 28 | ;; This package maintains a menu for visiting files that were operated | ||
| 29 | ;; on recently. When enabled a new "Open Recent" submenu is displayed | ||
| 30 | ;; in the "Files" menu. The recent files list is automatically saved | ||
| 31 | ;; across Emacs sessions. You can customize the number of recent | ||
| 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 | ||
| 34 | ;; your Emacs-Lisp load path and add the following into your ~/.emacs | ||
| 35 | ;; startup file: | ||
| 36 | ;; | ||
| 37 | ;; (require 'recentf) | ||
| 38 | ;; (recentf-mode 1) | ||
| 39 | |||
| 28 | ;;; Code: | 40 | ;;; Code: |
| 29 | 41 | ||
| 30 | (require 'easymenu) | 42 | (require 'easymenu) |
| 31 | (require 'widget) | 43 | (require 'wid-edit) |
| 32 | (eval-when-compile | ||
| 33 | (require 'wid-edit)) | ||
| 34 | 44 | ||
| 35 | (defconst recentf-save-file-header | 45 | (defconst recentf-save-file-header |
| 36 | ";;; Automatically generated by `recentf' on %s.\n" | 46 | ";;; Automatically generated by `recentf' on %s.\n" |
| @@ -124,9 +134,16 @@ Nil means no filter. The following functions are predefined: | |||
| 124 | 134 | ||
| 125 | - - `recentf-sort-ascending' to sort menu items in ascending order. | 135 | - - `recentf-sort-ascending' to sort menu items in ascending order. |
| 126 | - - `recentf-sort-descending' to sort menu items in descending order. | 136 | - - `recentf-sort-descending' to sort menu items in descending order. |
| 127 | 137 | - - `recentf-sort-basenames-ascending' to sort file names in descending order. | |
| 128 | The filter function is called with one argument, the list of filenames to be | 138 | - - `recentf-sort-basenames-descending' to sort file names in descending order. |
| 129 | displayed in the menu and must return a new list of filenames." | 139 | - - `recentf-show-basenames' to show file names (no directories) in menu items. |
| 140 | - - `recentf-show-basenames-ascending' to show file names in ascending order. | ||
| 141 | - - `recentf-show-basenames-descending' to show file names in descending order. | ||
| 142 | - - `recentf-relative-filter' to show file names relative to `default-directory'. | ||
| 143 | |||
| 144 | The filter function is called with one argument, the list of menu elements | ||
| 145 | used to build the menu and must return a new list of menu elements (see | ||
| 146 | `recentf-menu-elements' for menu element form)." | ||
| 130 | :group 'recentf | 147 | :group 'recentf |
| 131 | :type 'function | 148 | :type 'function |
| 132 | :set 'recentf-menu-customization-changed) | 149 | :set 'recentf-menu-customization-changed) |
| @@ -143,11 +160,11 @@ displayed in the menu and must return a new list of filenames." | |||
| 143 | :type 'boolean | 160 | :type 'boolean |
| 144 | :require 'recentf | 161 | :require 'recentf |
| 145 | :initialize 'custom-initialize-default | 162 | :initialize 'custom-initialize-default |
| 146 | :set (lambda (sym val) | 163 | :set (lambda (sym val) |
| 147 | (if val | 164 | (if val |
| 148 | (remove-hook 'kill-buffer-hook 'recentf-remove-file-hook) | 165 | (remove-hook 'kill-buffer-hook 'recentf-remove-file-hook) |
| 149 | (add-hook 'kill-buffer-hook 'recentf-remove-file-hook)) | 166 | (add-hook 'kill-buffer-hook 'recentf-remove-file-hook)) |
| 150 | (custom-set-default sym val))) | 167 | (custom-set-default sym val))) |
| 151 | 168 | ||
| 152 | (defcustom recentf-mode nil | 169 | (defcustom recentf-mode nil |
| 153 | "Toggle recentf mode. | 170 | "Toggle recentf mode. |
| @@ -216,11 +233,11 @@ were operated on recently." | |||
| 216 | (when recentf-update-menu-p | 233 | (when recentf-update-menu-p |
| 217 | (condition-case nil | 234 | (condition-case nil |
| 218 | (progn | 235 | (progn |
| 236 | (setq recentf-update-menu-p nil) | ||
| 219 | (easy-menu-change recentf-menu-path | 237 | (easy-menu-change recentf-menu-path |
| 220 | recentf-menu-title | 238 | recentf-menu-title |
| 221 | (recentf-make-menu-items) | 239 | (recentf-make-menu-items) |
| 222 | recentf-menu-before) | 240 | recentf-menu-before)) |
| 223 | (setq recentf-update-menu-p nil)) | ||
| 224 | (error nil)))) | 241 | (error nil)))) |
| 225 | 242 | ||
| 226 | ;;;###autoload | 243 | ;;;###autoload |
| @@ -309,19 +326,26 @@ from `recentf-list'.") | |||
| 309 | (message "Command canceled.")) | 326 | (message "Command canceled.")) |
| 310 | "Cancel") | 327 | "Cancel") |
| 311 | (use-local-map widget-keymap) | 328 | (use-local-map widget-keymap) |
| 312 | (widget-setup))) | 329 | (widget-setup) |
| 330 | (goto-char (point-min)))) | ||
| 313 | 331 | ||
| 314 | ;;;###autoload | 332 | ;;;###autoload |
| 315 | (defun recentf-cleanup () | 333 | (defun recentf-cleanup () |
| 316 | "Remove all non-readable and excluded files from `recentf-list'." | 334 | "Remove all non-readable and excluded files from `recentf-list'." |
| 317 | (interactive) | 335 | (interactive) |
| 318 | (setq recentf-list | 336 | (let ((count (length recentf-list))) |
| 319 | (delq nil | 337 | (setq recentf-list |
| 320 | (mapcar '(lambda (filename) | 338 | (delq nil |
| 321 | (and (file-readable-p filename) | 339 | (mapcar '(lambda (filename) |
| 322 | (recentf-include-p filename) | 340 | (and (file-readable-p filename) |
| 323 | filename)) | 341 | (recentf-include-p filename) |
| 324 | recentf-list))) | 342 | filename)) |
| 343 | recentf-list))) | ||
| 344 | (setq count (- count (length recentf-list))) | ||
| 345 | (message "%s removed from the list" | ||
| 346 | (cond ((= count 0) "No file") | ||
| 347 | ((= count 1) "One file") | ||
| 348 | (t (format "%d files" count))))) | ||
| 325 | (setq recentf-update-menu-p t)) | 349 | (setq recentf-update-menu-p t)) |
| 326 | 350 | ||
| 327 | (defun recentf-open-more-files-action (widget &rest ignore) | 351 | (defun recentf-open-more-files-action (widget &rest ignore) |
| @@ -367,7 +391,8 @@ from `recentf-list'.") | |||
| 367 | (message "Command canceled.")) | 391 | (message "Command canceled.")) |
| 368 | "Cancel") | 392 | "Cancel") |
| 369 | (use-local-map widget-keymap) | 393 | (use-local-map widget-keymap) |
| 370 | (widget-setup))) | 394 | (widget-setup) |
| 395 | (goto-char (point-min)))) | ||
| 371 | 396 | ||
| 372 | (defvar recentf-menu-items-for-commands | 397 | (defvar recentf-menu-items-for-commands |
| 373 | (list ["Cleanup list" recentf-cleanup t] | 398 | (list ["Cleanup list" recentf-cleanup t] |
| @@ -379,10 +404,9 @@ from `recentf-list'.") | |||
| 379 | (defun recentf-make-menu-items () | 404 | (defun recentf-make-menu-items () |
| 380 | "Make menu items from `recentf-list'." | 405 | "Make menu items from `recentf-list'." |
| 381 | (let ((file-items | 406 | (let ((file-items |
| 382 | (mapcar '(lambda (entry) | 407 | (mapcar 'recentf-make-menu-item |
| 383 | (vector entry (list recentf-menu-action entry) t)) | 408 | (funcall (or recentf-menu-filter 'identity) |
| 384 | (funcall (or recentf-menu-filter 'identity) | 409 | (recentf-menu-elements recentf-max-menu-items))))) |
| 385 | (recentf-elements recentf-max-menu-items))))) | ||
| 386 | (append (or file-items (list ["No files" t nil])) | 410 | (append (or file-items (list ["No files" t nil])) |
| 387 | (and (< recentf-max-menu-items (length recentf-list)) | 411 | (and (< recentf-max-menu-items (length recentf-list)) |
| 388 | (list ["More..." recentf-open-more-files t])) | 412 | (list ["More..." recentf-open-more-files t])) |
| @@ -390,6 +414,10 @@ from `recentf-list'.") | |||
| 390 | (cons ["---" nil nil] | 414 | (cons ["---" nil nil] |
| 391 | recentf-menu-items-for-commands))))) | 415 | recentf-menu-items-for-commands))))) |
| 392 | 416 | ||
| 417 | (defun recentf-make-menu-item (menu-element) | ||
| 418 | "Make a menu item from a menu element (see `recentf-menu-elements')." | ||
| 419 | (vector (car menu-element) (list recentf-menu-action (cdr menu-element)) t)) | ||
| 420 | |||
| 393 | (defun recentf-add-file (filename) | 421 | (defun recentf-add-file (filename) |
| 394 | "Add or move FILENAME at the beginning of `recentf-list'. | 422 | "Add or move FILENAME at the beginning of `recentf-list'. |
| 395 | Does nothing if FILENAME matches one of the `recentf-exclude' regexps." | 423 | Does nothing if FILENAME matches one of the `recentf-exclude' regexps." |
| @@ -429,13 +457,93 @@ If FILENAME is not readable it is removed from `recentf-list'." | |||
| 429 | (setq l (cdr l))) | 457 | (setq l (cdr l))) |
| 430 | (nreverse lh))) | 458 | (nreverse lh))) |
| 431 | 459 | ||
| 460 | (defun recentf-menu-elements (n) | ||
| 461 | "Return a list of the first N menu elements from `recentf-list'. | ||
| 462 | Each menu element has this form: | ||
| 463 | |||
| 464 | (MENU-ITEM . FILE-PATH) | ||
| 465 | |||
| 466 | MENU-ITEM is the menu item string displayed. | ||
| 467 | |||
| 468 | FILE-PATH is the path used to open the file when the corresponding MENU-ITEM | ||
| 469 | is selected. | ||
| 470 | |||
| 471 | At the start each MENU-ITEM is set to its corresponding FILE-PATH." | ||
| 472 | (mapcar '(lambda (item) (cons item item)) (recentf-elements n))) | ||
| 473 | |||
| 474 | |||
| 475 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 476 | ;; Predefined menu filter functions ;; | ||
| 477 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 478 | |||
| 432 | (defun recentf-sort-ascending (l) | 479 | (defun recentf-sort-ascending (l) |
| 433 | "Sort the list of strings L in ascending order." | 480 | "Sort the list of menu elements L in ascending order. |
| 434 | (sort l '(lambda (e1 e2) (string-lessp e1 e2)))) | 481 | The MENU-ITEM part of each menu element is compared." |
| 482 | (sort l '(lambda (e1 e2) (string-lessp (car e1) (car e2))))) | ||
| 435 | 483 | ||
| 436 | (defun recentf-sort-descending (l) | 484 | (defun recentf-sort-descending (l) |
| 437 | "Sort the list of strings L in descending order." | 485 | "Sort the list of menu elements L in descending order. |
| 438 | (sort l '(lambda (e1 e2) (string-lessp e2 e1)))) | 486 | The MENU-ITEM part of each menu element is compared." |
| 487 | (sort l '(lambda (e1 e2) (string-lessp (car e2) (car e1))))) | ||
| 488 | |||
| 489 | (defun recentf-sort-basenames-ascending (l) | ||
| 490 | "Sort the list of menu elements L in ascending order. | ||
| 491 | Only file names (without directories) are compared." | ||
| 492 | (sort l '(lambda (e1 e2) (string-lessp | ||
| 493 | (file-name-nondirectory (cdr e1)) | ||
| 494 | (file-name-nondirectory (cdr e2)))))) | ||
| 495 | |||
| 496 | (defun recentf-sort-basenames-descending (l) | ||
| 497 | "Sort the list of menu elements L in descending order. | ||
| 498 | Only file names (without directories) are compared." | ||
| 499 | (sort l '(lambda (e1 e2) (string-lessp | ||
| 500 | (file-name-nondirectory (cdr e2)) | ||
| 501 | (file-name-nondirectory (cdr e1)))))) | ||
| 502 | |||
| 503 | (defun recentf-show-basenames (l) | ||
| 504 | "Filter the list of menu elements L to show only file names (no directories) | ||
| 505 | in the menu. When file names are duplicated their directory component is added." | ||
| 506 | (let ((names (mapcar '(lambda (item) (file-name-nondirectory (cdr item))) l)) | ||
| 507 | (dirs (mapcar '(lambda (item) (file-name-directory (cdr item))) l)) | ||
| 508 | (pathes (mapcar 'cdr l)) | ||
| 509 | (pos -1) | ||
| 510 | item filtered-items filtered-list) | ||
| 511 | (while names | ||
| 512 | (setq item (car names)) | ||
| 513 | (setq names (cdr names)) | ||
| 514 | (setq pos (1+ pos)) | ||
| 515 | (setq filtered-list | ||
| 516 | (cons (cons (if (or (member item names) (member item filtered-items)) | ||
| 517 | (concat item " (" (nth pos dirs) ")") | ||
| 518 | item) | ||
| 519 | (nth pos pathes)) | ||
| 520 | filtered-list)) | ||
| 521 | (setq filtered-items (cons item filtered-items))) | ||
| 522 | (nreverse filtered-list))) | ||
| 523 | |||
| 524 | (defun recentf-show-basenames-ascending (l) | ||
| 525 | "Filter the list of menu elements L to show only file names in the menu, | ||
| 526 | sorted in ascending order. This filter combines the `recentf-sort-basenames-ascending' | ||
| 527 | and `recentf-show-basenames' filters." | ||
| 528 | (recentf-show-basenames (recentf-sort-basenames-ascending l))) | ||
| 529 | |||
| 530 | (defun recentf-show-basenames-descending (l) | ||
| 531 | "Filter the list of menu elements L to show only file names in the menu, | ||
| 532 | sorted in descending order. This filter combines the `recentf-sort-basenames-descending' | ||
| 533 | and `recentf-show-basenames' filters." | ||
| 534 | (recentf-show-basenames (recentf-sort-basenames-descending l))) | ||
| 535 | |||
| 536 | (defun recentf-relative-filter (l) | ||
| 537 | "Filter the list of `recentf-menu-elements' L to show filenames | ||
| 538 | relative to `default-directory'." | ||
| 539 | (setq recentf-update-menu-p t) ; force menu update | ||
| 540 | (mapcar '(lambda (menu-element) | ||
| 541 | (let* ((ful-path (cdr menu-element)) | ||
| 542 | (rel-path (file-relative-name ful-path))) | ||
| 543 | (if (string-match "^\\.\\." rel-path) | ||
| 544 | menu-element | ||
| 545 | (cons rel-path ful-path)))) | ||
| 546 | l)) | ||
| 439 | 547 | ||
| 440 | (provide 'recentf) | 548 | (provide 'recentf) |
| 441 | 549 | ||