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