entered into RCS
[bpt/emacs.git] / lisp / ebuff-menu.el
CommitLineData
c0274f38
ER
1;;; ebuff-menu.el --- electric-buffer-list mode
2
e5167999
ER
3;; Author: Richard Mlynarik <mly@ai.mit.edu>
4;; Last-Modified: 21 Dec 1991
2076c87c
JB
5
6;; Copyright (C) 1985, 1986 Free Software Foundation, Inc.
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
e5167999 12;; the Free Software Foundation; either version 2, or (at your option)
2076c87c
JB
13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs; see the file COPYING. If not, write to
22;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
e5167999
ER
24;;; Commentary:
25
26;; who says one can't have typeout windows in gnu emacs?
27;; like ^r select buffer from its emacs lunar or tmacs libraries.
28
29;;; Code:
2076c87c
JB
30
31(require 'electric)
32
33;; this depends on the format of list-buffers (from src/buffer.c) and
34;; on stuff in lisp/buff-menu.el
35
36(defvar electric-buffer-menu-mode-map nil)
37
38;;;###autoload
39(defun electric-buffer-list (arg)
40 "Pops up a buffer describing the set of Emacs buffers.
41Vaguely like ITS lunar select buffer; combining typeoutoid buffer
42listing with menuoid buffer selection.
43
44If the very next character typed is a space then the buffer list
45window disappears. Otherwise, one may move around in the buffer list
46window, marking buffers to be selected, saved or deleted.
47
48To exit and select a new buffer, type a space when the cursor is on
49the appropriate line of the buffer-list window. Other commands are
50much like those of buffer-menu-mode.
51
52Calls value of `electric-buffer-menu-mode-hook' on entry if non-nil.
53
54\\{electric-buffer-menu-mode-map}"
55 (interactive "P")
56 (let (select buffer)
57 (save-window-excursion
58 (save-window-excursion (list-buffers arg))
59 (setq buffer (window-buffer (Electric-pop-up-window "*Buffer List*")))
60 (unwind-protect
61 (progn
62 (set-buffer buffer)
63 (Electric-buffer-menu-mode)
64 (setq select
65 (catch 'electric-buffer-menu-select
66 (message "<<< Press Space to bury the buffer list >>>")
67 (if (= (setq unread-command-char (read-char)) ?\ )
68 (progn (setq unread-command-char -1)
69 (throw 'electric-buffer-menu-select nil)))
70 (let ((first (progn (goto-char (point-min))
71 (forward-line 2)
72 (point)))
73 (last (progn (goto-char (point-max))
74 (forward-line -1)
75 (point)))
76 (goal-column 0))
77 (goto-char first)
78 (Electric-command-loop 'electric-buffer-menu-select
79 nil
80 t
81 'electric-buffer-menu-looper
82 (cons first last))))))
83 (set-buffer buffer)
84 (Buffer-menu-mode)
85 (bury-buffer buffer)
86 (message "")))
87 (if select
88 (progn (set-buffer buffer)
89 (let ((opoint (point-marker)))
90 (Buffer-menu-execute)
91 (goto-char (point-min))
92 (if (prog1 (search-forward "\n>" nil t)
93 (goto-char opoint) (set-marker opoint nil))
94 (Buffer-menu-select)
95 (switch-to-buffer (Buffer-menu-buffer t))))))))
96
97(defun electric-buffer-menu-looper (state condition)
98 (cond ((and condition
99 (not (memq (car condition) '(buffer-read-only
100 end-of-buffer
101 beginning-of-buffer))))
102 (signal (car condition) (cdr condition)))
103 ((< (point) (car state))
104 (goto-char (point-min))
105 (forward-line 2))
106 ((> (point) (cdr state))
107 (goto-char (point-max))
108 (forward-line -1)
109 (if (pos-visible-in-window-p (point-max))
110 (recenter -1)))))
111
112(put 'Electric-buffer-menu-mode 'mode-class 'special)
113(defun Electric-buffer-menu-mode ()
114 "Major mode for editing a list of buffers.
115Each line describes one of the buffers in Emacs.
116Letters do not insert themselves; instead, they are commands.
117\\<electric-buffer-menu-mode-map>
118\\[keyboard-quit] or \\[Electric-buffer-menu-quit] -- exit buffer menu, returning to previous window and buffer
119 configuration. If the very first character typed is a space, it
120 also has this effect.
121\\[Electric-buffer-menu-select] -- select buffer of line point is on.
122 Also show buffers marked with m in other windows,
123 deletes buffers marked with \"D\", and saves those marked with \"S\".
124\\[Buffer-menu-mark] -- mark buffer to be displayed.
125\\[Buffer-menu-not-modified] -- clear modified-flag on that buffer.
126\\[Buffer-menu-save] -- mark that buffer to be saved.
127\\[Buffer-menu-delete] or \\[Buffer-menu-delete-backwards] -- mark that buffer to be deleted.
128\\[Buffer-menu-unmark] -- remove all kinds of marks from current line.
129\\[Electric-buffer-menu-mode-view-buffer] -- view buffer, returning when done.
130\\[Buffer-menu-backup-unmark] -- back up a line and remove marks.
131
132\\{electric-buffer-menu-mode-map}
133
134Entry to this mode via command electric-buffer-list calls the value of
135electric-buffer-menu-mode-hook if it is non-nil."
136 (kill-all-local-variables)
137 (use-local-map electric-buffer-menu-mode-map)
138 (setq mode-name "Electric Buffer Menu")
139 (setq mode-line-buffer-identification "Electric Buffer List")
140 (make-local-variable 'Helper-return-blurb)
141 (setq Helper-return-blurb "return to buffer editing")
142 (setq truncate-lines t)
143 (setq buffer-read-only t)
144 (setq major-mode 'Electric-buffer-menu-mode)
145 (goto-char (point-min))
146 (if (search-forward "\n." nil t) (forward-char -1))
147 (run-hooks 'electric-buffer-menu-mode-hook))
148
149;; generally the same as Buffer-menu-mode-map
150;; (except we don't indirect to global-map)
151(put 'Electric-buffer-menu-undefined 'suppress-keymap t)
152(if electric-buffer-menu-mode-map
153 nil
154 (let ((map (make-keymap)))
155 (fillarray map 'Electric-buffer-menu-undefined)
156 (define-key map "\e" (make-keymap))
157 (fillarray (lookup-key map "\e") 'Electric-buffer-menu-undefined)
158 (define-key map "\C-z" 'suspend-emacs)
159 (define-key map "v" 'Electric-buffer-menu-mode-view-buffer)
160 (define-key map "\C-h" 'Helper-help)
161 (define-key map "?" 'Helper-describe-bindings)
162 (define-key map "\C-c" nil)
163 (define-key map "\C-c\C-c" 'Electric-buffer-menu-quit)
164 (define-key map "\C-]" 'Electric-buffer-menu-quit)
165 (define-key map "q" 'Electric-buffer-menu-quit)
166 (define-key map " " 'Electric-buffer-menu-select)
167 (define-key map "\C-l" 'recenter)
168 (define-key map "s" 'Buffer-menu-save)
169 (define-key map "d" 'Buffer-menu-delete)
170 (define-key map "k" 'Buffer-menu-delete)
171 (define-key map "\C-d" 'Buffer-menu-delete-backwards)
172 ;(define-key map "\C-k" 'Buffer-menu-delete)
173 (define-key map "\177" 'Buffer-menu-backup-unmark)
174 (define-key map "~" 'Buffer-menu-not-modified)
175 (define-key map "u" 'Buffer-menu-unmark)
176 (let ((i ?0))
177 (while (<= i ?9)
178 (define-key map (char-to-string i) 'digit-argument)
179 (define-key map (concat "\e" (char-to-string i)) 'digit-argument)
180 (setq i (1+ i))))
181 (define-key map "-" 'negative-argument)
182 (define-key map "\e-" 'negative-argument)
183 (define-key map "m" 'Buffer-menu-mark)
184 (define-key map "\C-u" 'universal-argument)
185 (define-key map "\C-p" 'previous-line)
186 (define-key map "\C-n" 'next-line)
187 (define-key map "p" 'previous-line)
188 (define-key map "n" 'next-line)
189 (define-key map "\C-v" 'scroll-up)
190 (define-key map "\ev" 'scroll-down)
191 (define-key map ">" 'scroll-right)
192 (define-key map "<" 'scroll-left)
193 (define-key map "\e\C-v" 'scroll-other-window)
194 (define-key map "\e>" 'end-of-buffer)
195 (define-key map "\e<" 'beginning-of-buffer)
196 (setq electric-buffer-menu-mode-map map)))
197
198(defun Electric-buffer-menu-exit ()
199 (interactive)
200 (setq unread-command-char last-input-char)
201 ;; for robustness
202 (condition-case ()
203 (throw 'electric-buffer-menu-select nil)
204 (error (Buffer-menu-mode)
205 (other-buffer))))
206
207(defun Electric-buffer-menu-select ()
208 "Leave Electric Buffer Menu, selecting buffers and executing changes.
209Saves buffers marked \"S\". Deletes buffers marked \"K\".
210Selects buffer at point and displays buffers marked \">\" in other windows."
211 (interactive)
212 (throw 'electric-buffer-menu-select (point)))
213
214(defun Electric-buffer-menu-quit ()
215 "Leave Electric Buffer Menu, restoring previous window configuration.
216Does not execute select, save, or delete commands."
217 (interactive)
218 (throw 'electric-buffer-menu-select nil))
219
220(defun Electric-buffer-menu-undefined ()
221 (interactive)
222 (ding)
223 (message (if (and (eq (key-binding "\C-c\C-c") 'Electric-buffer-menu-quit)
224 (eq (key-binding " ") 'Electric-buffer-menu-select)
225 (eq (key-binding "\C-h") 'Helper-help)
226 (eq (key-binding "?") 'Helper-describe-bindings))
227 "Type C-c C-c to exit, Space to select, C-h for help, ? for commands"
228 (substitute-command-keys "\
229Type \\[Electric-buffer-menu-quit] to exit, \
230\\[Electric-buffer-menu-select] to select, \
231\\[Helper-help] for help, \\[Helper-describe-bindings] for commands.")))
232 (sit-for 4))
233
234(defun Electric-buffer-menu-mode-view-buffer ()
235 "View buffer on current line in Electric Buffer Menu.
236Returns to Electric Buffer Menu when done."
237 (interactive)
238 (let ((bufnam (Buffer-menu-buffer nil)))
239 (if bufnam
240 (view-buffer bufnam)
241 (ding)
242 (message "Buffer %s does not exist!" bufnam)
243 (sit-for 4))))
244
c0274f38 245;;; ebuff-menu.el ends here