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