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