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