home *** CD-ROM | disk | FTP | other *** search
- ;;;; buffer-menu.jl -- interactive buffer manipulation
- ;;; Copyright (C) 1994 John Harper <jsh@ukc.ac.uk>
-
- ;;; This file is part of Jade.
-
- ;;; Jade is free software; you can redistribute it and/or modify it
- ;;; under the terms of the GNU General Public License as published by
- ;;; the Free Software Foundation; either version 2, or (at your option)
- ;;; any later version.
-
- ;;; Jade is distributed in the hope that it will be useful, but
- ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
- ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;;; GNU General Public License for more details.
-
- ;;; You should have received a copy of the GNU General Public License
- ;;; along with Jade; see the file COPYING. If not, write to
- ;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- (provide 'buffer-menu)
-
-
- (defvar bm-buffer (make-buffer "*Buffer Menu*"))
- (set-buffer-special bm-buffer t)
- (set-buffer-read-only bm-buffer t)
- (with-buffer bm-buffer
- (setq buffer-record-undo nil))
-
- (defvar bm-keymap (make-keylist))
- (bind-keys bm-keymap
- "d" 'bm-toggle-deletion
- "s" 'bm-toggle-save
- "Ctrl-s" 'bm-toggle-save
- "u" 'bm-unmark-line
- "x" 'bm-execute
- "1" 'bm-select-buffer
- "RET" 'bm-select-buffer
- "f" 'bm-select-buffer
- "q" 'bury-buffer
- "~" 'bm-toggle-modified
- "-" 'bm-toggle-read-only
- "%" 'bm-toggle-read-only
- "o" 'bm-other-window-select-buffer
- "Ctrl-f" 'bm-next
- "TAB" 'bm-next
- "Ctrl-b" 'bm-prev
- "Shift-TAB" 'bm-prev
- "Ctrl-l" 'bm-update
- "LMB-Click1" '(goto-char (mouse-pos))
- "LMB-Click2" 'bm-select-buffer)
-
- (defvar bm-pending-deletions '()
- "List of buffers marked for deletion.")
-
- (defvar bm-pending-saves '()
- "List of buffers marked to be saved.")
-
-
- (defun buffer-menu-mode ()
- "Buffer Menu Mode:\n
- This major mode is used in the `*Buffer Menu*' buffer; it provides
- interactive commands for manipulating the list of buffers loaded into
- the editor.\n
- Commands available are,\n
- `d' Mark buffer for deletion.
- `s', `Ctrl-s' Mark buffer to be saved.
- `x' Execute marked saves and deletions.
- `u' Unmark the current line.
- `1' Select the current line's buffer in this window.
- `o' Display the current line's buffer in a different
- window.
- `~' Toggle the buffer's `modified' flag.
- `%', `-' Toggle the buffer's read-only status.
- `Ctrl-f', `TAB' Move forwards through the menu.
- `Ctrl-b', `Shift-TAB' Cycle backwards through the menu.
- `Ctrl-l' Redraw the menu, incorporating any changes to the
- buffer-list.
- `q' Quit the buffer menu."
- (when major-mode-kill
- (funcall major-mode-kill))
- (setq major-mode 'buffer-menu-mode
- major-mode-kill 'buffer-menu-kill
- mode-name "Buffer Menu"
- keymap-path (cons 'bm-keymap keymap-path))
- (add-hook 'unbound-key-hook 'bm-unbound-function)
- (eval-hook 'buffer-menu-mode-hook))
-
- (defun buffer-menu-kill ()
- (setq major-mode nil
- major-mode-kill nil
- mode-name nil
- keymap-path (delq 'bm-keymap keymap-path))
- (remove-hook 'unbound-key-hook 'bm-unbound-function))
-
- ;;;###autoload
- (defun buffer-menu ()
- (interactive)
- (goto-buffer bm-buffer)
- (unless (eq major-mode 'buffer-menu-mode)
- (buffer-menu-mode))
- (bm-list-buffers)
- (goto-char (pos 0 2)))
-
-
- (defun bm-unbound-function ()
- (error "No command bound to this key!"))
-
- (defun bm-list-buffers ()
- (let
- ((inhibit-read-only t))
- (clear-buffer)
- (insert " MR\tName\t\tMode\t\tFile\n --\t----\t\t----\t\t----\n")
- (let
- ((list buffer-list)
- buf)
- (while (setq buf (car list))
- (format bm-buffer "%c%c %c%c\t%s\t"
- (if (memq buf bm-pending-deletions) ?D ?\ )
- (if (memq buf bm-pending-saves) ?S ?\ )
- (if (buffer-modified-p buf) ?+ ?\ )
- (if (buffer-read-only-p buf) ?- ?\ )
- (buffer-name buf))
- (indent-to 24)
- (format bm-buffer "%s%s\t"
- (or (with-buffer buf mode-name) "Generic")
- (or (with-buffer buf minor-mode-names) ""))
- (indent-to 40)
- (format bm-buffer "%s\n" (buffer-file-name buf))
- (setq list (cdr list))))))
-
- (defun bm-get-buffer ()
- (unless (> (pos-line (cursor-pos)) 1)
- ;; on the heading
- (error "Can't work on the heading!"))
- (if (regexp-match-line "^[^\t]+[\t]+([^\t]+)\t")
- (get-buffer (copy-area (match-start 1) (match-end 1)))
- (error "Can't find buffer name")))
-
- (defun bm-find-buffer-line (buf)
- (find-next-regexp (concat "^[^\t]+[\t]+"
- (regexp-quote (buffer-name buf))
- "\t")
- (pos 0 2)))
-
- (defun bm-toggle-deletion ()
- (interactive)
- (let
- ((buf (bm-get-buffer))
- (inhibit-read-only t))
- (if (memq buf bm-pending-deletions)
- (progn
- (setq bm-pending-deletions (delq buf bm-pending-deletions))
- (set-char ?\ (pos 0 nil)))
- (setq bm-pending-deletions (cons buf bm-pending-deletions))
- (set-char ?D (pos 0 nil)))
- (bm-next)))
-
- (defun bm-toggle-save ()
- (interactive)
- (let
- ((buf (bm-get-buffer))
- (inhibit-read-only t))
- (if (memq buf bm-pending-saves)
- (progn
- (setq bm-pending-saves (delq buf bm-pending-saves))
- (set-char ?\ (pos 1 nil)))
- (setq bm-pending-saves (cons buf bm-pending-saves))
- (set-char ?S (pos 1 nil)))
- (bm-next)))
-
- (defun bm-unmark-line ()
- (interactive)
- (let
- ((buf (bm-get-buffer))
- (inhibit-read-only t))
- (setq bm-pending-saves (delq buf bm-pending-saves)
- bm-pending-deletions (delq buf bm-pending-deletions))
- (set-char ?\ (pos 0 nil))
- (set-char ?\ (pos 1 nil))
- (bm-next)))
-
- (defun bm-execute ()
- (interactive)
- (let
- ((list bm-pending-saves)
- (inhibit-read-only t)
- buf)
- (setq bm-pending-saves nil)
- (while (setq buf (car list))
- (when (save-file buf)
- (let
- ((pos (bm-find-buffer-line buf)))
- (when pos
- (set-char ?\ (pos 1 (pos-line pos)))
- (unless (buffer-modified-p buf)
- (set-char ?\ (pos 3 (pos-line pos)))))))
- (setq list (cdr list)))
- (setq list bm-pending-deletions
- bm-pending-deletions nil)
- (while (setq buf (car list))
- (let
- ((pos (bm-find-buffer-line buf)))
- (when (kill-buffer buf)
- (when pos
- (delete-area pos (next-line 1 (copy-pos pos))))))
- (setq list (cdr list)))))
-
- (defun bm-select-buffer ()
- (interactive)
- (let
- ((new-buf (bm-get-buffer)))
- (bury-buffer bm-buffer)
- (goto-buffer new-buf)))
-
- (defun bm-other-window-select-buffer ()
- (interactive)
- (let
- ((buf (bm-get-buffer)))
- (in-other-window '(goto-buffer buf))))
-
- (defun bm-toggle-modified ()
- (interactive)
- (let
- ((buf (bm-get-buffer))
- (inhibit-read-only t))
- (if (buffer-modified-p buf)
- (progn
- (set-buffer-modified buf nil)
- (set-char ?\ (pos 3 nil)))
- (set-buffer-modified buf t)
- (when (buffer-modified-p buf)
- (set-char ?+ (pos 3 nil)))))
- (bm-next))
-
- (defun bm-toggle-read-only ()
- (interactive)
- (let
- ((buf (bm-get-buffer))
- (inhibit-read-only t))
- (if (buffer-read-only-p buf)
- (progn
- (set-buffer-read-only buf nil)
- (set-char ?\ (pos 4 nil)))
- (set-buffer-read-only buf t)
- (set-char ?- (pos 4 nil))))
- (bm-next))
-
- (defun bm-update ()
- (interactive)
- (let
- ((old-buf (bm-get-buffer)))
- (bm-list-buffers)
- (goto-char (or (bm-find-buffer-line old-buf)
- (pos 0 2)))))
-
- (defun bm-next ()
- (interactive)
- (if (>= (pos-line (cursor-pos)) (- (buffer-length) 2))
- ;; last line
- (goto-glyph (pos nil 2))
- (goto-next-line)))
-
- (defun bm-prev ()
- (interactive)
- (if (<= (pos-line (cursor-pos)) 2)
- ;; first line
- (goto-glyph (pos nil (- (buffer-length) 2)))
- (goto-prev-line)))
-