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