1 ;;; ibuffer.el --- operate on buffers like dired
3 ;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
5 ;; Author: Colin Walters <walters@verbum.org>
7 ;; Keywords: buffer, convenience
9 ;; This file is not currently part of GNU Emacs.
11 ;; This program is free software; you can redistribute it and/or
12 ;; modify it under the terms of the GNU General Public License as
13 ;; published by the Free Software Foundation; either version 2, or (at
14 ;; your option) any later version.
16 ;; This program is distributed in the hope that it will be useful, but
17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ;; General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with this program ; see the file COPYING. If not, write to
23 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
28 ;; ibuffer.el is an advanced replacement for the `buffer-menu' which
29 ;; is normally distributed with Emacs. Its interface is intended to
30 ;; be analogous to that of Dired.
39 ;; This is loaded lazily, via byte-compile-dynamic
44 (if (fboundp 'window-list)
45 (defun ibuffer-window-list ()
46 (window-list nil 'nomini))
47 (defun ibuffer-window-list ()
48 (let ((ibuffer-window-list-result nil))
49 (walk-windows #'(lambda (win) (push win ibuffer-window-list-result)) 'nomini)
50 (nreverse ibuffer-window-list-result))))
52 (cond ((boundp 'global-font-lock-mode)
53 (defsubst ibuffer-use-fontification ()
54 (when (boundp 'font-lock-mode)
56 ((boundp 'font-lock-auto-fontify)
57 (defsubst ibuffer-use-fontification ()
58 font-lock-auto-fontify))
60 (defsubst ibuffer-use-fontification ()
64 "An advanced replacement for `buffer-menu'.
66 Ibuffer allows you to operate on buffers in a manner much like Dired.
67 Operations include sorting, marking by regular expression, and
68 the ability to filter the displayed buffers by various criteria."
69 :link '(url-link "http://cvs.verbum.org/ibuffer")
72 (defcustom ibuffer-formats '((mark modified read-only " " (name 16 16 :left :elide)
73 " " (size 6 -1 :right)
74 " " (mode 16 16 :right :elide) " " filename)
75 (mark " " (name 16 -1) " " filename))
76 "A list of ways to display buffer lines.
78 With Ibuffer, you are not limited to displaying just certain
79 attributes of a buffer such as size, name, and mode in a particular
80 fashion. Through this variable, you can completely customize and
81 control the appearance of an Ibuffer buffer. See also
82 `define-ibuffer-column', which allows you to define your own columns
85 This variable has the form
86 ((COLUMN COLUMN ...) (COLUMN COLUMN ...) ...)
87 Each element in `ibuffer-formats' should be a list containing COLUMN
88 specifiers. A COLUMN can be any of the following:
90 SYMBOL - A symbol naming the column. Predefined columns are:
91 mark modified read-only name size mode process filename
92 When you define your own columns using `define-ibuffer-column', just
93 use their name like the predefined columns here. This entry can
94 also be a function of two arguments, which should return a string.
95 The first argument is the buffer object, and the second is the mark
98 \"STRING\" - A literal string to display.
100 (SYMBOL MIN-SIZE MAX-SIZE &optional ALIGN ELIDE) - SYMBOL is a
101 symbol naming the column, and MIN-SIZE and MAX-SIZE are integers (or
102 functions of no arguments returning an integer) which constrict the
103 size of a column. If MAX-SIZE is -1, there is no upper bound. The
104 default values are 0 and -1, respectively. If MIN-SIZE is negative,
105 use the end of the string. The optional element ALIGN describes the
106 alignment of the column; it can be :left, :center or :right. The
107 optional element ELIDE describes whether or not to elide the column
108 if it is too long; valid values are :elide and nil. The default is
111 Some example of valid entries in `ibuffer-formats', with
112 description (also, feel free to try them out, and experiment with your
116 This format just displays the current mark (if any) and the name of
117 the buffer, separated by a space.
118 (mark modified read-only \" \" (name 16 16 :left) \" \" (size 6 -1 :right))
119 This format displays the current mark (if any), its modification and
120 read-only status, as well as the name of the buffer and its size. In
121 this format, the name is restricted to 16 characters (longer names
122 will be truncated, nad shorter names will be padded with spaces), and
123 the name is also aligned to the right. The size of the buffer will
124 be padded with spaces up to a minimum of six characters, but there is
125 no upper limit on its size. The size will also be aligned to the
128 Thus, if you wanted to use these two formats, add
130 (setq ibuffer-formats '((mark \" \" name)
131 (mark modified read-only
132 (name 16 16 :left) (size 6 -1 :right))))
134 to your ~/.emacs file.
136 Using \\[ibuffer-switch-format], you can rotate the display between
137 the specified formats in the list."
141 (defcustom ibuffer-always-compile-formats (featurep 'bytecomp)
142 "If non-nil, then use the byte-compiler to optimize `ibuffer-formats'.
143 This will increase the redisplay speed, at the cost of loading the
144 elisp byte-compiler."
148 (defcustom ibuffer-fontification-alist
149 `((10 buffer-read-only font-lock-reference-face)
150 (15 (string-match "^*" (buffer-name)) font-lock-keyword-face)
151 (20 (string-match "^ " (buffer-name)) font-lock-warning-face)
152 (25 (memq major-mode '(help-mode apropos-mode info-mode)) font-lock-comment-face)
153 (30 (eq major-mode 'dired-mode) font-lock-function-name-face))
154 "An alist describing how to fontify buffers.
155 Each element should be of the form (PRIORITY FORM FACE), where
156 PRIORITY is an integer, FORM is an arbitrary form to evaluate in the
157 buffer, and FACE is the face to use for fontification. If the FORM
158 evaluates to non-nil, then FACE will be put on the buffer name. The
159 element with the highest PRIORITY takes precedence."
161 (list (integer :tag "Priority")
162 (sexp :tag "Test Form")
166 (defcustom ibuffer-use-other-window nil
167 "If non-nil, display the Ibuffer in another window by default."
171 (defcustom ibuffer-default-shrink-to-minimum-size nil
172 "If non-nil, minimize the size of the Ibuffer window by default."
175 (defvar ibuffer-shrink-to-minimum-size nil)
177 (defcustom ibuffer-case-fold-search case-fold-search
178 "If non-nil, ignore case when searching."
182 (defcustom ibuffer-default-sorting-mode 'recency
183 "The criteria by which to sort the buffers.
185 Note that this variable is local to each ibuffer buffer. Thus, you
186 can have multiple ibuffer buffers open, each with a different sorted
187 view of the buffers."
188 :type '(choice (const :tag "Last view time" :value recency)
189 (const :tag "Lexicographic" :value alphabetic)
190 (const :tag "Buffer size" :value size)
191 (const :tag "Major mode" :value major-mode))
193 (defvar ibuffer-sorting-mode nil)
195 (defcustom ibuffer-default-sorting-reversep nil
196 "If non-nil, reverse the default sorting order."
199 (defvar ibuffer-sorting-reversep nil)
201 (defcustom ibuffer-elide-long-columns nil
202 "If non-nil, then elide column entries which exceed their max length.
203 This variable is deprecated; use the :elide argument of
204 `ibuffer-formats' to elide just certain columns."
208 (defcustom ibuffer-eliding-string "..."
209 "The string to use for eliding long columns."
213 (defcustom ibuffer-maybe-show-predicates `(,(lambda (buf)
214 (and (string-match "^ " (buffer-name buf))
215 (null buffer-file-name))))
216 "A list of predicates (a regexp or function) for buffers to display conditionally.
217 If a regexp, then it will be matched against the buffer's name.
218 If a function, it will be called with the buffer as an argument, and
219 should return non-nil if this buffer should be shown.
221 Viewing of buffers hidden because of these predicates is enabled by
222 giving a non-nil prefix argument to `ibuffer-update'. Note that this
223 specialized filtering occurs before real filtering."
224 :type '(repeat (choice regexp function))
227 (defvar ibuffer-current-format nil)
229 (defcustom ibuffer-modified-char ?*
230 "The character to display for modified buffers."
234 (defcustom ibuffer-read-only-char ?%
235 "The character to display for read-only buffers."
239 (defcustom ibuffer-marked-char ?>
240 "The character to display for marked buffers."
244 (defcustom ibuffer-deletion-char ?D
245 "The character to display for buffers marked for deletion."
249 (defcustom ibuffer-expert nil
250 "If non-nil, don't ask for confirmation of \"dangerous\" operations."
254 (defcustom ibuffer-view-ibuffer nil
255 "If non-nil, display the current Ibuffer buffer itself.
256 Note that this has a drawback - the data about the current Ibuffer
257 buffer will most likely be inaccurate. This includes modification
262 (defcustom ibuffer-always-show-last-buffer nil
263 "If non-nil, always display the previous buffer. This variable
264 takes precedence over filtering, and even
265 `ibuffer-never-show-predicates'."
266 :type '(choice (const :tag "Always" :value t)
267 (const :tag "Never" :value nil)
268 (const :tag "Always except minibuffer" :value :nomini))
271 (defcustom ibuffer-use-header-line (boundp 'header-line-format)
272 "If non-nil, display a header line containing current filters.
273 This feature only works on Emacs 21 or later."
277 (defcustom ibuffer-default-directory nil
278 "The default directory to use for a new ibuffer buffer.
279 If nil, inherit the directory of the buffer in which `ibuffer' was
280 called. Otherwise, this variable should be a string naming a
281 directory, like `default-directory'."
282 :type '(choice (const :tag "Inherit" :value nil)
286 (defcustom ibuffer-hooks nil
287 "Hooks run when `ibuffer' is called."
291 (defcustom ibuffer-mode-hooks nil
292 "Hooks run upon entry into `ibuffer-mode'."
296 (defcustom ibuffer-marked-face 'font-lock-warning-face
297 "Face used for displaying marked buffers."
301 (defcustom ibuffer-deletion-face 'font-lock-type-face
302 "Face used for displaying buffers marked for deletion."
306 (defcustom ibuffer-title-face 'font-lock-type-face
307 "Face used for the title string."
311 (defcustom ibuffer-directory-abbrev-alist nil
312 "An alist of file name abbreviations like `directory-abbrev-alist'."
313 :type '(repeat (cons :format "%v"
319 (defvar ibuffer-mode-map nil)
320 (defvar ibuffer-mode-operate-map nil)
321 (unless ibuffer-mode-map
322 (let ((map (make-sparse-keymap))
323 (operate-map (make-sparse-keymap "Operate")))
324 (define-key map (kbd "0") 'digit-argument)
325 (define-key map (kbd "1") 'digit-argument)
326 (define-key map (kbd "2") 'digit-argument)
327 (define-key map (kbd "3") 'digit-argument)
328 (define-key map (kbd "4") 'digit-argument)
329 (define-key map (kbd "5") 'digit-argument)
330 (define-key map (kbd "6") 'digit-argument)
331 (define-key map (kbd "7") 'digit-argument)
332 (define-key map (kbd "8") 'digit-argument)
333 (define-key map (kbd "9") 'digit-argument)
335 (define-key map (kbd "m") 'ibuffer-mark-forward)
336 (define-key map (kbd "t") 'ibuffer-toggle-marks)
337 (define-key map (kbd "u") 'ibuffer-unmark-forward)
338 (define-key map (kbd "=") 'ibuffer-diff-with-file)
339 (define-key map (kbd "j") 'ibuffer-jump-to-buffer)
340 (define-key map (kbd "DEL") 'ibuffer-unmark-backward)
341 (define-key map (kbd "M-DEL") 'ibuffer-unmark-all)
342 (define-key map (kbd "* *") 'ibuffer-unmark-all)
343 (define-key map (kbd "* M") 'ibuffer-mark-by-mode)
344 (define-key map (kbd "* m") 'ibuffer-mark-modified-buffers)
345 (define-key map (kbd "* u") 'ibuffer-mark-unsaved-buffers)
346 (define-key map (kbd "* s") 'ibuffer-mark-special-buffers)
347 (define-key map (kbd "* r") 'ibuffer-mark-read-only-buffers)
348 (define-key map (kbd "* /") 'ibuffer-mark-dired-buffers)
349 (define-key map (kbd "* e") 'ibuffer-mark-dissociated-buffers)
350 (define-key map (kbd "* h") 'ibuffer-mark-help-buffers)
351 (define-key map (kbd ".") 'ibuffer-mark-old-buffers)
353 (define-key map (kbd "d") 'ibuffer-mark-for-delete)
354 (define-key map (kbd "C-d") 'ibuffer-mark-for-delete-backwards)
355 (define-key map (kbd "k") 'ibuffer-mark-for-delete)
356 (define-key map (kbd "x") 'ibuffer-do-kill-on-deletion-marks)
358 ;; immediate operations
359 (define-key map (kbd "n") 'ibuffer-forward-line)
360 (define-key map (kbd "SPC") 'forward-line)
361 (define-key map (kbd "p") 'ibuffer-backward-line)
362 (define-key map (kbd "M-}") 'ibuffer-forward-next-marked)
363 (define-key map (kbd "M-{") 'ibuffer-backwards-next-marked)
364 (define-key map (kbd "l") 'ibuffer-redisplay)
365 (define-key map (kbd "g") 'ibuffer-update)
366 (define-key map "`" 'ibuffer-switch-format)
367 (define-key map "-" 'ibuffer-add-to-tmp-hide)
368 (define-key map "+" 'ibuffer-add-to-tmp-show)
369 (define-key map "b" 'ibuffer-bury-buffer)
370 (define-key map (kbd ",") 'ibuffer-toggle-sorting-mode)
371 (define-key map (kbd "s i") 'ibuffer-invert-sorting)
372 (define-key map (kbd "s a") 'ibuffer-do-sort-by-alphabetic)
373 (define-key map (kbd "s v") 'ibuffer-do-sort-by-recency)
374 (define-key map (kbd "s s") 'ibuffer-do-sort-by-size)
375 (define-key map (kbd "s m") 'ibuffer-do-sort-by-major-mode)
377 (define-key map (kbd "/ m") 'ibuffer-filter-by-mode)
378 (define-key map (kbd "/ n") 'ibuffer-filter-by-name)
379 (define-key map (kbd "/ c") 'ibuffer-filter-by-content)
380 (define-key map (kbd "/ e") 'ibuffer-filter-by-predicate)
381 (define-key map (kbd "/ f") 'ibuffer-filter-by-filename)
382 (define-key map (kbd "/ >") 'ibuffer-filter-by-size-gt)
383 (define-key map (kbd "/ <") 'ibuffer-filter-by-size-lt)
384 (define-key map (kbd "/ r") 'ibuffer-switch-to-saved-filters)
385 (define-key map (kbd "/ a") 'ibuffer-add-saved-filters)
386 (define-key map (kbd "/ x") 'ibuffer-delete-saved-filters)
387 (define-key map (kbd "/ d") 'ibuffer-decompose-filter)
388 (define-key map (kbd "/ s") 'ibuffer-save-filters)
389 (define-key map (kbd "/ p") 'ibuffer-pop-filter)
390 (define-key map (kbd "/ !") 'ibuffer-negate-filter)
391 (define-key map (kbd "/ t") 'ibuffer-exchange-filters)
392 (define-key map (kbd "/ TAB") 'ibuffer-exchange-filters)
393 (define-key map (kbd "/ o") 'ibuffer-or-filter)
394 (define-key map (kbd "/ /") 'ibuffer-filter-disable)
396 (define-key map (kbd "q") 'ibuffer-quit)
397 (define-key map (kbd "h") 'describe-mode)
398 (define-key map (kbd "?") 'describe-mode)
400 (define-key map (kbd "% n") 'ibuffer-mark-by-name-regexp)
401 (define-key map (kbd "% m") 'ibuffer-mark-by-mode-regexp)
402 (define-key map (kbd "% f") 'ibuffer-mark-by-file-name-regexp)
404 (define-key map (kbd "C-t") 'ibuffer-visit-tags-table)
406 (define-key map (kbd "|") 'ibuffer-do-shell-command-pipe)
407 (define-key map (kbd "!") 'ibuffer-do-shell-command-file)
408 (define-key map (kbd "~") 'ibuffer-do-toggle-modified)
410 (define-key map (kbd "A") 'ibuffer-do-view)
411 (define-key map (kbd "D") 'ibuffer-do-delete)
412 (define-key map (kbd "E") 'ibuffer-do-eval)
413 (define-key map (kbd "F") 'ibuffer-do-shell-command-file)
414 (define-key map (kbd "I") 'ibuffer-do-query-replace-regexp)
415 (define-key map (kbd "H") 'ibuffer-do-view-other-frame)
416 (define-key map (kbd "N") 'ibuffer-do-shell-command-pipe-replace)
417 (define-key map (kbd "M") 'ibuffer-do-toggle-modified)
418 (define-key map (kbd "O") 'ibuffer-do-occur)
419 (define-key map (kbd "P") 'ibuffer-do-print)
420 (define-key map (kbd "Q") 'ibuffer-do-query-replace)
421 (define-key map (kbd "R") 'ibuffer-do-rename-uniquely)
422 (define-key map (kbd "S") 'ibuffer-do-save)
423 (define-key map (kbd "T") 'ibuffer-do-toggle-read-only)
424 (define-key map (kbd "U") 'ibuffer-do-replace-regexp)
425 (define-key map (kbd "V") 'ibuffer-do-revert)
426 (define-key map (kbd "W") 'ibuffer-do-view-and-eval)
427 (define-key map (kbd "X") 'ibuffer-do-shell-command-pipe)
429 (define-key map (kbd "k") 'ibuffer-do-kill-lines)
430 (define-key map (kbd "w") 'ibuffer-copy-filename-as-kill)
432 (define-key map (kbd "RET") 'ibuffer-visit-buffer)
433 (define-key map (kbd "e") 'ibuffer-visit-buffer)
434 (define-key map (kbd "f") 'ibuffer-visit-buffer)
435 (define-key map (kbd "C-x C-f") 'ibuffer-find-file)
436 (define-key map (kbd "o") 'ibuffer-visit-buffer-other-window)
437 (define-key map (kbd "C-o") 'ibuffer-visit-buffer-other-window-noselect)
438 (define-key map (kbd "M-o") 'ibuffer-visit-buffer-1-window)
439 (define-key map (kbd "v") 'ibuffer-do-view)
440 (define-key map (kbd "C-x v") 'ibuffer-do-view-horizontally)
441 (define-key map (kbd "C-c C-a") 'ibuffer-auto-mode)
442 (define-key map (kbd "C-x 4 RET") 'ibuffer-visit-buffer-other-window)
443 (define-key map (kbd "C-x 5 RET") 'ibuffer-visit-buffer-other-frame)
445 (define-key map [menu-bar view]
446 (cons "View" (make-sparse-keymap "View")))
448 (define-key-after map [menu-bar view visit-buffer]
449 '(menu-item "View this buffer" ibuffer-visit-buffer))
450 (define-key-after map [menu-bar view visit-buffer-other-window]
451 '(menu-item "View (other window)" ibuffer-visit-buffer-other-window))
452 (define-key-after map [menu-bar view visit-buffer-other-frame]
453 '(menu-item "View (other frame)" ibuffer-visit-buffer-other-frame))
454 (define-key-after map [menu-bar view ibuffer-update]
455 '(menu-item "Update" ibuffer-update
456 :help "Regenerate the list of buffers"))
457 (define-key-after map [menu-bar view switch-format]
458 '(menu-item "Switch display format" ibuffer-switch-format
459 :help "Toggle between available values of `ibuffer-formats'"))
461 (define-key-after map [menu-bar view dashes]
464 (define-key-after map [menu-bar view sort]
465 (cons "Sort" (make-sparse-keymap "Sort")))
467 (define-key-after map [menu-bar view sort do-sort-by-major-mode]
468 '(menu-item "Sort by major mode" ibuffer-do-sort-by-major-mode
469 :help "Sort by the alphabetic order of the buffer's major mode"))
470 (define-key-after map [menu-bar view sort do-sort-by-size]
471 '(menu-item "Sort by buffer size" ibuffer-do-sort-by-size
472 :help "Sort by the size of the buffer"))
473 (define-key-after map [menu-bar view sort do-sort-by-alphabetic]
474 '(menu-item "Sort lexicographically" ibuffer-do-sort-by-alphabetic
475 :help "Sort by the alphabetic order of buffer name"))
476 (define-key-after map [menu-bar view sort do-sort-by-recency]
477 '(menu-item "Sort by view time" ibuffer-do-sort-by-recency
478 :help "Sort by the last time the buffer was displayed"))
479 (define-key-after map [menu-bar view sort invert-sorting]
480 '(menu-item "Reverse sorting order" ibuffer-invert-sorting))
481 (define-key-after map [menu-bar view sort toggle-sorting-mode]
482 '(menu-item "Switch sorting mode" ibuffer-toggle-sorting-mode
483 :help "Switch between the various sorting criteria"))
485 (define-key-after map [menu-bar view filter]
486 (cons "Filter" (make-sparse-keymap "Filter")))
488 (define-key-after map [menu-bar view filter filter-disable]
489 '(menu-item "Disable all filtering" ibuffer-filter-disable))
490 (define-key-after map [menu-bar view filter filter-by-mode]
491 '(menu-item "Add filter by major mode..." ibuffer-filter-by-mode
492 :help "Show only buffers in a major mode"))
493 (define-key-after map [menu-bar view filter filter-by-name]
494 '(menu-item "Add filter by buffer name..." ibuffer-filter-by-name
495 :help "Show only buffers whose name matches a regexp"))
496 (define-key-after map [menu-bar view filter filter-by-filename]
497 '(menu-item "Add filter by filename..." ibuffer-filter-by-filename
498 :help "Show only buffers whose filename matches a regexp"))
499 (define-key-after map [menu-bar view filter filter-by-size-lt]
500 '(menu-item "Add filter by size less than..." ibuffer-filter-by-size-lt
501 :help "Show only buffers of size less than..."))
502 (define-key-after map [menu-bar view filter filter-by-size-gt]
503 '(menu-item "Add filter by size greater than..." ibuffer-filter-by-size-gt
504 :help "Show only buffers of size greater than..."))
505 (define-key-after map [menu-bar view filter filter-by-content]
506 '(menu-item "Add filter by content (regexp)..." ibuffer-filter-by-content
507 :help "Show only buffers containing a regexp"))
508 (define-key-after map [menu-bar view filter filter-by-predicate]
509 '(menu-item "Add filter by Lisp predicate..." ibuffer-filter-by-predicate
510 :help "Show only buffers for which a predicate is true"))
511 (define-key-after map [menu-bar view filter pop-filter]
512 '(menu-item "Remove top filter" ibuffer-pop-filter))
513 (define-key-after map [menu-bar view filter or-filter]
514 '(menu-item "OR top two filters" ibuffer-or-filter
515 :help "Create a new filter which is the logical OR of the top two filters"))
516 (define-key-after map [menu-bar view filter negate-filter]
517 '(menu-item "Negate top filter" ibuffer-negate-filter))
518 (define-key-after map [menu-bar view filter decompose-filter]
519 '(menu-item "Decompose top filter" ibuffer-decompose-filter
520 :help "Break down a complex filter like OR or NOT"))
521 (define-key-after map [menu-bar view filter exchange-filters]
522 '(menu-item "Swap top two filters" ibuffer-exchange-filters))
523 (define-key-after map [menu-bar view filter save-filters]
524 '(menu-item "Save current filters permanently..." ibuffer-save-filters
525 :help "Use a mnemnonic name to store current filter stack"))
526 (define-key-after map [menu-bar view filter switch-to-saved-filters]
527 '(menu-item "Restore permanently saved filters..." ibuffer-switch-to-saved-filters
528 :help "Replace current filters with a saved stack"))
529 (define-key-after map [menu-bar view filter add-saved-filters]
530 '(menu-item "Add to permanently saved filters..." ibuffer-add-saved-filters
531 :help "Include current filters in an already saved stack"))
532 (define-key-after map [menu-bar view filter delete-saved-filters]
533 '(menu-item "Delete permanently saved filters..." ibuffer-delete-saved-filters
534 :help "Remove stack of filters from saved list"))
535 (define-key-after map [menu-bar view dashes2]
537 (define-key-after map [menu-bar view diff-with-file]
538 '(menu-item "Diff with file" ibuffer-diff-with-file
539 :help "View the differences between this buffer and its file"))
540 (define-key-after map [menu-bar view auto-mode]
541 '(menu-item "Toggle Auto Mode" ibuffer-auto-mode
542 :help "Attempt to automatically update the Ibuffer buffer"))
543 (define-key-after map [menu-bar view customize]
544 '(menu-item "Customize Ibuffer" (lambda () (interactive)
545 (customize-group 'ibuffer))
546 :help "Use Custom to customize Ibuffer"))
548 (define-key-after map [menu-bar mark]
549 (cons "Mark" (make-sparse-keymap "Mark")))
551 (define-key-after map [menu-bar mark toggle-marks]
552 '(menu-item "Toggle marks" ibuffer-toggle-marks
553 :help "Unmark marked buffers, and mark unmarked buffers"))
554 (define-key-after map [menu-bar mark mark-forward]
555 '(menu-item "Mark" ibuffer-mark-forward
556 :help "Mark the buffer at point"))
557 (define-key-after map [menu-bar mark unmark-forward]
558 '(menu-item "Unmark" ibuffer-unmark-forward
559 :help "Unmark the buffer at point"))
560 (define-key-after map [menu-bar mark mark-by-mode]
561 '(menu-item "Mark by mode..." ibuffer-mark-by-mode
562 :help "Mark all buffers in a particular major mode"))
563 (define-key-after map [menu-bar mark mark-modified-buffers]
564 '(menu-item "Mark modified buffers" ibuffer-mark-modified-buffers
565 :help "Mark all buffers which have been modified"))
566 (define-key-after map [menu-bar mark mark-unsaved-buffers]
567 '(menu-item "Mark unsaved buffers" ibuffer-mark-unsaved-buffers
568 :help "Mark all buffers which have a file and are modified"))
569 (define-key-after map [menu-bar mark mark-read-only-buffers]
570 '(menu-item "Mark read-only buffers" ibuffer-mark-read-only-buffers
571 :help "Mark all buffers which are read-only"))
572 (define-key-after map [menu-bar mark mark-special-buffers]
573 '(menu-item "Mark special buffers" ibuffer-mark-special-buffers
574 :help "Mark all buffers whose name begins with a *"))
575 (define-key-after map [menu-bar mark mark-dired-buffers]
576 '(menu-item "Mark dired buffers" ibuffer-mark-dired-buffers
577 :help "Mark buffers in dired-mode"))
578 (define-key-after map [menu-bar mark mark-dissociated-buffers]
579 '(menu-item "Mark dissociated buffers" ibuffer-mark-dissociated-buffers
580 :help "Mark buffers with a non-existent associated file"))
581 (define-key-after map [menu-bar mark mark-help-buffers]
582 '(menu-item "Mark help buffers" ibuffer-mark-help-buffers
583 :help "Mark buffers in help-mode"))
584 (define-key-after map [menu-bar mark mark-old-buffers]
585 '(menu-item "Mark old buffers" ibuffer-mark-old-buffers
586 :help "Mark buffers which have not been viewed recently"))
587 (define-key-after map [menu-bar mark unmark-all]
588 '(menu-item "Unmark All" ibuffer-unmark-all))
590 (define-key-after map [menu-bar mark dashes]
593 (define-key-after map [menu-bar mark mark-by-name-regexp]
594 '(menu-item "Mark by buffer name (regexp)..." ibuffer-mark-by-name-regexp
595 :help "Mark buffers whose name matches a regexp"))
596 (define-key-after map [menu-bar mark mark-by-mode-regexp]
597 '(menu-item "Mark by major mode (regexp)..." ibuffer-mark-by-mode-regexp
598 :help "Mark buffers whose major mode name matches a regexp"))
599 (define-key-after map [menu-bar mark mark-by-file-name-regexp]
600 '(menu-item "Mark by file name (regexp)..." ibuffer-mark-by-file-name-regexp
601 :help "Mark buffers whose file name matches a regexp"))
603 ;; Operate map is added later
605 (define-key-after operate-map [do-view]
606 '(menu-item "View" ibuffer-do-view))
607 (define-key-after operate-map [do-view-other-frame]
608 '(menu-item "View (separate frame)" ibuffer-do-view-other-frame))
609 (define-key-after operate-map [do-save]
610 '(menu-item "Save" ibuffer-do-save))
611 (define-key-after operate-map [do-replace-regexp]
612 '(menu-item "Replace (regexp)..." ibuffer-do-replace-regexp
613 :help "Replace text inside marked buffers"))
614 (define-key-after operate-map [do-query-replace]
615 '(menu-item "Query Replace..." ibuffer-do-query-replace
616 :help "Replace text in marked buffers, asking each time"))
617 (define-key-after operate-map [do-query-replace-regexp]
618 '(menu-item "Query Replace (regexp)..." ibuffer-do-query-replace-regexp
619 :help "Replace text in marked buffers by regexp, asking each time"))
620 (define-key-after operate-map [do-print]
621 '(menu-item "Print" ibuffer-do-print))
622 (define-key-after operate-map [do-toggle-modified]
623 '(menu-item "Toggle modification flag" ibuffer-do-toggle-modified))
624 (define-key-after operate-map [do-revert]
625 '(menu-item "Revert" ibuffer-do-revert
626 :help "Revert marked buffers to their associated file"))
627 (define-key-after operate-map [do-rename-uniquely]
628 '(menu-item "Rename Uniquely" ibuffer-do-rename-uniquely
629 :help "Rename marked buffers to a new, unique name"))
630 (define-key-after operate-map [do-delete]
631 '(menu-item "Kill" ibuffer-do-delete))
632 (define-key-after operate-map [do-occur]
633 '(menu-item "List lines matching..." ibuffer-do-occur
634 :help "View all lines in marked buffers matching a regexp"))
635 (define-key-after operate-map [do-shell-command-pipe]
636 '(menu-item "Pipe to shell command..." ibuffer-do-shell-command-pipe
637 :help "For each marked buffer, send its contents to a shell command"))
638 (define-key-after operate-map [do-shell-command-pipe-replace]
639 '(menu-item "Pipe to shell command (replace)..." ibuffer-do-shell-command-pipe-replace
640 :help "For each marked buffer, replace its contents with output of shell command"))
641 (define-key-after operate-map [do-shell-command-file]
642 '(menu-item "Shell command on buffer's file..." ibuffer-do-shell-command-file
643 :help "For each marked buffer, run a shell command with its file as argument"))
644 (define-key-after operate-map [do-eval]
645 '(menu-item "Eval..." ibuffer-do-eval
646 :help "Evaluate a Lisp form in each marked buffer"))
647 (define-key-after operate-map [do-view-and-eval]
648 '(menu-item "Eval (viewing buffer)..." ibuffer-do-view-and-eval
649 :help "Evaluate a Lisp form in each marked buffer while viewing it"))
651 (setq ibuffer-mode-map map
652 ibuffer-mode-operate-map operate-map)))
654 (defvar ibuffer-name-map nil)
655 (unless ibuffer-name-map
656 (let ((map (make-sparse-keymap)))
657 (set-keymap-parent map ibuffer-mode-map)
658 (define-key map [(mouse-1)] 'ibuffer-mouse-toggle-mark)
659 (define-key map [(mouse-2)] 'ibuffer-mouse-visit-buffer)
660 (define-key map [down-mouse-3] 'ibuffer-mouse-popup-menu)
661 (setq ibuffer-name-map map)))
663 (defvar ibuffer-mode-name-map nil)
664 (unless ibuffer-mode-name-map
665 (let ((map (make-sparse-keymap)))
666 (set-keymap-parent map ibuffer-mode-map)
667 (define-key map [(mouse-2)] 'ibuffer-mouse-filter-by-mode)
668 (define-key map (kbd "RET") 'ibuffer-interactive-filter-by-mode)
669 (setq ibuffer-mode-name-map map)))
671 ;; quiet the byte-compiler
672 (defvar ibuffer-mode-operate-menu nil)
673 (defvar ibuffer-mode-mark-menu nil)
674 (defvar ibuffer-mode-view-menu nil)
676 (defvar ibuffer-mode-hooks nil)
678 (defvar ibuffer-delete-window-on-quit nil
679 "Whether or not to delete the window upon exiting `ibuffer'.")
681 (defvar ibuffer-did-modification nil)
683 (defvar ibuffer-sorting-functions-alist nil
684 "An alist of functions which describe how to sort buffers.
686 Note: You most likely do not want to modify this variable directly;
687 use `define-ibuffer-sorter' instead.
689 The alist elements are constructed like (NAME DESCRIPTION FUNCTION)
690 Where NAME is a symbol describing the sorting method, DESCRIPTION is a
691 short string which will be displayed in the minibuffer and menu, and
692 FUNCTION is a function of two arguments, which will be the buffers to
695 ;;; Utility functions
696 (defun ibuffer-columnize-and-insert-list (list &optional pad-width)
697 "Insert LIST into the current buffer in as many columns as possible.
698 The maximum number of columns is determined by the current window
699 width and the longest string in LIST."
702 (let ((width (window-width))
703 (max (+ (apply #'max (mapcar #'length list))
705 (let ((columns (/ width max)))
706 (when (zerop columns)
709 (dotimes (i (1- columns))
710 (insert (concat (car list) (make-string (- max (length (car list)))
712 (setq list (cdr list)))
713 (when (not (null list))
717 (defun ibuffer-accumulate-lines (count)
719 (let ((forwardp (> count 0))
721 (while (not (or (zerop count)
730 (line-beginning-position)
733 (forward-line (if forwardp 1 -1)))
736 (defsubst ibuffer-current-mark ()
737 (cadr (get-text-property (line-beginning-position)
738 'ibuffer-properties)))
740 (defun ibuffer-mouse-toggle-mark (event)
741 "Toggle the marked status of the buffer chosen with the mouse."
745 (mouse-set-point event)
746 (let ((mark (ibuffer-current-mark)))
747 (setq buffer-read-only nil)
748 (if (eq mark ibuffer-marked-char)
749 (ibuffer-set-mark ? )
750 (ibuffer-set-mark ibuffer-marked-char))))
751 (setq buffer-read-only t)))
753 (defun ibuffer-find-file (file &optional wildcards)
754 "Like `find-file', but default to the directory of the buffer at point."
756 (let ((default-directory (let ((buf (ibuffer-current-buffer)))
757 (if (buffer-live-p buf)
758 (with-current-buffer buf
760 default-directory))))
761 (list (read-file-name "Find file: " default-directory)
762 current-prefix-arg)))
763 (find-file file wildcards))
765 (defun ibuffer-mouse-visit-buffer (event)
766 "Visit the buffer chosen with the mouse."
770 (mouse-set-point event)
771 (ibuffer-current-buffer))))
773 (defun ibuffer-mouse-popup-menu (event)
774 "Display a menu of operations."
776 (let ((origline (count-lines (point-min) (point))))
779 (setq buffer-read-only nil)
781 ;; hm. we could probably do this in a better fashion
782 (ibuffer-unmark-all ?\r)
783 (setq buffer-read-only nil)
784 (mouse-set-point event)
785 (ibuffer-set-mark ibuffer-marked-char)
786 (setq buffer-read-only nil)
788 (popup-menu ibuffer-mode-operate-map))))
790 (setq buffer-read-only t)
791 (goto-line (1+ origline))))))
793 (defun ibuffer-backward-line (&optional arg)
794 "Move backwards ARG lines, wrapping around the list if necessary."
801 (when (get-text-property (point) 'ibuffer-title)
802 (goto-char (point-max))
805 (setq arg (1- arg))))
807 (defun ibuffer-forward-line (&optional arg)
808 "Move forward ARG lines, wrapping around the list if necessary."
814 (ibuffer-backward-line (- arg))
816 (when (get-text-property (point) 'ibuffer-title)
817 ;; If we're already on the title, moving past it counts as
820 (while (and (get-text-property (point) 'ibuffer-title)
826 (goto-char (point-min)))
827 (while (and (get-text-property (point) 'ibuffer-title)
830 (setq arg (1- arg))))))
832 (defun ibuffer-visit-buffer ()
833 "Visit the buffer on this line."
835 (let ((buf (ibuffer-current-buffer)))
836 (unless (buffer-live-p buf)
837 (error "Buffer %s has been killed!" buf))
838 (bury-buffer (current-buffer))
839 (switch-to-buffer buf)))
841 (defun ibuffer-visit-buffer-other-window (&optional noselect)
842 "Visit the buffer on this line in another window."
844 (let ((buf (ibuffer-current-buffer)))
845 (unless (buffer-live-p buf)
846 (error "Buffer %s has been killed!" buf))
847 (bury-buffer (current-buffer))
849 (let ((curwin (selected-window)))
851 (select-window curwin))
852 (switch-to-buffer-other-window buf))))
854 (defun ibuffer-visit-buffer-other-window-noselect ()
855 "Visit the buffer on this line in another window, but don't select it."
857 (ibuffer-visit-buffer-other-window t))
859 (defun ibuffer-visit-buffer-other-frame ()
860 "Visit the buffer on this line in another frame."
862 (let ((buf (ibuffer-current-buffer)))
863 (unless (buffer-live-p buf)
864 (error "Buffer %s has been killed!" buf))
865 (bury-buffer (current-buffer))
866 (switch-to-buffer-other-frame buf)))
868 (defun ibuffer-visit-buffer-1-window ()
869 "Visit the buffer on this line, and delete other windows."
871 (let ((buf (ibuffer-current-buffer)))
872 (unless (buffer-live-p buf)
873 (error "Buffer %s has been killed!" buf))
874 (switch-to-buffer buf)
875 (delete-other-windows)))
877 (defun ibuffer-bury-buffer ()
878 "Bury the buffer on this line."
880 (let ((buf (ibuffer-current-buffer))
881 (line (+ 1 (count-lines 1 (point)))))
882 (unless (buffer-live-p buf)
883 (error "Buffer %s has been killed!" buf))
885 (ibuffer-update nil t)
888 (defun ibuffer-visit-tags-table ()
889 "Visit the tags table in the buffer on this line. See `visit-tags-table'."
891 (let ((file (buffer-file-name (ibuffer-current-buffer))))
893 (visit-tags-table file)
894 (error "Specified buffer has no file"))))
896 (defun ibuffer-do-view (&optional other-frame)
897 "View marked buffers, or the buffer on the current line.
898 If optional argument OTHER-FRAME is non-nil, then display each
899 marked buffer in a new frame. Otherwise, display each buffer as
900 a new window in the current frame, splitting vertically."
902 (ibuffer-do-view-1 (if other-frame 'other-frame 'vertically)))
904 (defun ibuffer-do-view-horizontally (&optional other-frame)
905 "As `ibuffer-do-view', but split windows horizontally."
907 (ibuffer-do-view-1 (if other-frame 'other-frame 'horizontally)))
909 (defun ibuffer-do-view-1 (type)
910 (let ((marked-bufs (ibuffer-get-marked-buffers)))
911 (when (null marked-bufs)
912 (setq marked-bufs (list (ibuffer-current-buffer))))
913 (unless (and (eq type 'other-frame)
915 (> (length marked-bufs) 3)
916 (not (y-or-n-p (format "Really create a new frame for %s buffers? "
917 (length marked-bufs)))))
918 (set-buffer-modified-p nil)
919 (delete-other-windows)
920 (switch-to-buffer (pop marked-bufs))
921 (let ((height (/ (1- (if (eq type 'horizontally) (frame-width)
923 (1+ (length marked-bufs)))))
924 (mapcar (if (eq type 'other-frame)
926 (let ((curframe (selected-frame)))
927 (select-frame (new-frame))
928 (switch-to-buffer buf)
929 (select-frame curframe)))
931 (split-window nil height (eq type 'horizontally))
933 (switch-to-buffer buf)))
936 (defun ibuffer-do-view-other-frame ()
937 "View each of the marked buffers in a separate frame."
941 (defsubst ibuffer-map-marked-lines (func)
942 (prog1 (ibuffer-map-on-mark ibuffer-marked-char func)
943 (ibuffer-redisplay t)))
945 (defun ibuffer-shrink-to-fit (&optional owin)
946 (fit-window-to-buffer nil (when owin (/ (frame-height)
947 (length (window-list (selected-frame)))))))
949 (defun ibuffer-confirm-operation-on (operation names)
950 "Display a buffer asking whether to perform OPERATION on NAMES."
952 (if (= (length names) 1)
953 (y-or-n-p (format "Really %s buffer %s? " operation (car names)))
954 (let ((buf (get-buffer-create "*Ibuffer confirmation*")))
955 (with-current-buffer buf
956 (setq buffer-read-only nil)
958 (ibuffer-columnize-and-insert-list names)
959 (goto-char (point-min))
960 (setq buffer-read-only t))
961 (let ((lastwin (car (last (ibuffer-window-list)))))
962 ;; Now attempt to display the buffer...
963 (save-window-excursion
964 (select-window lastwin)
965 ;; The window might be too small to split; in that case,
966 ;; try a few times to increase its size before giving up.
976 (if (or (> (incf attempts) 4)
977 (and (stringp (cadr err))
978 ;; This definitely falls in the ghetto hack category...
979 (not (string-match "too small" (cadr err)))))
981 (enlarge-window 3))))))
982 ;; This part doesn't work correctly sometimes under XEmacs.
983 (select-window (next-window))
984 (switch-to-buffer buf)
987 (fit-window-to-buffer)
988 (y-or-n-p (format "Really %s %d buffers? "
989 operation (length names))))
990 (kill-buffer buf))))))))
992 (defsubst ibuffer-map-lines-nomodify (function)
993 "As `ibuffer-map-lines', but don't set the modification flag."
994 (ibuffer-map-lines function t))
996 (defun ibuffer-buffer-names-with-mark (mark)
997 (let ((ibuffer-buffer-names-with-mark-result nil))
998 (ibuffer-map-lines-nomodify
999 #'(lambda (buf mk beg end)
1000 (when (char-equal mark mk)
1001 (push (buffer-name buf)
1002 ibuffer-buffer-names-with-mark-result))))
1003 ibuffer-buffer-names-with-mark-result))
1005 (defsubst ibuffer-marked-buffer-names ()
1006 (ibuffer-buffer-names-with-mark ibuffer-marked-char))
1008 (defsubst ibuffer-deletion-marked-buffer-names ()
1009 (ibuffer-buffer-names-with-mark ibuffer-deletion-char))
1011 (defun ibuffer-count-marked-lines (&optional all)
1013 (ibuffer-map-lines-nomodify
1014 #'(lambda (buf mark beg end)
1015 (not (char-equal mark ? ))))
1016 (ibuffer-map-lines-nomodify
1017 #'(lambda (buf mark beg end)
1018 (char-equal mark ibuffer-marked-char)))))
1020 (defsubst ibuffer-count-deletion-lines ()
1021 (ibuffer-map-lines-nomodify
1022 #'(lambda (buf mark beg end)
1023 (char-equal mark ibuffer-deletion-char))))
1025 (defsubst ibuffer-map-deletion-lines (func)
1026 (ibuffer-map-on-mark ibuffer-deletion-char func))
1028 (define-ibuffer-op save ()
1029 "Save marked buffers as with `save-buffer'."
1033 (when (buffer-modified-p buf)
1034 (if (not (with-current-buffer buf
1036 ;; handle the case where we're prompted
1038 (save-window-excursion
1039 (switch-to-buffer buf)
1041 (with-current-buffer buf
1045 (define-ibuffer-op toggle-modified ()
1046 "Toggle modification flag of marked buffers."
1047 (:opstring "(un)marked as modified"
1049 (set-buffer-modified-p (not (buffer-modified-p))))
1051 (define-ibuffer-op toggle-read-only ()
1052 "Toggle read only status in marked buffers."
1053 (:opstring "toggled read only status in"
1057 (define-ibuffer-op delete ()
1058 "Kill marked buffers as with `kill-this-buffer'."
1060 :active-opstring "kill"
1064 (if (kill-buffer buf)
1068 (define-ibuffer-op kill-on-deletion-marks ()
1069 "Kill buffers marked for deletion as with `kill-this-buffer'."
1071 :active-opstring "kill"
1076 (if (kill-buffer buf)
1080 (defun ibuffer-unmark-all (mark)
1081 "Unmark all buffers with mark MARK."
1082 (interactive "cRemove marks (RET means all):")
1083 (if (= (ibuffer-count-marked-lines t) 0)
1084 (message "No buffers marked; use 'm' to mark a buffer")
1086 ((char-equal mark ibuffer-marked-char)
1087 (ibuffer-map-marked-lines
1088 #'(lambda (buf mark beg end)
1089 (ibuffer-set-mark-1 ? )
1091 ((char-equal mark ibuffer-deletion-char)
1092 (ibuffer-map-deletion-lines
1093 #'(lambda (buf mark beg end)
1094 (ibuffer-set-mark-1 ? )
1098 #'(lambda (buf mark beg end)
1099 (when (not (char-equal mark ? ))
1100 (ibuffer-set-mark-1 ? ))
1102 (ibuffer-redisplay t))
1104 (defun ibuffer-toggle-marks ()
1105 "Toggle which buffers are marked.
1106 In other words, unmarked buffers become marked, and marked buffers
1111 #'(lambda (buf mark beg end)
1112 (cond ((eq mark ibuffer-marked-char)
1113 (ibuffer-set-mark-1 ? )
1116 (ibuffer-set-mark-1 ibuffer-marked-char)
1120 (message "%s buffers marked" count))
1121 (ibuffer-redisplay t))
1123 (defun ibuffer-mark-forward (arg)
1124 "Mark the buffer on this line, and move forward ARG lines."
1126 (ibuffer-mark-interactive arg ibuffer-marked-char 1))
1128 (defun ibuffer-unmark-forward (arg)
1129 "Unmark the buffer on this line, and move forward ARG lines."
1131 (ibuffer-mark-interactive arg ? 1))
1133 (defun ibuffer-unmark-backward (arg)
1134 "Unmark the buffer on this line, and move backward ARG lines."
1136 (ibuffer-mark-interactive arg ? -1))
1138 (defun ibuffer-mark-interactive (arg mark movement)
1139 (assert (eq major-mode 'ibuffer-mode))
1142 (while (and (get-text-property (line-beginning-position)
1147 (let ((inhibit-read-only t))
1149 (ibuffer-set-mark mark)
1150 (forward-line movement)
1151 (when (or (get-text-property (line-beginning-position)
1154 (forward-line (- movement))
1156 (setq arg (1- arg)))))
1158 (defun ibuffer-set-mark (mark)
1159 (assert (eq major-mode 'ibuffer-mode))
1160 (let ((inhibit-read-only t))
1161 (ibuffer-set-mark-1 mark)
1162 (setq ibuffer-did-modification t)
1163 (ibuffer-redisplay-current)))
1165 (defun ibuffer-set-mark-1 (mark)
1166 (let ((beg (line-beginning-position))
1167 (end (line-end-position)))
1168 (put-text-property beg end 'ibuffer-properties
1169 (list (ibuffer-current-buffer)
1172 (defun ibuffer-mark-for-delete (arg)
1173 "Mark the buffers on ARG lines forward for deletion."
1175 (ibuffer-mark-interactive arg ibuffer-deletion-char 1))
1177 (defun ibuffer-mark-for-delete-backwards (arg)
1178 "Mark the buffers on ARG lines backward for deletion."
1180 (ibuffer-mark-interactive arg ibuffer-deletion-char -1))
1182 (defun ibuffer-current-buffer (&optional must-be-live)
1183 (let ((buf (car (get-text-property (line-beginning-position)
1184 'ibuffer-properties))))
1185 (when (and must-be-live
1186 (not (buffer-live-p buf)))
1187 (error "Buffer %s has been killed!" buf))
1190 (defun ibuffer-current-format ()
1191 (when (null ibuffer-formats)
1192 (error "No format!"))
1193 (ibuffer-check-formats)
1194 (or ibuffer-current-format
1195 (setq ibuffer-current-format 0))
1196 (nth ibuffer-current-format ibuffer-compiled-formats))
1198 (defun ibuffer-expand-format-entry (form)
1199 (if (or (consp form)
1201 (let ((sym (intern (concat "ibuffer-make-column-"
1202 (symbol-name (if (consp form)
1205 (unless (or (fboundp sym)
1206 (assq sym ibuffer-inline-columns))
1207 (error "Unknown column %s in ibuffer-formats" form))
1208 (let (min max align elide)
1210 (setq min (or (nth 1 form) 0)
1211 max (or (nth 2 form) -1)
1212 align (or (nth 3 form) :left)
1213 elide (or (nth 4 form) nil))
1218 (list sym min max align elide)))
1221 (defun ibuffer-compile-make-eliding-form (strvar elide from-end-p)
1222 (let ((ellipsis (if (ibuffer-use-fontification)
1223 (propertize ibuffer-eliding-string 'face 'bold)
1224 ibuffer-eliding-string)))
1225 (if (or elide ibuffer-elide-long-columns)
1230 (length ibuffer-eliding-string)))
1232 (substring ,strvar 0 (- strlen ,(length ellipsis)))
1237 (defun ibuffer-compile-make-substring-form (strvar maxvar from-end-p)
1241 `(substring ,strvar 0 ,maxvar)))
1243 (defun ibuffer-compile-make-format-form (strvar widthform alignment)
1244 (let* ((left `(make-string tmp2 ? ))
1245 (right `(make-string (- tmp1 tmp2) ? )))
1247 (setq tmp1 ,widthform
1250 (:right `(concat ,left ,right ,strvar))
1251 (:center `(concat ,left ,strvar ,right))
1252 (:left `(concat ,strvar ,left ,right))
1253 (t (error "Invalid alignment %s" alignment))))))
1255 (defun ibuffer-compile-format (format)
1258 tmp1-used tmp2-used global-strlen-used)
1259 (dolist (form format)
1263 (let* ((form (ibuffer-expand-format-entry form))
1267 (align (nth 3 form))
1268 (elide (nth 4 form)))
1269 (let* ((from-end-p (when (minusp min)
1276 min-used max-used strlen-used)
1277 (when (or (not (integerp min)) (>= min 0))
1279 (setq str-used t strlen-used t global-strlen-used t
1280 tmp1-used t tmp2-used t)
1281 (setq minform `(progn
1283 ,(ibuffer-compile-make-format-form
1285 `(- ,(if (integerp min)
1290 (when (or (not (integerp max)) (> max 0))
1291 (setq str-used t max-used t)
1292 (setq maxform `(progn
1294 ,(ibuffer-compile-make-substring-form
1300 (setq strlen (length str))
1302 ,(ibuffer-compile-make-eliding-form 'str
1305 (let ((callform (ibuffer-aif (assq sym ibuffer-inline-columns)
1307 `(,sym buffer mark)))
1308 (mincompform `(< strlen ,(if (integerp min)
1311 (maxcompform `(> strlen ,(if (integerp max)
1314 (if (or min-used max-used)
1316 (when (and min-used (not (integerp min)))
1317 (push `(min ,min) letbindings))
1318 (when (and max-used (not (integerp max)))
1319 (push `(max ,max) letbindings))
1321 (if (and min-used max-used)
1333 `(setq str ,callform)
1335 `(strlen (length str))))
1338 (append outforms `((insert str)))))
1339 (push `(insert ,callform) outforms))
1344 (funcall (if (or ibuffer-always-compile-formats
1345 (featurep 'bytecomp))
1348 (nconc (list 'lambda '(buffer mark))
1349 `((let ,(append '(pt)
1352 (when global-strlen-used
1358 ,@(nreverse result))))))))
1360 (defvar ibuffer-compiled-formats nil)
1361 (defvar ibuffer-cached-formats nil)
1362 (defvar ibuffer-cached-eliding-string nil)
1363 (defvar ibuffer-cached-elide-long-columns 0)
1365 (defun ibuffer-recompile-formats ()
1366 "Recompile `ibuffer-formats'."
1368 (setq ibuffer-compiled-formats
1369 (mapcar #'ibuffer-compile-format ibuffer-formats)))
1371 (defun ibuffer-check-formats ()
1372 (when (or (null ibuffer-compiled-formats)
1373 (null ibuffer-cached-formats)
1374 (not (equal ibuffer-cached-formats ibuffer-formats))
1375 (null ibuffer-cached-eliding-string)
1376 (not (equal ibuffer-cached-eliding-string ibuffer-eliding-string))
1377 (eql 0 ibuffer-cached-elide-long-columns)
1378 (not (eql ibuffer-cached-elide-long-columns
1379 ibuffer-elide-long-columns)))
1380 (message "Formats have changed, recompiling...")
1381 (ibuffer-recompile-formats)
1382 (setq ibuffer-cached-formats ibuffer-formats
1383 ibuffer-cached-eliding-string ibuffer-eliding-string
1384 ibuffer-cached-elide-long-columns ibuffer-elide-long-columns)
1385 (message "Formats have changed, recompiling...done")))
1387 (defvar ibuffer-inline-columns nil)
1389 (define-ibuffer-column mark (:name " " :inline t)
1392 (define-ibuffer-column read-only (:name "R" :inline t)
1393 (if buffer-read-only
1397 (define-ibuffer-column modified (:name "M" :inline t)
1398 (if (buffer-modified-p)
1399 (string ibuffer-modified-char)
1402 (define-ibuffer-column name (:inline t
1404 ('mouse-face 'highlight 'keymap ibuffer-name-map
1405 'ibuffer-name-column t
1406 'help-echo "mouse-1: mark this buffer\nmouse-2: select this buffer\nmouse-3: operate on this buffer"))
1409 (define-ibuffer-column size (:inline t)
1410 (format "%s" (buffer-size)))
1412 (define-ibuffer-column mode (:inline t
1414 ('mouse-face 'highlight
1415 'keymap ibuffer-mode-name-map
1416 'help-echo "mouse-2: filter by this mode"))
1417 (format "%s" mode-name))
1419 (define-ibuffer-column process ()
1420 (let ((proc (get-buffer-process buffer)))
1421 (format "%s" (if proc
1422 (list proc (process-status proc))
1425 (define-ibuffer-column filename ()
1426 (let ((directory-abbrev-alist ibuffer-directory-abbrev-alist))
1427 (abbreviate-file-name
1428 (or buffer-file-name
1429 (and (boundp 'dired-directory)
1433 (defun ibuffer-format-column (str width alignment)
1434 (let ((left (make-string (/ width 2) ? ))
1435 (right (make-string (- width (/ width 2)) ? )))
1437 (:right (concat left right str))
1438 (:center (concat left str right))
1439 (t (concat str left right)))))
1441 (defun ibuffer-fontify-region-function (beg end &optional verbose)
1442 (when verbose (message "Fontifying..."))
1443 (let ((inhibit-read-only t))
1447 (while (< (point) end)
1448 (if (get-text-property (point) 'ibuffer-title-header)
1449 (put-text-property (point) (line-end-position) 'face ibuffer-title-face)
1450 (unless (get-text-property (point) 'ibuffer-title)
1451 (multiple-value-bind (buf mark)
1452 (get-text-property (point) 'ibuffer-properties)
1453 (let* ((namebeg (next-single-property-change (point) 'ibuffer-name-column
1454 nil (line-end-position)))
1455 (nameend (next-single-property-change namebeg 'ibuffer-name-column
1456 nil (line-end-position))))
1457 (put-text-property namebeg
1460 (cond ((char-equal mark ibuffer-marked-char)
1461 ibuffer-marked-face)
1462 ((char-equal mark ibuffer-deletion-char)
1463 ibuffer-deletion-face)
1467 (dolist (e ibuffer-fontification-alist result)
1468 (when (and (> (car e) level)
1469 (with-current-buffer buf
1473 (if (symbolp (caddr e))
1474 (if (facep (caddr e))
1476 (symbol-value (caddr e)))))))))))))))
1478 (when verbose (message "Fontifying...done")))
1480 (defun ibuffer-unfontify-region-function (beg end)
1481 (let ((inhibit-read-only t))
1482 (remove-text-properties beg end '(face nil))))
1484 (defun ibuffer-insert-buffer-line (buffer mark format)
1485 "Insert a line describing BUFFER and MARK using FORMAT."
1486 (assert (eq major-mode 'ibuffer-mode))
1487 (let ((beg (point)))
1488 ;; Here we inhibit `syntax-ppss-after-change-function' and other
1489 ;; things font-lock uses. Otherwise, updating is slowed down dramatically.
1490 (funcall format buffer mark)
1491 (put-text-property beg (point) 'ibuffer-properties (list buffer mark))
1495 (defun ibuffer-redisplay-current ()
1496 (assert (eq major-mode 'ibuffer-mode))
1500 (let ((buf (ibuffer-current-buffer)))
1502 (let ((mark (ibuffer-current-mark)))
1503 (delete-region (point) (1+ (line-end-position)))
1504 (ibuffer-insert-buffer-line
1506 (ibuffer-current-format))
1507 (when ibuffer-shrink-to-minimum-size
1508 (ibuffer-shrink-to-fit))))))
1510 (defun ibuffer-map-on-mark (mark func)
1512 #'(lambda (buf mk beg end)
1513 (if (char-equal mark mk)
1514 (funcall func buf mark beg end)
1517 (defun ibuffer-map-lines (function &optional nomodify)
1518 "Call FUNCTION for each buffer in an ibuffer.
1519 Don't set the ibuffer modification flag iff NOMODIFY is non-nil.
1521 FUNCTION is called with four arguments: the buffer object itself, the
1522 current mark symbol, and the beginning and ending line positions."
1523 (assert (eq major-mode 'ibuffer-mode))
1524 (let ((curline (count-lines (point-min)
1525 (line-beginning-position)))
1526 (deleted-lines-count 0)
1527 (ibuffer-map-lines-total 0)
1528 (ibuffer-map-lines-count 0))
1531 (setq buffer-read-only nil)
1532 (goto-char (point-min))
1533 (while (and (get-text-property (point) 'ibuffer-title)
1538 (if (buffer-live-p (ibuffer-current-buffer))
1541 (ibuffer-current-buffer)
1542 (ibuffer-current-mark)
1543 (line-beginning-position)
1544 (1+ (line-end-position))))
1545 ;; Kill the line if the buffer is dead
1547 ;; A given mapping function should return:
1548 ;; `nil' if it chose not to affect the buffer
1549 ;; `kill' means the remove line from the buffer list
1551 (incf ibuffer-map-lines-total)
1552 (cond ((null result)
1555 (delete-region (line-beginning-position)
1556 (1+ (line-end-position)))
1557 (incf deleted-lines-count)
1558 (incf ibuffer-map-lines-count))
1560 (incf ibuffer-map-lines-count)
1561 (forward-line 1)))))
1562 ibuffer-map-lines-count)
1564 (setq buffer-read-only t)
1566 (set-buffer-modified-p nil))
1567 (goto-line (- (1+ curline) deleted-lines-count))))))
1569 (defun ibuffer-get-marked-buffers ()
1570 "Return a list of buffer objects currently marked."
1572 (mapcar #'(lambda (e)
1573 (when (eq (cdr e) ibuffer-marked-char)
1575 (ibuffer-current-state-list))))
1577 (defun ibuffer-current-state-list (&optional include-lines)
1578 "Return a list like (BUF . MARK) of all buffers in an ibuffer.
1579 If optional argument INCLUDE-LINES is non-nil, return a list like
1581 (let ((ibuffer-current-state-list-tmp '()))
1582 ;; ah, if only we had closures. I bet this will mysteriously
1583 ;; break later. Don't blame me.
1584 (ibuffer-map-lines-nomodify
1586 #'(lambda (buf mark beg end)
1587 (when (buffer-live-p buf)
1588 (push (list buf mark beg) ibuffer-current-state-list-tmp)))
1589 #'(lambda (buf mark beg end)
1590 (when (buffer-live-p buf)
1591 (push (cons buf mark) ibuffer-current-state-list-tmp)))))
1592 (nreverse ibuffer-current-state-list-tmp)))
1594 (defsubst ibuffer-canonicalize-state-list (bmarklist)
1595 "Order BMARKLIST in the same way as the current buffer list."
1597 (mapcar #'(lambda (buf) (assq buf bmarklist)) (buffer-list))))
1599 (defun ibuffer-current-buffers-with-marks ()
1600 "Return a list like (BUF . MARK) of all open buffers."
1601 (let ((bufs (ibuffer-current-state-list)))
1602 (mapcar #'(lambda (buf) (let ((e (assq buf bufs)))
1608 (defun ibuffer-buf-matches-predicates (buf predicates)
1610 (name (buffer-name buf)))
1611 (dolist (pred predicates)
1612 (when (if (stringp pred)
1613 (string-match pred name)
1618 (defun ibuffer-filter-buffers (ibuffer-buf last bmarklist all)
1619 (let ((ext-loaded (featurep 'ibuf-ext)))
1622 ;; element should be like (BUFFER . MARK)
1624 (let* ((buf (car e)))
1626 ;; This takes precedence over anything else
1627 (or (and ibuffer-always-show-last-buffer
1629 (funcall (if ext-loaded
1630 #'ibuffer-ext-visible-p
1631 #'ibuffer-visible-p)
1632 buf all ibuffer-buf))
1636 (defun ibuffer-visible-p (buf all &optional ibuffer-buf)
1639 (ibuffer-buf-matches-predicates buf ibuffer-maybe-show-predicates)))
1640 (or ibuffer-view-ibuffer
1642 (not (eq ibuffer-buf buf))))))
1644 ;; This function is a special case; it's not defined by
1645 ;; `ibuffer-define-sorter'.
1646 (defun ibuffer-do-sort-by-recency ()
1647 "Sort the buffers by last view time."
1649 (setq ibuffer-sorting-mode 'recency)
1650 (ibuffer-redisplay t))
1652 (defun ibuffer-update-format ()
1653 (when (null ibuffer-current-format)
1654 (setq ibuffer-current-format 0))
1655 (when (null ibuffer-formats)
1656 (error "Ibuffer error: no formats!")))
1658 (defun ibuffer-switch-format ()
1659 "Switch the current display format."
1661 (assert (eq major-mode 'ibuffer-mode))
1662 (unless (consp ibuffer-formats)
1663 (error "Ibuffer error: No formats!"))
1664 (setq ibuffer-current-format
1665 (if (>= ibuffer-current-format (1- (length ibuffer-formats)))
1667 (1+ ibuffer-current-format)))
1668 (ibuffer-update-format)
1669 (ibuffer-redisplay t))
1671 (defun ibuffer-update-title (format)
1672 (assert (eq major-mode 'ibuffer-mode))
1673 ;; Don't do funky font-lock stuff here
1674 (let ((after-change-functions nil))
1675 (if (get-text-property (point-min) 'ibuffer-title)
1676 (delete-region (point-min)
1677 (next-single-property-change
1678 (point-min) 'ibuffer-title)))
1679 (goto-char (point-min))
1683 (let ((opos (point)))
1684 ;; Insert the title names.
1685 (dolist (element (mapcar #'ibuffer-expand-format-entry format))
1687 (if (stringp element)
1689 (let ((sym (car element))
1690 (min (cadr element))
1691 ;; (max (caddr element))
1692 (align (cadddr element)))
1693 ;; Ignore a negative min when we're inserting the title
1696 (let* ((name (or (get sym 'ibuffer-column-name)
1697 (error "Unknown column %s in ibuffer-formats" sym)))
1698 (len (length name)))
1701 (ibuffer-format-column name
1705 (put-text-property opos (point) 'ibuffer-title-header t)
1707 ;; Add the underlines
1708 (let ((str (save-excursion
1711 (buffer-substring (point) (line-end-position)))))
1712 (apply #'insert (mapcar
1714 (if (not (or (char-equal c ? )
1715 (char-equal c ?\n)))
1723 (defun ibuffer-update-mode-name ()
1724 (setq mode-name (format "Ibuffer by %s" (if ibuffer-sorting-mode
1725 ibuffer-sorting-mode
1727 (when ibuffer-sorting-reversep
1728 (setq mode-name (concat mode-name " [rev]")))
1729 (when (and (featurep 'ibuf-ext)
1731 (setq mode-name (concat mode-name " (Auto)")))
1733 (when (featurep 'ibuf-ext)
1734 (dolist (qualifier ibuffer-filtering-qualifiers)
1736 (concat result (ibuffer-format-qualifier qualifier))))
1737 (if ibuffer-use-header-line
1738 (setq header-line-format
1739 (when ibuffer-filtering-qualifiers
1740 (replace-regexp-in-string "%" "%%"
1741 (concat mode-name result))))
1743 (setq mode-name (concat mode-name result))
1744 (when (boundp 'header-line-format)
1745 (setq header-line-format nil)))))))
1747 (defun ibuffer-redisplay (&optional silent)
1748 "Redisplay the current list of buffers.
1750 This does not show new buffers; use `ibuffer-update' for that.
1752 If SILENT is non-`nil', do not generate progress messages."
1755 (message "Redisplaying current buffer list..."))
1756 (let ((blist (ibuffer-current-state-list)))
1758 (if (and (featurep 'ibuf-ext)
1759 ibuffer-filtering-qualifiers)
1760 (message "No buffers! (note: filtering in effect)")
1761 (error "No buffers!")))
1762 (ibuffer-insert-buffers-and-marks blist t)
1763 (ibuffer-update-mode-name)
1765 (message "Redisplaying current buffer list...done"))))
1767 (defun ibuffer-update (arg &optional silent)
1768 "Regenerate the list of all buffers.
1770 Display buffers whose name matches one of `ibuffer-maybe-show-predicates'
1771 iff arg ARG is non-nil.
1773 Do not display messages if SILENT is non-nil."
1775 (let* ((bufs (buffer-list))
1776 (blist (ibuffer-filter-buffers
1780 (eq ibuffer-always-show-last-buffer
1783 (string-match " \\*Minibuf"
1784 (buffer-name (cadr bufs))))
1787 (ibuffer-current-buffers-with-marks)
1790 (if (and (featurep 'ibuf-ext)
1791 ibuffer-filtering-qualifiers)
1792 (message "No buffers! (note: filtering in effect)")
1793 (error "No buffers!")))
1795 (message "Updating buffer list..."))
1796 (ibuffer-insert-buffers-and-marks blist
1798 (ibuffer-update-mode-name)
1800 (message "Updating buffer list...done")))
1801 (if (eq ibuffer-shrink-to-minimum-size 'onewindow)
1802 (ibuffer-shrink-to-fit t)
1803 (when ibuffer-shrink-to-minimum-size
1804 (ibuffer-shrink-to-fit)))
1805 (ibuffer-forward-line 0))
1807 (defun ibuffer-insert-buffers-and-marks (bmarklist &optional all)
1808 (assert (eq major-mode 'ibuffer-mode))
1809 (let ((--ibuffer-insert-buffers-and-marks-format
1810 (ibuffer-current-format))
1811 (orig (count-lines (point-min) (point)))
1812 ;; Inhibit font-lock caching tricks, since we're modifying the
1813 ;; entire buffer at once
1814 (after-change-functions nil))
1817 (setq buffer-read-only nil)
1819 (ibuffer-update-format)
1821 (let* ((sortdat (assq ibuffer-sorting-mode
1822 ibuffer-sorting-functions-alist))
1823 (func (caddr sortdat)))
1825 ;; actually sort the buffers
1826 (if (and sortdat func)
1827 (sort bmarklist func)
1829 ;; perhaps reverse the sorted buffer list
1830 (if ibuffer-sorting-reversep
1832 (nreverse result))))))
1833 (dolist (entry entries)
1834 (ibuffer-insert-buffer-line
1837 --ibuffer-insert-buffers-and-marks-format)))
1838 (ibuffer-update-title (nth ibuffer-current-format ibuffer-formats)))
1839 (setq buffer-read-only t)
1840 (set-buffer-modified-p ibuffer-did-modification)
1841 (setq ibuffer-did-modification nil)
1842 (goto-line (1+ orig)))))
1844 (defun ibuffer-quit ()
1845 "Quit this `ibuffer' session.
1846 Delete the current window iff `ibuffer-delete-window-on-quit' is non-nil."
1848 (if ibuffer-delete-window-on-quit
1851 (unless (= (count-windows) 1)
1856 (defun ibuffer-list-buffers (&optional files-only)
1857 "Display a list of buffers, in another window.
1858 If optional argument FILES-ONLY is non-nil, then add a filter for
1859 buffers which are visiting a file."
1861 (ibuffer t nil (when files-only
1862 '((filename . ".*"))) t))
1865 (defun ibuffer-other-window (&optional files-only)
1866 "Like `ibuffer', but displayed in another window by default.
1867 If optional argument FILES-ONLY is non-nil, then add a filter for
1868 buffers which are visiting a file."
1870 (ibuffer t nil (when files-only
1871 '((filename . ".*")))))
1874 (defun ibuffer (&optional other-window-p name qualifiers noselect shrink)
1875 "Begin using `ibuffer' to edit a list of buffers.
1876 Type 'h' after entering ibuffer for more information.
1878 Optional argument OTHER-WINDOW-P says to use another window.
1879 Optional argument NAME specifies the name of the buffer; it defaults
1881 Optional argument QUALIFIERS is an initial set of filtering qualifiers
1882 to use; see `ibuffer-filtering-qualifiers'.
1883 Optional argument NOSELECT means don't select the Ibuffer buffer.
1884 Optional argument SHRINK means shrink the buffer to minimal size. The
1885 special value `onewindow' means always use another window."
1887 (when ibuffer-use-other-window
1888 (setq other-window-p (not other-window-p)))
1889 (let* ((buf (get-buffer-create (or name "*Ibuffer*")))
1890 (already-in (eq (current-buffer) buf))
1893 (funcall (if noselect #'(lambda (buf) (display-buffer buf t)) #'pop-to-buffer) buf)
1894 (funcall (if noselect #'display-buffer #'switch-to-buffer) buf))
1895 (with-current-buffer buf
1896 (let ((owin (selected-window)))
1899 ;; We switch to the buffer's window in order to be able
1900 ;; to modify the value of point
1901 (select-window (get-buffer-window buf))
1902 (unless (eq major-mode 'ibuffer-mode)
1904 (setq need-update t))
1905 (when (ibuffer-use-fontification)
1906 (require 'font-lock))
1907 (setq ibuffer-delete-window-on-quit other-window-p)
1909 (setq ibuffer-shrink-to-minimum-size shrink))
1911 (setq ibuffer-filtering-qualifiers qualifiers))
1912 (ibuffer-update nil)
1915 (setq buffer-read-only nil)
1916 (run-hooks 'ibuffer-hooks))
1917 (setq buffer-read-only t))
1918 (unless ibuffer-expert
1919 (message "Commands: m, u, t, RET, g, k, S, D, Q; q to quit; h for help")))
1920 (select-window owin))))))
1922 (defun ibuffer-mode ()
1923 "A major mode for viewing a list of buffers.
1924 In ibuffer, you can conveniently perform many operations on the
1925 currently open buffers, in addition to filtering your view to a
1926 particular subset of them, and sorting by various criteria.
1928 Operations on marked buffers:
1930 '\\[ibuffer-do-save]' - Save the marked buffers
1931 '\\[ibuffer-do-view]' - View the marked buffers in this frame.
1932 '\\[ibuffer-do-view-other-frame]' - View the marked buffers in another frame.
1933 '\\[ibuffer-do-revert]' - Revert the marked buffers.
1934 '\\[ibuffer-do-toggle-read-only]' - Toggle read-only state of marked buffers.
1935 '\\[ibuffer-do-delete]' - Kill the marked buffers.
1936 '\\[ibuffer-do-replace-regexp]' - Replace by regexp in each of the marked
1938 '\\[ibuffer-do-query-replace]' - Query replace in each of the marked buffers.
1939 '\\[ibuffer-do-query-replace-regexp]' - As above, with a regular expression.
1940 '\\[ibuffer-do-print]' - Print the marked buffers.
1941 '\\[ibuffer-do-occur]' - List lines in all marked buffers which match
1942 a given regexp (like the function `occur').
1943 '\\[ibuffer-do-shell-command-pipe]' - Pipe the contents of the marked
1944 buffers to a shell command.
1945 '\\[ibuffer-do-shell-command-pipe-replace]' - Replace the contents of the marked
1946 buffers with the output of a shell command.
1947 '\\[ibuffer-do-shell-command-file]' - Run a shell command with the
1948 buffer's file as an argument.
1949 '\\[ibuffer-do-eval]' - Evaluate a form in each of the marked buffers. This
1950 is a very flexible command. For example, if you want to make all
1951 of the marked buffers read only, try using (toggle-read-only 1) as
1953 '\\[ibuffer-do-view-and-eval]' - As above, but view each buffer while the form
1955 '\\[ibuffer-do-kill-lines]' - Remove the marked lines from the *Ibuffer* buffer,
1956 but don't kill the associated buffer.
1957 '\\[ibuffer-do-kill-on-deletion-marks]' - Kill all buffers marked for deletion.
1961 '\\[ibuffer-mark-forward]' - Mark the buffer at point.
1962 '\\[ibuffer-toggle-marks]' - Unmark all currently marked buffers, and mark
1963 all unmarked buffers.
1964 '\\[ibuffer-unmark-forward]' - Unmark the buffer at point.
1965 '\\[ibuffer-unmark-backward]' - Unmark the buffer at point, and move to the
1967 '\\[ibuffer-unmark-all]' - Unmark all marked buffers.
1968 '\\[ibuffer-mark-by-mode]' - Mark buffers by major mode.
1969 '\\[ibuffer-mark-unsaved-buffers]' - Mark all \"unsaved\" buffers.
1970 This means that the buffer is modified, and has an associated file.
1971 '\\[ibuffer-mark-modified-buffers]' - Mark all modified buffers,
1972 regardless of whether or not they have an associated file.
1973 '\\[ibuffer-mark-special-buffers]' - Mark all buffers whose name begins and
1975 '\\[ibuffer-mark-dissociated-buffers]' - Mark all buffers which have
1976 an associated file, but that file doesn't currently exist.
1977 '\\[ibuffer-mark-read-only-buffers]' - Mark all read-only buffers.
1978 '\\[ibuffer-mark-dired-buffers]' - Mark buffers in `dired' mode.
1979 '\\[ibuffer-mark-help-buffers]' - Mark buffers in `help-mode', `apropos-mode', etc.
1980 '\\[ibuffer-mark-old-buffers]' - Mark buffers older than `ibuffer-old-time'.
1981 '\\[ibuffer-mark-for-delete]' - Mark the buffer at point for deletion.
1982 '\\[ibuffer-mark-by-name-regexp]' - Mark buffers by their name, using a regexp.
1983 '\\[ibuffer-mark-by-mode-regexp]' - Mark buffers by their major mode, using a regexp.
1984 '\\[ibuffer-mark-by-file-name-regexp]' - Mark buffers by their filename, using a regexp.
1988 '\\[ibuffer-filter-by-mode]' - Add a filter by major mode.
1989 '\\[ibuffer-filter-by-name]' - Add a filter by buffer name.
1990 '\\[ibuffer-filter-by-content]' - Add a filter by buffer content.
1991 '\\[ibuffer-filter-by-filename]' - Add a filter by filename.
1992 '\\[ibuffer-filter-by-size-gt]' - Add a filter by buffer size.
1993 '\\[ibuffer-filter-by-size-lt]' - Add a filter by buffer size.
1994 '\\[ibuffer-filter-by-predicate]' - Add a filter by an arbitrary Lisp predicate.
1995 '\\[ibuffer-save-filters]' - Save the current filters with a name.
1996 '\\[ibuffer-switch-to-saved-filters]' - Switch to previously saved filters.
1997 '\\[ibuffer-add-saved-filters]' - Add saved filters to current filters.
1998 '\\[ibuffer-or-filter]' - Replace the top two filters with their logical OR.
1999 '\\[ibuffer-pop-filter]' - Remove the top filter.
2000 '\\[ibuffer-negate-filter]' - Invert the logical sense of the top filter.
2001 '\\[ibuffer-decompose-filter]' - Break down the topmost filter.
2002 '\\[ibuffer-filter-disable]' - Remove all filtering currently in effect.
2006 '\\[ibuffer-toggle-sorting-mode]' - Rotate between the various sorting modes.
2007 '\\[ibuffer-invert-sorting]' - Reverse the current sorting order.
2008 '\\[ibuffer-do-sort-by-alphabetic]' - Sort the buffers lexicographically.
2009 '\\[ibuffer-do-sort-by-recency]' - Sort the buffers by last viewing time.
2010 '\\[ibuffer-do-sort-by-size]' - Sort the buffers by size.
2011 '\\[ibuffer-do-sort-by-major-mode]' - Sort the buffers by major mode.
2015 '\\[ibuffer-switch-format]' - Change the current display format.
2016 '\\[forward-line]' - Move point to the next line.
2017 '\\[previous-line]' - Move point to the previous line.
2018 '\\[ibuffer-update]' - As above, but add new buffers to the list.
2019 '\\[ibuffer-quit]' - Bury the Ibuffer buffer.
2020 '\\[describe-mode]' - This help.
2021 '\\[ibuffer-diff-with-file]' - View the differences between this buffer
2022 and its associated file.
2023 '\\[ibuffer-visit-buffer]' - View the buffer on this line.
2024 '\\[ibuffer-visit-buffer-other-window]' - As above, but in another window.
2025 '\\[ibuffer-visit-buffer-other-window-noselect]' - As both above, but don't select
2027 '\\[ibuffer-bury-buffer]' - Bury (not kill!) the buffer on this line.
2029 Information on Filtering:
2031 You can filter your ibuffer view via different critera. Each Ibuffer
2032 buffer has its own stack of active filters. For example, suppose you
2033 are working on an Emacs Lisp project. You can create an Ibuffer
2034 buffer displays buffers in just `emacs-lisp' modes via
2035 '\\[ibuffer-filter-by-mode] emacs-lisp-mode RET'. In this case, there
2036 is just one entry on the filtering stack.
2038 You can also combine filters. The various filtering commands push a
2039 new filter onto the stack, and the filters combine to show just
2040 buffers which satisfy ALL criteria on the stack. For example, suppose
2041 you only want to see buffers in `emacs-lisp' mode, whose names begin
2042 with \"gnus\". You can accomplish this via:
2043 '\\[ibuffer-filter-by-mode] emacs-lisp-mode RET
2044 \\[ibuffer-filter-by-name] ^gnus RET'.
2046 Additionally, you can OR the top two filters together with
2047 '\\[ibuffer-or-filters]'. To see all buffers in either
2048 `emacs-lisp-mode' or `lisp-interaction-mode', type:
2050 '\\[ibuffer-filter-by-mode] emacs-lisp-mode RET \\[ibuffer-filter-by-mode] lisp-interaction-mode RET \\[ibuffer-or-filters]'.
2052 Filters can also be saved and restored using mnemonic names: see the
2053 functions `ibuffer-save-filters' and `ibuffer-switch-to-saved-filters'.
2055 To remove the top filter on the stack, use '\\[ibuffer-pop-filter]', and
2056 to disable all filtering currently in effect, use
2057 '\\[ibuffer-filter-disable]'."
2058 (kill-all-local-variables)
2059 (use-local-map ibuffer-mode-map)
2060 (setq major-mode 'ibuffer-mode)
2061 (setq mode-name "Ibuffer")
2062 (setq buffer-read-only t)
2063 (buffer-disable-undo)
2064 (setq truncate-lines t)
2065 ;; This makes things less ugly for Emacs 21 users with a non-nil
2066 ;; `show-trailing-whitespace'.
2067 (setq show-trailing-whitespace nil)
2068 ;; Dummy font-lock-defaults to make font-lock turn on. We want this
2069 ;; so we know when to enable ibuffer's internal fontification.
2070 (set (make-local-variable 'font-lock-defaults)
2072 (font-lock-fontify-region-function . ibuffer-fontify-region-function)
2073 (font-lock-unfontify-region-function . ibuffer-unfontify-region-function)))
2074 (set (make-local-variable 'revert-buffer-function)
2076 (set (make-local-variable 'ibuffer-sorting-mode)
2077 ibuffer-default-sorting-mode)
2078 (set (make-local-variable 'ibuffer-sorting-reversep)
2079 ibuffer-default-sorting-reversep)
2080 (set (make-local-variable 'ibuffer-shrink-to-minimum-size)
2081 ibuffer-default-shrink-to-minimum-size)
2082 (set (make-local-variable 'ibuffer-filtering-qualifiers) nil)
2083 (set (make-local-variable 'ibuffer-compiled-formats) nil)
2084 (set (make-local-variable 'ibuffer-cached-formats) nil)
2085 (set (make-local-variable 'ibuffer-cached-eliding-string) nil)
2086 (set (make-local-variable 'ibuffer-cached-elide-long-columns) nil)
2087 (set (make-local-variable 'ibuffer-current-format) nil)
2088 (set (make-local-variable 'ibuffer-did-modifiction) nil)
2089 (set (make-local-variable 'ibuffer-delete-window-on-quit) nil)
2090 (set (make-local-variable 'ibuffer-did-modification) nil)
2091 (when (featurep 'ibuf-ext)
2092 (set (make-local-variable 'ibuffer-tmp-hide-regexps) nil)
2093 (set (make-local-variable 'ibuffer-tmp-show-regexps) nil))
2094 (define-key ibuffer-mode-map [menu-bar edit] 'undefined)
2095 (define-key ibuffer-mode-map [menu-bar operate] (cons "Operate" ibuffer-mode-operate-map))
2096 (ibuffer-update-format)
2097 (when ibuffer-default-directory
2098 (setq default-directory ibuffer-default-directory))
2099 (run-hooks 'ibuffer-mode-hooks)
2100 ;; called after mode hooks to allow the user to add filters
2101 (ibuffer-update-mode-name))
2106 ;; coding: iso-8859-1
2109 ;;; ibuffer.el ends here