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