home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!elroy.jpl.nasa.gov!ames!agate!agate.berkeley.edu!dodd
- From: dodd@mycenae.cchem.berkeley.edu (Lawrence R. Dodd)
- Newsgroups: gnu.emacs.sources
- Subject: new release of GTbuf-menu.el, v 1.25
- Date: 22 Jan 93 13:33:17
- Organization: Dept of Chemical Engineering, Polytechnic Univ, NY, USA
- Lines: 939
- Distribution: gnu
- Message-ID: <DODD.93Jan22133317@mycenae.cchem.berkeley.edu>
- NNTP-Posting-Host: mycenae.cchem.berkeley.edu
- Keywords: buffer-menu, GTbuf-menu.el, update
-
-
- here is the newest release of GTbuf-menu.el a more dired-like buffer menu.
- I am posting this for the authors Bill Benedetto and Tom Wurgler since the
- copy in the elisp-archive is out of date.
-
- it has some new features in it like using `N' and `P' to display buffers in
- the other window as you scroll through the list in the buffer-menu.
-
- [Edward J. Hartnett <ejh@khonshu.Colorado.EDU> had asked about "Subject:
- anyone got a way to cycle through buffers with a keystroke?" back in
- November. There was a lot of discussion about it back then. The above
- feature of GTBuf-menu.el addresses this his question.]
-
- for whatever it is worth, I have been using this for a couple of months now
- and I really love it.
-
- Also available via anonymous ftp to roebling.poly.edu in /pub/GTbuf-men.el.
-
- share and enjoy
- Larry
-
- ........................... cut along dotted line ...........................
- ;;;; GTbuf-men.el - more dired-like buffer menu
-
- (defconst GTbuf-men-version (substring "$Revision: 1.25 $" 11 -2)
- "$Id: GTbuf-men.el,v 1.25 1992/12/13 22:30:45 wurgler Exp wurgler $")
-
- ;; Copyright (C) 1991 by Bill Benedetto and Tom Wurgler
-
- ;; This program 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 1, or (at your option)
- ;; any later version.
- ;;
- ;; This program 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 this program; if not, write to the Free Software
- ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ;; LISPDIR ENTRY for the Elisp Archive ===============================
- ;; LCD Archive Entry:
- ;; GTbuf-men| Tom Wurgler and Bill Benedetto
- ;; |wurgler@gentire.com and benedett@gentire.com
- ;; |more dired-like buffer menu
- ;; |$Date: 1992/12/13 22:30:45 $|$Revision: 1.25 $|
-
- ;; INSTALLATION ======================================================
- ;;
- ;; Put this file into your load-path and the following in your ~/.emacs:
- ;;
- ;; (autoload 'buffer-menu-dired-extended "GTbuf-men")
- ;; (define-key ctl-x-map "\C-b" 'buffer-menu-dired-extended)
-
- ;; OVERVIEW ==========================================================
- ;
- ; extended buff-menu functions
- ;
- ; Global keybinding:
- ; \C-c\C-j - switch to buffer list
- ;
- ; Buffer-menu mode keybindings
- ; %d - mark buffers for deletion containing regexp
- ; %m - mark buffers for viewing containing regexp
- ; m - mark the next ARG buffers
- ; M-del - unflag all buffers
- ; M-< - goto the first buffer
- ; M-> - goto the last buffer
- ; M-{ - goto the next marked buffer
- ; M-} - goto the previous marked buffer
- ; F - display marked buffers
- ; L - display the buffer list based on files only, direds only, plain
- ; buffers (those not associated with a file) or all buffers
- ; R - list only buffers containing regexp
- ; S - sort the buffer list
- ; g - to revert a buffer list
- ; q - quit buffer-menu
- ; r - rename the buffer
- ; w - copy the marked or current buffer name(s) to the kill ring
- ; C-n, n - go to the next buffer line and postion on the name
- ; C-p, p - go to the previous buffer line and postion on the name
- ; N - display next buffer in another window
- ; P - display previous buffer in another window
- ; J - display this buffer in another window
- ; T - switches marked and unmarked buffers
- ; X - deletes marked buffers
- ;
- ; This package is based on and requires Sebastian Kremer's dired and gmhist
- ; code, which can be otained via anonymous ftp from:
- ;
- ; ftp.thp.Uni-Koeln.DE[134.95.64.1]:/pub/gnu/emacs/diredall.tar.Z
- ; ftp.thp.Uni-Koeln.DE[134.95.64.1]:/pub/gnu/emacs/gmhist.tar.Z
- ;
- ; Many thanks to Sebastian for all the clean code for dired and the start
- ; of this package, and his helpful comments and debugging of this code.
- ;
- ; Also, thanks to Larry Dodd for acting as a beta tester and for his many
- ; suggestions for improving the code.
- ;
- ; Bill Benedetto and Tom Wurgler, wurgler@gentire.com
- ;
-
- (require 'dired)
- (require 'gmhist)
-
- (defvar buffer-menu-restricted nil
- "Whether buffer-menu is restricted by regexp, sort, files or direds.")
-
- (defvar buffer-menu-full-screen nil
- "*If t, use the full screen when displaying marked buffers using 'F'.")
-
- (defvar buffer-menu-confirm-deletes t
- "*In buffer menu, if non-nil will ask you to confirm deletions.
- If nil, you will not be asked if you want to make deletes --
- they will just be done.")
-
- (defvar buffer-marker-char ?>
- "In buffer menu, character used to mark buffers for later commands.")
-
- (defvar buffer-delete-marker ?D
- "In buffer menu, character used to mark buffers for later deletions.")
-
- (defvar buffer-options ""
- "*Contains the last string of buffer-menu-options such as sort, regexp etc.")
-
- (defvar buffer-menu-regexp nil
- "*Contains the last regexp used in buffer-menu.")
-
- (defvar buffer-menu-list nil
- "*In buffer menu, contains a list of the marked buffers.")
-
- (defvar buffer-menu-ignore-modified-regexp "^\\*"
- "Buffers matching this regexp are marked as unmodified in the
- buffer menu.")
-
- (defvar buffer-menu-strange-buf-regexp "\
- ^... \\*Buffer List\\*\\|\
- ^... \\*Messages\\*"
-
- "These buffers must have their modified mark cleared after the listing
- has been made.")
-
- (defvar buffer-menu-ignore-modified-modes '(ange-ftp-shell-mode)
- "Buffers in this mode will show up unmodified in the buffer menu.")
-
- (defvar buffer-menu-mode-options nil
- "Whether buffer-menu lists by regexp or files only or etc.")
-
- (defconst buffer-menu-modified-mark-column 1)
-
- (defun buffer-menu-dired-extended (&optional buff-opt fromp)
- "Make a menu of buffers so you can save, delete or select them.
- With \\[universal-argument] you will be allowed to choose whether you want just
- files, just direds or plain buffers and whether or not you want the list
- sorted. Type ? after invocation to get help on commands available.
- Type \\[Buffer-menu-quit] immediately to make the buffer menu go away."
- (interactive)
- (if (or current-prefix-arg (and buffer-menu-restricted fromp))
- (let ((buffer-menu-opts "")
- (buffer-menu-sort-it nil))
- (if (not buff-opt)
- (setq buffer-menu-opts
- (read-string "Choose direds or files or plain buffers, regexp, sort (d/f/n,r,s): "))
- (setq buffer-menu-opts buff-opt))
- (setq buffer-options buffer-menu-opts)
- (if (not (string-equal buffer-menu-opts ""))
- (progn
- (setq buffer-menu-restricted t)
- (if (string-match "s" buffer-menu-opts)
- (setq buffer-menu-sort-it t))
- (if (string-match "r" buffer-menu-opts)
- (if (not buff-opt)
- (setq buffer-menu-regexp (read-with-history-in
- 'buffer-menu-regexp-history
- "Regexp: ")))
- (setq buffer-menu-regexp nil))
- (if (string-match "f" buffer-menu-opts)
- (buffer-menu t)
- (buffer-menu nil))
- (if (string-match "n" buffer-menu-opts)
- (let ((buffer-read-only nil))
- (delete-matching-lines "[0-9]+[ \t]+Dired[ \t]*")
- (Buffer-menu-goto-first-buffer)
- (while (not (eobp))
- (if (buffer-file-name (Buffer-menu-buffer nil))
- (delete-region (progn (beginning-of-line) (point))
- (progn (forward-line 1) (point)))
- (forward-line 1)))
- (Buffer-menu-goto-first-buffer)
- (delete-region (point-min) (point))
- (insert "\
- MR Buffer Size Mode\n\
- -- ------ ---- ----\n")
- (Buffer-menu-goto-first-buffer)))
- (if (string-match "d" buffer-menu-opts)
- (let ((buffer-read-only nil) buf dir)
- ;; Epoch 3.2 appends the filename for dired buffers
- (keep-lines "[0-9]+[ \t]+Dired[ \t]*") ; ugh
- (Buffer-menu-goto-first-buffer)
- (delete-region 1 (point))
- (insert "\
- MR Buffer Size Mode Directory\n\
- -- ------ ---- ---- ---------\n")
- (or (string-match "^3\\.2" emacs-version)
- ;; Epoch 3.2 appends the filename for dired buffers
- (save-excursion
- (while (not (eobp))
- (if (setq buf (Buffer-menu-buffer nil))
- (progn
- (save-excursion
- (set-buffer buf)
- (setq dir (or (and (boundp
- 'dired-directory)
- dired-directory)
- ;; 18.55 Dired does not
- ;; have this variable
- default-directory)))
- (end-of-line)
- (insert dir)))
- (forward-line))))))
- (if buffer-menu-sort-it
- (let ((buffer-read-only nil))
- (require 'sort)
- (Buffer-menu-goto-first-buffer)
- (sort-subr nil 'forward-line 'end-of-line
- 'Buffer-menu-buffer-no-arg)
- (Buffer-menu-goto-first-buffer)))
- (if buffer-menu-regexp
- (let ((buffer-read-only nil))
- (Buffer-menu-goto-first-buffer)
- (buffer-mark-files-regexp buffer-menu-regexp "_")
- (keep-lines "^_.. ")
- (buffer-unflag-all-files "_")
- (message "")
- (Buffer-menu-goto-first-buffer))))
- (buffer-menu nil)
- (setq buffer-menu-restricted nil)))
- (setq buffer-options "")
- (setq buffer-menu-restricted nil)
- (buffer-menu nil))
- (buffer-menu-list-options)
- (make-local-variable 'buffer-menu-restricted)
- (make-local-variable 'buffer-menu-mode-options)
- (setq buffer-menu-restricted nil)
- (run-hooks 'buffer-menu-hook)
- (buffer-menu-move-to-name)
- (message "q to quit, ? for help."))
-
-
-
- (defun Buffer-menu-buffer (error-if-non-existent-p)
- "Return buffer described by this line of buffer menu."
- (if (<= (buffer-menu-cur-line) 2)
- (error "Must point at a buffer."))
- (save-excursion
- (beginning-of-line)
- (if (eobp) (forward-line -1))
- (forward-char Buffer-menu-buffer-column)
- (let ((start (point))
- string)
- ;; End of buffer name marked by tab or two spaces.
- (re-search-forward "\t\\| ")
- (skip-chars-backward " \t")
- (setq string (buffer-substring start (point)))
- (or (get-buffer string)
- (if error-if-non-existent-p
- (error "No buffer named \"%s\"" string)
- nil)))))
-
- (defun Buffer-menu-buffer-no-arg ()
- "Return buffer described by this line of buffer menu.
- A version of the original except this one doesn't require an arg."
- (if (<= (buffer-menu-cur-line) 2)
- (error "Must point at a buffer."))
- (save-excursion
- (beginning-of-line)
- (if (eobp) (forward-line -1))
- (forward-char Buffer-menu-buffer-column)
- (let ((start (point))
- string)
- ;; End of buffer name marked by tab or two spaces.
- (re-search-forward "\t\\| ")
- (skip-chars-backward " \t")
- (buffer-substring start (point)))))
-
-
- ;; Make the `modified' marker in buffer menu more meaningful by
- ;; putting buffer-menu-set-some-buffers-unmodified on buffer-menu-hook.
-
- (defun dired-pending-marks-p ()
- (save-excursion
- (goto-char (point-min))
- (re-search-forward dired-re-mark nil t)))
-
- (defun dired-set-buffer-modified-p ()
- "Mark all Dired buffers as modified iff there are pending marks."
- (interactive)
- (let ((blist (buffer-list)))
- (while blist
- (save-excursion
- (set-buffer (car blist))
- (setq blist (cdr blist))
- (if (eq major-mode 'dired-mode)
- (set-buffer-modified-p (dired-pending-marks-p)))))))
-
- (defun set-some-buffers-unmodified (name-regexp major-modes)
- "Clears the modification flag of buffers whose names match NAME-REGEXP
- or whose major mode is a member of MAJOR-MODES. Either or both of the
- arguments may be nil.
- Also sets dired buffer modification flags according to dired-pending-marks-p."
- (let ((blist (buffer-list)))
- (while blist
- (save-excursion
- (set-buffer (car blist))
- (setq blist (cdr blist))
- (cond ((eq major-mode 'dired-mode)
- (set-buffer-modified-p (dired-pending-marks-p)))
- ((buffer-modified-p)
- ;; Don't do the work unless the buffer is marked modified.
- (if (or (memq major-mode major-modes)
- (and name-regexp
- (string-match name-regexp (buffer-name))))
- (set-buffer-modified-p nil))))))))
-
- (defun buffer-menu-set-some-buffers-unmodified ()
- "Useful on `buffer-menu-hook' to make the modified marker in the
- buffer menu more meaningful."
- (set-some-buffers-unmodified buffer-menu-ignore-modified-regexp
- buffer-menu-ignore-modified-modes)
- (save-excursion
- (buffer-menu-home-to-tilde)
- (let ((buffer-read-only nil))
- (goto-char (point-min))
- ;; These buffers are modified during the listing, so
- ;; set-buffer-modified-p is too late.
- (while (re-search-forward buffer-menu-strange-buf-regexp nil t)
- (move-to-column buffer-menu-modified-mark-column)
- (delete-char 1)
- (insert " ")))))
-
- ;; Move to next and previous marked buffer line.
-
- (defun buffer-menu-next-marked-buffer (arg &optional wrap opoint string)
- "Move to the next marked buffer, wrapping around the end of the buffer list."
- (interactive "p\np")
- (or opoint (setq opoint (point)));; return to where interactively started
- (or string (setq string (concat "\n" (char-to-string buffer-marker-char))))
- (if (if (> arg 0)
- (search-forward string nil t arg)
- (beginning-of-line)
- (if (search-backward string nil t (- arg))
- (search-forward string)))
- (buffer-menu-move-to-name);; or the re-search will get stuck
- (if (null wrap)
- (progn
- (goto-char opoint)
- (error "No next marked buffer!"))
- (message "(Wraparound for next marked buffer)")
- (goto-char (if (> arg 0) (point-min) (point-max)))
- (buffer-menu-next-marked-buffer arg nil opoint))))
-
- (defun buffer-menu-prev-marked-buffer (arg &optional wrap)
- "Move to the previous marked buffer, wrapping around the end of the
- buffer list."
- (interactive "p\np")
- (buffer-menu-next-marked-buffer (- arg) wrap))
-
- (defconst buffer-menu-name-column 4)
-
- (defun buffer-menu-move-to-name ()
- (move-to-column buffer-menu-name-column))
-
- (defun buffer-mark-files-regexp (regexp &optional marker-char)
- "Mark all buffers matching REGEXP for use in later commands.
- A prefix argument means to unmark them instead."
- (interactive
- (list (dired-read-regexp (concat (if current-prefix-arg "Unmark" "Mark")
- " buffers (regexp): "))
- (if current-prefix-arg ?\040)))
- (let ((dired-marker-char (or marker-char buffer-marker-char)))
- (save-excursion
- (Buffer-menu-goto-first-buffer)
- (save-restriction
- (narrow-to-region (point) (point-max))
- (dired-mark-if
- (and (not (eolp)) ; empty line
- (let ((fn (buffer-name (Buffer-menu-buffer t))))
- (and fn (string-match regexp fn))))
- "matching buffer")))))
-
- (defun buffer-flag-regexp-files (regexp)
- "In buffer-menu, flag all buffers containing the specified REGEXP for deletion.
- Use `^' and `$' to anchor matches."
- (interactive (list (dired-read-regexp "Flag for deletion (regexp): ")))
- (buffer-mark-files-regexp regexp buffer-delete-marker))
-
- (defun buffer-unflag-all-files (flag &optional arg)
- "Remove a specific or all flags from every buffer line.
- With an arg, queries for each marked buffer.
- Type \\[help-command] at that time for help."
- (interactive "sRemove flag: (default: all flags) \nP")
- (let ((count 0)
- (re (if (zerop (length flag)) dired-re-mark
- (concat "^" (regexp-quote flag)))))
- (save-excursion
- (let (buffer-read-only case-fold-search query
- (help-form "\
- Type SPC or `y' to unflag one buffer, DEL or `n' to skip to next,
- `!' to unflag all remaining buffers with no more questions."))
- (goto-char (point-min))
- (while (re-search-forward re nil t)
- (if (or (not arg)
- (dired-query 'query "Unflag buffer `%s' ? "
- (Buffer-menu-buffer t)))
- (progn (delete-char -1) (insert " ") (setq count (1+ count))))
- (forward-line 1))))
- (message "%s" (format "Flags removed: %d %s" count flag) )))
-
- ;; redefines buff-menu.el's version to make a pop-up for deletions
- ;; like Dired does
-
- (defun Buffer-menu-execute (&optional marked-buffers-instead)
- "Save and/or delete buffers marked with \\[Buffer-menu-save] or \\[Buffer-menu-delete] commands."
- (interactive)
- (if (not marked-buffers-instead)
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward "^.S" nil t)
- (let ((modp nil))
- (save-excursion
- (set-buffer (Buffer-menu-buffer t))
- (save-buffer)
- (setq modp (buffer-modified-p)))
- (let ((buffer-read-only nil))
- (delete-char -1)
- (insert (if modp ?* ? )))))))
- (save-excursion
- (goto-char (point-min))
- (let ((buffer-menu-buffer (current-buffer))
- (dired-marker-char buffer-delete-marker)
- (buffer-menu-do-deletes nil)
- (buffer-read-only nil))
- (buffer-menu-list (if marked-buffers-instead
- (char-to-string buffer-marker-char)
- (char-to-string buffer-delete-marker)))
- (if buffer-menu-confirm-deletes
- (if (dired-mark-pop-up
- " *Deletions*" 'deletions buffer-menu-list
- dired-deletion-confirmer
- (format "Delete %s " (buffer-mark-prompt nil buffer-menu-list)))
- (setq buffer-menu-do-deletes t)
- (setq buffer-menu-do-deletes nil))
- (setq buffer-menu-do-deletes t))
- (if buffer-menu-do-deletes
- (while (search-forward
- (if marked-buffers-instead
- (concat "\n" (char-to-string buffer-marker-char))
- (concat "\n" (char-to-string buffer-delete-marker))) nil t)
- (forward-char -1)
- (let ((buf (Buffer-menu-buffer nil)))
- (or (eq buf nil)
- (eq buf buffer-menu-buffer)
- (save-excursion (kill-buffer buf))))
- (if (Buffer-menu-buffer nil)
- (progn (delete-char 1)
- (insert ? ))
- (delete-region (point) (progn (forward-line 1) (point)))
- (forward-char -1)))))))
-
- (defun buffer-mark-prompt (arg files)
- ;; Return a string for use in a prompt, either the current file
- ;; name, or the marker and a count of marked files.
- (let ((count (length files)))
- (if (= count 1)
- (car files)
- ;; more than 1 file:
- (if (integerp arg)
- ;; abs(arg) = count
- ;; Perhaps this is nicer, but it also takes more screen space:
- ;;(format "[%s %d files]" (if (> arg 0) "next" "previous")
- ;; count)
- (format "[next %d buffers]" arg)
- (format "%c [%d buffers]" dired-marker-char count)))))
-
- (defun Buffer-menu-select (&optional arg)
- "Visit all marked buffers at once, and display them simultaneously.
- Visit just the buffer the cursor is on if no buffers are marked.
- With an arg, visit arg next buffers."
- (interactive "P")
- (simultaneous-find-buffer (buffer-menu-list nil arg)))
-
- (defun simultaneous-find-buffer (file-list)
- "Visit all buffers in BUFFER-LIST and display them simultaneously.
-
- The current window is split across all buffers in BUFFER-LIST, as evenly
- as possible. Remaining lines go to the bottommost window.
- If variable buffer-menu-full-screen is t, then use the whole screen.
- The number of buffers that can be displayed this way is restricted by
- the height of the current window and the variable `window-min-height'."
- (let ((size (/ (if buffer-menu-full-screen (1- (screen-height))
- (window-height)) (length file-list))))
- (or (<= window-min-height size)
- (error "Too many buffers to visit simultaneously"))
- (if buffer-menu-full-screen (delete-other-windows))
- (switch-to-buffer (car file-list))
- (setq file-list (cdr file-list))
- (while file-list
- ;; Split off vertically a window of the desired size
- ;; The upper window will have SIZE lines. We select the lower
- ;; (larger) window because we want to split that again.
- (select-window (split-window nil size))
- (switch-to-buffer (car file-list))
- (setq file-list (cdr file-list)))))
-
- (defun Buffer-menu-quit ()
- "Bury the current buffer-menu."
- (interactive)
- (bury-buffer)
- (if (not (one-window-p))
- (delete-window)))
-
- (defun Buffer-menu-goto-first-buffer ()
- (goto-line 3))
-
-
- (defun buffer-copy-buffername-as-kill (&optional arg)
- "Copy names of marked buffers into the kill ring.
- The names are separated by a space.
- With a prefix arg, use just current buffer.
- You can then feed the file name to other commands with \\[yank]."
- (interactive "P")
- (copy-string-as-kill
- (if arg
- (buffer-name (Buffer-menu-buffer t))
- (mapconcat (function identity) (buffer-menu-list) " ")))
- (message "%s" (car kill-ring)))
-
- (defun buffer-menu-list (&optional marker-char arg)
- (let ((marker (or marker-char (char-to-string buffer-marker-char)))
- (there-are-some))
- (if arg
- (progn
- (setq buffer-menu-list nil)
- (while (> arg 0)
- (setq buffer-menu-list (cons (buffer-name (Buffer-menu-buffer t))
- buffer-menu-list))
- (next-line 1)
- (setq arg (1- arg)))
- (setq buffer-menu-list (nreverse buffer-menu-list)))
- (save-excursion
- (goto-char (point-min))
- (if (search-forward (concat "\n" marker) nil t)
- (setq there-are-some t)
- (error "No buffers marked.")))
- (if there-are-some
- (save-excursion
- (setq buffer-menu-list nil)
- (goto-char (point-min))
- (while (search-forward (concat "\n" marker) nil t)
- (setq buffer-menu-list
- (cons (buffer-name (Buffer-menu-buffer t))
- buffer-menu-list)))
- (setq buffer-menu-list (nreverse buffer-menu-list)))
- (setq buffer-menu-list (cons (buffer-name (Buffer-menu-buffer t))
- nil))))))
-
- (defun Buffer-menu-revert ()
- (interactive)
- (let ((opoint (point))
- (buf (Buffer-menu-buffer-no-arg))
- (mark-alist nil)
- case-fold-search
- buffer-read-only)
- (goto-char (point-min))
- (setq mark-alist (buffer-remember-marks (point-min) (point-max)))
- (setq buffer-menu-restricted t)
- (buffer-menu-dired-extended buffer-options t)
- (buffer-mark-remembered mark-alist)
- (run-hooks 'buffer-menu-hook)
- (buffer-goto-buffer buf opoint)
- (beginning-of-line)
- (buffer-menu-move-to-name)))
-
- (defun buffer-remember-marks (beg end)
- "Return alist of buffers and their marks, from BEG to END."
- (let (fil chr alist)
- (save-excursion
- (goto-char beg)
- (while (re-search-forward dired-re-mark end t)
- (if (setq fil (buffer-name (Buffer-menu-buffer nil)))
- (setq chr (preceding-char)
- alist (cons (cons fil chr) alist)))))
- alist))
-
- (defun buffer-mark-remembered (alist)
- ;; Mark all files remembered in ALIST.
- (let (elt fil chr)
- (while alist
- (setq elt (car alist)
- alist (cdr alist)
- fil (car elt)
- chr (cdr elt))
- (if (buffer-goto-buffer fil)
- (save-excursion
- (beginning-of-line)
- (setq buffer-read-only nil)
- (delete-char 1)
- (insert chr)
- (setq buffer-read-only t))))))
-
- (defun buffer-goto-buffer (buf &optional pos)
- (interactive)
- (let ((beg (or pos (point))))
- (goto-char (point-min))
- (if (re-search-forward (concat "\n...." buf) nil t)
- t
- (goto-char beg)
- nil)))
-
- (defun buffer-menu-home-to-tilde ()
- "Function to convert the \"home\" to \"~\"."
- (let* ((home (regexp-quote (expand-file-name "~/")))
- (hleng (length home))
- (buffer-read-only nil))
- ;; Unexpand home directory:
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward home nil t)
- (if (not (= (- (current-column) hleng) 4))
- (replace-match "~/" t t))))))
-
- (defun buffer-menu-toggle-sort ()
- "Toggles between sorted and unsorted buffer-menu. Maintains all other
- buffer-menu options."
- (interactive)
- (let ((opoint (point))
- (buf (Buffer-menu-buffer-no-arg))
- (mark-alist (buffer-remember-marks (point-min) (point-max))))
- (if (string-match "s" buffer-options)
- (setq buffer-options (buffer-menu-translate buffer-options "s" ""))
- (setq buffer-options (concat buffer-options "s")))
- (setq buffer-menu-restricted t)
- (buffer-menu-dired-extended buffer-options t)
- (buffer-mark-remembered mark-alist)
- (buffer-goto-buffer buf)
- (beginning-of-line)))
-
- (defun buffer-menu-list-regexp ()
- "Lists only buffer conatining the specified regexp. Maintains all other
- buffer-menu options."
- (interactive)
- (setq buffer-menu-regexp (read-string "Regexp: "))
- (if (string-equal buffer-menu-regexp "")
- (setq buffer-options (buffer-menu-translate buffer-options "r" ""))
- (if (not (string-match "r" buffer-options))
- (setq buffer-options (concat buffer-options "r")))
- (setq buffer-menu-restricted t))
- (buffer-menu-dired-extended buffer-options t))
-
- (defun buffer-menu-toggle-direds-or-files ()
- "Cycles listing buffers by direds, files, plain buffers and all buffers."
- (interactive)
- (if (string-match "d" buffer-options)
- (progn
- (setq buffer-options (buffer-menu-translate buffer-options "f" ""))
- (setq buffer-options (buffer-menu-translate buffer-options "n" ""))
- (setq buffer-options (buffer-menu-translate buffer-options "d" "f")))
- (if (string-match "f" buffer-options)
- (progn
- (setq buffer-options (buffer-menu-translate buffer-options "d" ""))
- (setq buffer-options (buffer-menu-translate buffer-options "n" ""))
- (setq buffer-options (buffer-menu-translate buffer-options "f" "n")))
- (if (string-match "n" buffer-options)
- (progn
- (setq buffer-options (buffer-menu-translate buffer-options "d" ""))
- (setq buffer-options (buffer-menu-translate buffer-options "f" ""))
- (setq buffer-options (buffer-menu-translate buffer-options "n" "")))
- (setq buffer-options (concat buffer-options "d")))))
- (setq buffer-menu-restricted t)
- (buffer-menu-dired-extended buffer-options t))
-
- (or (equal (assq 'buffer-menu-mode-options minor-mode-alist)
- '(buffer-menu-mode-options buffer-menu-mode-options))
- ;; Test whether this has already been done in case dired is reloaded
- ;; There may be several elements with buffer-menu-mode-options as car.
- (setq minor-mode-alist
- (cons '(buffer-menu-mode-options buffer-menu-mode-options)
- ;; buffer-menu-mode-options is nil outside dired
- minor-mode-alist)))
-
- (defun buffer-menu-list-options ()
- (setq buffer-menu-mode-options
- (concat ""
- (if (string-match "r" buffer-options)
- " regexp")
- (if (string-match "s" buffer-options)
- " sorted")
- (if (string-match "d" buffer-options)
- " direds only")
- (if (string-match "f" buffer-options)
- " files only")
- (if (string-match "n" buffer-options)
- " plain buffers only")))
- ;; update mode line:
- (set-buffer-modified-p (buffer-modified-p)))
-
- (defun buffer-menu-translate (string1 string2 string3)
- "Change every occurence in STRING of FSTRING with RSTRING."
- (let ((case-fold-search nil))
- (while (string-match string2 string1)
- (if (not (string-equal string3 ""))
- (aset string1
- (match-beginning 0) (string-to-char string3))
- (setq string1 (concat
- (substring string1 0 (match-beginning 0))
- (substring string1 (match-end 0)))))))
- string1)
-
- (defun beginning-of-buffer-menu ()
- "Go to first buffer."
- (interactive)
- (Buffer-menu-goto-first-buffer))
-
- (defun end-of-buffer-menu ()
- "Go to last buffer."
- (interactive)
- (goto-char (point-max))
- (forward-line -1)
- (buffer-menu-move-to-name))
-
- (defun buffer-menu-rename ()
- "Rename the current buffer and optionally the associated file."
- (interactive)
- (let ((buffer (Buffer-menu-buffer nil))
- new-buffer)
- (setq new-buffer (read-buffer
- (concat "Rename " (buffer-name buffer) " to: ")))
- (if (get-buffer new-buffer)
- (error "Buffer %s already exists" new-buffer)
- (save-excursion
- (set-buffer buffer)
- (rename-buffer new-buffer))
- (Buffer-menu-revert)
- ;; I don't think it should do anything with filenames, this
- ;; should be done in dired.
- ;; The code below is not tested much!
- (if (and (buffer-file-name buffer)
- (y-or-n-p "Change the filename too? "))
- (let ((new-file (concat (file-name-directory
- (buffer-file-name buffer)) new-buffer)))
- (if (file-exists-p new-file)
- (error "File already exists.")
- (save-excursion
- (set-buffer buffer)
- (set-visited-file-name new-file))
- (message ""))))
- )))
-
- (defun buffer-menu-next-line (arg)
- "Move down lines then position at buffer name.
- Optional prefix ARG says how many lines to move; default is one line."
- (interactive "p")
- (if (> arg 0)
- (while (> arg 0)
- (forward-line 1)
- (if (eobp)
- (goto-line 3)
- (if (< (buffer-menu-cur-line) 3)
- (end-of-buffer-menu)))
- (setq arg (1- arg)))
- (while (< arg 0)
- (forward-line -1)
- (if (eobp)
- (goto-line 3)
- (if (< (buffer-menu-cur-line) 3)
- (end-of-buffer-menu)))
- (setq arg (1+ arg))))
- (buffer-menu-move-to-name))
-
- (defun buffer-menu-previous-line (arg)
- "Move up lines then position at buffer name.
- Optional prefix ARG says how many lines to move; default is one line."
- (interactive "p")
- (buffer-menu-next-line (- arg)))
-
- (defun buffer-jump-back ()
- "Jump back to the buffer menu (*Buffer List*) if it exists, if not
- do a buffer-menu."
- (interactive)
- (if (get-buffer "*Buffer List*")
- (switch-to-buffer "*Buffer List*")
- (buffer-menu-dired-extended)))
-
- (defun Buffer-menu-mark (arg)
- "Mark next ARG buffers. Default arg is 1."
- (interactive "p")
- (if (> arg 0)
- (while (> arg 0)
- (beginning-of-line)
- (if (looking-at " [-M]")
- (ding)
- (let ((buffer-read-only nil))
- (if (not (get-buffer (Buffer-menu-buffer-no-arg)))
- (progn
- (buffer-menu-move-to-name)
- (error (concat
- "Buffer '" (Buffer-menu-buffer-no-arg)
- "' no longer exists."))))
- (delete-char 1)
- (insert buffer-marker-char)
- (buffer-menu-next-line 1)))
- (setq arg (1- arg)))
- (while (< arg 0)
- (beginning-of-line)
- (if (looking-at " [-M]")
- (ding)
- (let ((buffer-read-only nil))
- (delete-char 1)
- (insert buffer-marker-char)
- (buffer-menu-next-line -1)))
- (setq arg (1+ arg)))))
-
- (defun Buffer-menu-unmark ()
- "Cancel all requested operations on buffer on this line. Same as original
- except this version positions point on the buffername."
- (interactive)
- (beginning-of-line)
- (if (looking-at " [-M]")
- (ding)
- (let* ((buf (Buffer-menu-buffer t))
- (mod (buffer-modified-p buf))
- (readonly (save-excursion (set-buffer buf) buffer-read-only))
- (buffer-read-only nil))
- (delete-char 3)
- (insert (if readonly (if mod " *%" " %") (if mod " * " " ")))))
- (buffer-menu-next-line 1))
-
- (defun Buffer-menu-backup-unmark ()
- "Move up and cancel all requested operations on buffer on line above.
- Same as original except this version positions point on the buffername."
- (interactive)
- (forward-line -1)
- (Buffer-menu-unmark)
- (forward-line -1)
- (buffer-menu-move-to-name))
-
- (defun Buffer-menu-delete (arg)
- "In buffer-menu, flag the current line's buffer for deletion."
- (interactive "p")
- (let ((buffer-marker-char buffer-delete-marker))
- (Buffer-menu-mark arg)))
-
- (defun Buffer-menu-display-next-buffer (arg)
- "Move down ARG lines and display the buffer in another window."
- (interactive "p")
- (buffer-menu-next-line arg)
- (Buffer-menu-display-this-buffer))
-
- (defun Buffer-menu-display-prev-buffer (arg)
- "Move up ARG lines and display the buffer in another window."
- (interactive "p")
- (Buffer-menu-display-next-buffer (- arg)))
-
- (defun Buffer-menu-display-this-buffer ()
- "Display this buffer in another window, keeping cursor in *Buffer list*."
- (interactive)
- (let ((name-buffer (Buffer-menu-buffer-no-arg)))
- (if (get-buffer name-buffer)
- (pop-to-buffer name-buffer)
- (if (y-or-n-p (concat "Buffer '" name-buffer
- "' no longer exists, create it? "))
- (pop-to-buffer name-buffer)
- (message "Reverting buffer list...")
- (sit-for 1)
- (Buffer-menu-revert))))
- (pop-to-buffer "*Buffer List*"))
-
- (defun buffer-menu-cur-line ()
- "Function to return the current line number. GT"
- (save-excursion
- (beginning-of-line)
- (setq buffer-menu-cur-line (1+ (count-lines 1 (point))))))
-
- (defun buffer-menu-do-toggle ()
- "Toggle marks.
- That is, currently marked buffers become unmarked and vice versa.
- Buffers marked with other flags (such as `D') are not affected."
- (interactive)
- (save-excursion
- (goto-line 3)
- (beginning-of-line)
- (let (buffer-read-only)
- (while (not (eobp))
- (apply 'subst-char-in-region
- (point) (1+ (point))
- (if (eq ?\040 (following-char)) ; SPC
- (list ?\040 buffer-marker-char)
- (list buffer-marker-char ?\040)))
- (forward-line 1)))))
-
- (defun buffer-do-delete ()
- "Deletes the buffers marked with the buffer-mark-char. Interactive if
- buffer-menu-confirm-deletes is t."
- (interactive)
- (Buffer-menu-execute t))
-
- (define-key global-map "\C-c\C-j" 'buffer-jump-back)
-
- (fset 'buffer-regexp-prefix (make-sparse-keymap))
- (define-key Buffer-menu-mode-map "r" 'buffer-menu-rename)
- (define-key Buffer-menu-mode-map "\e<" 'beginning-of-buffer-menu)
- (define-key Buffer-menu-mode-map "\e>" 'end-of-buffer-menu)
- (define-key Buffer-menu-mode-map "\e{" 'buffer-menu-prev-marked-buffer)
- (define-key Buffer-menu-mode-map "\e}" 'buffer-menu-next-marked-buffer)
- (define-key Buffer-menu-mode-map "%" 'buffer-regexp-prefix)
- (define-key Buffer-menu-mode-map "%d" 'buffer-flag-regexp-files)
- (define-key Buffer-menu-mode-map "%m" 'buffer-mark-files-regexp)
- (define-key Buffer-menu-mode-map "\M-\C-?" 'buffer-unflag-all-files)
- (define-key Buffer-menu-mode-map "F" 'Buffer-menu-select)
- (define-key Buffer-menu-mode-map "q" 'Buffer-menu-quit)
- (define-key Buffer-menu-mode-map "g" 'Buffer-menu-revert)
- (define-key Buffer-menu-mode-map "w" 'buffer-copy-buffername-as-kill)
- (define-key Buffer-menu-mode-map "R" 'buffer-menu-list-regexp)
- (define-key Buffer-menu-mode-map "S" 'buffer-menu-toggle-sort)
- (define-key Buffer-menu-mode-map "L" 'buffer-menu-toggle-direds-or-files)
- (define-key Buffer-menu-mode-map "n" 'buffer-menu-next-line)
- (define-key Buffer-menu-mode-map "p" 'buffer-menu-previous-line)
- (define-key Buffer-menu-mode-map " " 'buffer-menu-next-line)
- (define-key Buffer-menu-mode-map "\C-n" 'buffer-menu-next-line)
- (define-key Buffer-menu-mode-map "\C-p" 'buffer-menu-previous-line)
- (define-key Buffer-menu-mode-map "N" 'Buffer-menu-display-next-buffer)
- (define-key Buffer-menu-mode-map "P" 'Buffer-menu-display-prev-buffer)
- (define-key Buffer-menu-mode-map "J" 'Buffer-menu-display-this-buffer)
- (define-key Buffer-menu-mode-map "T" 'buffer-menu-do-toggle)
- (define-key Buffer-menu-mode-map "X" 'buffer-do-delete)
- ........................... cut along dotted line ...........................
-