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