home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / modes / ibuff-menu.el < prev    next >
Encoding:
Text File  |  1993-04-21  |  97.9 KB  |  2,735 lines

  1. ;; ibuff-menu.el -- Indexed buffer menu for GNU Emacs
  2.  
  3. ;; Copyright (C) 1992, 1993 Bernd Petersohn.
  4.  
  5. ;; ibuff-menu is free software; you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation; either version 1, or (at your option)
  8. ;; any later version.
  9.  
  10. ;; ibuff-menu is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the
  13. ;; GNU General Public License for more details.
  14.  
  15. ;; You should have received a copy of the GNU General Public License
  16. ;; along with GNU Emacs; see the file COPYING.    If not, write to
  17. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  20.  
  21. ;; LCD Archive Entry:
  22. ;; ibuff-menu|Bernd Petersohn|muecke@cs.tu-berlin.de|
  23. ;; Convenient menu to edit the buffer list and to switch to buffers|
  24. ;; 20-Apr-1993|2.0|~/modes/ibuff-menu.el.Z|
  25.  
  26. (defconst ibuff-menu-version
  27.   (let ((rev "$Revision: 2.0 $"))
  28.     (if (string-match "[0-9.]+" rev)
  29.     (substring rev (match-beginning 0) (match-end 0))
  30.       "?"))
  31.   "The version number of this `ibuff-menu' program.
  32. Author:        Bernd Petersohn
  33. Email address:    muecke@cs.tu-berlin.de
  34. RCS Id:        $Id: ibuff-menu.el,v 2.0 1993/04/20 22:53:26 muecke Rel $
  35. Copyright (C) 1992, 1993 by Bernd Petersohn.")
  36.  
  37. (provide 'ibuff-menu)
  38. (require 'backquote)
  39.  
  40. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  41.  
  42. ;; ibuff-menu is a new kind of buffer menu designed to be convenient to
  43. ;; handle and to make it possible for you to manage even a large number
  44. ;; of Emacs buffers without losing track of them.
  45. ;; See the documentation of `ibuff-menu-mode' for details.
  46.  
  47. ;; Installation
  48.  
  49. ;; Put the file into your load-path, byte-compile it and add an
  50. ;; autoload entry to your ".emacs" file.
  51. ;; Example:
  52.  
  53. ;;    (autoload 'ibuff-menu "ibuff-menu" "Edit the buffer list." t)
  54. ;;    (global-set-key "\C-x\C-b" 'ibuff-menu)
  55.  
  56. ;; Release note
  57.  
  58. ;; ibuff-menu version 2 is completely different from prior releases.
  59. ;; Many new commands have been added and I found it necessary to choose
  60. ;; clearer names for commands and some customization variables. The
  61. ;; following table may help you to update your customizations.
  62.  
  63. ;; Old name:                   New name:
  64.  
  65. ;; ibuff-modify-mode-line              ibuff-show-buffer-in-mode-line
  66. ;; ibuff-bury-buffer-regexp            ibuff-bury-buffers-regexp
  67. ;; ibuff-hide-buffer-regexp            ibuff-hide-buffers-regexp
  68. ;; ibuff-hide-buffers                  (obsolete)
  69. ;; ibuff-move-after-mark-kill          ibuff-mark-delete-pre-set-prefix
  70. ;; ibuff-move-after-mark-display       ibuff-mark-display-pre-set-prefix
  71. ;; ibuff-move-after-mark-save          ibuff-mark-save-pre-set-prefix
  72. ;; ibuff-move-after-mark-modified      ibuff-mark-modified-pre-set-prefix
  73. ;; ibuff-move-after-mark-read-only     ibuff-mark-read-only-pre-set-prefix
  74.  
  75. ;; ibuff-help                          ibuff-brief-help
  76. ;; ibuff-exit                          ibuff-perform-quit
  77. ;; ibuff-select-exit                   ibuff-select-buffer-perform-quit
  78. ;; ibuff-execute                       ibuff-expunge
  79. ;; ibuff-cancel                        ibuff-cancel-quit
  80. ;; ibuff-unmark-backwards              ibuff-backward-unmark
  81. ;; ibuff-kill                          ibuff-mark-delete
  82. ;; ibuff-display                       ibuff-mark-display
  83. ;; ibuff-save                          ibuff-mark-save
  84. ;; ibuff-modified                      ibuff-mark-modified
  85. ;; ibuff-read-only                     ibuff-mark-read-only
  86. ;; ibuff-view                          ibuff-view-buffer
  87. ;; ibuff-bob                           ibuff-beginning-of-menu
  88. ;; ibuff-eob                           ibuff-end-of-menu
  89. ;; ibuff-jump-command                  ibuff-goto-this-line
  90. ;; ibuff-save-modified                 ibuff-mark-modified-buffers-save
  91. ;; ibuff-mark-for-redisplay            ibuff-mark-displayed-buffers-display
  92. ;; ibuff-undo                          (not available)
  93.  
  94. ;; Some key bindings have also changed. Especially the RET key is now
  95. ;; bound to another command; the prior command is still available via
  96. ;; the `q' key.
  97.  
  98. ;;;; CUSTOMIZATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  99.  
  100. (defvar ibuff-menu-mode-hook nil
  101.   "Run after ibuff-menu-mode has been set up.
  102. Note that the menu is not yet drawn, but `ibuff-source-file-name' has
  103. already been loaded at that time.
  104. You can use this hook to make little changes to `ibuff-menu-mode'. 
  105. Example: Swap the bindings of SPC and RET:
  106.  
  107.   (setq ibuff-menu-mode-hook
  108.     (function
  109.      (lambda ()
  110.        (local-set-key \" \" 'ibuff-replace-buffer-perform-quit)
  111.        (local-set-key \"\\r\" 'ibuff-select-buffer-perform-quit))))")
  112.  
  113. (defvar ibuff-menu-hook
  114.   (function (lambda () (and (sit-for 2) (ibuff-brief-help))))
  115.   "Run exclusively by the `ibuff-menu' command.
  116. The predefined value is a function that starts `ibuff-brief-help' after 2
  117. seconds of no key input:
  118.  
  119.   (setq ibuff-menu-hook
  120.     (function
  121.      (lambda ()
  122.        (and (sit-for 2) (ibuff-brief-help)))))")
  123.  
  124. (defvar ibuff-buffer-name " *Buffer Menu*"
  125.   "The name used for the `ibuff-menu' buffer. Should start with a blank.")
  126.  
  127. (defvar ibuff-source-file-name "~/.ibuff-menu"
  128.   "If it exists, this file is loaded the first time you call `ibuff-menu'
  129. or if you supply a negative prefix argument to `ibuff-menu'.
  130. You can use it to customize variables or key bindings or to extent
  131. `ibuff-menu-mode'. Note that `ibuff-menu-mode-hook' is run after this file
  132. has been loaded. The file name may have the additional suffixes \".el\" or
  133. \".elc\". If it is a relative path name, Emacs searches your `load-path'
  134. for this file.")
  135.  
  136. (defvar ibuff-restrict-window-height t
  137.   "*Non-nil means limit the `ibuff-menu' window height.
  138. If t, limit the height of the window to the half of the screen height.
  139. An integer means limit the height to its value.
  140. Note that the window may be up to `window-min-height' - 1 lines higher
  141. than expected or necessary and uses at least `window-min-height' lines.")
  142.  
  143. (defvar ibuff-adjust-window-heights 'maybe
  144.   "*Non-nil means `ibuff-menu' should equalize window heights.
  145. This variable affects the way `ibuff-menu' uses to display buffers when you
  146. quit the menu.
  147.  
  148. If the value is t it tries to resize all windows to the same height.
  149. If the value is neither t nor nil, it tries to resize all windows to the
  150. same height only in the case that one or more new windows had to be
  151. created.
  152.  
  153. In both cases it also ensures that newly displayed buffers are
  154. shown in screen wide windows (except for a buffer that replaces another if
  155. the command `ibuff-replace-buffer-perform-quit' is used). A consequence
  156. thereof is that under certain circumstances a partial width window can
  157. disappear.
  158.  
  159. If the variable is nil `ibuff-menu' does not adjust window sizes and may
  160. rigidly split even partial width windows if necessary.
  161.  
  162. Examples:
  163.  
  164.   Previous        Variable is         Variable is      Variable is
  165.   configuration        t             not nil or t     nil
  166.  
  167.             Additionally display buffer D:
  168.   +-----------+        +-----------+    +-----------+    +-----------+
  169.   |    |     |        |      |    |    |       |     |    |        |      |
  170.   |  A    |  B  |        |  A  |  B    |    |    A  |  B     |    |     A  |  B  |
  171.   |    |     |        |-----------|    |-----------|    |        |      |
  172.   |    |     |        |        |    |         |    |        |      |
  173.   |-----------|        |      C    |    |       C     |    |-----------|
  174.   |          |        |-----------|    |-----------|    |        C      |
  175.   |    C     |        |        |    |         |    |-----------|
  176.   |          |        |      D    |    |       D     |    |        D      |
  177.   +-----------+        +-----+-----+    +-----+-----+    +-----------+
  178.  
  179.             Additionally display buffer C:
  180.   +-----+-----+        +-----------+    +-----------+    +-----------+
  181.   |    |     |        |        |    |         |    |        |      |
  182.   |    |     |        |      A    |    |       A     |    |     A  |  B  |
  183.   |    |     |        |        |    |         |    |        |      |
  184.   |  A    |  B  |        |-----------|    |-----------|    |        |-----|
  185.   |    |     |        |        |    |         |    |        |      |
  186.   |    |     |        |      C    |    |       C     |    |        |  C  |
  187.   |    |     |        |        |    |         |    |        |      |
  188.   +-----------+        +-----------+    +-----------+    +-----+-----+
  189.  
  190.             Display buffers A, B, and D:
  191.   +-----------+        +-----------+    +-----------+    +-----------+
  192.   |    |     |        |      |    |    |       |     |    |        |      |
  193.   |  A    |  B  |        |  A  |  B    |    |    A  |  B     |    |     A  |  B  |
  194.   |    |     |        |      |    |    |       |     |    |        |      |
  195.   |    |     |        |-----------|    |       |     |    |        |      |
  196.   |    |     |        |        |    |       |     |    |        |      |
  197.   |-----------|        |      D    |    |-----------|    |-----------|
  198.   |    C     |        |        |    |       D     |    |        D      |
  199.   +-----------+        +-----+-----+    +-----+-----+    +-----------+")
  200.  
  201. (defvar ibuff-show-buffer-in-mode-line t
  202.   "*Non-nil means display current buffer name and size in the mode line.
  203. The current buffer is the buffer described by the line the point is on.")
  204.  
  205. (defvar ibuff-use-count-effect 7
  206.   "*Integer that regulates the effect of use count on `ibuff-propose-buffer'.
  207. Can range from 0 to 20; values between 5 and 10 are recommended.
  208. `ibuff-propose-buffer' which is called automatically when `ibuff-menu' is
  209. invoked puts the point on the line for a buffer which may be a good
  210. candidate to be next switched to. It usually favours buffers that were
  211. often selected the last time. A zero value disables this feature, higher
  212. values enhance it.")
  213.  
  214. (defvar ibuff-initial-sublist-modes "bdfpk"
  215.   "String that describes the initial composition of the sublist mode ring.
  216. May contain the following key characters. (These are the same characters
  217. the `ibuff-edit-mode-ring' command will prompt for.):
  218.  
  219.     b: basic mode (full listing)
  220.     d: mode that lists dired buffers
  221.     f: mode that lists file buffers
  222.     p: mode that lists plain buffers
  223.     k: mode that lists buffers flagged to be deleted.
  224.  
  225. The first character in the string refers to the initial mode that will
  226. be set up when `ibuff-menu' is called.
  227. Example:
  228.     (setq ibuff-initial-sublist-modes \"bdfpk\")")
  229.  
  230. (defvar ibuff-bury-buffers-regexp
  231.   (format "^\\( .*\\|sent .*\\|\\*ftp .*\\|%s\\)$"
  232.       (mapconcat 'regexp-quote
  233.              '("*Help*" "*Directory*" "*Dired log*" "*Compile-Log*")
  234.              "\\|"))
  235.   "Regexp that matches buffers that should be buried automatically.
  236. Buffers that match this regular expression are moved to the end of the
  237. buffer list each time `ibuff-menu' is called. These should be buffers you
  238. rarely want to switch to. Example:
  239.  
  240.   (setq ibuff-bury-buffers-regexp
  241.     (format \"^\\\\( .*\\\\|sent .*\\\\|\\\\*ftp .*\\\\|%s\\\\)$\"
  242.         (mapconcat 'regexp-quote
  243.                '(\"*Help*\" \"*Directory*\"
  244.                  \"*Dired log*\" \"*Compile-Log*\")
  245.                \"\\\\|\"))
  246.  
  247. matches all buffer names that begin with a blank, sent VM mail
  248. buffers, ftp buffers, and the buffers *Help*, *Directory*, *Dired log*,
  249. and *Compile-Log*.
  250. Automatic burying is disabled if the variable `ibuff-bury-buffers' is nil.")
  251.  
  252. (defvar ibuff-bury-buffers t
  253.   "*Non-nil means `ibuff-menu' should bury certain buffers automatically.
  254. See also \\[describe-variable] ibuff-bury-buffers-regexp.")
  255.  
  256. (defvar ibuff-hide-buffers-regexp "^ "
  257.   "Regexp that matches buffers that should be hidden initially.
  258. These are usually buffers with names that start with a blank.
  259. Example:
  260.  
  261.   (setq ibuff-hide-buffers-regexp \"^ \")
  262.  
  263. In `ibuff-menu-mode', the command `ibuff-toggle-hiding-buffers' can be used
  264. to make such buffers visible temporarily.")
  265.  
  266. (defvar ibuff-mark-delete-pre-set-prefix t
  267.   "*Controls behaviour of `ibuff-mark-delete' in absence of a prefix arg.
  268. ---------------------------------------------------------------------------
  269. Variable   Equivalent    Resulting behaviour
  270.  value         prefix
  271. ---------------------------------------------------------------------------
  272. nil or 0   M-0        Set or delete the flag, don't move.
  273. t or 1       M-1        Set or delete the flag, then move down one line.
  274. '- or -1   - or M--    Move up one line, set or delete the flag, then return.
  275. '(4)       C-u        Set the flag, don't move.
  276. '(16)       C-u C-u    Delete the flag, don't move.
  277. ---------------------------------------------------------------------------
  278. In the case of display, save, or kill flags the term `delete' means restore
  279. the initial marks. It is advisable not to use any other pre-set values than
  280. nil/0 or t/1. The C-u and C-u C-u prefixes are intended to be used in
  281. conjunction with the `ibuff-apply-command-region' command.")
  282.  
  283. (defvar ibuff-mark-display-pre-set-prefix t
  284.   "*Controls behaviour of `ibuff-mark-display' in absence of a prefix arg.
  285. Do \\[describe-variable] ibuff-mark-delete-pre-set-prefix for details.")
  286.  
  287. (defvar ibuff-mark-save-pre-set-prefix nil
  288.   "*Controls behaviour of `ibuff-mark-save' in absence of a prefix arg.
  289. Do \\[describe-variable] ibuff-mark-delete-pre-set-prefix for details.")
  290.  
  291. (defvar ibuff-mark-modified-pre-set-prefix nil
  292.   "*Controls behaviour of `ibuff-mark-modified' in absence of a prefix arg.
  293. Do \\[describe-variable] ibuff-mark-delete-pre-set-prefix for details.")
  294.  
  295. (defvar ibuff-mark-read-only-pre-set-prefix nil
  296.   "*Controls behaviour of `ibuff-mark-read-only' in absence of a prefix arg.
  297. Do \\[describe-variable] ibuff-mark-delete-pre-set-prefix for details.")
  298.  
  299. ;; The following variable is defined here to avoid byte-compiler warnings.
  300. ;; It is used by tree-dired 6.0, Lucid Emacs buffer-menu and `ibuff-menu'.
  301.  
  302. (defvar list-buffers-directory nil
  303.   "String to be displayed in the file name column of `ibuff-menu'.
  304. If this buffer local variable is defined and a string and the buffer
  305. does not visit a file it is displayed in the file name column of the
  306. menu line for this buffer.")
  307.  
  308. (make-variable-buffer-local 'list-buffers-directory)
  309.  
  310. (defvar ibuff-cannot-do-selective-display (string-match "Lucid" emacs-version)
  311.   "*Non-nil means fake `selective-display' in the `ibuff-menu' buffer.
  312. Lucid Emacs 19.4 is unable to handle `selective-display', which is used
  313. to display subgroups of buffers in the menu. A non-nil value causes
  314. `ibuff-menu' to fill up all menu lines with whitespace such that lines
  315. which should be hidden become invisible effectively.")
  316.  
  317. ;;;; END OF CUSTOMIZATION SECTION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  318.  
  319. ;; To avoid byte-compiler warnings:
  320.  
  321. (defun ibuff-flush-undo (buff))
  322.  
  323. (if (fboundp 'buffer-disable-undo)
  324.     (fset 'ibuff-flush-undo (symbol-function 'buffer-disable-undo)) ; Lucid
  325.   (fset 'ibuff-flush-undo (symbol-function 'buffer-flush-undo)))
  326.  
  327. (or (boundp 'zmacs-regions) (defvar zmacs-regions nil))
  328.  
  329. ;;;; INTERNAL VARIABLES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  330.  
  331. (defconst ibuff-delete-flag ?D)        ; Column 1
  332. (defconst ibuff-display-flag ?>)    ; Column 1
  333. (defconst ibuff-visible-flag ?.)    ; Column 1
  334. (defconst ibuff-modified-flag ?*)    ; Column 2
  335. (defconst ibuff-save-flag ?S)        ; Column 2
  336. (defconst ibuff-read-only-flag ?%)    ; Column 3
  337. (defconst ibuff-no-flag ? )
  338. ;; Character constants for marks.
  339.  
  340. (defconst ibuff-line-numbers "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
  341. ;; Line indices for the first 36 lines.
  342.  
  343. ;;; Miscellaneous regular expressions for menu lines
  344.  
  345. (defconst ibuff-regexp-format
  346.   "^%s: \\(%s\\) [^\n\r]+\\([\n\r]\\)")
  347. ;; Format string to create miscellaneous menu line regexps
  348. ;; (match-beginning 0): index
  349. ;; subexpression 1:    flags
  350. ;; (1+ (match-end 1):    buffer name
  351. ;; subexpression 2:    line delimiter
  352.  
  353. (defconst ibuff-mark-regexp-format
  354.   (format ibuff-regexp-format "[ 0-9A-Z]" "%s%s%s"))
  355. ;; Format string to create a regexp that matches lines with specific marks.
  356.  
  357. (defconst ibuff-line-regexp
  358.   (format ibuff-mark-regexp-format "." "." "."))
  359. ;; Regexp for all valid menu lines.
  360.  
  361. (defconst ibuff-modified-buffers-regexp
  362.   (format ibuff-mark-regexp-format
  363.       "." (regexp-quote (char-to-string ibuff-modified-flag)) "."))
  364. ;; Regexp for lines with modified buffers
  365.  
  366. (defconst ibuff-visible-buffers-regexp
  367.   (format ibuff-mark-regexp-format
  368.       (regexp-quote (char-to-string ibuff-visible-flag)) "." "."))
  369. ;; Regexp for lines with previously displayed buffers
  370.  
  371. ;;; Sublist modes
  372.  
  373. (defconst ibuff-standard-sublist-modes
  374.   '((?b . (nil . "basic"))
  375.     (?d . ((ibuff-narrow-to-dired) . "dired"))
  376.     (?f . ((ibuff-narrow-to-files) . "files"))
  377.     (?p . ((ibuff-narrow-to-plain-buffers) . "plain"))
  378.     (?k . ((ibuff-narrow-to-killed-buffers) . "delete"))))
  379. ;; Alist of (KEY . MODE) cells for standard sublist modes.
  380. ;; MODE is a ((CLOSURES)) . NAME) cell as described below.
  381.  
  382. (defvar ibuff-mode-ring nil)
  383. ;; List of ((CLOSURES) . NAME) cons cells for different sublist modes.
  384. ;; (CLOSURES) is a list of (NARROW-FUNCTION . ARGUMENT) cells, of
  385. ;; NARROW-FUNCTION  symbols (for functions that take no argument), or nil.
  386. ;; NAME is a string displayed in the mode-line.
  387. ;; The composition of the mode ring can be changed interactively.
  388.  
  389. (defvar ibuff-mode-ring-ptr nil)
  390. ;; Points to the cell of the currently active mode.
  391.  
  392. ;;; Stack for regexp matches
  393.  
  394. (defvar ibuff-match-stack '(nil))
  395. ;; List of (NARROW-FUNCTION . ARGUMENT) cells, first entry is nil.
  396. ;; The stack is used to store successful pattern matches or buffer
  397. ;; hiding commands and to switch between different match levels.
  398.  
  399. (defvar ibuff-match-stack-ptr nil)
  400. ;; Points to the cell of the currently active match level.
  401.  
  402. (defvar ibuff-move-down-stack nil)
  403. ;; Direction in which the next step on the match stack should go.
  404. ;; Nil means up.
  405.  
  406. (defvar ibuff-last-buffer-regexp nil)
  407. ;; Stores last regexp if buffer name matching fails.
  408. ;; Prompted at the next call.
  409.  
  410. (defvar ibuff-last-file-regexp nil)
  411. ;; Stores last regexp if file name matching fails.
  412. ;; Prompted at the next call.
  413.  
  414. (defvar ibuff-last-mode-regexp nil)
  415. ;; Stores last regexp if mode name matching fails.
  416. ;; Prompted at the next call.
  417.  
  418. ;;; Mode line variables
  419.  
  420. (defvar ibuff-current-buffer-name "")
  421. ;; Name of buffer described by line point is on;
  422. (defvar ibuff-current-buffer-size 0)
  423. ;; its size as integer;
  424. (defvar ibuff-current-buffer-size-string "0")
  425. ;; as string.
  426. (defvar ibuff-current-mode-name "")
  427. ;; Current sublist mode name.
  428. (defvar ibuff-match-level 0)
  429. ;; Level of match stack pointer as integer;
  430. (defvar ibuff-match-level-string "-")
  431. ;; as string.
  432. (defvar ibuff-current-match-name "")
  433. ;; Kind of match level currently active (match or hide).
  434. (defvar ibuff-widen nil)
  435. ;; Nil if buffers matched by `ibuff-hide-buffers-regexp' are not displayed.
  436.  
  437. (defconst ibuff-mode-line-format
  438.   (list "-----> "
  439.     '(24 . (-24 . ibuff-current-buffer-name))
  440.     " "
  441.     '(12 . ibuff-current-buffer-size-string)
  442.     " %[("
  443.     'mode-name
  444.     '(ibuff-widen " wide")
  445.     ")-|"
  446.     '(ibuff-move-down-stack "<" ">")
  447.     'ibuff-current-match-name
  448.     'ibuff-match-level-string
  449.     '(ibuff-move-down-stack "<" ">")
  450.     "|-{" 'ibuff-current-mode-name "}%]-"
  451.     '(-3 . "%p")
  452.     "-%-"))
  453. ;; Mode line format used when `ibuff-show-buffer-in-mode-line' is t.
  454.  
  455. (defconst ibuff-fixed-mode-line-format
  456.   (nconc
  457.    (list "" 'mode-line-modified 'mode-line-buffer-identification "  ")
  458.    (nthcdr 4 ibuff-mode-line-format)))
  459. ;; Mode line format used when `ibuff-show-buffer-in-mode-line' is nil.
  460.  
  461. ;;; Markers for buffers in the menu
  462.  
  463. (defvar ibuff-buffer-markers nil)
  464. ;; Alist of (MARKER . BUFFER) cells to associate menu positions with
  465. ;; buffers. It would be easier and clearer to read the buffer names from
  466. ;; the menu text, but that would require to create a new buffer substring
  467. ;; each time the name must be read. Since the latter is done very often,
  468. ;; the use of such a marker list saves a significant amount of memory.
  469. ;; The markers and cons cells are recycled each time the menu is drawn.
  470.  
  471. ;;; Miscellaneous variables
  472.  
  473. (defvar ibuff-user-home-directory nil)
  474. ;; The user's home directory as regexp.
  475.  
  476. (defvar ibuff-rc-loaded nil)
  477. ;; t if `ibuff-source-file-name' has been loaded.
  478.  
  479. (defvar ibuff-last-window-configuration nil)
  480. ;; Window configuration before `ibuff-menu' pops up.
  481.  
  482. (defvar ibuff-last-buffers nil)
  483. ;; List of all buffers displayed in `ibuff-last-window-configuration'.
  484.  
  485. (defvar ibuff-killed-buffer nil)
  486. ;; Temporarily used as a replacement for buffers killed by `ibuff-parse'.
  487. ;; Their windows are kept unless `ibuff-show-buffers' decides to delete them.
  488.  
  489. (defvar ibuff-goal-marker 1)
  490. ;; Position to keep track of the goal menu line if sublist mode or match
  491. ;; level are changed.
  492.  
  493. (defvar ibuff-menu-lines nil)
  494. ;; Number of lines the menu has currently.
  495.  
  496. (defconst ibuff-file-name-column 45)
  497. ;; Column where the file names are displayed
  498.  
  499. (defvar ibuff-command-application nil)
  500. ;; Temporarily t if `ibuff-apply-command-region' is active.
  501. ;; `ibuff-adjust-point' does nothing if this variable is t.
  502.  
  503. (defvar ibuff-numbers-changed nil)
  504. ;; Temporarily t if the menu needs to be renumbered.
  505. ;; `ibuff-adjust-point' will then do that.
  506.  
  507. (defvar ibuff-buffer-queue (make-vector 10 nil))
  508. ;; The last 10 selected buffers. Used to calculate use counts.
  509.  
  510. (defvar ibuff-buffer-queue-ptr 0)
  511. ;; Index of last entry in ibuff-buffer-queue.
  512.  
  513. (defvar ibuff-menu-mode-map nil)
  514. ;; Full keymap. Please use `ibuff-menu-mode-hook' to change key bindings.
  515.  
  516.  
  517. ;;;; KEYMAP AND MAJOR MODE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  518.  
  519. (if ibuff-menu-mode-map
  520.     ()
  521.   (setq ibuff-menu-mode-map (make-keymap))
  522.   (suppress-keymap ibuff-menu-mode-map t)
  523.   (mapcar (function
  524.        (lambda (c)
  525.          (define-key ibuff-menu-mode-map
  526.            (char-to-string c) 'ibuff-goto-this-line)))
  527.       ibuff-line-numbers)
  528.   (define-key ibuff-menu-mode-map "x" 'ibuff-expunge)
  529.   (define-key ibuff-menu-mode-map "q" 'ibuff-perform-quit)
  530.   (define-key ibuff-menu-mode-map " " 'ibuff-select-buffer-perform-quit)
  531.   (define-key ibuff-menu-mode-map "\r" 'ibuff-replace-buffer-perform-quit)
  532.   (define-key ibuff-menu-mode-map "\t" 'ibuff-add-buffer-perform-quit)
  533.   (define-key ibuff-menu-mode-map "c" 'ibuff-cancel-quit)
  534.   (define-key ibuff-menu-mode-map "g" 'ibuff-revert-menu)
  535.   (define-key ibuff-menu-mode-map "z" 'ibuff-copy-buffer-as-kill)
  536.   (define-key ibuff-menu-mode-map "\M-w" 'ibuff-copy-buffer-as-kill)
  537.   (define-key ibuff-menu-mode-map "y" 'ibuff-yank-perform-quit)
  538.   (define-key ibuff-menu-mode-map "?" 'ibuff-brief-help)
  539.   (define-key ibuff-menu-mode-map "h" 'describe-mode)
  540.   (define-key ibuff-menu-mode-map "d" 'ibuff-mark-delete)
  541.   (define-key ibuff-menu-mode-map "k" 'ibuff-mark-delete)
  542.   (define-key ibuff-menu-mode-map "s" 'ibuff-mark-save)
  543.   (define-key ibuff-menu-mode-map "m" 'ibuff-mark-display)
  544.   (define-key ibuff-menu-mode-map "~" 'ibuff-mark-modified)
  545.   (define-key ibuff-menu-mode-map "%" 'ibuff-mark-read-only)
  546.   (define-key ibuff-menu-mode-map "*" 'ibuff-mark-modified-buffers-save)
  547.   (define-key ibuff-menu-mode-map "." 'ibuff-mark-displayed-buffers-display)
  548.   (define-key ibuff-menu-mode-map "u" 'ibuff-unmark)
  549.   (define-key ibuff-menu-mode-map "\C-?" 'ibuff-backward-unmark)
  550.   (define-key ibuff-menu-mode-map "\C-d" 'ibuff-unmark-forward)
  551.   (define-key ibuff-menu-mode-map "a" 'ibuff-apply-command-region)
  552.   (define-key ibuff-menu-mode-map ":" 'ibuff-match-buffer-names)
  553.   (define-key ibuff-menu-mode-map "/" 'ibuff-match-file-names)
  554.   (define-key ibuff-menu-mode-map "=" 'ibuff-match-mode-names)
  555.   (define-key ibuff-menu-mode-map "\C-k" 'ibuff-hide-buffer-as-match)
  556.   (define-key ibuff-menu-mode-map "t" 'ibuff-toggle-hiding-buffers)
  557.   (define-key ibuff-menu-mode-map "w" 'ibuff-next-match-level)
  558.   (define-key ibuff-menu-mode-map "l" 'ibuff-next-sublist-mode)
  559.   (define-key ibuff-menu-mode-map "i" 'ibuff-store-match-as-mode)
  560.   (define-key ibuff-menu-mode-map "e" 'ibuff-edit-mode-ring)
  561.   (define-key ibuff-menu-mode-map "r" 'ibuff-rename-buffer)
  562.   (define-key ibuff-menu-mode-map "f" 'ibuff-set-file-name)
  563.   (define-key ibuff-menu-mode-map "v" 'ibuff-view-buffer)
  564.   (define-key ibuff-menu-mode-map "b" 'ibuff-bury-buffer)
  565.   (define-key ibuff-menu-mode-map "<" 'ibuff-beginning-of-menu)
  566.   (define-key ibuff-menu-mode-map ">" 'ibuff-end-of-menu)
  567.   (define-key ibuff-menu-mode-map "\C-n" 'ibuff-next-line)
  568.   (define-key ibuff-menu-mode-map "n" 'ibuff-next-line)
  569.   (define-key ibuff-menu-mode-map "\C-p" 'ibuff-previous-line)
  570.   (define-key ibuff-menu-mode-map "p" 'ibuff-previous-line)
  571.   (define-key ibuff-menu-mode-map "j" 'ibuff-back-to-mark)
  572.   (define-key ibuff-menu-mode-map "#" 'ibuff-propose-buffer)
  573.   (define-key ibuff-menu-mode-map "\C-r" 'ibuff-isearch-backward)
  574.   (define-key ibuff-menu-mode-map "\C-s" 'ibuff-isearch-forward)
  575.   (define-key ibuff-menu-mode-map "|" 'ibuff-show-long-file-names)
  576.   (define-key ibuff-menu-mode-map "-" 'negative-argument)
  577.   )
  578.  
  579. (defconst ibuff-brief-help-messages
  580.   '("QUIT:   SPC select   TAB add   RET replace   q perform   y yank  c cancel"
  581.     "MARK:   m display   s save   d delete    ~ not modified  %% not read-only"
  582.     "MARK:   * save some buffers   . display again   a apply command in region"
  583.     "UNMARK:   u unmark   DEL backward unmark   C-d unmark forward    g revert"
  584.     "MOVE:   0..1A..Z goto this line  n next  p previous line   j back to mark"
  585.     "MATCH:  : buffers  / file names  = modes   w next match   C-k hide buffer"
  586.     "LIST:   l dired, files, deleted   i insert match mode   e edit list modes"
  587.     "IMMEDIATE:   f set file    r rename    b bury    v view     z copy buffer"
  588.     "HELP:   h verbose   ? brief   | long file names   t toggle hidden buffers"
  589.     ))
  590.  
  591. (put 'ibuff-menu-mode 'mode-class 'special)
  592.  
  593. (defun ibuff-menu-mode (&optional preserve)
  594.   ;;A positive prefix argument preserves previous match level and sublist mode.
  595.   ;;A negative prefix argument forces to load `ibuff-source-file-name'.
  596.   "\
  597.  For a very brief command summary, type M-1 \\[set-selective-display] \
  598. in this buffer.
  599.  (This does not work in Lucid Emacs 19.4.)
  600. Type \\[set-selective-display] for detailed notes.
  601. \040
  602.  Indexed Buffer Menu mode is a major mode to edit a specially formatted
  603.  list of buffers generated by the \\[ibuff-menu] (`ibuff-menu') command.
  604.  Except for slow terminals, \\[ibuff-menu] may also be the preferred way to
  605.  display and switch to particular buffers.
  606. \040
  607.  Characters do not insert themselves; instead they are commands. Many
  608.  commands do not take effect immediately; they merely work on a set of
  609.  markings or flags that stand for requests to be performed later.
  610. \040
  611.  Each buffer is described by one line of the menu. Each menu line consists
  612.  of:
  613.     - a line number,
  614.     - three columns of flags,
  615.     - the buffer name,
  616.     - its major mode name,
  617.     - and either:
  618.         -- the name of a visited file,
  619.         -- the dired directory,
  620.         -- ID, state and name of an associated process,
  621.         -- nothing
  622.       dependend on what is appropriate.
  623. \040
  624.  The first 36 lines are numbered with digits or capital letters. Type such
  625.  a character to move the cursor to the line with this index. Most commands
  626.  affect the buffer described by the line the point is on.
  627. \040
  628.  Undo is disabled in the `ibuff-menu' buffer to avoid inconsistencies. But
  629.  several commands are provided to rub out mistakenly set flags. As a last
  630.  resort you can always type `g' to restore the initial menu set-up or you
  631.  can type `c' to cancel all requests and to quit the menu.
  632. \040
  633. COMMAND SUMMARY
  634. \040
  635.     1. Commands that set flags
  636.     -------------------------------------------------------------------
  637.     The only immediate effect of the following commands is to change
  638.     flags associated with buffers in order to make requests that will
  639.     be performed by the commands in section 3.
  640. \040
  641. m    Request to display this buffer or cancel a given request.
  642.      Such buffers are marked \">\".
  643. s    Request to save this buffer or cancel a given request.
  644.      Such buffers are marked \"S\".
  645. d or k    Request to delete this buffer or cancel a given request.
  646.      Such buffers are marked \"D\".
  647. ~    Request to change the buffer-modified flag of this buffer.
  648.      Modified buffers are marked \"*\".
  649. %    Request to make this buffer read-only or writable.
  650.      Read-only buffers are marked \"%\".
  651. \040
  652.      The commands above accept a prefix argument which is interpreted as
  653.      follows:
  654.      - or M--  Move up one line, set or remove the mark, then return.
  655.      M-0       Set or remove the mark, don't move.
  656.      M-1       Set or remove the mark, then move down one line.
  657.      C-u       Set the mark unconditionally, don't move.
  658.      C-u C-u   Remove the mark unconditionally, don't move.
  659.      If no prefix argument is supplied, a customizable pre-set prefix is
  660.      used. Do \\[apropos] ibuff-.*-pre to find the related variables.
  661.      Their standard definition is like M-1 for the m, d, and k commands
  662.      and M-0 for the others.
  663. \040
  664. *    Request to save all modified buffers that refer to writable files.
  665. .    Request to show again all previously displayed buffers (period).
  666.      Previously displayed buffers are marked \".\".
  667. \040
  668.      The two commands above do not recognize buffers described by menu
  669.      lines which are actually hidden.
  670. \040
  671. u    Unmark: restore the initial marks for this buffer.
  672. DEL    Move up one line, then restore the initial marks for that buffer.
  673. C-d    Restore the initial marks for this buffer, then move down on line.
  674. \040
  675.      The unmark commands above accept a prefix argument which causes
  676.      them to clear all marks in the line instead of restoring the
  677.      initial values. The u command additionaly accepts a numeric prefix
  678.      which has the same meaning as for the m, s, d, or k commands.
  679. \040
  680. g    Revert: discard all requests and update the menu.
  681.      A positive prefix argument preserves the current match level and
  682.      sublist mode (see below). A negative prefix argument forces to load
  683.      the `ibuff-source-file-name' customization file again. Note that
  684.      prefix arguments for the \\[ibuff-menu] command have the same
  685.      meanings.
  686. \040
  687.     2. Commands that move the point
  688.     -------------------------------------------------------------------
  689. 0..1 or
  690. A..Z    Move the point to the line with this index (digits or capitals).
  691. <    Go to the first menu line.
  692. >    Go to the last menu line.
  693. \040
  694.      The three commands above set the mark (for buffer positions) before
  695.      they move the point. A prefix argument inhibits them from setting
  696.      the mark.
  697. \040
  698. n    Move down one line. (Synonym: C-n).
  699. p    Move up one line. (Synonym: C-p).
  700. \040
  701.      The two commands above accept a prefix argument which is
  702.      interpreted as a line count.
  703. \040
  704. j    Jump back to the positions stored in the mark ring.
  705. #    Propose a buffer that is a good candidate to be next switched to.
  706.      The command moves the point to the menu line for such a buffer. It
  707.      is called automatically when you invoke `ibuff-menu'. The choice
  708.      depends on how often you have switched to particular buffers and on
  709.      some other characteristics. A prefix argument clears the use
  710.      counter for buffers previously switched to. This feature is useful
  711.      if you make a considerable change to your \"working set\" of Emacs
  712.      buffers. The effect use count has on the selection of a buffer can
  713.      be regulated with the variable `ibuff-use-count-effect'.
  714. \040
  715.     3. Commands that execute and quit
  716.     -------------------------------------------------------------------
  717. SPC    Display and select this buffer.
  718. TAB    Additionally display and select this buffer.
  719. RET    Switch to this buffer in the previously selected window.
  720. \040
  721.      The three commands above perform all requests and quit the menu.
  722.      They also display buffers marked \">\" in addition to the one
  723.      described by the current menu line. The SPC command will not
  724.      redisplay previously displayed buffers unless they are explicitely
  725.      marked. The TAB command always redisplays the previously shown
  726.      buffers. The RET command redisplays all previously displayed
  727.      buffers except for the one that is replaced with the buffer
  728.      described by the current menu line. However, if the replaced buffer
  729.      has been displayed in more than one window, the remaining windows
  730.      will still show it.
  731. \040
  732. q    Perform all requests and quit.
  733.      Buffers that are marked to be displayed are shown. If no buffers are
  734.      marked \">\", the previous window configuration is restored (as far
  735.      as possible).
  736. x    Expunge: perform all requests except for those to display buffers
  737.      and update the menu. Especially buffers flagged to be deleted are
  738.      killed.  If a buffer is deleted that has been displayed in a
  739.      window, the window is not deleted; instead it displays a special
  740.      buffer named \" #<killed buffer>\" that will be removed when you
  741.      quit the menu.
  742. \040
  743. y    Yank: Additionally select this buffer and insert killed text.
  744.      This command behaves like the TAB command, except that the contents
  745.      of the first entry in the kill ring are inserted before the point of
  746.      the selected buffer. You can use \\[yank-pop] immediately after
  747.      this command to choose another entry of the kill ring.
  748.      The command can be used to copy text from buffer to buffer. See
  749.      also the `z' or M-w command described in section 6.
  750. \040
  751. c    Cancel all requests and quit.
  752. \040
  753.     4. Commands that list subgroups of buffers
  754.     -------------------------------------------------------------------
  755.     These commands restrict the visible portion of the menu to buffers
  756.     in the list that satisfy particular conditions. Applied in the
  757.     right way, they allow you to keep track even of a large number of
  758.     buffers. They do not affect already made requests for buffers they
  759.     hide; their menu lines are simply hidden, nothing else.
  760. \040
  761.     The following two mechanisms are provided for convenience:
  762. \040
  763.     - A stack that automatically records commands that restrict the
  764.       menu based on regular expressions or that hide certain buffers
  765.       directly. Such commands can be used additively, i.e. they may
  766.       follow one another. The stack is called \"match stack\", its
  767.       entries are associated with \"match levels\" or \"hide levels\".
  768.       A command is provided that can increase or decrease the current
  769.       match level so that you can easily resume previously made
  770.       matches. The current match level is indicated in the mode line.
  771. \040
  772.     - A ring of minor modes that list buffers dependend on certain
  773.       conditions. It is called \"sublist mode ring\" and its initial
  774.       composition contains modes that list dired, file, plain buffers,
  775.       or buffers flagged to be deleted. A command is provided that steps
  776.       cyclically through this ring; the current mode is indicated in the
  777.       mode line. The initial composition is customizable with the
  778.       variable `ibuff-initial-sublist-modes'.  It is also possible to
  779.       change its composition interactively in the course of an Emacs
  780.       session. Another command is provided to store the configuration
  781.       that consists of the current state of match level and the
  782.       underlying sublist mode as a new mode in the ring so that you can
  783.       easily return to such a configuration later.
  784. \040
  785. /    Show buffers with file names that match a regular expression.
  786.      Dired buffers are also shown if their directory matches. A tilde
  787.      (\"~\") in the regexp is expanded to your home directory if it is
  788.      not escaped by a backslash, not followed or preceded by another
  789.      tilde, and not the last character in the regexp.  With prefix
  790.      argument, the command restricts the menu to buffers with file names
  791.      that do not match against the regular expression.
  792. :    Show buffers with names that match a regular expression (colon).
  793.      With prefix argument, the complement is shown.
  794. =    Show buffers with major mode names that match a regular expression.
  795.      With prefix argument, the complement is shown.
  796. \040
  797.      The three commands above prompt for the regular expression. A
  798.      pattern match is based on the currently visible portion of the
  799.      menu, so different kinds of matches may follow one another. On a
  800.      successful match, the command that led to this match is pushed on
  801.      the match stack; at the same time all previously stored matches of
  802.      the same and higher levels are discarded. Note that the command,
  803.      associated with the regexp, is pushed on the stack, not the result
  804.      of the match.
  805. \040
  806. C-k    Hide this buffer.
  807.      This command is also pushed on the match stack. Future references
  808.      to the associated \"hide level\" will hide the menu line for this
  809.      buffer again. If the current match level is already a hide level,
  810.      then this buffer is merged into the buffer list of this level
  811.      instead of being pushed to a new level. However, a prefix argument
  812.      makes the command generate a new hide level unconditionally. If you
  813.      want to hide a set of buffers at once, use the `a' command
  814.      described below.
  815. \040
  816. w    \"Wax and wane\": Step up and down from match level to match level.
  817.      The current match level is indicated in the mode line. A pair of
  818.      either \"<\" or \">\" signs indicates in which direction the next
  819.      call of this command will go; \"<\" means to lower levels.
  820.      A prefix argument is interpreted as the number of steps the command
  821.      should take. If it is negative, it also changes the direction for
  822.      future calls.
  823. \040
  824. l    List dired, file, plain, or other categories of buffers (lower L).
  825.      The command cyclically steps through the sublist mode ring. A
  826.      prefix argument is interpreted as the number of steps the command
  827.      should take.  The command skips a mode if there are no buffers that
  828.      belong to its associated category.  In addition, switching to
  829.      another sublist mode can lower the actually active match level in
  830.      order to avoid an empty menu.
  831. \040
  832. i    Store and insert the current match level as another sublist mode.
  833.      The command stores the combination of the current match stack
  834.      entries up to the indicated level and of the underlying sublist mode
  835.      as a new mode in the mode ring. It also prompts for a name with
  836.      which it will be indicated in the mode line. With a prefix argument,
  837.      the new mode is inserted before the currently active one, otherwise
  838.      it is inserted after it. NB: if you insert a new mode before the
  839.      basic mode, i.e. that one that does not hide buffers and that should
  840.      be active initially, your new mode will be the initial mode used
  841.      when `ibuff-menu' is invoked.
  842. \040
  843. e    Edit the sublist mode ring. Delete modes or insert standard modes.
  844.      This command prompts for a key, then it will either delete the
  845.      current sublist mode (requests confirmation), or it inserts one of
  846.      the standard modes (basic, dired, files, plain, deleted). With
  847.      prefix argument, the insertion occurs before the current mode,
  848.      otherwise after it.
  849. \040
  850. t    Toggle the display of buffers matched by `ibuff-hide-buffers-regexp'.
  851. \040
  852.     5. Region based higher order command
  853.     -------------------------------------------------------------------
  854. a    Apply a command to each menu line touched by the current region.
  855.      A region can be defined with the 0 .. 9 or A .. Z commands.
  856.      With prefix argument, apply the command to the whole visible
  857.      portion of the menu. Prompts for a command key sequence which may
  858.      contain prefix arguments. Only the commands m, d, k, s, ~, %, u,
  859.      C-k, r, f, b, v, and z or M-w are applicable.
  860. \040
  861.      Examples:
  862.        -- Delete buffers from lines 3 to 7:
  863.         3 7 a d
  864.        -- Delete all buffers indicated in the menu:
  865.         C-u a d
  866.        -- Delete all buffers that visit files from your directory foo,
  867.           assuming that some of these are already flagged to be killed:
  868.         / \"~/foo/[^/]+$\" RET C-u a C-u d
  869.           (A less complicated regexp should be sufficient in most cases.)
  870.        -- Hide buffers from lines 4 to 8:
  871.         4 8 a C-k
  872.           Here a single \"hide level\" will be pushed on the match
  873.           stack unless you don't provide a prefix argument to C-k.
  874. \040
  875.     6. Commands that take effect immediately
  876.     -------------------------------------------------------------------
  877. r    Rename this buffer. Prompts for the new name.
  878. f    Set or change the visited file name of this buffer.
  879.      To make the buffer no longer visit a file, use an empty string as
  880.      the new file name. Note that you have to rub out the initial
  881.      contents of the minibuffer for this purpose. This command also
  882.      changes the buffer name.
  883. \040
  884. b    Bury: shift this bothersome buffer to the end of the list.
  885. v    View this buffer in view mode, then return to the menu.
  886.      This command does not work correctly in Lucid Emacs 19.4.
  887. \040
  888. z    Push the contents of this buffer on the kill ring (Synonym: M-w).
  889.      Like `copy-region-as-kill' of the whole buffer. With prefix
  890.      argument, the contents are appended to the first entry of the kill
  891.      ring. See also the `y' command described in section 3.
  892. \040
  893.     7. Miscellaneous commands
  894.     -------------------------------------------------------------------
  895. |    Show a larger part of the file name column of the menu.
  896.      The command splits the menu window horizontally and scrolls the
  897.      right part to the left such that you can read long file names
  898.      bether. A second call of this command or the w, t, or l commands
  899.      will reset the window size.
  900.      This command does not work in Lucid Emacs 19.4.
  901. \040
  902. ?    Show brief command summaries in the minibuffer.
  903.      The command cyclically displays a set of short instruction notes in
  904.      a 2 sec. rhythm. The next key you type stops this cycle *and*
  905.      executes the command it is bound to. A numeric prefix argument can
  906.      be used to specify another time intervall.
  907. \040
  908. C-s    Incremental search forwards.
  909. C-r    Incremental search backwards.
  910.      With prefix argument, search for a regular expression. Note that
  911.      these commands also search in lines which are actually hidden. If
  912.      your current input matches a piece of text in such lines, the
  913.      cursor gets stuck on the right side of the window. In such cases
  914.      you should type one of the `search-repeat-char's (C-s or C-r) to
  915.      continue.
  916. \040
  917. -    Negative argument. Abbreviation for M-- or C-u - 1.
  918. \040
  919. CUSTOMIZATION VARIABLES
  920. \040
  921.  Please refer to the variable documentations for detailed notes.
  922.  (Use \\[describe-variable] <variable name>.)
  923. \040
  924. ibuff-menu-mode-hook
  925.     Can be used to make little changes to `ibuff-menu-mode'.
  926. ibuff-menu-hook
  927.     Exclusively run by `ibuff-menu', not by `ibuff-revert-menu'.
  928. \040
  929. ibuff-buffer-name
  930.     The name used for the menu buffer.
  931. ibuff-source-file-name
  932.     Loaded only once -- intended for extensive customizations.
  933. ibuff-restrict-window-height
  934.     Controls the menu window height.
  935. ibuff-adjust-window-heights
  936.     Affects the display algorithm of `ibuff-menu'.
  937. ibuff-show-buffer-in-mode-line
  938.     Non-nil means display current buffer name and size in the mode line.
  939. ibuff-use-count-effect
  940.     Regulates the effect of use count on `ibuff-propose-buffer'.
  941. ibuff-initial-sublist-modes
  942.     String to describe the initial composition of the sublist mode ring.
  943. ibuff-bury-buffers-regexp
  944.     Buffers that match this regexp are buried automatically.
  945. ibuff-bury-buffers
  946.     Non-nil means `ibuff-menu' should bury such buffers automatically.
  947. ibuff-hide-buffers-regexp
  948.     Buffers that match this regexp are hidden initially.
  949. \040
  950. ibuff-mark-delete-pre-set-prefix
  951. ibuff-mark-display-pre-set-prefix
  952. ibuff-mark-save-pre-set-prefix
  953. ibuff-mark-modified-pre-set-prefix
  954. ibuff-mark-read-only-pre-set-prefix
  955.     Used in absence of a prefix argument for flag setting commands.
  956. \040
  957. list-buffers-directory
  958.     If this buffer local variable is defined and a string, it is
  959.     displayed in the file name column of the menu line that refers to
  960.     this buffer if the buffer does not visit a file.
  961. ibuff-cannot-do-selective-display
  962.     Non-nil means fake `selective-display' in the `ibuff-menu' buffer.
  963.     It defaults to non-nil if the value of `emacs-version' contains the
  964.     string \"Lucid\". Set it to nil if your version of Lucid Emacs
  965.     supports `selective-display'.
  966. \040
  967. PRECISE BINDINGS
  968. \\{ibuff-menu-mode-map}"
  969.  
  970.   (interactive "P")
  971.   (kill-all-local-variables)
  972.   (use-local-map ibuff-menu-mode-map)
  973.   (make-local-variable 'scroll-step)
  974.   (make-local-variable 'revert-buffer-function)
  975.   (make-local-variable 'zmacs-regions)    ; Lucid
  976.   (setq truncate-lines t
  977.     buffer-read-only t
  978.     scroll-step 2
  979.     revert-buffer-function 'ibuff-revert-menu
  980.     zmacs-regions nil        ; Lucid -- for apply-command-region
  981.     selective-display t
  982.     selective-display-ellipses nil
  983.     major-mode 'ibuff-menu-mode
  984.     mode-name "iBM")
  985.   (if (or (< preserve 0) (not ibuff-rc-loaded))
  986.       (load ibuff-source-file-name t))
  987.   (setq ibuff-rc-loaded t)
  988.   ;; Init variables that cannot have preloaded values
  989.   ;; (in the case ibuff-menu is preloaded in a dumped out Emacs)
  990.   (or (consp ibuff-mode-ring)
  991.       (setq ibuff-mode-ring
  992.         (apply 'nconc
  993.            (mapcar (function
  994.                 (lambda (key)
  995.                   (let ((mode (assq key
  996.                         ibuff-standard-sublist-modes)))
  997.                 (and mode (list (cdr mode))))))
  998.                (or ibuff-initial-sublist-modes "b")))))
  999.   (or (stringp ibuff-user-home-directory)
  1000.       (setq ibuff-user-home-directory (regexp-quote (expand-file-name "~"))))
  1001.   (or (and (bufferp ibuff-killed-buffer)
  1002.        (buffer-name ibuff-killed-buffer))
  1003.       (save-excursion
  1004.     (setq ibuff-killed-buffer (get-buffer-create " #<killed buffer>"))
  1005.     (ibuff-flush-undo (set-buffer ibuff-killed-buffer))
  1006.     (setq buffer-read-only nil)
  1007.     (erase-buffer)
  1008.     (insert "\
  1009. \(Stands for a buffer killed from within `ibuff-menu'.\)\n")
  1010.     (setq buffer-read-only t)
  1011.     (set-buffer-modified-p nil)
  1012.     (bury-buffer ibuff-killed-buffer)))
  1013.   (or (and (> preserve 0) (consp ibuff-mode-ring-ptr))
  1014.       (setq ibuff-mode-ring-ptr ibuff-mode-ring))
  1015.   (or (and (> preserve 0) (consp ibuff-match-stack-ptr))
  1016.       (setq ibuff-match-stack-ptr ibuff-match-stack
  1017.         ibuff-move-down-stack nil))
  1018.   (or (> preserve 0) (setq ibuff-widen nil))
  1019.   (or (mark) (set-mark 1))
  1020.   (run-hooks 'ibuff-menu-mode-hook))
  1021.  
  1022.  
  1023. ;;;; AUXILIARY FUNCTIONS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1024.  
  1025. ;;; Macros that can be applied after a regexp match with ibuff-line-regexp
  1026.  
  1027. (defmacro ibuff-get-index ()
  1028.   (` (char-after (match-beginning 0))))
  1029.  
  1030. (defmacro ibuff-get-delete-flag ()
  1031.   (` (char-after (match-beginning 1))))
  1032.  
  1033. (defmacro ibuff-put-delete-flag (flag)
  1034.   (` (let (buffer-read-only)
  1035.        (goto-char (match-beginning 1))
  1036.        (delete-char 1)
  1037.        (insert (, flag)))))
  1038.  
  1039. (defmacro ibuff-get-save-flag ()
  1040.   (` (char-after (1+ (match-beginning 1)))))
  1041.  
  1042. (defmacro ibuff-put-save-flag (flag)
  1043.   (` (let (buffer-read-only)
  1044.        (goto-char (1+ (match-beginning 1)))
  1045.        (delete-char 1)
  1046.        (insert (, flag)))))
  1047.  
  1048. (defmacro ibuff-get-read-only-flag ()
  1049.   (` (char-after (1- (match-end 1)))))
  1050.  
  1051. (defmacro ibuff-get-end-of-line ()
  1052.   (` (match-beginning 2)))
  1053.  
  1054. (defun ibuff-get-buffer-marker (&optional pos)
  1055.   ;; Return (MARKER . BUFFER) cell for buffer in line or at position.
  1056.   ;; Can be applied after a match by a menu line regexp
  1057.   (let ((list ibuff-buffer-markers))
  1058.     (or pos (setq pos (1+ (match-end 1))))
  1059.     (while (and list (not (= pos (car (car list)))))
  1060.       (setq list (cdr list)))
  1061.     (car-safe list)))
  1062.  
  1063. (defmacro ibuff-get-buffer ()
  1064.   ;; Can be applied after a match by a menu line regexp
  1065.   (` (cdr-safe (ibuff-get-buffer-marker))))
  1066.  
  1067. ;;; Miscellaneous
  1068.  
  1069. (defun ibuff-enqueue-buffer (b)
  1070.   ;; Insert BUFFER in `ibuff-buffer-queue'
  1071.   (setq ibuff-buffer-queue-ptr (% (1+ ibuff-buffer-queue-ptr)
  1072.                   (length ibuff-buffer-queue)))
  1073.   (aset ibuff-buffer-queue ibuff-buffer-queue-ptr b))
  1074.  
  1075. (defun ibuff-use-count (b)
  1076.   ;; Weighted use count of buffer.
  1077.   (let ((i 0)
  1078.     (len (length ibuff-buffer-queue))
  1079.     (count 0))
  1080.     (while (< i len)
  1081.       (if (eq (aref ibuff-buffer-queue i) b)
  1082.       (setq count (1+ count)))
  1083.       (setq i (1+ i)))
  1084.     (/ (* count (max 20 (min 0 ibuff-use-count-effect))) 10)))
  1085.  
  1086. (defun ibuff-bury-buffers ()
  1087.   ;; Buries all buffers that match `ibuff-bury-buffers-regexp'.
  1088.   (if (and ibuff-bury-buffers ibuff-bury-buffers-regexp)
  1089.       (let ((list (buffer-list)))
  1090.     (while list
  1091.       (if (string-match ibuff-bury-buffers-regexp
  1092.                 (buffer-name (car list)))
  1093.           (bury-buffer (car list)))
  1094.       (setq list (cdr list))))))
  1095.  
  1096. (defun ibuff-read-command (prompt)
  1097.   ;; Read an `ibuff-menu' command key sequence and return the command
  1098.   ;; if it has the ibuff-applicable property.
  1099.   ;; Return the command name as a string on failure.
  1100.  
  1101.   (let ((key "")
  1102.     (cursor-in-echo-area t)
  1103.     com)
  1104.     (discard-input)
  1105.     (setq prefix-arg nil)
  1106.     (while (progn
  1107.          (setq key (read-key-sequence prompt)
  1108.            com (key-binding key))
  1109.          (memq com '(universal-argument negative-argument digit-argument)))
  1110.       (setq prompt (format "%s %s" prompt (key-description key)))
  1111.       (command-execute com)
  1112.       (if (eq com 'digit-argument)
  1113.       (discard-input)))
  1114.     (if (and (symbolp com) (get com 'ibuff-applicable))
  1115.     com
  1116.       (prin1-to-string com))))
  1117.  
  1118. (defun ibuff-adjust-point (&optional keep-goal-pos)
  1119.   ;; Find nearest valid menu line, adjust point and update mode line.
  1120.   ;; Numbers menu lines if necessary.
  1121.  
  1122.   (if ibuff-command-application
  1123.       ()
  1124.     (if ibuff-numbers-changed
  1125.     (progn
  1126.       (ibuff-number-lines)
  1127.       (setq ibuff-numbers-changed nil)))
  1128.     ;; Point adjustment
  1129.     (beginning-of-line)
  1130.     (if (or (looking-at ibuff-line-regexp)
  1131.         (re-search-forward ibuff-line-regexp nil t)
  1132.         (re-search-backward ibuff-line-regexp nil t))
  1133.     (let ((mark (ibuff-get-buffer-marker)))
  1134.       (goto-char (1+ (match-beginning 0)))
  1135.       (or keep-goal-pos
  1136.           (setq ibuff-goal-marker (car mark)))
  1137.       (ibuff-update-mode-line (cdr mark))))
  1138.     ;; Scroll away menu headers if window is small
  1139.     (if (>= ibuff-menu-lines (window-height))
  1140.     (set-window-start (selected-window)
  1141.               (save-excursion
  1142.                 (goto-char (point-min))
  1143.                 (forward-line 2)
  1144.                 (point))
  1145.               t)
  1146.       (set-window-start (selected-window) (point-min) t))
  1147.     (or (pos-visible-in-window-p) (recenter (- scroll-step)))))
  1148.  
  1149. (defun ibuff-update-mode-line (buff)
  1150.   ;; Update the mode-line format.
  1151.  
  1152.   (let ((name (buffer-name buff)))
  1153.     (or name
  1154.     (message "Buffer has already been killed."))
  1155.     ;; Buffer name and size
  1156.     (if ibuff-show-buffer-in-mode-line
  1157.     (let ((size (and name
  1158.              (save-excursion (set-buffer name) (buffer-size)))))
  1159.       (setq mode-line-format ibuff-mode-line-format
  1160.         ibuff-current-buffer-name (or name "?"))
  1161.       (or (eq size ibuff-current-buffer-size)
  1162.           (setq ibuff-current-buffer-size size
  1163.             ibuff-current-buffer-size-string
  1164.             (if size (int-to-string size) "?"))))
  1165.       (setq mode-line-format ibuff-fixed-mode-line-format))
  1166.  
  1167.     ;; match level indication
  1168.     (let ((level (- (length ibuff-match-stack)
  1169.             (length ibuff-match-stack-ptr)))
  1170.       (match (car ibuff-match-stack-ptr)))
  1171.       (or (= level ibuff-match-level)
  1172.       (setq ibuff-match-level level
  1173.         ibuff-match-level-string
  1174.         (if (= level 0) "-" (int-to-string level))))
  1175.       (setq ibuff-current-match-name
  1176.         (cond ((null match)
  1177.            "------")
  1178.           ((eq (car-safe match) 'ibuff-narrow-to-buffers-inverse)
  1179.            "hide  ")
  1180.           (t
  1181.            "match "))))
  1182.  
  1183.     ;; sublist mode indication
  1184.     (setq ibuff-current-mode-name (cdr (car ibuff-mode-ring-ptr)))
  1185.     (set-buffer-modified-p (buffer-modified-p))))
  1186.  
  1187. (defun ibuff-set-mark (&optional pos)
  1188.   (let ((opos (point)))
  1189.     (and pos (goto-char pos))
  1190.     (beginning-of-line)
  1191.     (if (looking-at ibuff-line-regexp)
  1192.     (progn
  1193.       (goto-char (1+ (match-beginning 0)))
  1194.       (or (= (point) (or (mark) 0))
  1195.           (push-mark (point) t))
  1196.       (message "Mark at %c" (ibuff-get-index))))
  1197.     (goto-char opos)))
  1198.  
  1199. (defun ibuff-do-mark (flag arg)
  1200.   ;; Guts of all mark setting commands, incl. unmark.
  1201.   ;; arg is the prefix argument as described in
  1202.   ;; `ibuff-mark-delete-pre-set-prefix'
  1203.   ;; `ibuff-no-flag' as first arg means unmark.
  1204.  
  1205.   (let ((move 0)
  1206.     (opos (point))
  1207.     set delete)
  1208.     (if (consp arg)
  1209.     (if (> (prefix-numeric-value arg) 4)
  1210.         (setq delete t)
  1211.       (setq set t))
  1212.       (if arg
  1213.       (if (eq arg t)
  1214.           (setq move 1)
  1215.         (setq move (prefix-numeric-value arg)))))
  1216.     (forward-line (if (<= move 0) move 0))
  1217.     (if (looking-at ibuff-line-regexp)
  1218.     (let* ((index (ibuff-get-index))
  1219.            (kill (ibuff-get-delete-flag))
  1220.            (save (ibuff-get-save-flag))
  1221.            (read (ibuff-get-read-only-flag))
  1222.            (mark (ibuff-get-buffer-marker))
  1223.            (buff (cdr mark))
  1224.            buffer-read-only)
  1225.       (if (buffer-name buff)
  1226.           (progn
  1227.         (cond ((or (eq flag ibuff-delete-flag)
  1228.                (eq flag ibuff-display-flag))
  1229.                (setq kill (cond (set flag)
  1230.                     (delete nil)
  1231.                     ((not (eq kill flag)) flag))))
  1232.               ((eq flag ibuff-save-flag)
  1233.                (setq save (cond (set flag)
  1234.                     (delete nil)
  1235.                     ((not (eq save flag)) flag))))
  1236.               ((eq flag ibuff-modified-flag)
  1237.                (setq save (cond (set flag)
  1238.                     (delete ibuff-no-flag)
  1239.                     ((not (eq save flag)) flag)
  1240.                     (ibuff-no-flag))))
  1241.               ((eq flag ibuff-read-only-flag)
  1242.                (setq read (cond (set flag)
  1243.                     (delete ibuff-no-flag)
  1244.                     ((not (eq read flag)) flag)
  1245.                     (ibuff-no-flag))))
  1246.               ((eq flag ibuff-no-flag)
  1247.                (setq kill (cond (set flag)
  1248.                     (delete flag))
  1249.                  save kill
  1250.                  read kill)))
  1251.         (delete-region (match-beginning 0) (ibuff-get-end-of-line))
  1252.         (set-marker (car mark)
  1253.                 (ibuff-format-line buff index kill save read ""))
  1254.         ))))
  1255.     (goto-char opos)
  1256.     (if (> move 0)
  1257.     (forward-line move))
  1258.     (ibuff-adjust-point)))
  1259.  
  1260. (defun ibuff-select-buffer (mode)
  1261.   ;; Select this buffer, perform requests and display buffers with MODE.
  1262.   ;; MODE is described in `ibuff-show-buffers'.
  1263.   (beginning-of-line)
  1264.   (if (looking-at ibuff-line-regexp)
  1265.       (let ((buff (ibuff-get-buffer)))
  1266.     (if (buffer-name buff)
  1267.         (progn
  1268.           (ibuff-put-delete-flag ibuff-no-flag)
  1269.           (ibuff-show-buffers (cons buff (ibuff-parse)) mode))
  1270.       (ibuff-adjust-point)))
  1271.     (ibuff-adjust-point)))
  1272.  
  1273.  
  1274. ;;;; WINDOW MANAGEMENT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1275.  
  1276. (defun ibuff-window-list ()
  1277.   ;; Return a list of the currently displayed windows
  1278.  
  1279.   (let* ((focus (selected-window))
  1280.      (win (next-window focus))
  1281.      (windows (list focus)))
  1282.     (while (not (eq focus win))
  1283.       (setq windows (cons win windows)
  1284.         win (next-window win)))
  1285.     (delq (minibuffer-window) windows)))
  1286.  
  1287. (defun ibuff-save-window-configuration ()
  1288.   ;; Stores window configuration and makes a list of displayed buffers
  1289.   (setq ibuff-last-window-configuration (current-window-configuration)
  1290.     ibuff-last-buffers (mapcar 'window-buffer (ibuff-window-list))))
  1291.  
  1292. (defun ibuff-restore-window-configuration ()
  1293.   ;; Restores last window config if it does not refer to killed buffers.
  1294.   ;; Epoch 4.2 can crash under certain circumstances if such a window
  1295.   ;; configuration is restored.
  1296.   (let ((ok t)
  1297.     (list ibuff-last-buffers)
  1298.     win)
  1299.     (while list
  1300.       (or (buffer-name (car list))
  1301.       (setq ok nil))
  1302.       (setq list (cdr list)))
  1303.     (if ok
  1304.     (set-window-configuration ibuff-last-window-configuration)
  1305.       (message "\
  1306. Not save to restore window configuration because of killed buffers."))
  1307.     (while (setq win (get-buffer-window ibuff-buffer-name))
  1308.       (set-window-buffer win ibuff-killed-buffer))))
  1309.  
  1310. (defun ibuff-pop-up ()
  1311.   ;; Pop up `ibuff-menu' window and adjust its size.
  1312.   ;; Always pop up in a bottom window.
  1313.   (let ((lower (function (lambda (a b) (> (nth 3 (window-edges a))
  1314.                       (nth 3 (window-edges b))))))
  1315.     (window (get-buffer-window ibuff-buffer-name)))
  1316.     (if window
  1317.     (progn
  1318.       (select-window window)
  1319.       (ibuff-adjust-window t))
  1320.       (select-window (car (sort (ibuff-window-list) lower)))
  1321.       (ibuff-adjust-window))))
  1322.  
  1323. (defun ibuff-adjust-window (&optional no-shrink)
  1324.   ;; Adjust `ibuff-menu' window height, assuming it is the bottom window.
  1325.   ;; Set the window buffer for `ibuff-menu'.
  1326.   ;; Non-nil NO-SHRINK means don't make the window smaller.
  1327.  
  1328.   (set-buffer ibuff-buffer-name)
  1329.   (setq ibuff-menu-lines
  1330.     ;; Lucid Emacs has a brain damaged count-line function
  1331.     ;; that also counts CR if selective-display is t
  1332.     (save-excursion
  1333.       (goto-char (point-min))
  1334.       (- (buffer-size) (forward-line (buffer-size)))))
  1335.   (let (goalh maxh win start)
  1336.     (cond ((eq t ibuff-restrict-window-height)
  1337.        (setq goalh (min (/ (screen-height) 2) (1+ ibuff-menu-lines))))
  1338.       ((integerp ibuff-restrict-window-height)
  1339.        (setq goalh (min ibuff-restrict-window-height
  1340.                 (1+ ibuff-menu-lines))))
  1341.       (t
  1342.        (setq goalh (1+ ibuff-menu-lines))))
  1343.     (setq goalh (min (1- (screen-height)) (max window-min-height goalh))
  1344.       maxh (+ goalh (1- window-min-height)))
  1345.     ;; adjust size
  1346.     (cond ((> goalh (window-height))
  1347.        (enlarge-window (- goalh (window-height))))
  1348.       ((and (> (window-height) maxh) (null no-shrink))
  1349.        (setq start (window-start))
  1350.        (setq win (split-window nil (- (window-height) goalh)))
  1351.        (set-window-start (selected-window) start)
  1352.        (select-window win)))
  1353.     ;; make the window screen-wide
  1354.     (or (= (window-width) (screen-width))
  1355.     (enlarge-window (screen-width) t))
  1356.     (set-window-buffer (selected-window) ibuff-buffer-name)))
  1357.  
  1358. (defun ibuff-show-buffers (buffers &optional mode)
  1359.   ;; Display buffers; adapt previous window configuration.
  1360.   ;; Mode means:
  1361.   ;; nil:    display the buffers in the list only;
  1362.   ;; t:        additional display the buffers in the list;
  1363.   ;; (else):    additional display the buffers in the list, but
  1364.   ;;        put the first buffer in the previously selected window.
  1365.  
  1366.   ;; Previous window config has already been restored by `ibuff-parse'
  1367.   (if (null buffers)
  1368.       (delete-windows-on ibuff-killed-buffer)
  1369.     (let* ((blist buffers)
  1370.        (first (car buffers))
  1371.        (focus (selected-window))
  1372.        (adjust ibuff-adjust-window-heights)
  1373.        (minh (* 2 window-min-height))
  1374.        (larger (function
  1375.             (lambda (a b)
  1376.               (let* ((aw (car a))
  1377.                  (bw (car b))
  1378.                  dh dw)
  1379.             (if (window-point aw)
  1380.                 (or (null (window-point bw))
  1381.                 (progn
  1382.                   (setq dw (- (window-width aw)
  1383.                           (window-width bw))
  1384.                     dh (- (window-height aw)
  1385.                           (window-height bw)))
  1386.                   (if adjust
  1387.                       (or (> dw 0) (and (= 0 dw) (> dh 0)))
  1388.                     (or (> dh 0) (and (= 0 dh) (> dw 0))))
  1389.                   )))))))
  1390.        (largest (function
  1391.              (lambda (list)
  1392.                (let (best)
  1393.              (setq best (car list)
  1394.                    list (cdr list))
  1395.              (while list
  1396.                (if (funcall larger (car list) best)
  1397.                    (setq best (car list)))
  1398.                (setq list (cdr list)))
  1399.              best))))
  1400.        wlist wl w goalh loop count)
  1401.  
  1402.       ;; Record buffer in use count queue
  1403.       (ibuff-enqueue-buffer first)
  1404.  
  1405.       ;; Replace buffer in selected window
  1406.       (if (and mode (not (eq mode t)))
  1407.       (progn
  1408.         (set-window-buffer focus first)
  1409.         (setq blist (cdr blist))))
  1410.  
  1411.       ;; Associate windows with buffers
  1412.       (if mode
  1413.       ;; Preserve displayed buffers
  1414.       (setq wlist (mapcar (function
  1415.                    (lambda (w)
  1416.                  (let ((b (window-buffer w)))
  1417.                    (if (eq b ibuff-killed-buffer)
  1418.                        (cons w nil)
  1419.                      (cons w b)))))
  1420.                   (ibuff-window-list)))
  1421.     ;; Preserve windows for already displayed buffers in the list,
  1422.     ;; but remove the others.
  1423.     (setq wlist (mapcar (function
  1424.                  (lambda (w)
  1425.                    (let ((b (window-buffer w)))
  1426.                  (if (memq b blist)
  1427.                      (cons w b)
  1428.                    (cons w nil)))))
  1429.                 (ibuff-window-list))))
  1430.  
  1431.       ;; Remove buffers from list which have a window.
  1432.       ;; Cannot be done above, because a buffer may have multiple windows.
  1433.       (setq blist (apply 'nconc
  1434.              (mapcar (function
  1435.                   (lambda (b)
  1436.                     (and (null (rassq b wlist)) (list b))))
  1437.                  blist)))
  1438.  
  1439.       ;; Recycle free windows, delete superfluous ones
  1440.       (setq wlist
  1441.         (apply 'nconc
  1442.            (mapcar
  1443.             (function
  1444.              (lambda (c)
  1445.                (let ((w (car c))
  1446.                  (b (cdr c)))
  1447.              (if (not (or blist b))
  1448.                  (and (window-point w) (delete-window w)) ;= nil
  1449.                (if (or b (null (window-point w)))
  1450.                    ()
  1451.                  ;; Recycle
  1452.                  (if (and adjust
  1453.                       (< (window-width w) (screen-width)))
  1454.                  ;; Ensure that window is screen wide
  1455.                  (progn
  1456.                    (select-window w)
  1457.                    (enlarge-window (screen-width) t)))
  1458.                  (setcdr c (car blist))
  1459.                  (setq blist (cdr blist)))
  1460.                (list c)))))
  1461.             (sort wlist larger))))
  1462.  
  1463.       ;; Create windows for remaining buffers
  1464.       (mapcar (function
  1465.            (lambda (b)
  1466.          ;; Split largest windows for remaining buffers
  1467.          (setq w (car (funcall largest wlist))) ; cannot be void
  1468.          ;; Ensure that window is high enough
  1469.          (if (< (window-height w) minh)
  1470.              (progn
  1471.                (select-window w)
  1472.                (enlarge-window (- minh (window-height w)))))
  1473.          ;; Ensure that window is as wide as screen
  1474.          (if (and adjust (< (window-width w) (screen-width)))
  1475.              (progn
  1476.                (select-window w)
  1477.                (enlarge-window (screen-width) t)))
  1478.          ;; Split window
  1479.          (if (>= (window-height w) minh) ; sic! -- enlarge can fail
  1480.              (setq wlist (cons (cons (split-window w) b) wlist))
  1481.            (message "OOPS!"))))
  1482.           blist)
  1483.  
  1484.       ;; Equalize window heights
  1485.       (if (or (eq adjust t)
  1486.           (and adjust blist))    ; new windows created
  1487.       (progn
  1488.         ;; Determine average height
  1489.         (setq count 0
  1490.           wl wlist)
  1491.         (while wl
  1492.           (setq w (car (car wl))
  1493.             wl (cdr wl))
  1494.           (if (and (window-point w)
  1495.                (eq 0 (nth 0 (window-edges w))))
  1496.           (setq count (1+ count))))
  1497.         (setq goalh (max window-min-height
  1498.                  (/ (+ (/ count 2) (screen-height)) count)))
  1499.         ;; Adjust heights
  1500.         (setq loop t
  1501.           count 3)        ; up to 3 consecutive runs
  1502.         (while (and loop (> count 0))
  1503.           (setq loop nil
  1504.             count (1- count))
  1505.           (mapcar (function
  1506.                (lambda (c)
  1507.              (let ((w (car c)))
  1508.                (if (and (window-point w)
  1509.                     (or (< (window-height w) (1- goalh))
  1510.                     (> (window-height w) (1+ goalh))))
  1511.                    (progn
  1512.                  (select-window w)
  1513.                  (enlarge-window (- goalh (window-height w)))
  1514.                  (setq loop t))))))
  1515.               wlist))))
  1516.  
  1517.       ;; Reorder the window list according to the original buffer list
  1518.       (mapcar (function
  1519.            (lambda (b)
  1520.          (let ((c (rassq b wlist)))
  1521.            (if c
  1522.                (setq wlist (cons c (delq c wlist)))))))
  1523.           (nreverse buffers))
  1524.  
  1525.       ;; Switch to buffers
  1526.       (mapcar (function
  1527.            (lambda (c)
  1528.          (let ((w (car c))
  1529.                (b (cdr c)))
  1530.            (if (window-point w)
  1531.                (progn
  1532.              (select-window w)
  1533.              (switch-to-buffer b (not (memq b buffers))))
  1534.              (message "OOPS!")))))
  1535.           (nreverse wlist))
  1536.       (if (and (window-point focus)
  1537.            (eq first (window-buffer focus)))
  1538.       (progn
  1539.         (select-window focus)
  1540.         (switch-to-buffer first))))))
  1541.  
  1542.  
  1543. ;;;; BUFFER PREPARATION AND PARSING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1544.  
  1545. (defun ibuff-format (idx f1 f2 f3 buff mode file eol)
  1546.   ;; Insert INDEX FLAG1 FLAG2 FLAG3 BUFFER-NAME MODE FILE-NAME EOL
  1547.   ;; into the `ibuff-menu' buffer.
  1548.   ;; buffer name, mode, and file name must be strings. The other args
  1549.   ;; may be characters.
  1550.   ;; Abbreviates or ommits mode if buffer name is to long.
  1551.   ;; Abbreviates buffer name if too long.
  1552.   ;; Replaces home directory in file name by a tilde.
  1553.   ;; Returns position of begin of buffer name.
  1554.  
  1555.   (let ((obuff (current-buffer))
  1556.     pos col)
  1557.     (set-buffer ibuff-buffer-name)
  1558.     (insert idx ": " f1 f2 f3 ? )
  1559.     (prog1
  1560.     (point)
  1561.       (insert buff ? )
  1562.       (setq col (indent-to 32))
  1563.       (if (= col 32)            ; ommit mode if buffer name too long
  1564.       (insert mode ? ))
  1565.       (setq col (indent-to ibuff-file-name-column))
  1566.       (if (and (> col ibuff-file-name-column)
  1567.            (> (length file) 0))
  1568.       (progn            ; abbreviate mode or buffer name
  1569.         (delete-char (- ibuff-file-name-column col 1))
  1570.         (insert ? )))
  1571.       (setq pos (point))
  1572.       (insert file)
  1573.       (if (eq 0 (string-match ibuff-user-home-directory file))
  1574.       (save-excursion
  1575.         (goto-char pos)
  1576.         (delete-char (match-end 0))
  1577.         (insert ?~)))
  1578.       (if ibuff-cannot-do-selective-display ; Lucid Emacs 19.4
  1579.       (indent-to (1- (screen-width))))
  1580.       (insert eol)
  1581.       (set-buffer obuff))))
  1582.  
  1583. (defun ibuff-format-line (buffer &optional index flag1 flag2 flag3 eol)
  1584.   ;; Insert a menu line for buffer.
  1585.   ;; Optional args overwrite the values derived from buffer.
  1586.   ;; Returns position of buffer name.
  1587.  
  1588.   (let* ((obuff (current-buffer))
  1589.      (buff (get-buffer buffer))
  1590.      (name (buffer-name buffer))
  1591.      proc)
  1592.     (set-buffer buff)
  1593.     (prog1
  1594.     (ibuff-format (or index ibuff-no-flag)
  1595.               (or flag1
  1596.               (and (memq buff ibuff-last-buffers)
  1597.                    ibuff-visible-flag)
  1598.               ibuff-no-flag)
  1599.               (or flag2
  1600.               (and (buffer-modified-p buff) ibuff-modified-flag)
  1601.               ibuff-no-flag)
  1602.               (or flag3
  1603.               (and buffer-read-only ibuff-read-only-flag)
  1604.               ibuff-no-flag)
  1605.               name
  1606.               mode-name
  1607.               (or buffer-file-name
  1608.               (and (boundp 'list-buffers-directory)
  1609.                    (stringp list-buffers-directory)
  1610.                    list-buffers-directory)
  1611.               (and (setq proc (get-buffer-process buff))
  1612.                    (format "(%s %s %s)"
  1613.                        (process-id proc)
  1614.                        (process-status proc)
  1615.                        (process-name proc)))
  1616.               (and (eq major-mode 'dired-mode)
  1617.                    default-directory)
  1618.               "")
  1619.               (or eol ?\n))
  1620.       (set-buffer obuff))))
  1621.  
  1622. (defun ibuff-format-menu (buffers)
  1623.   ;; Insert a menu description header and the menu lines for all buffers.
  1624.   ;; Does not number the lines.
  1625.   ;; Recycles old (MARKER. BUFFER) cells.
  1626.  
  1627.   (set-buffer ibuff-buffer-name)
  1628.   (let ((oldmarkers ibuff-buffer-markers)
  1629.     cell buffer-read-only)
  1630.     (erase-buffer)
  1631.     (ibuff-format ?# ?D ?M ?R "Buffer" "Mode" "File/Directory/Process" ?\n)
  1632.     (ibuff-format ?- ?- ?- ?- "------" "----" "----------------------" ?\n)
  1633.     (setq ibuff-buffer-markers
  1634.       (mapcar (function
  1635.            (lambda (b)
  1636.              (if oldmarkers
  1637.              (progn
  1638.                (setq cell (car oldmarkers)
  1639.                  oldmarkers (cdr oldmarkers))
  1640.                (set-marker (car cell) (ibuff-format-line b))
  1641.                (setcdr cell b)
  1642.                cell)
  1643.                (cons (copy-marker (ibuff-format-line b)) b))))
  1644.           buffers))))
  1645.  
  1646. (defun ibuff-number-lines ()
  1647.   ;; Generate or rearrange the line numbers in proper order.
  1648.   (let ((index 0)
  1649.     (limit (length ibuff-line-numbers))
  1650.     buffer-read-only)
  1651.     (save-excursion
  1652.       (goto-char (point-min))
  1653.       (forward-line 2)
  1654.       (while (and (< index limit) (not (eobp)))
  1655.     (delete-char 1)
  1656.     (insert (aref ibuff-line-numbers index))
  1657.     (setq index (1+ index))
  1658.     (forward-line 1))
  1659.       (while (not (eobp))
  1660.     (delete-char 1)
  1661.     (insert ? )
  1662.     (forward-line 1)))))
  1663.  
  1664. (defun ibuff-parse ()
  1665.   ;; Parse buffer contents and perform all requests indicated by flags.
  1666.   ;; Return the list of buffers which should be displayed.
  1667.  
  1668.   ;; First restore window configuration, because killing of buffers
  1669.   ;; requires special treatment if such buffers are displayed in a
  1670.   ;; window. These windows are kept, so that they can be recycled, but
  1671.   ;; their buffers are temporarily set to `ibuff-killed-buffer'.
  1672.   ;; ibuff-show-buffers will replace them or will delete the windows.
  1673.  
  1674.   (let ((markers ibuff-buffer-markers)
  1675.     display delete win mark)
  1676.     (ibuff-restore-window-configuration)
  1677.     (set-buffer ibuff-buffer-name)
  1678.     (ibuff-widen)
  1679.     (while markers
  1680.       (setq mark (car markers)
  1681.         markers (cdr markers))
  1682.       (goto-char (car mark))
  1683.       (beginning-of-line)
  1684.       (if (looking-at ibuff-line-regexp)
  1685.       (let* ((kill (ibuff-get-delete-flag))
  1686.          (save (ibuff-get-save-flag))
  1687.          (read (ibuff-get-read-only-flag))
  1688.          (buff (cdr mark))
  1689.          (name (buffer-name buff)))
  1690.         (if name
  1691.         (save-excursion
  1692.           (set-buffer buff)
  1693.           (if (eq read ibuff-read-only-flag)
  1694.               (setq buffer-read-only t)
  1695.             (setq buffer-read-only nil))
  1696.           (cond ((eq save ibuff-modified-flag)
  1697.              (set-buffer-modified-p t))
  1698.             ((eq save ibuff-no-flag)
  1699.              (set-buffer-modified-p nil))
  1700.             (t
  1701.              (set-buffer-modified-p t) ; force save
  1702.              (if buffer-file-name
  1703.                  (save-buffer)
  1704.                (write-file (read-file-name (format "\
  1705. File to save buffer %s in: " name))))))
  1706.           (cond ((eq kill ibuff-delete-flag)
  1707.              (setq delete (cons buff delete)))
  1708.             ((eq kill ibuff-display-flag)
  1709.              (setq display (cons buff display)))))))))
  1710.     (setq delete (delq ibuff-killed-buffer delete))
  1711.     (while delete
  1712.       (let ((buff (car delete)))
  1713.     (while (setq win (get-buffer-window buff))
  1714.       (set-window-buffer win ibuff-killed-buffer))
  1715.     (kill-buffer buff)
  1716.     (setq delete (cdr delete))))
  1717.     display))
  1718.  
  1719.  
  1720. ;;;; SELECTIVE DISPLAY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1721.  
  1722. (defun ibuff-narrow-to-predicate (predicate)
  1723.   ;; Restrict visible menu lines to buffers that satisfy predicate.
  1724.   ;; Predicate is called with on e arg, the buffer-marker.
  1725.   ;; Point is at the beginning of line when predicate is called.
  1726.   ;; Returns t if at least one line keeps visible.
  1727.  
  1728.   (let ((list ibuff-buffer-markers)
  1729.     ok buffer-read-only)
  1730.     (save-excursion
  1731.       (while list
  1732.     (goto-char (car (car list)))
  1733.     (skip-chars-backward "^\r\n")
  1734.     (if (eq (preceding-char) ?\n)    ; visible line
  1735.         (if (funcall predicate (car list))
  1736.         (setq ok t)
  1737.           (delete-char -1)
  1738.           (insert ?\r)))
  1739.     (setq list (cdr list))))
  1740.     ok))
  1741.  
  1742. (defun ibuff-widen ()
  1743.   ;; Unconditionally display all buffers.
  1744.   (let ((buffer-read-only nil))
  1745.     (subst-char-in-region (point-min) (point-max) ?\r ?\n)
  1746.     t))
  1747.  
  1748. (defun ibuff-narrow-to-dired ()
  1749.   (ibuff-narrow-to-predicate
  1750.    (function (lambda (mark)
  1751.            (let ((buff (cdr mark)))
  1752.          (and (buffer-name buff)
  1753.               (save-excursion
  1754.             (set-buffer buff)
  1755.             (eq major-mode 'dired-mode))))))))
  1756.  
  1757. (defun ibuff-narrow-to-files ()
  1758.   (ibuff-narrow-to-predicate
  1759.    (function (lambda (mark)
  1760.            (let ((buff (cdr mark)))
  1761.          (and (buffer-name buff) (buffer-file-name buff)))))))
  1762.  
  1763. (defun ibuff-narrow-to-plain-buffers ()
  1764.   ;; no files, no dired
  1765.   (ibuff-narrow-to-predicate
  1766.    (function (lambda (mark)
  1767.            (let ((buff (cdr mark)))
  1768.          (and (buffer-name buff)
  1769.               (save-excursion
  1770.             (set-buffer buff)
  1771.             (not (or buffer-file-name
  1772.                  (eq major-mode 'dired-mode))))))))))
  1773.  
  1774. (defun ibuff-narrow-to-killed-buffers ()
  1775.   ;; to buffers flagged to be deleted
  1776.   (ibuff-narrow-to-predicate
  1777.    (function (lambda (_)
  1778.            (and (looking-at ibuff-line-regexp)
  1779.             (eq ibuff-delete-flag (ibuff-get-delete-flag)))))))
  1780.  
  1781. (defun ibuff-narrow-to-buffer-regexp (regexp)
  1782.   (ibuff-narrow-to-predicate
  1783.    (function (lambda (mark)
  1784.            (let ((name (buffer-name (cdr mark))))
  1785.          (and name (string-match regexp name)))))))
  1786.  
  1787. (defun ibuff-narrow-to-buffer-regexp-inverse (regexp)
  1788.   ;; Matches complement
  1789.   (ibuff-narrow-to-predicate
  1790.    (function (lambda (mark)
  1791.            (let ((name (buffer-name (cdr mark))))
  1792.          (and name (null (string-match regexp name))))))))
  1793.  
  1794. (defun ibuff-basic-narrow ()
  1795.   ;; Initial narrowing
  1796.   (ibuff-narrow-to-buffer-regexp-inverse ibuff-hide-buffers-regexp))
  1797.  
  1798. (defun ibuff-narrow-to-file-regexp (regexp)
  1799.   (ibuff-narrow-to-predicate
  1800.    (function (lambda (mark)
  1801.            (let ((buff (cdr mark))
  1802.              file)
  1803.          (and (buffer-name buff)
  1804.               (save-excursion
  1805.             (set-buffer buff)
  1806.             (setq file (or buffer-file-name
  1807.                        (and (eq major-mode 'dired-mode)
  1808.                         default-directory)))
  1809.             (and file (string-match regexp file)))))))))
  1810.  
  1811. (defun ibuff-narrow-to-file-regexp-inverse (regexp)
  1812.   ;; Matches complement
  1813.   (ibuff-narrow-to-predicate
  1814.    (function (lambda (mark)
  1815.            (let ((buff (cdr mark))
  1816.              file)
  1817.          (and (buffer-name buff)
  1818.               (save-excursion
  1819.             (set-buffer buff)
  1820.             (setq file (or buffer-file-name
  1821.                        (and (eq major-mode 'dired-mode)
  1822.                         default-directory)))
  1823.             (and file (null (string-match regexp file))))))))))
  1824.  
  1825. (defun ibuff-narrow-to-mode-regexp (regexp)
  1826.   ;; matches major mode names
  1827.   (ibuff-narrow-to-predicate
  1828.    (function (lambda (mark)
  1829.            (let ((buff (cdr mark)))
  1830.          (and (buffer-name buff)
  1831.               (save-excursion
  1832.             (set-buffer buff)
  1833.             (if (stringp mode-name)
  1834.                 (string-match regexp mode-name)
  1835.               (string-match regexp (symbol-name major-mode))
  1836.               ))))))))
  1837.  
  1838. (defun ibuff-narrow-to-mode-regexp-inverse (regexp)
  1839.   ;; matches complement
  1840.   (ibuff-narrow-to-predicate
  1841.    (function (lambda (mark)
  1842.            (let ((buff (cdr mark)))
  1843.          (and (buffer-name buff)
  1844.               (save-excursion
  1845.             (set-buffer buff)
  1846.             (null (if (stringp mode-name)
  1847.                   (string-match regexp mode-name)
  1848.                 (string-match regexp (symbol-name major-mode))
  1849.                 )))))))))
  1850.  
  1851. (defun ibuff-narrow-to-buffers-inverse (buffers)
  1852.   ;; hide all buffers in list
  1853.   (ibuff-narrow-to-predicate
  1854.    (function (lambda (mark) (null (memq (cdr mark) buffers))))))
  1855.  
  1856. ;;;; MODE RING AND MATCH STACK ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1857.  
  1858. (defun ibuff-forward-mode (n)
  1859.   ;; Switch to Nth next listing mode.
  1860.   (let* ((len (length ibuff-mode-ring))
  1861.      (pos (- len (length ibuff-mode-ring-ptr))))
  1862.     (setq pos (% (+ pos n) len))
  1863.     (if (< pos 0)
  1864.     (setq pos (% (+ pos len) len)))
  1865.     (setq ibuff-mode-ring-ptr (nthcdr pos ibuff-mode-ring))))
  1866.  
  1867. (defun ibuff-insert-mode (mode &optional before)
  1868.   ;; Store a sublist mode
  1869.   (if before
  1870.       (let ((ri ibuff-mode-ring)
  1871.         (rp ibuff-mode-ring-ptr))
  1872.     (if (eq ri rp)
  1873.         (setq ibuff-mode-ring (cons mode ri)
  1874.           ibuff-mode-ring-ptr ibuff-mode-ring)
  1875.       (while (not (eq (cdr ri) rp))
  1876.         (setq ri (cdr ri)))
  1877.       (setcdr ri (cons mode rp))
  1878.       (setq ibuff-mode-ring-ptr (cdr ri))))
  1879.     (setcdr ibuff-mode-ring-ptr (cons mode (cdr ibuff-mode-ring-ptr)))
  1880.     (setq ibuff-mode-ring-ptr (cdr ibuff-mode-ring-ptr))))
  1881.  
  1882. (defun ibuff-delete-mode ()
  1883.   ;; Delete current sublist mode.
  1884.   (let ((ri ibuff-mode-ring)
  1885.     (rp ibuff-mode-ring-ptr))
  1886.     (if (eq ri rp)
  1887.     (setq ibuff-mode-ring
  1888.           (or (cdr ri) (list (cdr (assq ?b ibuff-standard-sublist-modes))))
  1889.           ibuff-mode-ring-ptr ibuff-mode-ring)
  1890.       (while (not (eq (cdr ri) rp))
  1891.     (setq ri (cdr ri)))
  1892.       (setcdr ri (cdr rp))
  1893.       (setq ibuff-mode-ring-ptr (or (cdr ri) ibuff-mode-ring)))))
  1894.  
  1895. (defun ibuff-forward-match (n)
  1896.   ;; Move n positions in the match stack
  1897.   (let* ((st ibuff-match-stack)
  1898.      (sp ibuff-match-stack-ptr)
  1899.      (len (length st))
  1900.      (pos (- len (length sp))))
  1901.     (and ibuff-move-down-stack (setq n (- n)))
  1902.     (setq pos (max 0 (min (1- len) (+ pos n))))
  1903.     (setq sp (nthcdr pos st))
  1904.     (cond ((eq st sp)
  1905.        (setq ibuff-move-down-stack nil))
  1906.       ((null (cdr sp))
  1907.        (setq ibuff-move-down-stack t)))
  1908.     (setq ibuff-match-stack-ptr sp)))
  1909.  
  1910. (defun ibuff-push-match (function arg)
  1911.   ;; Push a closure (FUNCTION . ARG) on the match stack.
  1912.   ;; Discard previous matches of same and higher level.
  1913.   (setcdr ibuff-match-stack-ptr (list (cons function arg)))
  1914.   (setq ibuff-match-stack-ptr (cdr ibuff-match-stack-ptr)
  1915.     ibuff-move-down-stack t))
  1916.  
  1917. (defun ibuff-insert-current-configuration (name &optional before)
  1918.   ;; Store combination of match level and current sublist mode in the mode
  1919.   ;; ring.
  1920.   (let ((sp ibuff-match-stack-ptr)
  1921.     tail)
  1922.     (setq tail (cdr sp))
  1923.     (setcdr sp nil)
  1924.     (ibuff-insert-mode (cons (append (cdr ibuff-match-stack)
  1925.                      (car (car ibuff-mode-ring-ptr)))
  1926.                  name)
  1927.                before)
  1928.     (setcdr sp tail)))
  1929.  
  1930. (defun ibuff-eval-closure (closure)
  1931.   ;; Call (FUNCTION-SYMBOL . ARGUMENT) or FUNCTION-SYMBOL
  1932.   (cond ((consp closure)
  1933.      (funcall (car closure) (cdr closure)))
  1934.     ((fboundp closure)
  1935.      (funcall closure))
  1936.     (t)))
  1937.  
  1938. (defun ibuff-do-narrow ()
  1939.   ;; Try to narrow menu to current match level and sublist mode.
  1940.   ;; If a mode fails, i.e. results in an empty menu, the next modes
  1941.   ;; are tried until one succeeds.
  1942.   ;; If a match level fails, the match stack pointer is lowered.
  1943.   ;; If basic narrowing fails, it is disabled temporarily.
  1944.  
  1945.   (let ((widen ibuff-widen)
  1946.     mp st sp tail ok)
  1947.     (while (not ok)            ; ibuff-basic-narrow
  1948.       (while (not ok)            ; match levels
  1949.     (while (not ok)            ; mode ring
  1950.       (ibuff-widen)
  1951.       (setq ok t
  1952.         mp (car (car ibuff-mode-ring-ptr)))
  1953.       (while (and ok mp)
  1954.         (setq ok (ibuff-eval-closure (car mp))
  1955.           mp (cdr mp)))
  1956.       (or ok (ibuff-forward-mode 1)))
  1957.     ;; match levels
  1958.     (setq st ibuff-match-stack
  1959.           sp ibuff-match-stack-ptr
  1960.           tail (cdr sp))
  1961.     (setcdr sp nil)
  1962.     (while (and ok (cdr st))
  1963.       (if (setq ok (ibuff-eval-closure (car (cdr st))))
  1964.           (setq st (cdr st))))
  1965.     (setcdr sp tail)
  1966.     (or ok (setq ibuff-match-stack-ptr st
  1967.              ibuff-move-down-stack nil)))
  1968.       ;; basic narrowing
  1969.       (or widen
  1970.       (setq ok (ibuff-basic-narrow))
  1971.       (setq widen t)))
  1972.     (setq ibuff-numbers-changed t)))
  1973.  
  1974. (defun ibuff-do-match (function regexp)
  1975.   ;; Handle regexp narrowing
  1976.   (if (funcall function regexp)
  1977.       (progn
  1978.     (ibuff-push-match function regexp)
  1979.     (setq ibuff-numbers-changed t))
  1980.     (message "No match.")
  1981.     (ibuff-do-narrow)
  1982.     nil))
  1983.  
  1984. (defun ibuff-adjust-point-after-narrowing ()
  1985.   ;; Adjust point and window (if too small), don't change the goal buffer.
  1986.   (if ibuff-command-application
  1987.       ()
  1988.     (ibuff-adjust-window t)
  1989.     (goto-char ibuff-goal-marker)
  1990.     (skip-chars-backward "^\r\n")
  1991.     (or (looking-at ibuff-line-regexp)
  1992.     (goto-char (point-min)))
  1993.     (ibuff-adjust-point t)))
  1994.  
  1995.  
  1996. ;;;; COMMANDS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1997.  
  1998. (defun ibuff-revert-menu (&optional preserve &rest _)
  1999.   "Discard all requests and update `ibuff-menu'.
  2000. A positive prefix argument preserves previous match level and sublist mode.
  2001. A negative prefix argument forces to load `ibuff-source-file-name'."
  2002.  
  2003.   (interactive "P")
  2004.   (ibuff-bury-buffers)
  2005.   (bury-buffer (get-buffer-create ibuff-buffer-name))
  2006.   (let ((buffers (buffer-list)))
  2007.     (ibuff-flush-undo (set-buffer ibuff-buffer-name))
  2008.     (ibuff-menu-mode (if preserve (prefix-numeric-value preserve) 0))
  2009.     (ibuff-format-menu buffers)
  2010.     (ibuff-do-narrow)
  2011.     (ibuff-pop-up)
  2012.     (ibuff-propose-buffer)))
  2013.  
  2014. (defun ibuff-menu (&optional preserve)
  2015.   "Begin editing an indexed buffer menu that describes all Emacs buffers.
  2016. See \\[describe-function] ibuff-menu-mode for details.
  2017. Runs `ibuff-menu-hook' after the menu has been prepared.
  2018. A positive prefix argument preserves previous match level and sublist mode.
  2019. A negative prefix argument forces to load `ibuff-source-file-name'."
  2020.   (interactive "P")
  2021.   (ibuff-save-window-configuration)
  2022.   (ibuff-revert-menu preserve)
  2023.   (run-hooks 'ibuff-menu-hook))
  2024.  
  2025. (defun ibuff-brief-help (&optional time)
  2026.   "Cyclically display a set of brief instruction notes in the minibuffer.
  2027. Any key you type aborts this cycle and is then executed.
  2028. A numeric prefix argument specifies the time intervall in seconds."
  2029.  
  2030.   (interactive "P")
  2031.   (let ((mess ibuff-brief-help-messages)
  2032.     (loop t)
  2033.     (secs (or (and time (max 0 (prefix-numeric-value time))) 2))
  2034.     head)
  2035.     (while loop
  2036.       (setq head mess)
  2037.       (while (and loop head)
  2038.     (message (car head))
  2039.     (setq head (cdr head)
  2040.           loop (sit-for secs))))))
  2041.  
  2042. (defun ibuff-propose-buffer (&optional clear-queue)
  2043.   "Move point to a buffer which is a good candidate to be next selected.
  2044. The choice depends on how often you have switched to a particular
  2045. buffer the last time, whether it is already displayed or not and some
  2046. other characteristics.
  2047. A prefix argument clears the use counter for buffers previously switched to.
  2048. The command is automatically executed when you call `ibuff-menu' or
  2049. `ibuff-revert-menu'."
  2050.  
  2051.   (interactive "P")
  2052.   (if clear-queue
  2053.       (fillarray ibuff-buffer-queue nil))
  2054.   (let ((index 0)
  2055.     (max-weight -100000)
  2056.     (best-index 0)
  2057.     (visible-points (- (/ 10 (max 1 (length ibuff-last-buffers)))))
  2058.     weight)
  2059.     (goto-char (point-min))
  2060.     (while (re-search-forward ibuff-line-regexp nil t)
  2061.       (let ((kill (ibuff-get-delete-flag))
  2062.         (buff (ibuff-get-buffer)))
  2063.     (if (buffer-name buff)
  2064.         (progn
  2065.           (setq weight (+ (ibuff-use-count buff)
  2066.                   (if (eq kill ibuff-delete-flag) -10000 0)
  2067.                   (if (memq buff ibuff-last-buffers)
  2068.                   visible-points
  2069.                 0)
  2070.                   (if (eq index 0) -1000 (- index))))
  2071.           (if (> weight max-weight)
  2072.           (setq max-weight weight
  2073.             best-index index))))
  2074.     (setq index (1+ index))))
  2075.     (goto-char (point-min))
  2076.     (forward-line (+ 2 best-index))
  2077.     (ibuff-adjust-point)))
  2078.  
  2079. (defun ibuff-next-match-level (n)
  2080.   "Move prefix ARG positions up or down the match stack.
  2081. A negative argument also changes the direction for future calls of
  2082. this command."
  2083.   (interactive "p")
  2084.   (if (< n 0)
  2085.       (setq n (- n)
  2086.         ibuff-move-down-stack (not ibuff-move-down-stack)))
  2087.   (ibuff-forward-match n)
  2088.   (ibuff-do-narrow)
  2089.   (ibuff-adjust-point-after-narrowing))
  2090.  
  2091. (defun ibuff-next-sublist-mode (n)
  2092.   "Step prefix ARG positions through the sublist mode ring."
  2093.   (interactive "p")
  2094.   (ibuff-forward-mode n)
  2095.   (ibuff-do-narrow)
  2096.   (ibuff-adjust-point-after-narrowing))
  2097.  
  2098. (defun ibuff-toggle-hiding-buffers ()
  2099.   "Show buffers that match `ibuff-hide-buffers-regexp'.
  2100. A second call of this command will hide them again."
  2101.   (interactive)
  2102.   (setq ibuff-widen (not ibuff-widen))
  2103.   (ibuff-do-narrow)
  2104.   (ibuff-adjust-point-after-narrowing))
  2105.  
  2106. (defun ibuff-match-buffer-names (regexp &optional inverse)
  2107.   "Restrict the listing to buffers with names that match REGEXP.
  2108. Prompts for the regular expression. A successful match is pushed on the
  2109. match stack. Prefix arg INVERSE means restrict the menu to buffers that do
  2110. not match."
  2111.  
  2112.   (interactive
  2113.    (list (let ((prompt (and (eq this-command last-command)
  2114.                 ibuff-last-buffer-regexp)))
  2115.        (read-string (format "Narrow to buffer names%s matching regexp: "
  2116.                 (if current-prefix-arg " NOT" ""))
  2117.             prompt))
  2118.      current-prefix-arg))
  2119.   (setq this-command 'ibuff-match-buffer-names)
  2120.   (let ((fun (if inverse
  2121.          'ibuff-narrow-to-buffer-regexp-inverse
  2122.            'ibuff-narrow-to-buffer-regexp)))
  2123.     (if (ibuff-do-match fun regexp)
  2124.     (setq ibuff-last-buffer-regexp nil)
  2125.       (setq ibuff-last-buffer-regexp regexp))
  2126.     (ibuff-adjust-point-after-narrowing)))
  2127.  
  2128. (defun ibuff-match-file-names (regexp &optional inverse)
  2129.   "Restrict the listing to buffers with file names that match REGEXP.
  2130. The default directories of dired buffers are also considered.
  2131. Prompts for the regular expression. A successful match is pushed on the
  2132. match stack. Prefix arg INVERSE means restrict the menu to buffers that do
  2133. not match."
  2134.  
  2135.   (interactive
  2136.    (list (let ((prompt (and (eq this-command last-command)
  2137.                 ibuff-last-file-regexp)))
  2138.        (read-string (format "Narrow to file names%s matching regexp: "
  2139.                 (if current-prefix-arg " NOT" ""))
  2140.             prompt))
  2141.      current-prefix-arg))
  2142.   (setq this-command 'ibuff-match-file-names)
  2143.   (let ((fun (if inverse
  2144.          'ibuff-narrow-to-file-regexp-inverse
  2145.            'ibuff-narrow-to-file-regexp)))
  2146.     (if (string-match "\\([^~\\\\]\\|^\\)\\(~\\)[^~]" regexp)
  2147.     (setq regexp (concat (substring regexp 0 (match-beginning 2))
  2148.                  ibuff-user-home-directory
  2149.                  (substring regexp (match-end 2)))))
  2150.     (if (ibuff-do-match fun regexp)
  2151.     (setq ibuff-last-file-regexp nil)
  2152.       (setq ibuff-last-file-regexp regexp))
  2153.     (ibuff-adjust-point-after-narrowing)))
  2154.  
  2155. (defun ibuff-match-mode-names (regexp &optional inverse)
  2156.   "Restrict the listing to buffers with mode names that match REGEXP.
  2157. Prompts for the regular expression. A successful match is pushed on the
  2158. match stack. Prefix arg INVERSE means restrict the menu to buffers that do
  2159. not match."
  2160.  
  2161.   (interactive
  2162.    (list (let ((prompt (and (eq this-command last-command)
  2163.                 ibuff-last-file-regexp)))
  2164.        (read-string (format "Narrow to mode names%s matching regexp: "
  2165.                 (if current-prefix-arg " NOT" ""))
  2166.             prompt))
  2167.      current-prefix-arg))
  2168.   (setq this-command 'ibuff-match-mode-names)
  2169.   (let ((fun (if inverse
  2170.          'ibuff-narrow-to-mode-regexp-inverse
  2171.            'ibuff-narrow-to-mode-regexp)))
  2172.     (if (ibuff-do-match fun regexp)
  2173.     (setq ibuff-last-mode-regexp nil)
  2174.       (setq ibuff-last-mode-regexp regexp))
  2175.     (ibuff-adjust-point-after-narrowing)))
  2176.  
  2177. (defun ibuff-hide-buffer-as-match (&optional new-level)
  2178.   "Hide the menu line for this buffer.
  2179. The command is pushed on the match stack. If the current match level refers
  2180. to a previous call of this command the buffer is merged into its list of
  2181. buffers that should be hidden. However, with prefix argument NEW-LEVEL a
  2182. separate stack entry is pushed on the match stack."
  2183.  
  2184.   (interactive "P")
  2185.   (beginning-of-line)
  2186.   (if (looking-at ibuff-line-regexp)
  2187.       (let* ((buff (ibuff-get-buffer))
  2188.          (bufflist (list buff))
  2189.          (match (car ibuff-match-stack-ptr))
  2190.          buffer-read-only)
  2191.     (if (buffer-name buff)
  2192.         (if (funcall 'ibuff-narrow-to-buffers-inverse bufflist)
  2193.         (progn
  2194.           (if (and (null new-level)
  2195.                (consp match)
  2196.                (eq (car match) 'ibuff-narrow-to-buffers-inverse))
  2197.               (setcdr match (cons buff (cdr match)))
  2198.             (ibuff-push-match
  2199.              'ibuff-narrow-to-buffers-inverse bufflist))
  2200.           (setq ibuff-numbers-changed t)
  2201.           (forward-line 1))
  2202.           (message "Only buffer.")
  2203.           (ibuff-do-narrow)))))
  2204.   (ibuff-adjust-point))
  2205.  
  2206. (put 'ibuff-hide-buffer-as-match 'ibuff-applicable t)
  2207.  
  2208. (defun ibuff-edit-mode-ring (key &optional before)
  2209.   "Edit the sublist mode ring. Prompts for KEY.
  2210. KEY is a character and stands for
  2211.  
  2212.     r: remove current mode
  2213.     b: insert basic mode (full listing)
  2214.     d: insert mode for dired buffers
  2215.     f: insert mode for file buffers
  2216.     p: insert mode for plain buffers
  2217.     k: insert mode for buffers flagged to be deleted.
  2218.  
  2219. With prefix arg BEFORE new modes are inserted before the current mode,
  2220. otherwise after it.  NB: If you insert a mode before the one which is
  2221. initially active when `ibuff-menu' is called it will become the new initial
  2222. mode."
  2223.  
  2224.   (interactive (list (let ((cursor-in-echo-area t))
  2225.                (discard-input)
  2226.                (read-quoted-char "\
  2227. r-emove this mode or insert b-asic, d-ired, f-iles, p-lain, k-illed: "))
  2228.              current-prefix-arg))
  2229.   (if (and (eq key ?r)
  2230.        (or (not (interactive-p))
  2231.            (y-or-n-p (format "Delete mode \"%s\"? "
  2232.                  (cdr (car ibuff-mode-ring-ptr))))))
  2233.       (ibuff-delete-mode)
  2234.     (let ((mode (assq key ibuff-standard-sublist-modes)))
  2235.       (if mode
  2236.       (ibuff-insert-mode (cdr mode) before))))
  2237.   (message "")
  2238.   (ibuff-do-narrow)
  2239.   (ibuff-adjust-point-after-narrowing))
  2240.  
  2241. (defun ibuff-store-match-as-mode (name &optional before)
  2242.   "Store the current combination of match level and sublist mode
  2243. in the mode ring.
  2244. The command prompts for NAME which is used to indicate the new sublist mode
  2245. in the mode line. With prefix arg BEFORE the combination is inserted before
  2246. the current mode, otherwise after it."
  2247.  
  2248.   (interactive
  2249.    (list (if (eq ibuff-match-stack-ptr ibuff-match-stack)
  2250.          (progn
  2251.            (message "\
  2252. Insertion of a new mode requires an active match or hide level.")
  2253.            nil)
  2254.        (read-string "Store current configuration under name: "))
  2255.      current-prefix-arg))
  2256.   (if name
  2257.       (progn
  2258.     (ibuff-insert-current-configuration name before)
  2259.     (ibuff-do-narrow)
  2260.     (ibuff-adjust-point-after-narrowing))
  2261.     (ibuff-adjust-point)))
  2262.  
  2263. (defun ibuff-perform-quit ()
  2264.   "In `ibuff-menu', perform all requests and leave the menu."
  2265.   (interactive)
  2266.   (ibuff-show-buffers (ibuff-parse)))
  2267.  
  2268. (defun ibuff-select-buffer-perform-quit ()
  2269.   "Perform all requests, display this buffer and leave `ibuff-menu'."
  2270.   (interactive)
  2271.   (ibuff-select-buffer nil))
  2272.  
  2273. (defun ibuff-replace-buffer-perform-quit ()
  2274.   "Perform all request, replace the previously selected buffer with this one
  2275. and leave `ibuff-menu'."
  2276.   (interactive)
  2277.   (ibuff-select-buffer 'replace))
  2278.  
  2279. (defun ibuff-add-buffer-perform-quit ()
  2280.   "Perform all requests, additionally display this buffer and leave
  2281. `ibuff-menu'."
  2282.   (interactive)
  2283.   (ibuff-select-buffer t))
  2284.  
  2285. (defun ibuff-expunge ()
  2286.   "Perform all requests, but don't display the marked buffers and return
  2287. to `ibuff-menu'."
  2288.   (interactive)
  2289.   (let ((list (ibuff-parse))
  2290.     mark)
  2291.     (ibuff-save-window-configuration)
  2292.     (ibuff-revert-menu 1)
  2293.     (save-excursion
  2294.       (while list
  2295.     (setq mark (rassq (car list) ibuff-buffer-markers)
  2296.           list (cdr list))
  2297.     (if mark
  2298.         (progn
  2299.           (goto-char (car mark))
  2300.           (beginning-of-line)
  2301.           (if (looking-at ibuff-line-regexp)
  2302.           (ibuff-put-delete-flag ibuff-display-flag))))))))
  2303.  
  2304. (defun ibuff-cancel-quit ()
  2305.   "Cancel all requests and leave `ibuff-menu'."
  2306.   (interactive)
  2307.   (ibuff-restore-window-configuration)
  2308.   (delete-windows-on ibuff-killed-buffer))
  2309.  
  2310. (defun ibuff-apply-command-region (whole beg end)
  2311.   "Apply an `ibuff-menu' command to all visible menu lines in current region.
  2312.  
  2313. A menu line is regarded inside the region if it is touched by it.
  2314. A region can be marked with the `ibuff-goto-this-line' command.
  2315. A prefix argument means ignore the region and apply the command to all
  2316. visible lines.
  2317.  
  2318. `ibuff-apply-command-region' prompts for a key sequence that refers to
  2319. the command you wish to execute. This key sequence may include prefix
  2320. arguments for the command.
  2321. \\<ibuff-menu-mode-map>
  2322. Example: the standard sequence to delete all buffers which visit files
  2323. >from your directory \"foo\" is as follows:
  2324.  
  2325.     \\[ibuff-match-file-names] \"~/foo/[^/]+$\" RET \
  2326. C-u \\[ibuff-apply-command-region] C-u \\[ibuff-mark-delete]
  2327.  
  2328. A less complicated regular expression should be sufficient in most cases.
  2329.  
  2330. The following commands can be applied:
  2331.  
  2332. \\[ibuff-unmark]    ibuff-unmark
  2333. \\[ibuff-mark-display]    ibuff-mark-display
  2334. \\[ibuff-mark-delete]    ibuff-mark-delete
  2335. \\[ibuff-mark-save]    ibuff-mark-save
  2336. \\[ibuff-mark-modified]    ibuff-mark-modified
  2337. \\[ibuff-mark-read-only]    ibuff-mark-read-only
  2338. \\[ibuff-hide-buffer-as-match]    ibuff-hide-buffer-as-match
  2339. \\[ibuff-bury-buffer]    ibuff-bury-buffer
  2340. \\[ibuff-rename-buffer]    ibuff-rename-buffer
  2341. \\[ibuff-set-file-name]    ibuff-set-file-name
  2342. \\[ibuff-view-buffer]    ibuff-view-buffer
  2343. \\[ibuff-copy-buffer-as-kill]    ibuff-copy-buffer-as-kill
  2344. \\<global-map>
  2345. If you apply `ibuff-rename-buffer' or `ibuff-set-file-name' by mistake,
  2346. use \\[keyboard-quit] to abort.
  2347. If you apply `ibuff-view-buffer' by mistake, do \\[top-level]."
  2348.  
  2349.   (interactive "P\nr")
  2350.   (if whole
  2351.       (setq beg (point-min-marker)
  2352.         end (point-max-marker))
  2353.     (setq beg (save-excursion
  2354.         (goto-char beg) (beginning-of-line) (point-marker))
  2355.       end (save-excursion
  2356.         (goto-char end) (forward-line 1) (point-marker))))
  2357.   (let (com prefix)
  2358.     (unwind-protect
  2359.     (save-excursion
  2360.       (save-restriction
  2361.         (narrow-to-region beg end)
  2362.         (goto-char (point-min))
  2363.         (setq com (ibuff-read-command
  2364.                "Apply command to these buffers (type key sequence): "
  2365.                )))
  2366.       (if (stringp com)
  2367.           (message "Command not applicable: `%s'." com)
  2368.         (message "")
  2369.         (setq prefix prefix-arg
  2370.           ibuff-command-application t)
  2371.         (goto-char beg)
  2372.         (while (re-search-forward ibuff-line-regexp end t)
  2373.           (save-excursion
  2374.         (goto-char (match-beginning 0))
  2375.         (setq prefix-arg prefix)
  2376.         (command-execute com)))))
  2377.       (set-marker beg nil)
  2378.       (set-marker end nil)
  2379.       (setq ibuff-command-application nil)
  2380.       (ibuff-adjust-point))))
  2381.  
  2382. (defun ibuff-unmark (&optional arg)
  2383.   "Restore the initial marks of this buffer.
  2384. A negative prefix arg means move up as much lines, then unmark.
  2385. A positive arg > 0 means first unmark, then move down as much lines.
  2386. A non-numeric prefix argument means clear all marks, don't move."
  2387.   (interactive "P")
  2388.   (ibuff-do-mark ibuff-no-flag arg))
  2389.  
  2390. (put 'ibuff-unmark 'ibuff-applicable t)
  2391.  
  2392. (defun ibuff-backward-unmark (&optional clear)
  2393.   "Move up one line, then restore the initial marks for that buffer."
  2394.   (interactive "P")
  2395.   (forward-line -1)
  2396.   (ibuff-do-mark ibuff-no-flag (and clear '(4))))
  2397.  
  2398. (defun ibuff-unmark-forward (&optional clear)
  2399.   "Restore the initial marks for this buffer, then move down one line."
  2400.   (interactive "P")
  2401.   (let ((ibuff-command-application t))    ; inhibits point adjustment
  2402.     (ibuff-do-mark ibuff-no-flag (and clear '(4))))
  2403.   (forward-line 1)
  2404.   (ibuff-adjust-point))
  2405.  
  2406. (defun ibuff-mark-delete (&optional move)
  2407.   "Request to delete this buffer or cancel such a request.
  2408. A negative prefix arg means move up as much lines, then change the flag.
  2409. A positive prefix arg > 0 means change the flag, then move down as much lines.
  2410. A single C-u as prefix arg means set the flag and don't move.
  2411. C-u C-u as prefix arg means remove the flag and don't move.
  2412. If no prefix argument is provided the value of
  2413. `ibuff-mark-delete-pre-set-prefix' is interpreted instead."
  2414.  
  2415.   (interactive "P")
  2416.   (ibuff-do-mark ibuff-delete-flag
  2417.          (or move ibuff-mark-delete-pre-set-prefix)))
  2418.  
  2419. (put 'ibuff-mark-delete 'ibuff-applicable t)
  2420.  
  2421. (defun ibuff-mark-display (&optional move)
  2422.   "Request to display this buffer or cancel such a request.
  2423. See also \\[describe-function] ibuff-mark-delete for details."
  2424.   (interactive "P")
  2425.   (ibuff-do-mark ibuff-display-flag
  2426.          (or move ibuff-mark-display-pre-set-prefix)))
  2427.  
  2428. (put 'ibuff-mark-display 'ibuff-applicable t)
  2429.  
  2430. (defun ibuff-mark-save (&optional move)
  2431.   "Request to save this buffer or cancel such a request.
  2432. See also \\[describe-function] ibuff-mark-delete for details."
  2433.   (interactive "P")
  2434.   (ibuff-do-mark ibuff-save-flag
  2435.          (or move ibuff-mark-save-pre-set-prefix)))
  2436.  
  2437. (put 'ibuff-mark-save 'ibuff-applicable t)
  2438.  
  2439. (defun ibuff-mark-modified (&optional move)
  2440.   "Request to change the buffer modified flag of this buffer.
  2441. See also \\[describe-function] ibuff-mark-delete for details."
  2442.   (interactive "P")
  2443.   (ibuff-do-mark ibuff-modified-flag
  2444.          (or move ibuff-mark-modified-pre-set-prefix)))
  2445.  
  2446. (put 'ibuff-mark-modified 'ibuff-applicable t)
  2447.  
  2448. (defun ibuff-mark-read-only (&optional move)
  2449.   "Request to make this buffer read-only or writable.
  2450. See also \\[describe-function] ibuff-mark-delete for details."
  2451.   (interactive "P")
  2452.   (ibuff-do-mark ibuff-read-only-flag
  2453.          (or move ibuff-mark-read-only-pre-set-prefix)))
  2454.  
  2455. (put 'ibuff-mark-read-only 'ibuff-applicable t)
  2456.  
  2457. (defun ibuff-rename-buffer ()
  2458.   "In `ibuff-menu', rename this buffer."
  2459.   (interactive)
  2460.   (beginning-of-line)
  2461.   (if (looking-at ibuff-line-regexp)
  2462.       (let* ((index (ibuff-get-index))
  2463.          (kill (ibuff-get-delete-flag))
  2464.          (save (ibuff-get-save-flag))
  2465.          (read (ibuff-get-read-only-flag))
  2466.          (mark (ibuff-get-buffer-marker))
  2467.          (buff (cdr mark))
  2468.          (name (buffer-name buff))
  2469.          (end (ibuff-get-end-of-line))
  2470.          buffer-read-only)
  2471.     (if name
  2472.         (unwind-protect
  2473.         (save-excursion
  2474.           (set-buffer buff)
  2475.           (rename-buffer
  2476.            (read-string (format "Rename buffer \"%s\" to: " name))))
  2477.           (delete-region (point) end)
  2478.           (set-marker (car mark)
  2479.               (ibuff-format-line buff index kill save read ""))
  2480.           (ibuff-adjust-point))
  2481.       (ibuff-adjust-point)))
  2482.     (ibuff-adjust-point)))
  2483.  
  2484. (put 'ibuff-rename-buffer 'ibuff-applicable t)
  2485.  
  2486. (defun ibuff-set-file-name ()
  2487.   "In `ibuff-menu', set the visited file name of this buffer."
  2488.   (interactive)
  2489.   (beginning-of-line)
  2490.   (if (looking-at ibuff-line-regexp)
  2491.       (let* ((index (ibuff-get-index))
  2492.          (kill (ibuff-get-delete-flag))
  2493.          (save (ibuff-get-save-flag))
  2494.          (read (ibuff-get-read-only-flag))
  2495.          (mark (ibuff-get-buffer-marker))
  2496.          (buff (cdr mark))
  2497.          (name (buffer-name buff))
  2498.          (end (ibuff-get-end-of-line))
  2499.          buffer-read-only)
  2500.     (if name
  2501.         (unwind-protect
  2502.         (save-excursion
  2503.           (set-buffer buff)
  2504.           (set-visited-file-name
  2505.            (read-file-name
  2506.             (format "Set file name of buffer \"%s\" to: " name)))
  2507.           (setq save (cond ((null buffer-file-name)
  2508.                     (if (eq save ibuff-no-flag)
  2509.                     ibuff-no-flag
  2510.                       ibuff-modified-flag))
  2511.                    ((eq save ibuff-no-flag)
  2512.                     ibuff-modified-flag)
  2513.                    (t
  2514.                     save))))
  2515.           (delete-region (point) end)
  2516.           (set-marker (car mark)
  2517.               (ibuff-format-line buff index kill save read ""))
  2518.           (ibuff-adjust-point))
  2519.       (ibuff-adjust-point)))
  2520.     (ibuff-adjust-point)))
  2521.  
  2522. (put 'ibuff-set-file-name 'ibuff-applicable t)
  2523.  
  2524. (defun ibuff-view-buffer ()
  2525.   "In `ibuff-menu', view this buffer in view-mode, then return.
  2526. This command does not work correctly in Lucid Emacs 19.4, because it
  2527. assumes that `view-buffer' is a function that uses `recursive-edit'."
  2528.   (interactive)
  2529.   (beginning-of-line)
  2530.   (if (looking-at ibuff-line-regexp)
  2531.       (let ((buff (ibuff-get-buffer))
  2532.         (wind (get-largest-window)))
  2533.     (if (buffer-name buff)
  2534.         (save-window-excursion
  2535.           (if (or (eq wind (get-buffer-window ibuff-buffer-name))
  2536.               (< (window-height wind) (/ (screen-height) 2)))
  2537.           (delete-other-windows)
  2538.         (select-window wind))
  2539.           (view-buffer buff)))))
  2540.   (ibuff-adjust-point))
  2541.  
  2542. (put 'ibuff-view-buffer 'ibuff-applicable t)
  2543.  
  2544. (defun ibuff-bury-buffer ()
  2545.   "In `ibuff-menu', move this buffer to the end of the buffer list."
  2546.   (interactive)
  2547.   (beginning-of-line)
  2548.   (if (looking-at ibuff-line-regexp)
  2549.       (let* ((beg (match-beginning 0))
  2550.          (end (ibuff-get-end-of-line))
  2551.          (kill (ibuff-get-delete-flag))
  2552.          (save (ibuff-get-save-flag))
  2553.          (read (ibuff-get-read-only-flag))
  2554.          (mark (ibuff-get-buffer-marker))
  2555.          (buff (cdr mark))
  2556.          buffer-read-only)
  2557.     (if (buffer-name buff)
  2558.         (progn
  2559.           (bury-buffer buff)
  2560.           (goto-char (point-max))
  2561.           (set-marker (car mark)
  2562.               (ibuff-format-line buff nil kill save read))
  2563.           (delete-region (1- beg) end)
  2564.           (goto-char beg)
  2565.           (if (eq (preceding-char) ?\r)
  2566.           (forward-line 1))
  2567.           (setq ibuff-numbers-changed t)))))
  2568.   (ibuff-adjust-point))
  2569.  
  2570. (put 'ibuff-bury-buffer 'ibuff-applicable t)
  2571.  
  2572. (defun ibuff-previous-line (n)
  2573.   "Move to Nth previous line."
  2574.   (interactive "p")
  2575.   (forward-line (- n))
  2576.   (ibuff-adjust-point))
  2577.  
  2578. (defun ibuff-next-line (n)
  2579.   "Move to Nth next line."
  2580.   (interactive "p")
  2581.   (forward-line n)
  2582.   (ibuff-adjust-point))
  2583.  
  2584. (defun ibuff-beginning-of-menu (&optional no-mark)
  2585.   "Set the mark, then move to the beginning of `ibuff-menu'.
  2586. With prefix argument, don't set the mark."
  2587.   (interactive "P")
  2588.   (or no-mark (ibuff-set-mark))
  2589.   (goto-char (point-min))
  2590.   (ibuff-adjust-point))
  2591.  
  2592. (defun ibuff-end-of-menu (&optional no-mark)
  2593.   "Set the mark, then move to the end of `ibuff-menu'.
  2594. With prefix argument, don't set the mark."
  2595.   (interactive "P")
  2596.   (or no-mark (ibuff-set-mark))
  2597.   (goto-char (point-max))
  2598.   (ibuff-adjust-point))
  2599.  
  2600. (defun ibuff-goto-this-line (&optional no-mark)
  2601.   "Set the mark and jump to the line with this index.
  2602. With prefix argument, don't set the mark."
  2603.  
  2604.   (interactive "P")
  2605.   (let ((index last-command-char)
  2606.     (opos  (point)))
  2607.     (goto-char (point-min))
  2608.     (while (not (or (eq index (following-char))
  2609.             (eq (following-char) ? )
  2610.             (eobp)))
  2611.       (forward-line 1))
  2612.     (if (eq index (following-char))
  2613.     (or no-mark (ibuff-set-mark opos))
  2614.       (message "Line %c not found" index)
  2615.       (goto-char opos))
  2616.     (ibuff-adjust-point)))
  2617.  
  2618. (defun ibuff-back-to-mark ()
  2619.   "Move the point back to the positions stored in the mark ring."
  2620.   (interactive)
  2621.   (ibuff-set-mark)
  2622.   (pop-mark)
  2623.   (goto-char (mark))
  2624.   (ibuff-adjust-point)
  2625.   ;; Point may now be different from mark, therefore:
  2626.   (set-mark (point)))
  2627.  
  2628. (defun ibuff-mark-modified-buffers-save ()
  2629.   "Request to save all modified file buffers."
  2630.   (interactive)
  2631.   (save-excursion
  2632.     (goto-char (point-min))
  2633.     (while (re-search-forward ibuff-modified-buffers-regexp nil t)
  2634.       (let ((buff (ibuff-get-buffer)))
  2635.     (if (save-excursion
  2636.           (and (buffer-name buff)
  2637.            (set-buffer buff)
  2638.            buffer-file-name
  2639.            (file-writable-p buffer-file-name)))
  2640.         (progn
  2641.           (ibuff-put-save-flag ibuff-save-flag)
  2642.           (forward-line 1))))))
  2643.   (ibuff-adjust-point))
  2644.  
  2645. (defun ibuff-mark-displayed-buffers-display ()
  2646.   "Request to display again all previously displayed buffers."
  2647.   (interactive)
  2648.   (save-excursion
  2649.     (goto-char (point-min))
  2650.     (while (re-search-forward ibuff-visible-buffers-regexp nil t)
  2651.       (ibuff-put-delete-flag ibuff-display-flag)
  2652.       (forward-line 1)))
  2653.   (ibuff-adjust-point))
  2654.  
  2655. (defun ibuff-isearch-forward (&optional regexp)
  2656.   "Incremental search forwards in `ibuff-menu'.
  2657. With prefix arg, search for a regexp."
  2658.   (interactive "P")
  2659.   (unwind-protect
  2660.       (if regexp
  2661.       (isearch-forward-regexp)
  2662.     (isearch-forward))
  2663.     (discard-input)
  2664.     (ibuff-adjust-point)))
  2665.  
  2666. (defun ibuff-isearch-backward (&optional regexp)
  2667.   "Incremental search backwards in `ibuff-menu'.
  2668. With prefix arg, search for a regexp."
  2669.   (interactive "P")
  2670.   (unwind-protect
  2671.       (if regexp
  2672.       (isearch-backward-regexp)
  2673.     (isearch-backward))
  2674.     (discard-input)
  2675.     (ibuff-adjust-point)))
  2676.  
  2677. (defun ibuff-show-long-file-names ()
  2678.   "Show a larger part of the file name column of `ibuff-menu' (toggle).
  2679. This command does not work in Lucid Emacs 19.4., because the latter
  2680. cannot split windows horizontally."
  2681.   (interactive)
  2682.   (let ((win (get-buffer-window ibuff-buffer-name)))
  2683.     (select-window win)
  2684.     (if (< (window-width win) (screen-width))
  2685.     (progn
  2686.       (enlarge-window (screen-width) t)
  2687.       (set-window-hscroll win 0))
  2688.       (if (> (screen-width) (+ 20 window-min-width))
  2689.       (progn
  2690.         (setq win (split-window win 20 t))
  2691.         (set-window-hscroll win ibuff-file-name-column))))
  2692.     (ibuff-adjust-point)))
  2693.  
  2694. (defun ibuff-copy-buffer-as-kill (&optional append)
  2695.   "Copy the contents of this buffer into the kill ring.
  2696. With prefix argument, append it to the previously killed or copied text."
  2697.  
  2698.   (interactive "P")
  2699.   (beginning-of-line)
  2700.   (if (looking-at ibuff-line-regexp)
  2701.       (let* ((buff (ibuff-get-buffer))
  2702.          (name (buffer-name buff)))
  2703.     (if name
  2704.         (save-excursion
  2705.           (set-buffer buff)
  2706.           (if append
  2707.           (setq last-command 'kill-region)
  2708.         (setq last-command nil))
  2709.           (copy-region-as-kill (point-min) (point-max))
  2710.           (message "Contents of \"%s\" %s the kill ring."
  2711.                name
  2712.                (if (eq last-command 'kill-region)
  2713.                "appended to the last entry in"
  2714.              "saved in"))))))
  2715.   (ibuff-adjust-point))
  2716.  
  2717. (put 'ibuff-copy-buffer-as-kill 'ibuff-applicable t)
  2718.  
  2719. (defun ibuff-yank-perform-quit ()
  2720.   "Like \\[ibuff-add-buffer-perform-quit] \
  2721. (ibuff-add-buffer-perform-quit), but also yank text from kill ring.
  2722. This command is intended to be used after a call of \
  2723. \\[ibuff-copy-buffer-as-kill]\ (ibuff-copy-buffer-as-kill),
  2724. but may be of general use to copy text from one buffer to another.
  2725. You can use \\[yank-pop] (yank-pop) immediately after this command."
  2726.  
  2727.   (interactive)
  2728.   (ibuff-add-buffer-perform-quit)
  2729.   (if (eq (selected-window) (get-buffer-window ibuff-buffer-name))
  2730.       ()
  2731.       (yank)
  2732.       (setq this-command 'yank)))
  2733.  
  2734. ;;;; END OF FILE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2735.