aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Ponce2005-06-26 07:42:38 +0000
committerDavid Ponce2005-06-26 07:42:38 +0000
commit7b2ab96952f2fd9c1ffde2e40f59dad62c8047f6 (patch)
tree43f8342ee13d34be835f178d427f75cd73f54e95
parentec9ac2bebb1f4dcbeb61d4a51403bf658a0f9a3c (diff)
downloademacs-7b2ab96952f2fd9c1ffde2e40f59dad62c8047f6.tar.gz
emacs-7b2ab96952f2fd9c1ffde2e40f59dad62c8047f6.zip
Require 'tree-widget instead of 'wid-edit.
(recentf-filename-handler): Fix widget :type. (recentf-cancel-dialog, recentf-open-more-files) (recentf-open-files-action): Doc fix. (recentf-dialog-goto-first): New function. (recentf-dialog-mode-map): Set parent keymap first. (recentf-dialog-mode): Define with define-derived-mode. Don't display continuation lines in dialogs. (recentf-edit-list): Rename from recentf-edit-selected-items. (recentf-edit-list-select): Rename from recentf-edit-list-action. Simplify. (recentf-edit-list-validate): New function. (recentf-edit-list): Update accordingly. (recentf-open-files-item-shift): Remove. (recentf-open-files-item): Convert menu elements into tree and link widgets. Don't create the widgets. (recentf-open-files): Update accordingly. (recentf-save-list): Untabify.
-rw-r--r--lisp/recentf.el285
1 files changed, 137 insertions, 148 deletions
diff --git a/lisp/recentf.el b/lisp/recentf.el
index 1ea3ae6ecb2..64af3b1da3f 100644
--- a/lisp/recentf.el
+++ b/lisp/recentf.el
@@ -28,18 +28,18 @@
28;;; Commentary: 28;;; Commentary:
29 29
30;; This package maintains a menu for visiting files that were operated 30;; This package maintains a menu for visiting files that were operated
31;; on recently. When enabled a new "Open Recent" submenu is displayed 31;; on recently. When enabled a new "Open Recent" sub menu is
32;; in the "Files" menu. The recent files list is automatically saved 32;; displayed in the "Files" menu. The recent files list is
33;; across Emacs sessions. You can customize the number of recent 33;; automatically saved across Emacs sessions. You can customize the
34;; files displayed, the location of the menu and others options (see 34;; number of recent files displayed, the location of the menu and
35;; the source code for details). 35;; others options (see the source code for details).
36 36
37;;; History: 37;;; History:
38;; 38;;
39 39
40;;; Code: 40;;; Code:
41(require 'easymenu) 41(require 'easymenu)
42(require 'wid-edit) 42(require 'tree-widget)
43(require 'timer) 43(require 'timer)
44 44
45;;; Internal data 45;;; Internal data
@@ -259,7 +259,8 @@ If `file-name-history' is not empty, do nothing."
259It is passed a filename to give a chance to transform it. 259It is passed a filename to give a chance to transform it.
260If it returns nil, the filename is left unchanged." 260If it returns nil, the filename is left unchanged."
261 :group 'recentf 261 :group 'recentf
262 :type 'function) 262 :type '(choice (const :tag "None" nil)
263 function))
263 264
264;;; Utilities 265;;; Utilities
265;; 266;;
@@ -904,30 +905,54 @@ unchanged."
904;; 905;;
905(defun recentf-cancel-dialog (&rest ignore) 906(defun recentf-cancel-dialog (&rest ignore)
906 "Cancel the current dialog. 907 "Cancel the current dialog.
907Used internally by recentf dialogs.
908IGNORE arguments." 908IGNORE arguments."
909 (interactive) 909 (interactive)
910 (kill-buffer (current-buffer)) 910 (kill-buffer (current-buffer))
911 (message "Dialog canceled")) 911 (message "Dialog canceled"))
912 912
913(defun recentf-dialog-goto-first (widget-type)
914 "Move the cursor to the first WIDGET-TYPE in current dialog.
915Go to the beginning of buffer if not found."
916 (goto-char (point-min))
917 (condition-case nil
918 (let (done)
919 (widget-move 1)
920 (while (not done)
921 (if (eq widget-type (widget-type (widget-at (point))))
922 (setq done t)
923 (widget-move 1))))
924 (goto-char (point-min))))
925
913(defvar recentf-dialog-mode-map 926(defvar recentf-dialog-mode-map
914 (let ((km (make-sparse-keymap))) 927 (let ((km (make-sparse-keymap)))
928 (set-keymap-parent km widget-keymap)
915 (define-key km "q" 'recentf-cancel-dialog) 929 (define-key km "q" 'recentf-cancel-dialog)
916 (define-key km [down-mouse-1] 'widget-button-click) 930 (define-key km [down-mouse-1] 'widget-button-click)
917 (set-keymap-parent km widget-keymap)
918 km) 931 km)
919 "Keymap used in recentf dialogs.") 932 "Keymap used in recentf dialogs.")
920 933
921(defun recentf-dialog-mode () 934(define-derived-mode recentf-dialog-mode nil "recentf-dialog"
922 "Major mode of recentf dialogs. 935 "Major mode of recentf dialogs.
923 936
924\\{recentf-dialog-mode-map}" 937\\{recentf-dialog-mode-map}"
925 (interactive) 938 :syntax-table nil
926 (kill-all-local-variables) 939 :abbrev-table nil
927 (setq major-mode 'recentf-dialog-mode) 940 (setq truncate-lines t))
928 (setq mode-name "recentf-dialog") 941
929 (use-local-map recentf-dialog-mode-map) 942(defmacro recentf-dialog (name &rest forms)
930 (run-mode-hooks 'recentf-dialog-mode-hook)) 943 "Show a dialog buffer with NAME, setup with FORMS."
944 (declare (indent 1) (debug t))
945 `(with-current-buffer (get-buffer-create ,name)
946 ;; Cleanup buffer
947 (let ((inhibit-read-only t)
948 (ol (overlay-lists)))
949 (mapc 'delete-overlay (car ol))
950 (mapc 'delete-overlay (cdr ol))
951 (erase-buffer))
952 (recentf-dialog-mode)
953 ,@forms
954 (widget-setup)
955 (switch-to-buffer (current-buffer))))
931 956
932;;; Hooks 957;;; Hooks
933;; 958;;
@@ -976,163 +1001,127 @@ That is, remove a non kept file from the recent list."
976 1001
977;;; Commands 1002;;; Commands
978;; 1003;;
979(defvar recentf-edit-selected-items nil
980 "List of files to be deleted from the recent list.
981Used internally by `recentf-edit-list'.")
982 1004
983(defun recentf-edit-list-action (widget &rest ignore) 1005;;; Edit list dialog
984 "Checkbox WIDGET action that toogles a file selection. 1006;;
985Used internally by `recentf-edit-list'. 1007(defvar recentf-edit-list nil)
1008
1009(defun recentf-edit-list-select (widget &rest ignore)
1010 "Toggle a file selection based on the checkbox WIDGET state.
986IGNORE other arguments." 1011IGNORE other arguments."
987 (let ((value (widget-get widget ':tag))) 1012 (let ((value (widget-get widget :tag))
988 ;; if value is already in the selected items 1013 (check (widget-value widget)))
989 (if (memq value recentf-edit-selected-items) 1014 (if check
990 ;; then remove it 1015 (add-to-list 'recentf-edit-list value)
991 (progn 1016 (setq recentf-edit-list (delq value recentf-edit-list)))
992 (setq recentf-edit-selected-items 1017 (message "%s %sselected" value (if check "" "un"))))
993 (delq value recentf-edit-selected-items)) 1018
994 (message "%s removed from selection" value)) 1019(defun recentf-edit-list-validate (&rest ignore)
995 ;; else add it 1020 "Process the recent list when the edit list dialog is committed.
996 (push value recentf-edit-selected-items) 1021IGNORE arguments."
997 (message "%s added to selection" value)))) 1022 (if recentf-edit-list
1023 (let ((i 0))
1024 (dolist (e recentf-edit-list)
1025 (setq recentf-list (delq e recentf-list)
1026 i (1+ i)))
1027 (kill-buffer (current-buffer))
1028 (message "%S file(s) removed from the list" i)
1029 (recentf-clear-data))
1030 (message "No file selected")))
998 1031
999(defun recentf-edit-list () 1032(defun recentf-edit-list ()
1000 "Show a dialog buffer to edit the recent list. 1033 "Show a dialog to delete selected files from the recent list."
1001That is to select files to be deleted from the recent list."
1002 (interactive) 1034 (interactive)
1003 (with-current-buffer 1035 (recentf-dialog (format "*%s - Edit list*" recentf-menu-title)
1004 (get-buffer-create (format "*%s - Edit list*" recentf-menu-title)) 1036 (set (make-local-variable 'recentf-edit-list) nil)
1005 (switch-to-buffer (current-buffer))
1006 ;; Cleanup buffer
1007 (let ((inhibit-read-only t)
1008 (ol (overlay-lists)))
1009 (erase-buffer)
1010 ;; Delete all the overlays.
1011 (mapc 'delete-overlay (car ol))
1012 (mapc 'delete-overlay (cdr ol)))
1013 (recentf-dialog-mode)
1014 (setq recentf-edit-selected-items nil)
1015 ;; Insert the dialog header
1016 (widget-insert 1037 (widget-insert
1017 "\ 1038 "Click on OK to delete selected files from the recent list.
1018Select the files to be deleted from the recent list.\n\n\ 1039Click on Cancel or type `q' to cancel.\n")
1019Click on Ok to update the list. \
1020Click on Cancel or type \"q\" to quit.\n")
1021 ;; Insert the list of files as checkboxes 1040 ;; Insert the list of files as checkboxes
1022 (dolist (item recentf-list) 1041 (dolist (item recentf-list)
1023 (widget-create 1042 (widget-create 'checkbox
1024 'checkbox 1043 :value nil ; unselected checkbox
1025 :value nil ; unselected checkbox 1044 :format "\n %[%v%] %t"
1026 :format "\n %[%v%] %t" 1045 :tag item
1027 :tag item 1046 :notify 'recentf-edit-list-select))
1028 :notify 'recentf-edit-list-action))
1029 (widget-insert "\n\n") 1047 (widget-insert "\n\n")
1030 ;; Insert the Ok button
1031 (widget-create 1048 (widget-create
1032 'push-button 1049 'push-button
1033 :notify (lambda (&rest ignore) 1050 :notify 'recentf-edit-list-validate
1034 (if recentf-edit-selected-items 1051 :help-echo "Delete selected files from the recent list"
1035 (let ((i 0)) 1052 "Ok")
1036 (kill-buffer (current-buffer))
1037 (dolist (e recentf-edit-selected-items)
1038 (setq recentf-list (delq e recentf-list)
1039 i (1+ i)))
1040 (message "%S file(s) removed from the list" i)
1041 (recentf-clear-data))
1042 (message "No file selected")))
1043 "Ok")
1044 (widget-insert " ") 1053 (widget-insert " ")
1045 ;; Insert the Cancel button
1046 (widget-create 1054 (widget-create
1047 'push-button 1055 'push-button
1048 :notify 'recentf-cancel-dialog 1056 :notify 'recentf-cancel-dialog
1049 "Cancel") 1057 "Cancel")
1050 (widget-setup) 1058 (recentf-dialog-goto-first 'checkbox)))
1051 (goto-char (point-min))))
1052 1059
1060;;; Open file dialog
1061;;
1053(defun recentf-open-files-action (widget &rest ignore) 1062(defun recentf-open-files-action (widget &rest ignore)
1054 "Button WIDGET action that open a file. 1063 "Open the file stored in WIDGET's value when notified.
1055Used internally by `recentf-open-files'.
1056IGNORE other arguments." 1064IGNORE other arguments."
1057 (kill-buffer (current-buffer)) 1065 (kill-buffer (current-buffer))
1058 (funcall recentf-menu-action (widget-value widget))) 1066 (funcall recentf-menu-action (widget-value widget)))
1059 1067
1060(defvar recentf-open-files-item-shift ""
1061 "Amount of space to shift right sub-menu items.
1062Used internally by `recentf-open-files'.")
1063
1064(defun recentf-open-files-item (menu-element) 1068(defun recentf-open-files-item (menu-element)
1065 "Insert an item widget for MENU-ELEMENT in the current dialog buffer. 1069 "Return a widget to display MENU-ELEMENT in a dialog buffer."
1066Used internally by `recentf-open-files'." 1070 (if (consp (cdr menu-element))
1067 (let ((item (car menu-element)) 1071 ;; Represent a sub-menu with a tree widget
1068 (file (cdr menu-element))) 1072 `(tree-widget
1069 (if (consp file) ; This is a sub-menu 1073 :open t
1070 (let* ((shift recentf-open-files-item-shift) 1074 :match ignore
1071 (recentf-open-files-item-shift (concat shift " "))) 1075 :node (item :tag ,(car menu-element)
1072 (widget-create 1076 :sample-face bold
1073 'item 1077 :format "%{%t%}:\n")
1074 :tag item 1078 ,@(mapcar 'recentf-open-files-item
1075 :sample-face 'bold 1079 (cdr menu-element)))
1076 :format (concat shift "%{%t%}:\n")) 1080 ;; Represent a single file with a link widget
1077 (mapc 'recentf-open-files-item file) 1081 `(link :tag ,(car menu-element)
1078 (widget-insert "\n")) 1082 :button-prefix ""
1079 (widget-create 1083 :button-suffix ""
1080 'push-button 1084 :button-face default
1081 :button-face 'default 1085 :format "%[%t%]\n"
1082 :tag item 1086 :help-echo ,(concat "Open " (cdr menu-element))
1083 :help-echo (concat "Open " file) 1087 :action recentf-open-files-action
1084 :format (concat recentf-open-files-item-shift "%[%t%]") 1088 ,(cdr menu-element))))
1085 :notify 'recentf-open-files-action
1086 file)
1087 (widget-insert "\n"))))
1088 1089
1089(defun recentf-open-files (&optional files buffer-name) 1090(defun recentf-open-files (&optional files buffer-name)
1090 "Show a dialog buffer to open a recent file. 1091 "Show a dialog to open a recent file.
1091If optional argument FILES is non-nil, it specifies the list of 1092If optional argument FILES is non-nil, it is a list of recently-opened
1092recently-opened files to choose from. It is the whole recent list 1093files to choose from. It defaults to the whole recent list.
1093otherwise. 1094If optional argument BUFFER-NAME is non-nil, it is a buffer name to
1094If optional argument BUFFER-NAME is non-nil, it specifies which buffer 1095use for the dialog. It defaults to \"*`recentf-menu-title'*\"."
1095name to use for the interaction. It is \"*`recentf-menu-title'*\" by
1096default."
1097 (interactive) 1096 (interactive)
1098 (unless files 1097 (recentf-dialog (or buffer-name (format "*%s*" recentf-menu-title))
1099 (setq files recentf-list)) 1098 (widget-insert "Click on a file to open it.
1100 (unless buffer-name 1099Click on Cancel or type `q' to cancel.\n" )
1101 (setq buffer-name (format "*%s*" recentf-menu-title))) 1100 ;; Use a L&F that looks like the recentf menu.
1102 (with-current-buffer (get-buffer-create buffer-name) 1101 (tree-widget-set-theme "folder")
1103 (switch-to-buffer (current-buffer)) 1102 (apply 'widget-create
1104 ;; Cleanup buffer 1103 `(group
1105 (let ((inhibit-read-only t) 1104 :indent 2
1106 (ol (overlay-lists))) 1105 :format "\n%v\n"
1107 (erase-buffer) 1106 ,@(mapcar 'recentf-open-files-item
1108 ;; Delete all the overlays. 1107 (recentf-apply-menu-filter
1109 (mapc 'delete-overlay (car ol)) 1108 recentf-menu-filter
1110 (mapc 'delete-overlay (cdr ol))) 1109 (mapcar 'recentf-make-default-menu-element
1111 (recentf-dialog-mode) 1110 (or files recentf-list))))))
1112 ;; Insert the dialog header
1113 (widget-insert "Click on a file to open it. ")
1114 (widget-insert "Click on Cancel or type \"q\" to quit.\n\n" )
1115 ;; Insert the list of files as buttons
1116 (let ((recentf-open-files-item-shift ""))
1117 (mapc 'recentf-open-files-item
1118 (recentf-apply-menu-filter
1119 recentf-menu-filter
1120 (mapcar 'recentf-make-default-menu-element files))))
1121 (widget-insert "\n")
1122 ;; Insert the Cancel button
1123 (widget-create 1111 (widget-create
1124 'push-button 1112 'push-button
1125 :notify 'recentf-cancel-dialog 1113 :notify 'recentf-cancel-dialog
1126 "Cancel") 1114 "Cancel")
1127 (widget-setup) 1115 (recentf-dialog-goto-first 'link)))
1128 (goto-char (point-min))))
1129 1116
1130(defun recentf-open-more-files () 1117(defun recentf-open-more-files ()
1131 "Show a dialog buffer to open a recent file that is not in the menu." 1118 "Show a dialog to open a recent file that is not in the menu."
1132 (interactive) 1119 (interactive)
1133 (recentf-open-files (nthcdr recentf-max-menu-items recentf-list) 1120 (recentf-open-files (nthcdr recentf-max-menu-items recentf-list)
1134 (format "*%s - More*" recentf-menu-title))) 1121 (format "*%s - More*" recentf-menu-title)))
1135 1122
1123;;; Save/load/cleanup the recent list
1124;;
1136(defconst recentf-save-file-header 1125(defconst recentf-save-file-header
1137 ";;; Automatically generated by `recentf' on %s.\n" 1126 ";;; Automatically generated by `recentf' on %s.\n"
1138 "Header to be written into the `recentf-save-file'.") 1127 "Header to be written into the `recentf-save-file'.")
@@ -1149,16 +1138,16 @@ Write data into the file specified by `recentf-save-file'."
1149 (interactive) 1138 (interactive)
1150 (condition-case error 1139 (condition-case error
1151 (with-temp-buffer 1140 (with-temp-buffer
1152 (erase-buffer) 1141 (erase-buffer)
1153 (set-buffer-file-coding-system recentf-save-file-coding-system) 1142 (set-buffer-file-coding-system recentf-save-file-coding-system)
1154 (insert (format recentf-save-file-header (current-time-string))) 1143 (insert (format recentf-save-file-header (current-time-string)))
1155 (recentf-dump-variable 'recentf-list recentf-max-saved-items) 1144 (recentf-dump-variable 'recentf-list recentf-max-saved-items)
1156 (recentf-dump-variable 'recentf-filter-changer-state) 1145 (recentf-dump-variable 'recentf-filter-changer-state)
1157 (insert "\n \n;;; Local Variables:\n" 1146 (insert "\n \n;;; Local Variables:\n"
1158 (format ";;; coding: %s\n" recentf-save-file-coding-system) 1147 (format ";;; coding: %s\n" recentf-save-file-coding-system)
1159 ";;; End:\n") 1148 ";;; End:\n")
1160 (write-file (expand-file-name recentf-save-file)) 1149 (write-file (expand-file-name recentf-save-file))
1161 nil) 1150 nil)
1162 (error 1151 (error
1163 (warn "recentf mode: %s" (error-message-string error))))) 1152 (warn "recentf mode: %s" (error-message-string error)))))
1164 1153
@@ -1218,5 +1207,5 @@ that were operated on recently."
1218 1207
1219(run-hooks 'recentf-load-hook) 1208(run-hooks 'recentf-load-hook)
1220 1209
1221;;; arch-tag: 78f1eec9-0d16-4d19-a4eb-2e4529edb62a 1210;; arch-tag: 78f1eec9-0d16-4d19-a4eb-2e4529edb62a
1222;;; recentf.el ends here 1211;;; recentf.el ends here