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
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
38(defvar electric-buffer-menu-mode-map nil)
39
5f20b653
TTN
40(defvar electric-buffer-menu-mode-hook nil
41 "Normal hook run by `electric-buffer-list'.")
42
2076c87c
JB
43;;;###autoload
44(defun electric-buffer-list (arg)
5f20b653 45 "Pop up a buffer describing the set of Emacs buffers.
2076c87c
JB
46Vaguely like ITS lunar select buffer; combining typeoutoid buffer
47listing with menuoid buffer selection.
48
49If the very next character typed is a space then the buffer list
50window disappears. Otherwise, one may move around in the buffer list
51window, marking buffers to be selected, saved or deleted.
52
53To exit and select a new buffer, type a space when the cursor is on
54the appropriate line of the buffer-list window. Other commands are
5f20b653 55much like those of `Buffer-menu-mode'.
2076c87c 56
5f20b653 57Run hooks in `electric-buffer-menu-mode-hook' on entry.
2076c87c 58
71296446 59\\{electric-buffer-menu-mode-map}"
2076c87c
JB
60 (interactive "P")
61 (let (select buffer)
62 (save-window-excursion
cf6ce50b
SM
63 (setq buffer (list-buffers-noselect arg))
64 (Electric-pop-up-window buffer)
2076c87c
JB
65 (unwind-protect
66 (progn
67 (set-buffer buffer)
68 (Electric-buffer-menu-mode)
ede8f2fe 69 (electric-buffer-update-highlight)
2076c87c
JB
70 (setq select
71 (catch 'electric-buffer-menu-select
fc7323e6 72 (message "<<< Press Return to bury the buffer list >>>")
d42cc509 73 (if (eq (setq unread-command-events (list (read-event)))
a8158099 74 ?\s)
dbc4e1c1 75 (progn (setq unread-command-events nil)
2076c87c 76 (throw 'electric-buffer-menu-select nil)))
69adebeb
KH
77 (let ((start-point (point))
78 (first (progn (goto-char (point-min))
a82c1267
JPW
79 (unless Buffer-menu-use-header-line
80 (forward-line 2))
2076c87c
JB
81 (point)))
82 (last (progn (goto-char (point-max))
83 (forward-line -1)
84 (point)))
85 (goal-column 0))
69adebeb
KH
86 ;; Use start-point if it is meaningful.
87 (goto-char (if (or (< start-point first)
88 (> start-point last))
89 first
90 start-point))
2076c87c
JB
91 (Electric-command-loop 'electric-buffer-menu-select
92 nil
93 t
94 'electric-buffer-menu-looper
95 (cons first last))))))
96 (set-buffer buffer)
97 (Buffer-menu-mode)
98 (bury-buffer buffer)
99 (message "")))
100 (if select
101 (progn (set-buffer buffer)
102 (let ((opoint (point-marker)))
103 (Buffer-menu-execute)
104 (goto-char (point-min))
105 (if (prog1 (search-forward "\n>" nil t)
106 (goto-char opoint) (set-marker opoint nil))
107 (Buffer-menu-select)
108 (switch-to-buffer (Buffer-menu-buffer t))))))))
109
110(defun electric-buffer-menu-looper (state condition)
111 (cond ((and condition
112 (not (memq (car condition) '(buffer-read-only
113 end-of-buffer
114 beginning-of-buffer))))
115 (signal (car condition) (cdr condition)))
116 ((< (point) (car state))
117 (goto-char (point-min))
a82c1267
JPW
118 (unless Buffer-menu-use-header-line
119 (forward-line 2)))
2076c87c
JB
120 ((> (point) (cdr state))
121 (goto-char (point-max))
122 (forward-line -1)
123 (if (pos-visible-in-window-p (point-max))
ede8f2fe
RS
124 (recenter -1))))
125 (electric-buffer-update-highlight))
2076c87c 126
784f8619
RS
127(defvar Helper-return-blurb)
128
2076c87c
JB
129(put 'Electric-buffer-menu-mode 'mode-class 'special)
130(defun Electric-buffer-menu-mode ()
131 "Major mode for editing a list of buffers.
132Each line describes one of the buffers in Emacs.
133Letters do not insert themselves; instead, they are commands.
134\\<electric-buffer-menu-mode-map>
135\\[keyboard-quit] or \\[Electric-buffer-menu-quit] -- exit buffer menu, returning to previous window and buffer
136 configuration. If the very first character typed is a space, it
137 also has this effect.
138\\[Electric-buffer-menu-select] -- select buffer of line point is on.
139 Also show buffers marked with m in other windows,
140 deletes buffers marked with \"D\", and saves those marked with \"S\".
141\\[Buffer-menu-mark] -- mark buffer to be displayed.
142\\[Buffer-menu-not-modified] -- clear modified-flag on that buffer.
143\\[Buffer-menu-save] -- mark that buffer to be saved.
144\\[Buffer-menu-delete] or \\[Buffer-menu-delete-backwards] -- mark that buffer to be deleted.
145\\[Buffer-menu-unmark] -- remove all kinds of marks from current line.
146\\[Electric-buffer-menu-mode-view-buffer] -- view buffer, returning when done.
147\\[Buffer-menu-backup-unmark] -- back up a line and remove marks.
148
149\\{electric-buffer-menu-mode-map}
150
5f20b653
TTN
151Entry to this mode via command `electric-buffer-list' calls the value of
152`electric-buffer-menu-mode-hook'."
e4edc5cd
TTN
153 (let ((saved header-line-format))
154 (kill-all-local-variables)
155 (setq header-line-format saved))
2076c87c
JB
156 (use-local-map electric-buffer-menu-mode-map)
157 (setq mode-name "Electric Buffer Menu")
158 (setq mode-line-buffer-identification "Electric Buffer List")
159 (make-local-variable 'Helper-return-blurb)
160 (setq Helper-return-blurb "return to buffer editing")
161 (setq truncate-lines t)
162 (setq buffer-read-only t)
163 (setq major-mode 'Electric-buffer-menu-mode)
164 (goto-char (point-min))
165 (if (search-forward "\n." nil t) (forward-char -1))
a3d9e1fa 166 (run-mode-hooks 'electric-buffer-menu-mode-hook))
2076c87c
JB
167
168;; generally the same as Buffer-menu-mode-map
169;; (except we don't indirect to global-map)
170(put 'Electric-buffer-menu-undefined 'suppress-keymap t)
171(if electric-buffer-menu-mode-map
172 nil
9be969d7 173 (let ((map (make-keymap)))
f536481d 174 (fillarray (car (cdr map)) 'Electric-buffer-menu-undefined)
9be969d7 175 (define-key map "\e" nil)
f35ca2fe 176 (define-key map "\C-z" 'suspend-frame)
2076c87c 177 (define-key map "v" 'Electric-buffer-menu-mode-view-buffer)
8892e83c 178 (define-key map (char-to-string help-char) 'Helper-help)
2076c87c
JB
179 (define-key map "?" 'Helper-describe-bindings)
180 (define-key map "\C-c" nil)
181 (define-key map "\C-c\C-c" 'Electric-buffer-menu-quit)
182 (define-key map "\C-]" 'Electric-buffer-menu-quit)
183 (define-key map "q" 'Electric-buffer-menu-quit)
184 (define-key map " " 'Electric-buffer-menu-select)
fc7323e6 185 (define-key map "\C-m" 'Electric-buffer-menu-select)
2076c87c
JB
186 (define-key map "\C-l" 'recenter)
187 (define-key map "s" 'Buffer-menu-save)
188 (define-key map "d" 'Buffer-menu-delete)
189 (define-key map "k" 'Buffer-menu-delete)
190 (define-key map "\C-d" 'Buffer-menu-delete-backwards)
191 ;(define-key map "\C-k" 'Buffer-menu-delete)
192 (define-key map "\177" 'Buffer-menu-backup-unmark)
193 (define-key map "~" 'Buffer-menu-not-modified)
194 (define-key map "u" 'Buffer-menu-unmark)
195 (let ((i ?0))
196 (while (<= i ?9)
197 (define-key map (char-to-string i) 'digit-argument)
198 (define-key map (concat "\e" (char-to-string i)) 'digit-argument)
199 (setq i (1+ i))))
200 (define-key map "-" 'negative-argument)
201 (define-key map "\e-" 'negative-argument)
202 (define-key map "m" 'Buffer-menu-mark)
203 (define-key map "\C-u" 'universal-argument)
204 (define-key map "\C-p" 'previous-line)
205 (define-key map "\C-n" 'next-line)
206 (define-key map "p" 'previous-line)
207 (define-key map "n" 'next-line)
208 (define-key map "\C-v" 'scroll-up)
209 (define-key map "\ev" 'scroll-down)
210 (define-key map ">" 'scroll-right)
211 (define-key map "<" 'scroll-left)
212 (define-key map "\e\C-v" 'scroll-other-window)
213 (define-key map "\e>" 'end-of-buffer)
214 (define-key map "\e<" 'beginning-of-buffer)
43145fb4 215 (define-key map "\e\e" nil)
ef946998
RS
216 (define-key map "\e\e\e" 'Electric-buffer-menu-quit)
217 (define-key map [escape escape escape] 'Electric-buffer-menu-quit)
3c59c255 218 (define-key map [mouse-2] 'Electric-buffer-menu-mouse-select)
2076c87c 219 (setq electric-buffer-menu-mode-map map)))
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
285 (save-excursion (beginning-of-line) (point))
286 (save-excursion (end-of-line) (point)))
287 (overlay-put electric-buffer-overlay 'face 'highlight)))
ede8f2fe 288
896546cd
RS
289(provide 'ebuff-menu)
290
cbee283d 291;; arch-tag: 1d4509b3-eece-4d4f-95ea-77c83eaf0275
c0274f38 292;;; ebuff-menu.el ends here