Add 2012 to FSF copyright years for Emacs files (do not merge to trunk)
[bpt/emacs.git] / lisp / ebuff-menu.el
CommitLineData
c0274f38
ER
1;;; ebuff-menu.el --- electric-buffer-list mode
2
e91081eb 3;; Copyright (C) 1985, 1986, 1994, 2001, 2002, 2003, 2004,
49f70d46 4;; 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
2076c87c 5
3a801d0c 6;; Author: Richard Mlynarik <mly@ai.mit.edu>
54138c9d 7;; Maintainer: FSF
3465cfd7 8;; Keywords: convenience
3a801d0c 9
2076c87c
JB
10;; This file is part of GNU Emacs.
11
eb3fa2cf 12;; GNU Emacs is free software: you can redistribute it and/or modify
2076c87c 13;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
2076c87c
JB
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
eb3fa2cf 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
2076c87c 24
e5167999
ER
25;;; Commentary:
26
e41b2db1
ER
27;; Who says one can't have typeout windows in GNU Emacs? The entry
28;; point, `electric-buffer-list' works like ^r select buffer from the
29;; ITS Emacs lunar or tmacs libraries.
e5167999
ER
30
31;;; Code:
2076c87c
JB
32
33(require 'electric)
34
35;; this depends on the format of list-buffers (from src/buffer.c) and
36;; on stuff in lisp/buff-menu.el
37
bb0bd45a
SM
38(defvar electric-buffer-menu-mode-map
39 (let ((map (make-keymap)))
40 (fillarray (car (cdr map)) 'Electric-buffer-menu-undefined)
41 (define-key map "\e" nil)
42 (define-key map "\C-z" 'suspend-frame)
43 (define-key map "v" 'Electric-buffer-menu-mode-view-buffer)
44 (define-key map (char-to-string help-char) 'Helper-help)
45 (define-key map "?" 'Helper-describe-bindings)
46 (define-key map "\C-c" nil)
47 (define-key map "\C-c\C-c" 'Electric-buffer-menu-quit)
48 (define-key map "\C-]" 'Electric-buffer-menu-quit)
49 (define-key map "q" 'Electric-buffer-menu-quit)
50 (define-key map " " 'Electric-buffer-menu-select)
51 (define-key map "\C-m" 'Electric-buffer-menu-select)
52 (define-key map "\C-l" 'recenter)
53 (define-key map "s" 'Buffer-menu-save)
54 (define-key map "d" 'Buffer-menu-delete)
55 (define-key map "k" 'Buffer-menu-delete)
56 (define-key map "\C-d" 'Buffer-menu-delete-backwards)
57 ;; (define-key map "\C-k" 'Buffer-menu-delete)
58 (define-key map "\177" 'Buffer-menu-backup-unmark)
59 (define-key map "~" 'Buffer-menu-not-modified)
60 (define-key map "u" 'Buffer-menu-unmark)
61 (let ((i ?0))
62 (while (<= i ?9)
63 (define-key map (char-to-string i) 'digit-argument)
64 (define-key map (concat "\e" (char-to-string i)) 'digit-argument)
65 (setq i (1+ i))))
66 (define-key map "-" 'negative-argument)
67 (define-key map "\e-" 'negative-argument)
68 (define-key map "m" 'Buffer-menu-mark)
69 (define-key map "\C-u" 'universal-argument)
70 (define-key map "\C-p" 'previous-line)
71 (define-key map "\C-n" 'next-line)
72 (define-key map "p" 'previous-line)
73 (define-key map "n" 'next-line)
74 (define-key map "\C-v" 'scroll-up)
75 (define-key map "\ev" 'scroll-down)
76 (define-key map ">" 'scroll-right)
77 (define-key map "<" 'scroll-left)
78 (define-key map "\e\C-v" 'scroll-other-window)
79 (define-key map "\e>" 'end-of-buffer)
80 (define-key map "\e<" 'beginning-of-buffer)
81 (define-key map "\e\e" nil)
82 (define-key map "\e\e\e" 'Electric-buffer-menu-quit)
83 ;; This binding prevents the "escape => ESC" function-key-map mapping from
84 ;; kicking in!
85 ;; (define-key map [escape escape escape] 'Electric-buffer-menu-quit)
86 (define-key map [mouse-2] 'Electric-buffer-menu-mouse-select)
87 map))
2076c87c 88
5f20b653
TTN
89(defvar electric-buffer-menu-mode-hook nil
90 "Normal hook run by `electric-buffer-list'.")
91
2076c87c
JB
92;;;###autoload
93(defun electric-buffer-list (arg)
5f20b653 94 "Pop up a buffer describing the set of Emacs buffers.
2076c87c
JB
95Vaguely like ITS lunar select buffer; combining typeoutoid buffer
96listing with menuoid buffer selection.
97
98If the very next character typed is a space then the buffer list
99window disappears. Otherwise, one may move around in the buffer list
100window, marking buffers to be selected, saved or deleted.
101
102To exit and select a new buffer, type a space when the cursor is on
103the appropriate line of the buffer-list window. Other commands are
5f20b653 104much like those of `Buffer-menu-mode'.
2076c87c 105
5f20b653 106Run hooks in `electric-buffer-menu-mode-hook' on entry.
2076c87c 107
71296446 108\\{electric-buffer-menu-mode-map}"
2076c87c
JB
109 (interactive "P")
110 (let (select buffer)
111 (save-window-excursion
cf6ce50b
SM
112 (setq buffer (list-buffers-noselect arg))
113 (Electric-pop-up-window buffer)
2076c87c
JB
114 (unwind-protect
115 (progn
116 (set-buffer buffer)
117 (Electric-buffer-menu-mode)
ede8f2fe 118 (electric-buffer-update-highlight)
2076c87c
JB
119 (setq select
120 (catch 'electric-buffer-menu-select
fc7323e6 121 (message "<<< Press Return to bury the buffer list >>>")
d42cc509 122 (if (eq (setq unread-command-events (list (read-event)))
a8158099 123 ?\s)
dbc4e1c1 124 (progn (setq unread-command-events nil)
2076c87c 125 (throw 'electric-buffer-menu-select nil)))
69adebeb
KH
126 (let ((start-point (point))
127 (first (progn (goto-char (point-min))
a82c1267
JPW
128 (unless Buffer-menu-use-header-line
129 (forward-line 2))
2076c87c
JB
130 (point)))
131 (last (progn (goto-char (point-max))
132 (forward-line -1)
133 (point)))
134 (goal-column 0))
69adebeb
KH
135 ;; Use start-point if it is meaningful.
136 (goto-char (if (or (< start-point first)
137 (> start-point last))
138 first
139 start-point))
2076c87c
JB
140 (Electric-command-loop 'electric-buffer-menu-select
141 nil
142 t
143 'electric-buffer-menu-looper
144 (cons first last))))))
145 (set-buffer buffer)
146 (Buffer-menu-mode)
147 (bury-buffer buffer)
148 (message "")))
149 (if select
150 (progn (set-buffer buffer)
151 (let ((opoint (point-marker)))
152 (Buffer-menu-execute)
153 (goto-char (point-min))
154 (if (prog1 (search-forward "\n>" nil t)
155 (goto-char opoint) (set-marker opoint nil))
156 (Buffer-menu-select)
157 (switch-to-buffer (Buffer-menu-buffer t))))))))
158
159(defun electric-buffer-menu-looper (state condition)
160 (cond ((and condition
161 (not (memq (car condition) '(buffer-read-only
162 end-of-buffer
163 beginning-of-buffer))))
164 (signal (car condition) (cdr condition)))
165 ((< (point) (car state))
166 (goto-char (point-min))
a82c1267
JPW
167 (unless Buffer-menu-use-header-line
168 (forward-line 2)))
2076c87c
JB
169 ((> (point) (cdr state))
170 (goto-char (point-max))
171 (forward-line -1)
172 (if (pos-visible-in-window-p (point-max))
ede8f2fe
RS
173 (recenter -1))))
174 (electric-buffer-update-highlight))
2076c87c 175
784f8619
RS
176(defvar Helper-return-blurb)
177
2076c87c
JB
178(put 'Electric-buffer-menu-mode 'mode-class 'special)
179(defun Electric-buffer-menu-mode ()
180 "Major mode for editing a list of buffers.
181Each line describes one of the buffers in Emacs.
182Letters do not insert themselves; instead, they are commands.
183\\<electric-buffer-menu-mode-map>
184\\[keyboard-quit] or \\[Electric-buffer-menu-quit] -- exit buffer menu, returning to previous window and buffer
185 configuration. If the very first character typed is a space, it
186 also has this effect.
187\\[Electric-buffer-menu-select] -- select buffer of line point is on.
188 Also show buffers marked with m in other windows,
189 deletes buffers marked with \"D\", and saves those marked with \"S\".
190\\[Buffer-menu-mark] -- mark buffer to be displayed.
191\\[Buffer-menu-not-modified] -- clear modified-flag on that buffer.
192\\[Buffer-menu-save] -- mark that buffer to be saved.
193\\[Buffer-menu-delete] or \\[Buffer-menu-delete-backwards] -- mark that buffer to be deleted.
194\\[Buffer-menu-unmark] -- remove all kinds of marks from current line.
195\\[Electric-buffer-menu-mode-view-buffer] -- view buffer, returning when done.
196\\[Buffer-menu-backup-unmark] -- back up a line and remove marks.
197
198\\{electric-buffer-menu-mode-map}
199
5f20b653
TTN
200Entry to this mode via command `electric-buffer-list' calls the value of
201`electric-buffer-menu-mode-hook'."
e4edc5cd
TTN
202 (let ((saved header-line-format))
203 (kill-all-local-variables)
204 (setq header-line-format saved))
2076c87c
JB
205 (use-local-map electric-buffer-menu-mode-map)
206 (setq mode-name "Electric Buffer Menu")
207 (setq mode-line-buffer-identification "Electric Buffer List")
208 (make-local-variable 'Helper-return-blurb)
209 (setq Helper-return-blurb "return to buffer editing")
210 (setq truncate-lines t)
211 (setq buffer-read-only t)
212 (setq major-mode 'Electric-buffer-menu-mode)
213 (goto-char (point-min))
214 (if (search-forward "\n." nil t) (forward-char -1))
a3d9e1fa 215 (run-mode-hooks 'electric-buffer-menu-mode-hook))
2076c87c
JB
216
217;; generally the same as Buffer-menu-mode-map
218;; (except we don't indirect to global-map)
219(put 'Electric-buffer-menu-undefined 'suppress-keymap t)
bb0bd45a 220
71296446 221
2076c87c
JB
222(defun Electric-buffer-menu-exit ()
223 (interactive)
d42cc509 224 (setq unread-command-events (listify-key-sequence (this-command-keys)))
2076c87c
JB
225 ;; for robustness
226 (condition-case ()
227 (throw 'electric-buffer-menu-select nil)
228 (error (Buffer-menu-mode)
229 (other-buffer))))
230
231(defun Electric-buffer-menu-select ()
232 "Leave Electric Buffer Menu, selecting buffers and executing changes.
5f20b653
TTN
233Save buffers marked \"S\". Delete buffers marked \"K\".
234Select buffer at point and display buffers marked \">\" in other windows."
2076c87c
JB
235 (interactive)
236 (throw 'electric-buffer-menu-select (point)))
237
3c59c255
KH
238(defun Electric-buffer-menu-mouse-select (event)
239 (interactive "e")
240 (select-window (posn-window (event-end event)))
241 (set-buffer (window-buffer (selected-window)))
242 (goto-char (posn-point (event-end event)))
243 (throw 'electric-buffer-menu-select (point)))
244
2076c87c
JB
245(defun Electric-buffer-menu-quit ()
246 "Leave Electric Buffer Menu, restoring previous window configuration.
5f20b653 247Skip execution of select, save, and delete commands."
2076c87c
JB
248 (interactive)
249 (throw 'electric-buffer-menu-select nil))
250
251(defun Electric-buffer-menu-undefined ()
252 (interactive)
253 (ding)
2bb7c30c
KH
254 (message "%s"
255 (if (and (eq (key-binding "\C-c\C-c") 'Electric-buffer-menu-quit)
2076c87c 256 (eq (key-binding " ") 'Electric-buffer-menu-select)
e17d2fd1 257 (eq (key-binding (char-to-string help-char)) 'Helper-help)
2076c87c 258 (eq (key-binding "?") 'Helper-describe-bindings))
573cd924 259 (substitute-command-keys "Type C-c C-c to exit, Space to select, \\[Helper-help] for help, ? for commands")
2076c87c
JB
260 (substitute-command-keys "\
261Type \\[Electric-buffer-menu-quit] to exit, \
262\\[Electric-buffer-menu-select] to select, \
263\\[Helper-help] for help, \\[Helper-describe-bindings] for commands.")))
264 (sit-for 4))
265
266(defun Electric-buffer-menu-mode-view-buffer ()
267 "View buffer on current line in Electric Buffer Menu.
5f20b653 268Return to Electric Buffer Menu when done."
2076c87c
JB
269 (interactive)
270 (let ((bufnam (Buffer-menu-buffer nil)))
271 (if bufnam
272 (view-buffer bufnam)
273 (ding)
274 (message "Buffer %s does not exist!" bufnam)
275 (sit-for 4))))
276
ede8f2fe
RS
277(defvar electric-buffer-overlay nil)
278(defun electric-buffer-update-highlight ()
080314d3
JPW
279 (when (eq major-mode 'Electric-buffer-menu-mode)
280 ;; Make sure we have an overlay to use.
281 (or electric-buffer-overlay
282 (progn
283 (make-local-variable 'electric-buffer-overlay)
284 (setq electric-buffer-overlay (make-overlay (point) (point)))))
285 (move-overlay electric-buffer-overlay
286 (save-excursion (beginning-of-line) (point))
287 (save-excursion (end-of-line) (point)))
288 (overlay-put electric-buffer-overlay 'face 'highlight)))
ede8f2fe 289
896546cd
RS
290(provide 'ebuff-menu)
291
cbee283d 292;; arch-tag: 1d4509b3-eece-4d4f-95ea-77c83eaf0275
c0274f38 293;;; ebuff-menu.el ends here