Convert consecutive FSF copyright years to ranges.
[bpt/emacs.git] / lisp / ibuffer.el
CommitLineData
25d2f683
CW
1;;; ibuffer.el --- operate on buffers like dired
2
73b0cd50 3;; Copyright (C) 2000-2011 Free Software Foundation, Inc.
25d2f683
CW
4
5;; Author: Colin Walters <walters@verbum.org>
4e4a724c 6;; Maintainer: John Paul Wallington <jpw@gnu.org>
25d2f683 7;; Created: 8 Sep 2000
25d2f683 8;; Keywords: buffer, convenience
25d2f683 9
b5cd37ea 10;; This file is part of GNU Emacs.
25d2f683 11
eb3fa2cf
GM
12;; GNU Emacs is free software: you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
25d2f683 16
eb3fa2cf
GM
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
25d2f683
CW
21
22;; You should have received a copy of the GNU General Public License
eb3fa2cf 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
25d2f683
CW
24
25;;; Commentary:
26
27;; ibuffer.el is an advanced replacement for the `buffer-menu' which
28;; is normally distributed with Emacs. Its interface is intended to
29;; be analogous to that of Dired.
30
31;;; Code:
32
33(eval-when-compile
34 (require 'cl)
35 (require 'ibuf-macs)
36 (require 'dired))
37
730da5b2 38(require 'font-core)
fd225d80 39
735d7026
JB
40;; These come from ibuf-ext.el, which can not be require'd at compile time
41;; because it has a recursive dependency on ibuffer.el
42(defvar ibuffer-auto-mode)
43(defvar ibuffer-cached-filter-formats)
44(defvar ibuffer-compiled-filter-formats)
45(defvar ibuffer-filter-format-alist)
46(defvar ibuffer-filter-group-kill-ring)
47(defvar ibuffer-filter-groups)
48(defvar ibuffer-filtering-qualifiers)
6d11a78b 49(defvar ibuffer-header-line-format)
735d7026
JB
50(defvar ibuffer-hidden-filter-groups)
51(defvar ibuffer-inline-columns)
52(defvar ibuffer-show-empty-filter-groups)
53(defvar ibuffer-tmp-hide-regexps)
54(defvar ibuffer-tmp-show-regexps)
63f0a166 55
2ead9289 56(declare-function ibuffer-mark-on-buffer "ibuf-ext"
004a00f4 57 (func &optional ibuffer-mark-on-buffer-mark group))
2ead9289 58(declare-function ibuffer-generate-filter-groups "ibuf-ext"
004a00f4
DN
59 (bmarklist &optional noempty nodefault))
60(declare-function ibuffer-format-filter-group-data "ibuf-ext" (filter))
61
25d2f683
CW
62(defgroup ibuffer nil
63 "An advanced replacement for `buffer-menu'.
64
65Ibuffer allows you to operate on buffers in a manner much like Dired.
66Operations include sorting, marking by regular expression, and
67the ability to filter the displayed buffers by various criteria."
bf247b6e 68 :version "22.1"
25d2f683
CW
69 :group 'convenience)
70
ac3c7293
JPW
71(defcustom ibuffer-formats '((mark modified read-only " " (name 18 18 :left :elide)
72 " " (size 9 -1 :right)
b9debd54 73 " " (mode 16 16 :left :elide) " " filename-and-process)
25d2f683
CW
74 (mark " " (name 16 -1) " " filename))
75 "A list of ways to display buffer lines.
76
77With Ibuffer, you are not limited to displaying just certain
78attributes of a buffer such as size, name, and mode in a particular
cba63a2d 79order. Through this variable, you can completely customize and
25d2f683
CW
80control the appearance of an Ibuffer buffer. See also
81`define-ibuffer-column', which allows you to define your own columns
82for display.
83
84This variable has the form
2e4fae7d 85 ((COLUMN COLUMN ...) (COLUMN COLUMN ...) ...)
25d2f683
CW
86Each element in `ibuffer-formats' should be a list containing COLUMN
87specifiers. A COLUMN can be any of the following:
88
89 SYMBOL - A symbol naming the column. Predefined columns are:
90 mark modified read-only name size mode process filename
91 When you define your own columns using `define-ibuffer-column', just
92 use their name like the predefined columns here. This entry can
93 also be a function of two arguments, which should return a string.
94 The first argument is the buffer object, and the second is the mark
95 on that buffer.
96 or
97 \"STRING\" - A literal string to display.
98 or
99 (SYMBOL MIN-SIZE MAX-SIZE &optional ALIGN ELIDE) - SYMBOL is a
100 symbol naming the column, and MIN-SIZE and MAX-SIZE are integers (or
101 functions of no arguments returning an integer) which constrict the
102 size of a column. If MAX-SIZE is -1, there is no upper bound. The
103 default values are 0 and -1, respectively. If MIN-SIZE is negative,
104 use the end of the string. The optional element ALIGN describes the
105 alignment of the column; it can be :left, :center or :right. The
106 optional element ELIDE describes whether or not to elide the column
107 if it is too long; valid values are :elide and nil. The default is
108 nil (don't elide).
109
110Some example of valid entries in `ibuffer-formats', with
111description (also, feel free to try them out, and experiment with your
112own!):
113
114 (mark \" \" name)
115 This format just displays the current mark (if any) and the name of
116 the buffer, separated by a space.
117 (mark modified read-only \" \" (name 16 16 :left) \" \" (size 6 -1 :right))
118 This format displays the current mark (if any), its modification and
119 read-only status, as well as the name of the buffer and its size. In
120 this format, the name is restricted to 16 characters (longer names
523304ed 121 will be truncated, and shorter names will be padded with spaces), and
cba63a2d 122 the name is also aligned to the left. The size of the buffer will
25d2f683
CW
123 be padded with spaces up to a minimum of six characters, but there is
124 no upper limit on its size. The size will also be aligned to the
125 right.
126
127Thus, if you wanted to use these two formats, add
128
129 (setq ibuffer-formats '((mark \" \" name)
130 (mark modified read-only
131 (name 16 16 :left) (size 6 -1 :right))))
132
133to your ~/.emacs file.
134
135Using \\[ibuffer-switch-format], you can rotate the display between
136the specified formats in the list."
137 :type '(repeat sexp)
138 :group 'ibuffer)
139
140(defcustom ibuffer-always-compile-formats (featurep 'bytecomp)
141 "If non-nil, then use the byte-compiler to optimize `ibuffer-formats'.
142This will increase the redisplay speed, at the cost of loading the
143elisp byte-compiler."
144 :type 'boolean
145 :group 'ibuffer)
146
147(defcustom ibuffer-fontification-alist
40c10465 148 `((10 buffer-read-only font-lock-constant-face)
9fe14abe
JPW
149 (15 (and buffer-file-name
150 (string-match ibuffer-compressed-file-name-regexp
151 buffer-file-name))
152 font-lock-doc-face)
153 (20 (string-match "^*" (buffer-name)) font-lock-keyword-face)
154 (25 (and (string-match "^ " (buffer-name))
da337a28
JPW
155 (null buffer-file-name))
156 italic)
9fe14abe
JPW
157 (30 (memq major-mode ibuffer-help-buffer-modes) font-lock-comment-face)
158 (35 (eq major-mode 'dired-mode) font-lock-function-name-face))
25d2f683
CW
159 "An alist describing how to fontify buffers.
160Each element should be of the form (PRIORITY FORM FACE), where
161PRIORITY is an integer, FORM is an arbitrary form to evaluate in the
162buffer, and FACE is the face to use for fontification. If the FORM
163evaluates to non-nil, then FACE will be put on the buffer name. The
fd225d80
CW
164element with the highest PRIORITY takes precedence.
165
4e4a724c 166If you change this variable, you must kill the Ibuffer buffer and
fd225d80 167recreate it for the change to take effect."
25d2f683
CW
168 :type '(repeat
169 (list (integer :tag "Priority")
170 (sexp :tag "Test Form")
171 face))
172 :group 'ibuffer)
173
174(defcustom ibuffer-use-other-window nil
7ad5b902 175 "If non-nil, display Ibuffer in another window by default."
25d2f683
CW
176 :type 'boolean
177 :group 'ibuffer)
178
179(defcustom ibuffer-default-shrink-to-minimum-size nil
180 "If non-nil, minimize the size of the Ibuffer window by default."
181 :type 'boolean
182 :group 'ibuffer)
183(defvar ibuffer-shrink-to-minimum-size nil)
184
0740098c
JPW
185(defcustom ibuffer-display-summary t
186 "If non-nil, summarize Ibuffer columns."
187 :type 'boolean
188 :group 'ibuffer)
189
3eda3649
CW
190(defcustom ibuffer-truncate-lines t
191 "If non-nil, do not display continuation lines."
192 :type 'boolean
193 :group 'ibuffer)
194
25d2f683
CW
195(defcustom ibuffer-case-fold-search case-fold-search
196 "If non-nil, ignore case when searching."
197 :type 'boolean
198 :group 'ibuffer)
199
200(defcustom ibuffer-default-sorting-mode 'recency
201 "The criteria by which to sort the buffers.
202
4e4a724c
JPW
203Note that this variable is local to each Ibuffer buffer. Thus, you
204can have multiple Ibuffer buffers open, each with a different sorted
25d2f683
CW
205view of the buffers."
206 :type '(choice (const :tag "Last view time" :value recency)
207 (const :tag "Lexicographic" :value alphabetic)
208 (const :tag "Buffer size" :value size)
d5794180 209 (const :tag "File name" :value filename/process)
25d2f683
CW
210 (const :tag "Major mode" :value major-mode))
211 :group 'ibuffer)
212(defvar ibuffer-sorting-mode nil)
e7820654 213(defvar ibuffer-last-sorting-mode nil)
25d2f683
CW
214
215(defcustom ibuffer-default-sorting-reversep nil
216 "If non-nil, reverse the default sorting order."
217 :type 'boolean
218 :group 'ibuffer)
219(defvar ibuffer-sorting-reversep nil)
220
221(defcustom ibuffer-elide-long-columns nil
972b8f82 222 "If non-nil, then elide column entries which exceed their max length."
25d2f683
CW
223 :type 'boolean
224 :group 'ibuffer)
972b8f82
JB
225(make-obsolete-variable 'ibuffer-elide-long-columns
226 "use the :elide argument of `ibuffer-formats'."
227 "22.1")
25d2f683
CW
228
229(defcustom ibuffer-eliding-string "..."
230 "The string to use for eliding long columns."
231 :type 'string
232 :group 'ibuffer)
233
234(defcustom ibuffer-maybe-show-predicates `(,(lambda (buf)
235 (and (string-match "^ " (buffer-name buf))
236 (null buffer-file-name))))
4e4a724c
JPW
237 "A list of predicates for buffers to display conditionally.
238
239A predicate can be a regexp or a function.
25d2f683
CW
240If a regexp, then it will be matched against the buffer's name.
241If a function, it will be called with the buffer as an argument, and
242should return non-nil if this buffer should be shown.
243
957237cb 244Viewing of buffers hidden because of these predicates may be customized
bf247b6e 245via `ibuffer-default-display-maybe-show-predicates' and is toggled by
957237cb
JPW
246giving a non-nil prefix argument to `ibuffer-update'.
247Note that this specialized filtering occurs before real filtering."
25d2f683
CW
248 :type '(repeat (choice regexp function))
249 :group 'ibuffer)
250
957237cb
JPW
251(defcustom ibuffer-default-display-maybe-show-predicates nil
252 "Non-nil means show buffers that match `ibuffer-maybe-show-predicates'."
253 :type 'boolean
254 :group 'ibuffer)
255
256(defvar ibuffer-display-maybe-show-predicates nil)
257
25d2f683
CW
258(defvar ibuffer-current-format nil)
259
0ce780e1
CW
260(defcustom ibuffer-movement-cycle t
261 "If non-nil, then forward and backwards movement commands cycle."
262 :type 'boolean
263 :group 'ibuffer)
264
25d2f683
CW
265(defcustom ibuffer-modified-char ?*
266 "The character to display for modified buffers."
267 :type 'character
268 :group 'ibuffer)
269
270(defcustom ibuffer-read-only-char ?%
271 "The character to display for read-only buffers."
272 :type 'character
273 :group 'ibuffer)
274
275(defcustom ibuffer-marked-char ?>
276 "The character to display for marked buffers."
277 :type 'character
278 :group 'ibuffer)
279
280(defcustom ibuffer-deletion-char ?D
281 "The character to display for buffers marked for deletion."
282 :type 'character
283 :group 'ibuffer)
284
285(defcustom ibuffer-expert nil
286 "If non-nil, don't ask for confirmation of \"dangerous\" operations."
287 :type 'boolean
288 :group 'ibuffer)
289
290(defcustom ibuffer-view-ibuffer nil
291 "If non-nil, display the current Ibuffer buffer itself.
292Note that this has a drawback - the data about the current Ibuffer
293buffer will most likely be inaccurate. This includes modification
294state, size, etc."
295 :type 'boolean
296 :group 'ibuffer)
297
298(defcustom ibuffer-always-show-last-buffer nil
4e4a724c
JPW
299 "If non-nil, always display the previous buffer.
300This variable takes precedence over filtering, and even
25d2f683
CW
301`ibuffer-never-show-predicates'."
302 :type '(choice (const :tag "Always" :value t)
303 (const :tag "Never" :value nil)
304 (const :tag "Always except minibuffer" :value :nomini))
305 :group 'ibuffer)
306
0bdd7ae4
JPW
307(defcustom ibuffer-jump-offer-only-visible-buffers nil
308 "If non-nil, only offer buffers visible in the Ibuffer buffer
309in completion lists of the `ibuffer-jump-to-buffer' command."
310 :type 'boolean
311 :group 'ibuffer)
312
25d2f683 313(defcustom ibuffer-use-header-line (boundp 'header-line-format)
7ad5b902 314 "If non-nil, display a header line containing current filters."
25d2f683
CW
315 :type 'boolean
316 :group 'ibuffer)
317
318(defcustom ibuffer-default-directory nil
4e4a724c 319 "The default directory to use for a new Ibuffer buffer.
2e4fae7d 320If nil, inherit the directory of the buffer in which `ibuffer' was
25d2f683
CW
321called. Otherwise, this variable should be a string naming a
322directory, like `default-directory'."
323 :type '(choice (const :tag "Inherit" :value nil)
324 string)
325 :group 'ibuffer)
326
4e4a724c
JPW
327(defcustom ibuffer-help-buffer-modes
328 '(help-mode apropos-mode Info-mode Info-edit-mode)
60356fb5
CW
329 "List of \"Help\" major modes."
330 :type '(repeat function)
331 :group 'ibuffer)
332
9fe14abe 333(defcustom ibuffer-compressed-file-name-regexp
4c964351 334 "\\.\\(arj\\|bgz\\|bz2\\|gz\\|lzh\\|taz\\|tgz\\|xz\\|zip\\|z\\)$"
9fe14abe 335 "Regexp to match compressed file names."
4c964351 336 :version "24.1" ; added xz
9fe14abe 337 :type 'regexp
c7f5c0a8 338 :group 'ibuffer)
9fe14abe 339
cd6ef82d
GM
340(define-obsolete-variable-alias 'ibuffer-hooks 'ibuffer-hook "22.1")
341
e9e96ba0 342(defcustom ibuffer-hook nil
4e4a724c 343 "Hook run when `ibuffer' is called."
25d2f683
CW
344 :type 'hook
345 :group 'ibuffer)
cd6ef82d
GM
346
347(define-obsolete-variable-alias 'ibuffer-mode-hooks 'ibuffer-mode-hook "22.1")
25d2f683 348
e9e96ba0 349(defcustom ibuffer-mode-hook nil
4e4a724c 350 "Hook run upon entry into `ibuffer-mode'."
25d2f683
CW
351 :type 'hook
352 :group 'ibuffer)
353
4e4a724c
JPW
354(defcustom ibuffer-load-hook nil
355 "Hook run when Ibuffer is loaded."
356 :type 'hook
357 :group 'ibuffer)
358
25d2f683
CW
359(defcustom ibuffer-marked-face 'font-lock-warning-face
360 "Face used for displaying marked buffers."
361 :type 'face
362 :group 'ibuffer)
363
364(defcustom ibuffer-deletion-face 'font-lock-type-face
365 "Face used for displaying buffers marked for deletion."
366 :type 'face
367 :group 'ibuffer)
368
369(defcustom ibuffer-title-face 'font-lock-type-face
370 "Face used for the title string."
371 :type 'face
372 :group 'ibuffer)
373
b5cd37ea
CW
374(defcustom ibuffer-filter-group-name-face 'bold
375 "Face used for displaying filtering group names."
376 :type 'face
377 :group 'ibuffer)
378
25d2f683
CW
379(defcustom ibuffer-directory-abbrev-alist nil
380 "An alist of file name abbreviations like `directory-abbrev-alist'."
381 :type '(repeat (cons :format "%v"
382 :value ("" . "")
383 (regexp :tag "From")
384 (regexp :tag "To")))
385 :group 'ibuffer)
386
4e4a724c 387
25d2f683
CW
388(defvar ibuffer-mode-map nil)
389(defvar ibuffer-mode-operate-map nil)
b5e80d1a 390(defvar ibuffer-mode-groups-popup nil)
25d2f683
CW
391(unless ibuffer-mode-map
392 (let ((map (make-sparse-keymap))
b5e80d1a
CW
393 (operate-map (make-sparse-keymap "Operate"))
394 (groups-map (make-sparse-keymap "Filter Groups")))
25d2f683
CW
395 (define-key map (kbd "0") 'digit-argument)
396 (define-key map (kbd "1") 'digit-argument)
397 (define-key map (kbd "2") 'digit-argument)
398 (define-key map (kbd "3") 'digit-argument)
399 (define-key map (kbd "4") 'digit-argument)
400 (define-key map (kbd "5") 'digit-argument)
401 (define-key map (kbd "6") 'digit-argument)
402 (define-key map (kbd "7") 'digit-argument)
403 (define-key map (kbd "8") 'digit-argument)
404 (define-key map (kbd "9") 'digit-argument)
405
406 (define-key map (kbd "m") 'ibuffer-mark-forward)
407 (define-key map (kbd "t") 'ibuffer-toggle-marks)
408 (define-key map (kbd "u") 'ibuffer-unmark-forward)
409 (define-key map (kbd "=") 'ibuffer-diff-with-file)
410 (define-key map (kbd "j") 'ibuffer-jump-to-buffer)
0bdd7ae4 411 (define-key map (kbd "M-g") 'ibuffer-jump-to-buffer)
78176075
JL
412 (define-key map (kbd "M-s a C-s") 'ibuffer-do-isearch)
413 (define-key map (kbd "M-s a M-C-s") 'ibuffer-do-isearch-regexp)
25d2f683
CW
414 (define-key map (kbd "DEL") 'ibuffer-unmark-backward)
415 (define-key map (kbd "M-DEL") 'ibuffer-unmark-all)
416 (define-key map (kbd "* *") 'ibuffer-unmark-all)
417 (define-key map (kbd "* M") 'ibuffer-mark-by-mode)
418 (define-key map (kbd "* m") 'ibuffer-mark-modified-buffers)
419 (define-key map (kbd "* u") 'ibuffer-mark-unsaved-buffers)
420 (define-key map (kbd "* s") 'ibuffer-mark-special-buffers)
421 (define-key map (kbd "* r") 'ibuffer-mark-read-only-buffers)
422 (define-key map (kbd "* /") 'ibuffer-mark-dired-buffers)
423 (define-key map (kbd "* e") 'ibuffer-mark-dissociated-buffers)
424 (define-key map (kbd "* h") 'ibuffer-mark-help-buffers)
9fe14abe 425 (define-key map (kbd "* z") 'ibuffer-mark-compressed-file-buffers)
25d2f683 426 (define-key map (kbd ".") 'ibuffer-mark-old-buffers)
71296446 427
25d2f683
CW
428 (define-key map (kbd "d") 'ibuffer-mark-for-delete)
429 (define-key map (kbd "C-d") 'ibuffer-mark-for-delete-backwards)
430 (define-key map (kbd "k") 'ibuffer-mark-for-delete)
431 (define-key map (kbd "x") 'ibuffer-do-kill-on-deletion-marks)
71296446 432
25d2f683
CW
433 ;; immediate operations
434 (define-key map (kbd "n") 'ibuffer-forward-line)
435 (define-key map (kbd "SPC") 'forward-line)
436 (define-key map (kbd "p") 'ibuffer-backward-line)
437 (define-key map (kbd "M-}") 'ibuffer-forward-next-marked)
438 (define-key map (kbd "M-{") 'ibuffer-backwards-next-marked)
439 (define-key map (kbd "l") 'ibuffer-redisplay)
440 (define-key map (kbd "g") 'ibuffer-update)
441 (define-key map "`" 'ibuffer-switch-format)
442 (define-key map "-" 'ibuffer-add-to-tmp-hide)
443 (define-key map "+" 'ibuffer-add-to-tmp-show)
444 (define-key map "b" 'ibuffer-bury-buffer)
445 (define-key map (kbd ",") 'ibuffer-toggle-sorting-mode)
446 (define-key map (kbd "s i") 'ibuffer-invert-sorting)
447 (define-key map (kbd "s a") 'ibuffer-do-sort-by-alphabetic)
448 (define-key map (kbd "s v") 'ibuffer-do-sort-by-recency)
449 (define-key map (kbd "s s") 'ibuffer-do-sort-by-size)
d5794180 450 (define-key map (kbd "s f") 'ibuffer-do-sort-by-filename/process)
25d2f683
CW
451 (define-key map (kbd "s m") 'ibuffer-do-sort-by-major-mode)
452
453 (define-key map (kbd "/ m") 'ibuffer-filter-by-mode)
5bc06df9 454 (define-key map (kbd "/ M") 'ibuffer-filter-by-used-mode)
25d2f683
CW
455 (define-key map (kbd "/ n") 'ibuffer-filter-by-name)
456 (define-key map (kbd "/ c") 'ibuffer-filter-by-content)
457 (define-key map (kbd "/ e") 'ibuffer-filter-by-predicate)
458 (define-key map (kbd "/ f") 'ibuffer-filter-by-filename)
459 (define-key map (kbd "/ >") 'ibuffer-filter-by-size-gt)
460 (define-key map (kbd "/ <") 'ibuffer-filter-by-size-lt)
461 (define-key map (kbd "/ r") 'ibuffer-switch-to-saved-filters)
462 (define-key map (kbd "/ a") 'ibuffer-add-saved-filters)
463 (define-key map (kbd "/ x") 'ibuffer-delete-saved-filters)
464 (define-key map (kbd "/ d") 'ibuffer-decompose-filter)
465 (define-key map (kbd "/ s") 'ibuffer-save-filters)
466 (define-key map (kbd "/ p") 'ibuffer-pop-filter)
467 (define-key map (kbd "/ !") 'ibuffer-negate-filter)
468 (define-key map (kbd "/ t") 'ibuffer-exchange-filters)
469 (define-key map (kbd "/ TAB") 'ibuffer-exchange-filters)
470 (define-key map (kbd "/ o") 'ibuffer-or-filter)
b5cd37ea
CW
471 (define-key map (kbd "/ g") 'ibuffer-filters-to-filter-group)
472 (define-key map (kbd "/ P") 'ibuffer-pop-filter-group)
2bd26a6f 473 (define-key map (kbd "/ D") 'ibuffer-decompose-filter-group)
25d2f683 474 (define-key map (kbd "/ /") 'ibuffer-filter-disable)
b5cd37ea
CW
475
476 (define-key map (kbd "M-n") 'ibuffer-forward-filter-group)
77aec221 477 (define-key map "\t" 'ibuffer-forward-filter-group)
b5cd37ea 478 (define-key map (kbd "M-p") 'ibuffer-backward-filter-group)
77aec221 479 (define-key map [backtab] 'ibuffer-backward-filter-group)
b5cd37ea 480 (define-key map (kbd "M-j") 'ibuffer-jump-to-filter-group)
cba63a2d
CW
481 (define-key map (kbd "C-k") 'ibuffer-kill-line)
482 (define-key map (kbd "C-y") 'ibuffer-yank)
483 (define-key map (kbd "/ S") 'ibuffer-save-filter-groups)
484 (define-key map (kbd "/ R") 'ibuffer-switch-to-saved-filter-groups)
485 (define-key map (kbd "/ X") 'ibuffer-delete-saved-filter-groups)
486 (define-key map (kbd "/ \\") 'ibuffer-clear-filter-groups)
71296446 487
25d2f683
CW
488 (define-key map (kbd "q") 'ibuffer-quit)
489 (define-key map (kbd "h") 'describe-mode)
490 (define-key map (kbd "?") 'describe-mode)
491
492 (define-key map (kbd "% n") 'ibuffer-mark-by-name-regexp)
493 (define-key map (kbd "% m") 'ibuffer-mark-by-mode-regexp)
494 (define-key map (kbd "% f") 'ibuffer-mark-by-file-name-regexp)
71296446 495
25d2f683
CW
496 (define-key map (kbd "C-t") 'ibuffer-visit-tags-table)
497
498 (define-key map (kbd "|") 'ibuffer-do-shell-command-pipe)
499 (define-key map (kbd "!") 'ibuffer-do-shell-command-file)
500 (define-key map (kbd "~") 'ibuffer-do-toggle-modified)
501 ;; marked operations
502 (define-key map (kbd "A") 'ibuffer-do-view)
503 (define-key map (kbd "D") 'ibuffer-do-delete)
504 (define-key map (kbd "E") 'ibuffer-do-eval)
505 (define-key map (kbd "F") 'ibuffer-do-shell-command-file)
506 (define-key map (kbd "I") 'ibuffer-do-query-replace-regexp)
507 (define-key map (kbd "H") 'ibuffer-do-view-other-frame)
508 (define-key map (kbd "N") 'ibuffer-do-shell-command-pipe-replace)
509 (define-key map (kbd "M") 'ibuffer-do-toggle-modified)
510 (define-key map (kbd "O") 'ibuffer-do-occur)
511 (define-key map (kbd "P") 'ibuffer-do-print)
512 (define-key map (kbd "Q") 'ibuffer-do-query-replace)
513 (define-key map (kbd "R") 'ibuffer-do-rename-uniquely)
514 (define-key map (kbd "S") 'ibuffer-do-save)
515 (define-key map (kbd "T") 'ibuffer-do-toggle-read-only)
516 (define-key map (kbd "U") 'ibuffer-do-replace-regexp)
517 (define-key map (kbd "V") 'ibuffer-do-revert)
518 (define-key map (kbd "W") 'ibuffer-do-view-and-eval)
519 (define-key map (kbd "X") 'ibuffer-do-shell-command-pipe)
71296446 520
25d2f683
CW
521 (define-key map (kbd "k") 'ibuffer-do-kill-lines)
522 (define-key map (kbd "w") 'ibuffer-copy-filename-as-kill)
523
524 (define-key map (kbd "RET") 'ibuffer-visit-buffer)
525 (define-key map (kbd "e") 'ibuffer-visit-buffer)
526 (define-key map (kbd "f") 'ibuffer-visit-buffer)
527 (define-key map (kbd "C-x C-f") 'ibuffer-find-file)
528 (define-key map (kbd "o") 'ibuffer-visit-buffer-other-window)
529 (define-key map (kbd "C-o") 'ibuffer-visit-buffer-other-window-noselect)
530 (define-key map (kbd "M-o") 'ibuffer-visit-buffer-1-window)
531 (define-key map (kbd "v") 'ibuffer-do-view)
532 (define-key map (kbd "C-x v") 'ibuffer-do-view-horizontally)
533 (define-key map (kbd "C-c C-a") 'ibuffer-auto-mode)
534 (define-key map (kbd "C-x 4 RET") 'ibuffer-visit-buffer-other-window)
535 (define-key map (kbd "C-x 5 RET") 'ibuffer-visit-buffer-other-frame)
536
537 (define-key map [menu-bar view]
538 (cons "View" (make-sparse-keymap "View")))
539
540 (define-key-after map [menu-bar view visit-buffer]
541 '(menu-item "View this buffer" ibuffer-visit-buffer))
542 (define-key-after map [menu-bar view visit-buffer-other-window]
543 '(menu-item "View (other window)" ibuffer-visit-buffer-other-window))
544 (define-key-after map [menu-bar view visit-buffer-other-frame]
545 '(menu-item "View (other frame)" ibuffer-visit-buffer-other-frame))
546 (define-key-after map [menu-bar view ibuffer-update]
547 '(menu-item "Update" ibuffer-update
548 :help "Regenerate the list of buffers"))
549 (define-key-after map [menu-bar view switch-format]
550 '(menu-item "Switch display format" ibuffer-switch-format
551 :help "Toggle between available values of `ibuffer-formats'"))
552
553 (define-key-after map [menu-bar view dashes]
554 '("--"))
555
556 (define-key-after map [menu-bar view sort]
557 (cons "Sort" (make-sparse-keymap "Sort")))
558
559 (define-key-after map [menu-bar view sort do-sort-by-major-mode]
cba63a2d 560 '(menu-item "Sort by major mode" ibuffer-do-sort-by-major-mode))
25d2f683 561 (define-key-after map [menu-bar view sort do-sort-by-size]
cba63a2d 562 '(menu-item "Sort by buffer size" ibuffer-do-sort-by-size))
25d2f683
CW
563 (define-key-after map [menu-bar view sort do-sort-by-alphabetic]
564 '(menu-item "Sort lexicographically" ibuffer-do-sort-by-alphabetic
565 :help "Sort by the alphabetic order of buffer name"))
566 (define-key-after map [menu-bar view sort do-sort-by-recency]
567 '(menu-item "Sort by view time" ibuffer-do-sort-by-recency
568 :help "Sort by the last time the buffer was displayed"))
4e4a724c
JPW
569 (define-key-after map [menu-bar view sort dashes]
570 '("--"))
25d2f683
CW
571 (define-key-after map [menu-bar view sort invert-sorting]
572 '(menu-item "Reverse sorting order" ibuffer-invert-sorting))
573 (define-key-after map [menu-bar view sort toggle-sorting-mode]
574 '(menu-item "Switch sorting mode" ibuffer-toggle-sorting-mode
575 :help "Switch between the various sorting criteria"))
576
577 (define-key-after map [menu-bar view filter]
578 (cons "Filter" (make-sparse-keymap "Filter")))
579
580 (define-key-after map [menu-bar view filter filter-disable]
05cc03af
CW
581 '(menu-item "Disable all filtering" ibuffer-filter-disable
582 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)))
25d2f683 583 (define-key-after map [menu-bar view filter filter-by-mode]
cba63a2d 584 '(menu-item "Add filter by major mode..." ibuffer-filter-by-mode))
5bc06df9
CW
585 (define-key-after map [menu-bar view filter filter-by-mode]
586 '(menu-item "Add filter by major mode in use..." ibuffer-filter-by-used-mode))
25d2f683 587 (define-key-after map [menu-bar view filter filter-by-name]
cba63a2d 588 '(menu-item "Add filter by buffer name..." ibuffer-filter-by-name))
25d2f683 589 (define-key-after map [menu-bar view filter filter-by-filename]
cba63a2d 590 '(menu-item "Add filter by filename..." ibuffer-filter-by-filename))
25d2f683 591 (define-key-after map [menu-bar view filter filter-by-size-lt]
cba63a2d 592 '(menu-item "Add filter by size less than..." ibuffer-filter-by-size-lt))
25d2f683 593 (define-key-after map [menu-bar view filter filter-by-size-gt]
cba63a2d 594 '(menu-item "Add filter by size greater than..." ibuffer-filter-by-size-gt))
25d2f683 595 (define-key-after map [menu-bar view filter filter-by-content]
cba63a2d 596 '(menu-item "Add filter by content (regexp)..." ibuffer-filter-by-content))
25d2f683 597 (define-key-after map [menu-bar view filter filter-by-predicate]
cba63a2d 598 '(menu-item "Add filter by Lisp predicate..." ibuffer-filter-by-predicate))
25d2f683 599 (define-key-after map [menu-bar view filter pop-filter]
05cc03af
CW
600 '(menu-item "Remove top filter" ibuffer-pop-filter
601 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)))
25d2f683
CW
602 (define-key-after map [menu-bar view filter or-filter]
603 '(menu-item "OR top two filters" ibuffer-or-filter
717339e5
CW
604 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers
605 (cdr ibuffer-filtering-qualifiers))
25d2f683
CW
606 :help "Create a new filter which is the logical OR of the top two filters"))
607 (define-key-after map [menu-bar view filter negate-filter]
05cc03af
CW
608 '(menu-item "Negate top filter" ibuffer-negate-filter
609 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)))
25d2f683
CW
610 (define-key-after map [menu-bar view filter decompose-filter]
611 '(menu-item "Decompose top filter" ibuffer-decompose-filter
717339e5 612 :enable (and (featurep 'ibuf-ext) (memq (car ibuffer-filtering-qualifiers) '(or saved not)))
25d2f683
CW
613 :help "Break down a complex filter like OR or NOT"))
614 (define-key-after map [menu-bar view filter exchange-filters]
05cc03af 615 '(menu-item "Swap top two filters" ibuffer-exchange-filters
717339e5
CW
616 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers
617 (cdr ibuffer-filtering-qualifiers))))
25d2f683
CW
618 (define-key-after map [menu-bar view filter save-filters]
619 '(menu-item "Save current filters permanently..." ibuffer-save-filters
4e4a724c 620 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)
25d2f683
CW
621 :help "Use a mnemnonic name to store current filter stack"))
622 (define-key-after map [menu-bar view filter switch-to-saved-filters]
623 '(menu-item "Restore permanently saved filters..." ibuffer-switch-to-saved-filters
05cc03af 624 :enable (and (featurep 'ibuf-ext) ibuffer-saved-filters)
25d2f683
CW
625 :help "Replace current filters with a saved stack"))
626 (define-key-after map [menu-bar view filter add-saved-filters]
627 '(menu-item "Add to permanently saved filters..." ibuffer-add-saved-filters
05cc03af 628 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)
cba63a2d 629 :help "Include already saved stack with current filters"))
25d2f683 630 (define-key-after map [menu-bar view filter delete-saved-filters]
cba63a2d 631 '(menu-item "Delete permanently saved filters..."
05cc03af
CW
632 ibuffer-delete-saved-filters
633 :enable (and (featurep 'ibuf-ext) ibuffer-saved-filters)))
cba63a2d 634
b5e80d1a 635 ;; Filter groups
cba63a2d 636
b5e80d1a 637 (define-key-after groups-map [filters-to-filter-group]
cba63a2d 638 '(menu-item "Create filter group from current filters..."
2bd26a6f
CW
639 ibuffer-filters-to-filter-group
640 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)))
b5e80d1a 641 (define-key-after groups-map [forward-filter-group]
cba63a2d 642 '(menu-item "Move point to the next filter group"
4e4a724c 643 ibuffer-forward-filter-group))
b5e80d1a 644 (define-key-after groups-map [backward-filter-group]
cba63a2d
CW
645 '(menu-item "Move point to the previous filter group"
646 ibuffer-backward-filter-group))
b5e80d1a 647 (define-key-after groups-map [jump-to-filter-group]
cba63a2d
CW
648 '(menu-item "Move point to a specific filter group..."
649 ibuffer-jump-to-filter-group))
b5e80d1a
CW
650 (define-key-after groups-map [kill-filter-group]
651 '(menu-item "Kill filter group named..."
652 ibuffer-kill-filter-group
653 :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups)))
654 (define-key-after groups-map [yank-filter-group]
655 '(menu-item "Yank last killed filter group before..."
656 ibuffer-yank-filter-group
657 :enable (and (featurep 'ibuf-ext) ibuffer-filter-group-kill-ring)))
658 (define-key-after groups-map [pop-filter-group]
b5cd37ea 659 '(menu-item "Remove top filter group"
b5e80d1a 660 ibuffer-pop-filter-group
2bd26a6f 661 :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups)))
b5e80d1a 662 (define-key-after groups-map [clear-filter-groups]
cba63a2d 663 '(menu-item "Remove all filter groups"
b5e80d1a 664 ibuffer-clear-filter-groups
2bd26a6f
CW
665 :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups)))
666 (define-key-after groups-map [pop-filter-group]
667 '(menu-item "Decompose filter group..."
668 ibuffer-pop-filter-group
669 :help "\"Unmake\" a filter group"
670 :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups)))
b5e80d1a 671 (define-key-after groups-map [save-filter-groups]
cba63a2d
CW
672 '(menu-item "Save current filter groups permanently..."
673 ibuffer-save-filter-groups
05cc03af 674 :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups)
cba63a2d 675 :help "Use a mnemnonic name to store current filter groups"))
b5e80d1a 676 (define-key-after groups-map [switch-to-saved-filter-groups]
cba63a2d
CW
677 '(menu-item "Restore permanently saved filters..."
678 ibuffer-switch-to-saved-filter-groups
05cc03af 679 :enable (and (featurep 'ibuf-ext) ibuffer-saved-filter-groups)
4e4a724c 680 :help "Replace current filters with a saved stack"))
b5e80d1a 681 (define-key-after groups-map [delete-saved-filter-groups]
cba63a2d 682 '(menu-item "Delete permanently saved filter groups..."
05cc03af
CW
683 ibuffer-delete-saved-filter-groups
684 :enable (and (featurep 'ibuf-ext) ibuffer-saved-filter-groups)))
b5e80d1a 685 (define-key-after groups-map [set-filter-groups-by-mode]
cba63a2d
CW
686 '(menu-item "Set current filter groups to filter by mode"
687 ibuffer-set-filter-groups-by-mode))
688
b5e80d1a
CW
689 (define-key-after map [menu-bar view filter-groups]
690 (cons "Filter Groups" groups-map))
691
25d2f683
CW
692 (define-key-after map [menu-bar view dashes2]
693 '("--"))
694 (define-key-after map [menu-bar view diff-with-file]
695 '(menu-item "Diff with file" ibuffer-diff-with-file
696 :help "View the differences between this buffer and its file"))
697 (define-key-after map [menu-bar view auto-mode]
698 '(menu-item "Toggle Auto Mode" ibuffer-auto-mode
699 :help "Attempt to automatically update the Ibuffer buffer"))
700 (define-key-after map [menu-bar view customize]
4e4a724c 701 '(menu-item "Customize Ibuffer" ibuffer-customize
25d2f683
CW
702 :help "Use Custom to customize Ibuffer"))
703
704 (define-key-after map [menu-bar mark]
705 (cons "Mark" (make-sparse-keymap "Mark")))
706
707 (define-key-after map [menu-bar mark toggle-marks]
708 '(menu-item "Toggle marks" ibuffer-toggle-marks
709 :help "Unmark marked buffers, and mark unmarked buffers"))
710 (define-key-after map [menu-bar mark mark-forward]
711 '(menu-item "Mark" ibuffer-mark-forward
712 :help "Mark the buffer at point"))
713 (define-key-after map [menu-bar mark unmark-forward]
714 '(menu-item "Unmark" ibuffer-unmark-forward
715 :help "Unmark the buffer at point"))
716 (define-key-after map [menu-bar mark mark-by-mode]
717 '(menu-item "Mark by mode..." ibuffer-mark-by-mode
718 :help "Mark all buffers in a particular major mode"))
719 (define-key-after map [menu-bar mark mark-modified-buffers]
720 '(menu-item "Mark modified buffers" ibuffer-mark-modified-buffers
721 :help "Mark all buffers which have been modified"))
722 (define-key-after map [menu-bar mark mark-unsaved-buffers]
723 '(menu-item "Mark unsaved buffers" ibuffer-mark-unsaved-buffers
724 :help "Mark all buffers which have a file and are modified"))
725 (define-key-after map [menu-bar mark mark-read-only-buffers]
726 '(menu-item "Mark read-only buffers" ibuffer-mark-read-only-buffers
727 :help "Mark all buffers which are read-only"))
728 (define-key-after map [menu-bar mark mark-special-buffers]
729 '(menu-item "Mark special buffers" ibuffer-mark-special-buffers
730 :help "Mark all buffers whose name begins with a *"))
731 (define-key-after map [menu-bar mark mark-dired-buffers]
732 '(menu-item "Mark dired buffers" ibuffer-mark-dired-buffers
733 :help "Mark buffers in dired-mode"))
734 (define-key-after map [menu-bar mark mark-dissociated-buffers]
735 '(menu-item "Mark dissociated buffers" ibuffer-mark-dissociated-buffers
736 :help "Mark buffers with a non-existent associated file"))
737 (define-key-after map [menu-bar mark mark-help-buffers]
738 '(menu-item "Mark help buffers" ibuffer-mark-help-buffers
739 :help "Mark buffers in help-mode"))
9fe14abe
JPW
740 (define-key-after map [menu-bar mark mark-compressed-file-buffers]
741 '(menu-item "Mark compressed file buffers" ibuffer-mark-compressed-file-buffers
742 :help "Mark buffers which have a file that is compressed"))
25d2f683
CW
743 (define-key-after map [menu-bar mark mark-old-buffers]
744 '(menu-item "Mark old buffers" ibuffer-mark-old-buffers
745 :help "Mark buffers which have not been viewed recently"))
746 (define-key-after map [menu-bar mark unmark-all]
747 '(menu-item "Unmark All" ibuffer-unmark-all))
71296446 748
25d2f683
CW
749 (define-key-after map [menu-bar mark dashes]
750 '("--"))
71296446 751
25d2f683
CW
752 (define-key-after map [menu-bar mark mark-by-name-regexp]
753 '(menu-item "Mark by buffer name (regexp)..." ibuffer-mark-by-name-regexp
754 :help "Mark buffers whose name matches a regexp"))
755 (define-key-after map [menu-bar mark mark-by-mode-regexp]
756 '(menu-item "Mark by major mode (regexp)..." ibuffer-mark-by-mode-regexp
757 :help "Mark buffers whose major mode name matches a regexp"))
758 (define-key-after map [menu-bar mark mark-by-file-name-regexp]
759 '(menu-item "Mark by file name (regexp)..." ibuffer-mark-by-file-name-regexp
760 :help "Mark buffers whose file name matches a regexp"))
761
762 ;; Operate map is added later
763
764 (define-key-after operate-map [do-view]
765 '(menu-item "View" ibuffer-do-view))
766 (define-key-after operate-map [do-view-other-frame]
767 '(menu-item "View (separate frame)" ibuffer-do-view-other-frame))
768 (define-key-after operate-map [do-save]
769 '(menu-item "Save" ibuffer-do-save))
770 (define-key-after operate-map [do-replace-regexp]
771 '(menu-item "Replace (regexp)..." ibuffer-do-replace-regexp
772 :help "Replace text inside marked buffers"))
773 (define-key-after operate-map [do-query-replace]
774 '(menu-item "Query Replace..." ibuffer-do-query-replace
775 :help "Replace text in marked buffers, asking each time"))
776 (define-key-after operate-map [do-query-replace-regexp]
777 '(menu-item "Query Replace (regexp)..." ibuffer-do-query-replace-regexp
778 :help "Replace text in marked buffers by regexp, asking each time"))
779 (define-key-after operate-map [do-print]
780 '(menu-item "Print" ibuffer-do-print))
781 (define-key-after operate-map [do-toggle-modified]
782 '(menu-item "Toggle modification flag" ibuffer-do-toggle-modified))
783 (define-key-after operate-map [do-revert]
784 '(menu-item "Revert" ibuffer-do-revert
785 :help "Revert marked buffers to their associated file"))
786 (define-key-after operate-map [do-rename-uniquely]
787 '(menu-item "Rename Uniquely" ibuffer-do-rename-uniquely
788 :help "Rename marked buffers to a new, unique name"))
789 (define-key-after operate-map [do-delete]
790 '(menu-item "Kill" ibuffer-do-delete))
791 (define-key-after operate-map [do-occur]
792 '(menu-item "List lines matching..." ibuffer-do-occur
793 :help "View all lines in marked buffers matching a regexp"))
794 (define-key-after operate-map [do-shell-command-pipe]
795 '(menu-item "Pipe to shell command..." ibuffer-do-shell-command-pipe
796 :help "For each marked buffer, send its contents to a shell command"))
797 (define-key-after operate-map [do-shell-command-pipe-replace]
798 '(menu-item "Pipe to shell command (replace)..." ibuffer-do-shell-command-pipe-replace
799 :help "For each marked buffer, replace its contents with output of shell command"))
800 (define-key-after operate-map [do-shell-command-file]
801 '(menu-item "Shell command on buffer's file..." ibuffer-do-shell-command-file
802 :help "For each marked buffer, run a shell command with its file as argument"))
803 (define-key-after operate-map [do-eval]
804 '(menu-item "Eval..." ibuffer-do-eval
805 :help "Evaluate a Lisp form in each marked buffer"))
806 (define-key-after operate-map [do-view-and-eval]
807 '(menu-item "Eval (viewing buffer)..." ibuffer-do-view-and-eval
808 :help "Evaluate a Lisp form in each marked buffer while viewing it"))
71296446 809
25d2f683 810 (setq ibuffer-mode-map map
b5e80d1a 811 ibuffer-mode-operate-map operate-map
2bd26a6f
CW
812 ibuffer-mode-groups-popup (copy-keymap groups-map))))
813
814(define-key ibuffer-mode-groups-popup [kill-filter-group]
4e4a724c
JPW
815 '(menu-item "Kill filter group"
816 ibuffer-kill-line
34a4faa0
JPW
817 :enable (and (featurep 'ibuf-ext)
818 ibuffer-filter-groups)))
545aad2f 819(define-key ibuffer-mode-groups-popup [yank-filter-group]
4e4a724c
JPW
820 '(menu-item "Yank last killed filter group"
821 ibuffer-yank
34a4faa0
JPW
822 :enable (and (featurep 'ibuf-ext)
823 ibuffer-filter-group-kill-ring)))
4e4a724c 824
acf88897 825(defvar ibuffer-name-map
25d2f683 826 (let ((map (make-sparse-keymap)))
25d2f683
CW
827 (define-key map [(mouse-1)] 'ibuffer-mouse-toggle-mark)
828 (define-key map [(mouse-2)] 'ibuffer-mouse-visit-buffer)
829 (define-key map [down-mouse-3] 'ibuffer-mouse-popup-menu)
acf88897 830 map))
25d2f683 831
d5794180
DN
832(defvar ibuffer-filename/process-header-map
833 (let ((map (make-sparse-keymap)))
834 (define-key map [(mouse-1)] 'ibuffer-do-sort-by-filename/process)
835 map))
836
acf88897 837(defvar ibuffer-mode-name-map
25d2f683 838 (let ((map (make-sparse-keymap)))
25d2f683
CW
839 (define-key map [(mouse-2)] 'ibuffer-mouse-filter-by-mode)
840 (define-key map (kbd "RET") 'ibuffer-interactive-filter-by-mode)
acf88897 841 map))
25d2f683 842
f0b31589
DN
843(defvar ibuffer-name-header-map
844 (let ((map (make-sparse-keymap)))
845 (define-key map [(mouse-1)] 'ibuffer-do-sort-by-alphabetic)
846 map))
847
848(defvar ibuffer-size-header-map
849 (let ((map (make-sparse-keymap)))
850 (define-key map [(mouse-1)] 'ibuffer-do-sort-by-size)
851 map))
852
853(defvar ibuffer-mode-header-map
854 (let ((map (make-sparse-keymap)))
855 (define-key map [(mouse-1)] 'ibuffer-do-sort-by-major-mode)
856 map))
857
acf88897 858(defvar ibuffer-mode-filter-group-map
b5cd37ea 859 (let ((map (make-sparse-keymap)))
b5cd37ea
CW
860 (define-key map [(mouse-1)] 'ibuffer-mouse-toggle-mark)
861 (define-key map [(mouse-2)] 'ibuffer-mouse-toggle-filter-group)
862 (define-key map (kbd "RET") 'ibuffer-toggle-filter-group)
b5e80d1a 863 (define-key map [down-mouse-3] 'ibuffer-mouse-popup-menu)
acf88897 864 map))
b5cd37ea 865
4ed1f829
JPW
866(defvar ibuffer-restore-window-config-on-quit nil
867 "If non-nil, restore previous window configuration upon exiting `ibuffer'.")
868
869(defvar ibuffer-prev-window-config nil
870 "Window configuration before starting Ibuffer.")
25d2f683
CW
871
872(defvar ibuffer-did-modification nil)
873
63f0a166
JB
874(defvar ibuffer-compiled-formats nil)
875(defvar ibuffer-cached-formats nil)
876(defvar ibuffer-cached-eliding-string nil)
877(defvar ibuffer-cached-elide-long-columns 0)
878
25d2f683
CW
879(defvar ibuffer-sorting-functions-alist nil
880 "An alist of functions which describe how to sort buffers.
881
882Note: You most likely do not want to modify this variable directly;
883use `define-ibuffer-sorter' instead.
884
885The alist elements are constructed like (NAME DESCRIPTION FUNCTION)
886Where NAME is a symbol describing the sorting method, DESCRIPTION is a
887short string which will be displayed in the minibuffer and menu, and
888FUNCTION is a function of two arguments, which will be the buffers to
889compare.")
890
891;;; Utility functions
892(defun ibuffer-columnize-and-insert-list (list &optional pad-width)
893 "Insert LIST into the current buffer in as many columns as possible.
894The maximum number of columns is determined by the current window
895width and the longest string in LIST."
896 (unless pad-width
897 (setq pad-width 3))
898 (let ((width (window-width))
899 (max (+ (apply #'max (mapcar #'length list))
900 pad-width)))
901 (let ((columns (/ width max)))
902 (when (zerop columns)
903 (setq columns 1))
904 (while list
905 (dotimes (i (1- columns))
906 (insert (concat (car list) (make-string (- max (length (car list)))
972b8f82 907 ?\s)))
25d2f683
CW
908 (setq list (cdr list)))
909 (when (not (null list))
910 (insert (pop list)))
911 (insert "\n")))))
912
25d2f683
CW
913(defsubst ibuffer-current-mark ()
914 (cadr (get-text-property (line-beginning-position)
915 'ibuffer-properties)))
916
917(defun ibuffer-mouse-toggle-mark (event)
918 "Toggle the marked status of the buffer chosen with the mouse."
919 (interactive "e")
920 (unwind-protect
b5cd37ea
CW
921 (let ((pt (save-excursion
922 (mouse-set-point event)
923 (point))))
924 (ibuffer-aif (get-text-property (point) 'ibuffer-filter-group-name)
925 (ibuffer-toggle-marks it)
926 (goto-char pt)
927 (let ((mark (ibuffer-current-mark)))
928 (setq buffer-read-only nil)
929 (if (eq mark ibuffer-marked-char)
972b8f82 930 (ibuffer-set-mark ?\s)
b5cd37ea 931 (ibuffer-set-mark ibuffer-marked-char)))))
25d2f683
CW
932 (setq buffer-read-only t)))
933
934(defun ibuffer-find-file (file &optional wildcards)
935 "Like `find-file', but default to the directory of the buffer at point."
936 (interactive
937 (let ((default-directory (let ((buf (ibuffer-current-buffer)))
938 (if (buffer-live-p buf)
939 (with-current-buffer buf
940 default-directory)
941 default-directory))))
942 (list (read-file-name "Find file: " default-directory)
fe78af29
JPW
943 t)))
944 (find-file file wildcards))
25d2f683
CW
945
946(defun ibuffer-mouse-visit-buffer (event)
947 "Visit the buffer chosen with the mouse."
948 (interactive "e")
949 (switch-to-buffer
950 (save-excursion
951 (mouse-set-point event)
b5cd37ea 952 (ibuffer-current-buffer t))))
25d2f683
CW
953
954(defun ibuffer-mouse-popup-menu (event)
955 "Display a menu of operations."
956 (interactive "e")
a1793b2d
JPW
957 (let ((eventpt (posn-point (event-end event)))
958 (origpt (point)))
25d2f683 959 (unwind-protect
51922c04 960 (if (get-text-property eventpt 'ibuffer-filter-group-name)
a1793b2d
JPW
961 (progn
962 (goto-char eventpt)
963 (popup-menu ibuffer-mode-groups-popup))
51922c04 964 (let ((inhibit-read-only t))
b5e80d1a 965 (ibuffer-save-marks
4e4a724c
JPW
966 ;; hm. we could probably do this in a better fashion
967 (ibuffer-unmark-all ?\r)
968 (save-excursion
969 (goto-char eventpt)
970 (ibuffer-set-mark ibuffer-marked-char))
971 (save-excursion
972 (popup-menu ibuffer-mode-operate-map)))))
a1793b2d 973 (setq buffer-read-only t)
4ba16127 974 (if (= eventpt (point))
a1793b2d 975 (goto-char origpt)))))
51922c04 976
b5cd37ea
CW
977(defun ibuffer-skip-properties (props direction)
978 (while (and (not (eobp))
979 (let ((hit nil))
980 (dolist (prop props hit)
981 (when (get-text-property (point) prop)
982 (setq hit t)))))
983 (forward-line direction)
984 (beginning-of-line)))
25d2f683 985
4e4a724c
JPW
986(defun ibuffer-customize ()
987 "Begin customizing Ibuffer interactively."
988 (interactive)
989 (customize-group 'ibuffer))
990
b5cd37ea 991(defun ibuffer-backward-line (&optional arg skip-group-names)
25d2f683
CW
992 "Move backwards ARG lines, wrapping around the list if necessary."
993 (interactive "P")
34a4faa0 994 (or arg (setq arg 1))
25d2f683
CW
995 (beginning-of-line)
996 (while (> arg 0)
997 (forward-line -1)
0ce780e1
CW
998 (when (and ibuffer-movement-cycle
999 (or (get-text-property (point) 'ibuffer-title)
1000 (and skip-group-names
34a4faa0
JPW
1001 (get-text-property (point)
1002 'ibuffer-filter-group-name))))
25d2f683 1003 (goto-char (point-max))
60356fb5 1004 (beginning-of-line))
b5cd37ea
CW
1005 (ibuffer-skip-properties (append '(ibuffer-summary)
1006 (when skip-group-names
1007 '(ibuffer-filter-group-name)))
1008 -1)
60356fb5
CW
1009 ;; Handle the special case of no buffers.
1010 (when (get-text-property (point) 'ibuffer-title)
1011 (forward-line 1)
1012 (setq arg 1))
1013 (decf arg)))
25d2f683 1014
b5cd37ea 1015(defun ibuffer-forward-line (&optional arg skip-group-names)
25d2f683
CW
1016 "Move forward ARG lines, wrapping around the list if necessary."
1017 (interactive "P")
34a4faa0 1018 (or arg (setq arg 1))
25d2f683 1019 (beginning-of-line)
0ce780e1
CW
1020 (when (and ibuffer-movement-cycle
1021 (or (eobp)
1022 (get-text-property (point) 'ibuffer-summary)))
214b39be 1023 (goto-char (point-min)))
b5cd37ea
CW
1024 (when (or (get-text-property (point) 'ibuffer-title)
1025 (and skip-group-names
1026 (get-text-property (point) 'ibuffer-filter-group-name)))
1027 (when (> arg 0)
1028 (decf arg))
1029 (ibuffer-skip-properties (append '(ibuffer-title)
1030 (when skip-group-names
1031 '(ibuffer-filter-group-name)))
1032 1))
25d2f683
CW
1033 (if (< arg 0)
1034 (ibuffer-backward-line (- arg))
60356fb5
CW
1035 (while (> arg 0)
1036 (forward-line 1)
0ce780e1
CW
1037 (when (and ibuffer-movement-cycle
1038 (or (eobp)
1039 (get-text-property (point) 'ibuffer-summary)))
60356fb5 1040 (goto-char (point-min)))
b5cd37ea
CW
1041 (decf arg)
1042 (ibuffer-skip-properties (append '(ibuffer-title)
1043 (when skip-group-names
1044 '(ibuffer-filter-group-name)))
1045 1))))
25d2f683 1046
d246cabf
CW
1047(defun ibuffer-visit-buffer (&optional single)
1048 "Visit the buffer on this line.
d246cabf
CW
1049If optional argument SINGLE is non-nil, then also ensure there is only
1050one window."
1051 (interactive "P")
b5cd37ea 1052 (let ((buf (ibuffer-current-buffer t)))
d246cabf
CW
1053 (switch-to-buffer buf)
1054 (when single
1055 (delete-other-windows))))
25d2f683
CW
1056
1057(defun ibuffer-visit-buffer-other-window (&optional noselect)
1058 "Visit the buffer on this line in another window."
1059 (interactive)
b5cd37ea 1060 (let ((buf (ibuffer-current-buffer t)))
25d2f683
CW
1061 (bury-buffer (current-buffer))
1062 (if noselect
1063 (let ((curwin (selected-window)))
1064 (pop-to-buffer buf)
1065 (select-window curwin))
1066 (switch-to-buffer-other-window buf))))
1067
1068(defun ibuffer-visit-buffer-other-window-noselect ()
1069 "Visit the buffer on this line in another window, but don't select it."
1070 (interactive)
1071 (ibuffer-visit-buffer-other-window t))
1072
1073(defun ibuffer-visit-buffer-other-frame ()
1074 "Visit the buffer on this line in another frame."
1075 (interactive)
b5cd37ea 1076 (let ((buf (ibuffer-current-buffer t)))
25d2f683
CW
1077 (bury-buffer (current-buffer))
1078 (switch-to-buffer-other-frame buf)))
1079
1080(defun ibuffer-visit-buffer-1-window ()
1081 "Visit the buffer on this line, and delete other windows."
1082 (interactive)
d246cabf 1083 (ibuffer-visit-buffer t))
25d2f683
CW
1084
1085(defun ibuffer-bury-buffer ()
1086 "Bury the buffer on this line."
1087 (interactive)
b5cd37ea 1088 (let ((buf (ibuffer-current-buffer t))
25d2f683 1089 (line (+ 1 (count-lines 1 (point)))))
25d2f683
CW
1090 (bury-buffer buf)
1091 (ibuffer-update nil t)
e6ce8c42
GM
1092 (goto-char (point-min))
1093 (forward-line (1- line))))
25d2f683
CW
1094
1095(defun ibuffer-visit-tags-table ()
1096 "Visit the tags table in the buffer on this line. See `visit-tags-table'."
1097 (interactive)
b5cd37ea 1098 (let ((file (buffer-file-name (ibuffer-current-buffer t))))
25d2f683
CW
1099 (if file
1100 (visit-tags-table file)
1101 (error "Specified buffer has no file"))))
1102
1103(defun ibuffer-do-view (&optional other-frame)
1104 "View marked buffers, or the buffer on the current line.
1105If optional argument OTHER-FRAME is non-nil, then display each
1106marked buffer in a new frame. Otherwise, display each buffer as
1107a new window in the current frame, splitting vertically."
1108 (interactive)
1109 (ibuffer-do-view-1 (if other-frame 'other-frame 'vertically)))
1110
1111(defun ibuffer-do-view-horizontally (&optional other-frame)
1112 "As `ibuffer-do-view', but split windows horizontally."
1113 (interactive)
1114 (ibuffer-do-view-1 (if other-frame 'other-frame 'horizontally)))
1115
1116(defun ibuffer-do-view-1 (type)
1117 (let ((marked-bufs (ibuffer-get-marked-buffers)))
1118 (when (null marked-bufs)
b5cd37ea 1119 (setq marked-bufs (list (ibuffer-current-buffer t))))
25d2f683
CW
1120 (unless (and (eq type 'other-frame)
1121 (not ibuffer-expert)
1122 (> (length marked-bufs) 3)
1123 (not (y-or-n-p (format "Really create a new frame for %s buffers? "
1124 (length marked-bufs)))))
4e4a724c 1125 (set-buffer-modified-p nil)
25d2f683
CW
1126 (delete-other-windows)
1127 (switch-to-buffer (pop marked-bufs))
1128 (let ((height (/ (1- (if (eq type 'horizontally) (frame-width)
4e4a724c 1129 (frame-height)))
25d2f683
CW
1130 (1+ (length marked-bufs)))))
1131 (mapcar (if (eq type 'other-frame)
1132 #'(lambda (buf)
1133 (let ((curframe (selected-frame)))
acf88897 1134 (select-frame (make-frame))
25d2f683
CW
1135 (switch-to-buffer buf)
1136 (select-frame curframe)))
1137 #'(lambda (buf)
1138 (split-window nil height (eq type 'horizontally))
1139 (other-window 1)
1140 (switch-to-buffer buf)))
1141 marked-bufs)))))
1142
1143(defun ibuffer-do-view-other-frame ()
1144 "View each of the marked buffers in a separate frame."
1145 (interactive)
1146 (ibuffer-do-view t))
1147
1148(defsubst ibuffer-map-marked-lines (func)
1149 (prog1 (ibuffer-map-on-mark ibuffer-marked-char func)
1150 (ibuffer-redisplay t)))
1151
1152(defun ibuffer-shrink-to-fit (&optional owin)
54124194
MO
1153 ;; Make sure that redisplay is performed, otherwise there can be a
1154 ;; bad interaction with code in the window-scroll-functions hook
1155 (redisplay t)
25d2f683
CW
1156 (fit-window-to-buffer nil (when owin (/ (frame-height)
1157 (length (window-list (selected-frame)))))))
1158
1159(defun ibuffer-confirm-operation-on (operation names)
1160 "Display a buffer asking whether to perform OPERATION on NAMES."
1161 (or ibuffer-expert
1162 (if (= (length names) 1)
1163 (y-or-n-p (format "Really %s buffer %s? " operation (car names)))
1164 (let ((buf (get-buffer-create "*Ibuffer confirmation*")))
1165 (with-current-buffer buf
1166 (setq buffer-read-only nil)
1167 (erase-buffer)
1168 (ibuffer-columnize-and-insert-list names)
1169 (goto-char (point-min))
1170 (setq buffer-read-only t))
4e4a724c 1171 (let ((lastwin (car (last (window-list nil 'nomini)))))
25d2f683
CW
1172 ;; Now attempt to display the buffer...
1173 (save-window-excursion
1174 (select-window lastwin)
1175 ;; The window might be too small to split; in that case,
7ad5b902 1176 ;; try a few times to increase its size before giving up.
25d2f683
CW
1177 (let ((attempts 0)
1178 (trying t))
1179 (while trying
1180 (condition-case err
1181 (progn
1182 (split-window)
1183 (setq trying nil))
1184 (error
1185 ;; Handle a failure
1186 (if (or (> (incf attempts) 4)
1187 (and (stringp (cadr err))
71296446 1188 ;; This definitely falls in the
4e4a724c 1189 ;; ghetto hack category...
25d2f683 1190 (not (string-match "too small" (cadr err)))))
8131c345 1191 (signal (car err) (cdr err))
25d2f683 1192 (enlarge-window 3))))))
25d2f683
CW
1193 (select-window (next-window))
1194 (switch-to-buffer buf)
1195 (unwind-protect
1196 (progn
1197 (fit-window-to-buffer)
1198 (y-or-n-p (format "Really %s %d buffers? "
1199 operation (length names))))
1200 (kill-buffer buf))))))))
1201
1202(defsubst ibuffer-map-lines-nomodify (function)
1203 "As `ibuffer-map-lines', but don't set the modification flag."
1204 (ibuffer-map-lines function t))
1205
1206(defun ibuffer-buffer-names-with-mark (mark)
1207 (let ((ibuffer-buffer-names-with-mark-result nil))
1208 (ibuffer-map-lines-nomodify
4e4a724c 1209 #'(lambda (buf mk)
25d2f683
CW
1210 (when (char-equal mark mk)
1211 (push (buffer-name buf)
1212 ibuffer-buffer-names-with-mark-result))))
1213 ibuffer-buffer-names-with-mark-result))
1214
1215(defsubst ibuffer-marked-buffer-names ()
1216 (ibuffer-buffer-names-with-mark ibuffer-marked-char))
1217
1218(defsubst ibuffer-deletion-marked-buffer-names ()
1219 (ibuffer-buffer-names-with-mark ibuffer-deletion-char))
1220
1221(defun ibuffer-count-marked-lines (&optional all)
1222 (if all
1223 (ibuffer-map-lines-nomodify
57c9cc3e 1224 #'(lambda (buf mark)
972b8f82 1225 (not (char-equal mark ?\s))))
25d2f683 1226 (ibuffer-map-lines-nomodify
57c9cc3e 1227 #'(lambda (buf mark)
25d2f683
CW
1228 (char-equal mark ibuffer-marked-char)))))
1229
1230(defsubst ibuffer-count-deletion-lines ()
1231 (ibuffer-map-lines-nomodify
57c9cc3e 1232 #'(lambda (buf mark)
25d2f683
CW
1233 (char-equal mark ibuffer-deletion-char))))
1234
1235(defsubst ibuffer-map-deletion-lines (func)
1236 (ibuffer-map-on-mark ibuffer-deletion-char func))
1237
87a6a53a 1238(defsubst ibuffer-assert-ibuffer-mode ()
2ead9289 1239 (assert (derived-mode-p 'ibuffer-mode)))
87a6a53a 1240
92cb2eaf
JPW
1241(defun ibuffer-buffer-file-name ()
1242 (or buffer-file-name
1243 (let ((dirname (or (and (boundp 'dired-directory)
1244 (if (stringp dired-directory)
1245 dired-directory
1246 (car dired-directory)))
414408cd 1247 (bound-and-true-p list-buffers-directory))))
9d458edc 1248 (and dirname (expand-file-name dirname)))))
92cb2eaf 1249
fd225d80 1250(define-ibuffer-op ibuffer-do-save ()
25d2f683
CW
1251 "Save marked buffers as with `save-buffer'."
1252 (:complex t
1253 :opstring "saved"
1254 :modifier-p :maybe)
1255 (when (buffer-modified-p buf)
1256 (if (not (with-current-buffer buf
1257 buffer-file-name))
1258 ;; handle the case where we're prompted
1259 ;; for a file name
1260 (save-window-excursion
1261 (switch-to-buffer buf)
1262 (save-buffer))
1263 (with-current-buffer buf
1264 (save-buffer))))
1265 t)
1266
fd225d80 1267(define-ibuffer-op ibuffer-do-toggle-modified ()
25d2f683
CW
1268 "Toggle modification flag of marked buffers."
1269 (:opstring "(un)marked as modified"
1270 :modifier-p t)
1271 (set-buffer-modified-p (not (buffer-modified-p))))
1272
92be491c
RW
1273(define-ibuffer-op ibuffer-do-toggle-read-only (&optional arg)
1274 "Toggle read only status in marked buffers.
320d3e68 1275With optional ARG, make read-only only if ARG is positive."
25d2f683 1276 (:opstring "toggled read only status in"
92be491c 1277 :interactive "P"
25d2f683 1278 :modifier-p t)
92be491c 1279 (toggle-read-only arg))
25d2f683 1280
fd225d80 1281(define-ibuffer-op ibuffer-do-delete ()
25d2f683
CW
1282 "Kill marked buffers as with `kill-this-buffer'."
1283 (:opstring "killed"
1284 :active-opstring "kill"
1285 :dangerous t
1286 :complex t
1287 :modifier-p t)
1288 (if (kill-buffer buf)
1289 'kill
1290 nil))
1291
fd225d80 1292(define-ibuffer-op ibuffer-do-kill-on-deletion-marks ()
25d2f683
CW
1293 "Kill buffers marked for deletion as with `kill-this-buffer'."
1294 (:opstring "killed"
1295 :active-opstring "kill"
1296 :dangerous t
1297 :complex t
1298 :mark :deletion
1299 :modifier-p t)
1300 (if (kill-buffer buf)
1301 'kill
1302 nil))
1303
1304(defun ibuffer-unmark-all (mark)
1305 "Unmark all buffers with mark MARK."
1306 (interactive "cRemove marks (RET means all):")
1307 (if (= (ibuffer-count-marked-lines t) 0)
1308 (message "No buffers marked; use 'm' to mark a buffer")
1309 (cond
1310 ((char-equal mark ibuffer-marked-char)
1311 (ibuffer-map-marked-lines
57c9cc3e 1312 #'(lambda (buf mark)
972b8f82 1313 (ibuffer-set-mark-1 ?\s)
25d2f683
CW
1314 t)))
1315 ((char-equal mark ibuffer-deletion-char)
1316 (ibuffer-map-deletion-lines
57c9cc3e 1317 #'(lambda (buf mark)
972b8f82 1318 (ibuffer-set-mark-1 ?\s)
25d2f683
CW
1319 t)))
1320 (t
1321 (ibuffer-map-lines
57c9cc3e 1322 #'(lambda (buf mark)
972b8f82
JB
1323 (when (not (char-equal mark ?\s))
1324 (ibuffer-set-mark-1 ?\s))
25d2f683
CW
1325 t)))))
1326 (ibuffer-redisplay t))
1327
b5cd37ea 1328(defun ibuffer-toggle-marks (&optional group)
25d2f683
CW
1329 "Toggle which buffers are marked.
1330In other words, unmarked buffers become marked, and marked buffers
cba63a2d
CW
1331become unmarked.
1332If point is on a group name, then this function operates on that
1333group."
25d2f683 1334 (interactive)
cba63a2d
CW
1335 (ibuffer-aif (get-text-property (point) 'ibuffer-filter-group-name)
1336 (setq group it))
25d2f683
CW
1337 (let ((count
1338 (ibuffer-map-lines
57c9cc3e 1339 #'(lambda (buf mark)
25d2f683 1340 (cond ((eq mark ibuffer-marked-char)
972b8f82 1341 (ibuffer-set-mark-1 ?\s)
25d2f683 1342 nil)
972b8f82 1343 ((eq mark ?\s)
25d2f683
CW
1344 (ibuffer-set-mark-1 ibuffer-marked-char)
1345 t)
1346 (t
b5cd37ea
CW
1347 nil)))
1348 nil group)))
25d2f683
CW
1349 (message "%s buffers marked" count))
1350 (ibuffer-redisplay t))
1351
1352(defun ibuffer-mark-forward (arg)
cba63a2d
CW
1353 "Mark the buffer on this line, and move forward ARG lines.
1354If point is on a group name, this function operates on that group."
25d2f683
CW
1355 (interactive "P")
1356 (ibuffer-mark-interactive arg ibuffer-marked-char 1))
1357
1358(defun ibuffer-unmark-forward (arg)
cba63a2d
CW
1359 "Unmark the buffer on this line, and move forward ARG lines.
1360If point is on a group name, this function operates on that group."
25d2f683 1361 (interactive "P")
972b8f82 1362 (ibuffer-mark-interactive arg ?\s 1))
25d2f683
CW
1363
1364(defun ibuffer-unmark-backward (arg)
cba63a2d
CW
1365 "Unmark the buffer on this line, and move backward ARG lines.
1366If point is on a group name, this function operates on that group."
25d2f683 1367 (interactive "P")
972b8f82 1368 (ibuffer-mark-interactive arg ?\s -1))
25d2f683
CW
1369
1370(defun ibuffer-mark-interactive (arg mark movement)
87a6a53a 1371 (ibuffer-assert-ibuffer-mode)
34a4faa0 1372 (or arg (setq arg 1))
cba63a2d
CW
1373 (ibuffer-forward-line 0)
1374 (ibuffer-aif (get-text-property (point) 'ibuffer-filter-group-name)
1375 (progn
1376 (require 'ibuf-ext)
1377 (ibuffer-mark-on-buffer #'identity mark it))
4e4a724c 1378 (ibuffer-forward-line 0 t)
cba63a2d
CW
1379 (let ((inhibit-read-only t))
1380 (while (> arg 0)
1381 (ibuffer-set-mark mark)
1382 (ibuffer-forward-line movement t)
1383 (setq arg (1- arg))))))
25d2f683
CW
1384
1385(defun ibuffer-set-mark (mark)
87a6a53a 1386 (ibuffer-assert-ibuffer-mode)
25d2f683
CW
1387 (let ((inhibit-read-only t))
1388 (ibuffer-set-mark-1 mark)
1389 (setq ibuffer-did-modification t)
559ac4c1
CW
1390 (ibuffer-redisplay-current)
1391 (beginning-of-line)))
25d2f683
CW
1392
1393(defun ibuffer-set-mark-1 (mark)
1394 (let ((beg (line-beginning-position))
1395 (end (line-end-position)))
1396 (put-text-property beg end 'ibuffer-properties
1397 (list (ibuffer-current-buffer)
1398 mark))))
1399
1400(defun ibuffer-mark-for-delete (arg)
cba63a2d
CW
1401 "Mark the buffers on ARG lines forward for deletion.
1402If point is on a group name, this function operates on that group."
25d2f683
CW
1403 (interactive "P")
1404 (ibuffer-mark-interactive arg ibuffer-deletion-char 1))
1405
1406(defun ibuffer-mark-for-delete-backwards (arg)
cba63a2d
CW
1407 "Mark the buffers on ARG lines backward for deletion.
1408If point is on a group name, this function operates on that group."
25d2f683
CW
1409 (interactive "P")
1410 (ibuffer-mark-interactive arg ibuffer-deletion-char -1))
1411
1412(defun ibuffer-current-buffer (&optional must-be-live)
1413 (let ((buf (car (get-text-property (line-beginning-position)
1414 'ibuffer-properties))))
b5cd37ea
CW
1415 (when must-be-live
1416 (if (bufferp buf)
1417 (unless (buffer-live-p buf)
1388485d 1418 (error "Buffer %s has been killed; %s" buf (substitute-command-keys "use `\\[ibuffer-update]' to update")))
b5cd37ea 1419 (error "No buffer on this line")))
25d2f683 1420 buf))
523304ed
CW
1421
1422(defun ibuffer-active-formats-name ()
1423 (if (boundp 'ibuffer-filter-format-alist)
1424 (let ((ret nil))
1425 (dolist (filter ibuffer-filtering-qualifiers ret)
1426 (let ((val (assq (car filter) ibuffer-filter-format-alist)))
1427 (when val
1428 (setq ret (car filter)))))
1429 (if ret
1430 ret
1431 :ibuffer-formats))
1432 :ibuffer-formats))
1433
1434(defun ibuffer-current-formats (uncompiledp)
1435 (let* ((name (ibuffer-active-formats-name)))
1436 (ibuffer-check-formats)
1437 (if (eq name :ibuffer-formats)
1438 (if uncompiledp
1439 ibuffer-formats
1440 ibuffer-compiled-formats)
1441 (cadr (assq name
1442 (if uncompiledp
1443 ibuffer-filter-format-alist
1444 ibuffer-compiled-filter-formats))))))
71296446 1445
523304ed 1446(defun ibuffer-current-format (&optional uncompiledp)
25d2f683
CW
1447 (or ibuffer-current-format
1448 (setq ibuffer-current-format 0))
4e4a724c 1449 (nth ibuffer-current-format (ibuffer-current-formats uncompiledp)))
25d2f683
CW
1450
1451(defun ibuffer-expand-format-entry (form)
1452 (if (or (consp form)
1453 (symbolp form))
4e4a724c
JPW
1454 (let ((sym (intern (concat "ibuffer-make-column-"
1455 (symbol-name (if (consp form)
1456 (car form)
1457 form))))))
1458 (unless (or (fboundp sym)
1459 (assq sym ibuffer-inline-columns))
1460 (error "Unknown column %s in ibuffer-formats" form))
1461 (let (min max align elide)
1462 (if (consp form)
1463 (setq min (or (nth 1 form) 0)
1464 max (or (nth 2 form) -1)
1465 align (or (nth 3 form) :left)
1466 elide (or (nth 4 form) nil))
1467 (setq min 0
1468 max -1
1469 align :left
1470 elide nil))
1471 (list sym min max align elide)))
25d2f683 1472 form))
71296446 1473
25d2f683 1474(defun ibuffer-compile-make-eliding-form (strvar elide from-end-p)
545aad2f 1475 (let ((ellipsis (propertize ibuffer-eliding-string 'font-lock-face 'bold)))
63f0a166 1476 (if (or elide (with-no-warnings ibuffer-elide-long-columns))
25d2f683
CW
1477 `(if (> strlen 5)
1478 ,(if from-end-p
1479 `(concat ,ellipsis
1480 (substring ,strvar
1481 (length ibuffer-eliding-string)))
1482 `(concat
1483 (substring ,strvar 0 (- strlen ,(length ellipsis)))
1484 ,ellipsis))
1485 ,strvar)
1486 strvar)))
1487
1488(defun ibuffer-compile-make-substring-form (strvar maxvar from-end-p)
1489 (if from-end-p
1490 `(substring str
1491 (- strlen ,maxvar))
1492 `(substring ,strvar 0 ,maxvar)))
1493
1494(defun ibuffer-compile-make-format-form (strvar widthform alignment)
972b8f82
JB
1495 (let* ((left `(make-string tmp2 ?\s))
1496 (right `(make-string (- tmp1 tmp2) ?\s)))
25d2f683
CW
1497 `(progn
1498 (setq tmp1 ,widthform
1499 tmp2 (/ tmp1 2))
1500 ,(case alignment
1501 (:right `(concat ,left ,right ,strvar))
1502 (:center `(concat ,left ,strvar ,right))
1503 (:left `(concat ,strvar ,left ,right))
1504 (t (error "Invalid alignment %s" alignment))))))
1505
1506(defun ibuffer-compile-format (format)
1507 (let ((result nil)
cb059426
CW
1508 ;; We use these variables to keep track of which variables
1509 ;; inside the generated function we need to bind, since
1510 ;; binding variables in Emacs takes time.
1511 str-used tmp1-used tmp2-used global-strlen-used)
25d2f683
CW
1512 (dolist (form format)
1513 (push
cb059426
CW
1514 ;; Generate a form based on a particular format entry, like
1515 ;; " ", mark, or (mode 16 16 :right).
25d2f683 1516 (if (stringp form)
cb059426 1517 ;; It's a string; all we need to do is insert it.
25d2f683
CW
1518 `(insert ,form)
1519 (let* ((form (ibuffer-expand-format-entry form))
1520 (sym (nth 0 form))
1521 (min (nth 1 form))
1522 (max (nth 2 form))
1523 (align (nth 3 form))
1524 (elide (nth 4 form)))
1525 (let* ((from-end-p (when (minusp min)
1526 (setq min (- min))
1527 t))
1528 (letbindings nil)
1529 (outforms nil)
1530 minform
1531 maxform
1532 min-used max-used strlen-used)
1533 (when (or (not (integerp min)) (>= min 0))
cb059426
CW
1534 ;; This is a complex case; they want it limited to a
1535 ;; minimum size.
25d2f683
CW
1536 (setq min-used t)
1537 (setq str-used t strlen-used t global-strlen-used t
1538 tmp1-used t tmp2-used t)
cb059426 1539 ;; Generate code to limit the string to a minimum size.
25d2f683
CW
1540 (setq minform `(progn
1541 (setq str
1542 ,(ibuffer-compile-make-format-form
1543 'str
1544 `(- ,(if (integerp min)
1545 min
1546 'min)
1547 strlen)
1548 align)))))
1549 (when (or (not (integerp max)) (> max 0))
1550 (setq str-used t max-used t)
cb059426 1551 ;; Generate code to limit the string to a maximum size.
25d2f683
CW
1552 (setq maxform `(progn
1553 (setq str
1554 ,(ibuffer-compile-make-substring-form
1555 'str
1556 (if (integerp max)
1557 max
1558 'max)
1559 from-end-p))
1560 (setq strlen (length str))
1561 (setq str
1562 ,(ibuffer-compile-make-eliding-form 'str
1563 elide
1564 from-end-p)))))
cb059426
CW
1565 ;; Now, put these forms together with the rest of the code.
1566 (let ((callform
1567 ;; Is this an "inline" column? This means we have
1568 ;; to get the code from the
1569 ;; `ibuffer-inline-columns' alist and insert it
1570 ;; into our generated code. Otherwise, we just
1571 ;; generate a call to the column function.
1572 (ibuffer-aif (assq sym ibuffer-inline-columns)
4e4a724c
JPW
1573 (nth 1 it)
1574 `(,sym buffer mark)))
cb059426
CW
1575 ;; You're not expected to understand this. Hell, I
1576 ;; don't even understand it, and I wrote it five
1577 ;; minutes ago.
1578 (insertgenfn (ibuffer-aif (get sym 'ibuffer-column-summarizer)
4e4a724c
JPW
1579 ;; I really, really wish Emacs Lisp had closures.
1580 (lambda (arg sym)
1581 `(insert
1582 (let ((ret ,arg))
1583 (put ',sym 'ibuffer-column-summary
1584 (cons ret (get ',sym 'ibuffer-column-summary)))
1585 ret)))
545aad2f
CW
1586 (lambda (arg sym)
1587 `(insert ,arg))))
25d2f683
CW
1588 (mincompform `(< strlen ,(if (integerp min)
1589 min
1590 'min)))
1591 (maxcompform `(> strlen ,(if (integerp max)
1592 max
1593 'max))))
4e4a724c
JPW
1594 (if (or min-used max-used)
1595 ;; The complex case, where we have to limit the
1596 ;; form to a maximum or minimum size.
1597 (progn
1598 (when (and min-used (not (integerp min)))
1599 (push `(min ,min) letbindings))
1600 (when (and max-used (not (integerp max)))
1601 (push `(max ,max) letbindings))
1602 (push
1603 (if (and min-used max-used)
1604 `(if ,mincompform
1605 ,minform
1606 (if ,maxcompform
1607 ,maxform))
1608 (if min-used
1609 `(when ,mincompform
1610 ,minform)
1611 `(when ,maxcompform
1612 ,maxform)))
1613 outforms)
1614 (push (append
1615 `(setq str ,callform)
1616 (when strlen-used
1617 `(strlen (length str))))
1618 outforms)
1619 (setq outforms
1620 (append outforms (list (funcall insertgenfn 'str sym)))))
1621 ;; The simple case; just insert the string.
1622 (push (funcall insertgenfn callform sym) outforms))
1623 ;; Finally, return a `let' form which binds the
1624 ;; variables in `letbindings', and contains all the
1625 ;; code in `outforms'.
1626 `(let ,letbindings
1627 ,@outforms)))))
25d2f683
CW
1628 result))
1629 (setq result
cb059426 1630 ;; We don't want to unconditionally load the byte-compiler.
25d2f683
CW
1631 (funcall (if (or ibuffer-always-compile-formats
1632 (featurep 'bytecomp))
1633 #'byte-compile
1634 #'identity)
cb059426
CW
1635 ;; Here, we actually create a lambda form which
1636 ;; inserts all the generated forms for each entry
1637 ;; in the format string.
25d2f683 1638 (nconc (list 'lambda '(buffer mark))
d99b259b 1639 `((let ,(append (when str-used
25d2f683
CW
1640 '(str))
1641 (when global-strlen-used
1642 '(strlen))
1643 (when tmp1-used
1644 '(tmp1))
1645 (when tmp2-used
1646 '(tmp2)))
1647 ,@(nreverse result))))))))
1648
25d2f683
CW
1649(defun ibuffer-recompile-formats ()
1650 "Recompile `ibuffer-formats'."
1651 (interactive)
1652 (setq ibuffer-compiled-formats
4e4a724c 1653 (mapcar #'ibuffer-compile-format ibuffer-formats))
523304ed
CW
1654 (when (boundp 'ibuffer-filter-format-alist)
1655 (setq ibuffer-compiled-filter-formats
1656 (mapcar #'(lambda (entry)
1657 (cons (car entry)
1658 (mapcar #'(lambda (formats)
1659 (mapcar #'ibuffer-compile-format formats))
1660 (cdr entry))))
1661 ibuffer-filter-format-alist))))
25d2f683 1662
cb059426
CW
1663(defun ibuffer-clear-summary-columns (format)
1664 (dolist (form format)
1665 (ibuffer-awhen (and (consp form)
1666 (get (car form) 'ibuffer-column-summarizer))
1667 (put (car form) 'ibuffer-column-summary nil))))
71296446 1668
25d2f683 1669(defun ibuffer-check-formats ()
523304ed
CW
1670 (when (null ibuffer-formats)
1671 (error "No formats!"))
b5cd37ea
CW
1672 (let ((ext-loaded (featurep 'ibuf-ext)))
1673 (when (or (null ibuffer-compiled-formats)
1674 (null ibuffer-cached-formats)
1675 (not (eq ibuffer-cached-formats ibuffer-formats))
1676 (null ibuffer-cached-eliding-string)
1677 (not (equal ibuffer-cached-eliding-string ibuffer-eliding-string))
1678 (eql 0 ibuffer-cached-elide-long-columns)
1679 (not (eql ibuffer-cached-elide-long-columns
63f0a166 1680 (with-no-warnings ibuffer-elide-long-columns)))
b5cd37ea
CW
1681 (and ext-loaded
1682 (not (eq ibuffer-cached-filter-formats
1683 ibuffer-filter-format-alist))
1684 (and ibuffer-filter-format-alist
1685 (null ibuffer-compiled-filter-formats))))
1686 (message "Formats have changed, recompiling...")
1687 (ibuffer-recompile-formats)
1688 (setq ibuffer-cached-formats ibuffer-formats
1689 ibuffer-cached-eliding-string ibuffer-eliding-string
63f0a166 1690 ibuffer-cached-elide-long-columns (with-no-warnings ibuffer-elide-long-columns))
b5cd37ea
CW
1691 (when ext-loaded
1692 (setq ibuffer-cached-filter-formats ibuffer-filter-format-alist))
1693 (message "Formats have changed, recompiling...done"))))
25d2f683
CW
1694
1695(defvar ibuffer-inline-columns nil)
1696
1697(define-ibuffer-column mark (:name " " :inline t)
1698 (string mark))
1699
1700(define-ibuffer-column read-only (:name "R" :inline t)
1701 (if buffer-read-only
34a4faa0 1702 (string ibuffer-read-only-char)
25d2f683
CW
1703 " "))
1704
1705(define-ibuffer-column modified (:name "M" :inline t)
1706 (if (buffer-modified-p)
1707 (string ibuffer-modified-char)
1708 " "))
1709
34a4faa0
JPW
1710(define-ibuffer-column name
1711 (:inline t
f0b31589 1712 :header-mouse-map ibuffer-name-header-map
34a4faa0
JPW
1713 :props
1714 ('mouse-face 'highlight 'keymap ibuffer-name-map
1715 'ibuffer-name-column t
1716 'help-echo '(if tooltip-mode
1717 "mouse-1: mark this buffer\nmouse-2: select this buffer\nmouse-3: operate on this buffer"
1718 "mouse-1: mark buffer mouse-2: select buffer mouse-3: operate"))
1719 :summarizer
1720 (lambda (strings)
1721 (let ((bufs (length strings)))
1722 (cond ((zerop bufs) "No buffers")
1723 ((= 1 bufs) "1 buffer")
1724 (t (format "%s buffers" bufs))))))
545aad2f 1725 (propertize (buffer-name) 'font-lock-face (ibuffer-buffer-name-face buffer mark)))
71296446 1726
34a4faa0
JPW
1727(define-ibuffer-column size
1728 (:inline t
f0b31589 1729 :header-mouse-map ibuffer-size-header-map
34a4faa0
JPW
1730 :summarizer
1731 (lambda (column-strings)
1732 (let ((total 0))
1733 (dolist (string column-strings)
1734 (setq total
1735 ;; like, ewww ...
7ad938e7 1736 (+ (float (string-to-number string))
34a4faa0
JPW
1737 total)))
1738 (format "%.0f" total))))
25d2f683
CW
1739 (format "%s" (buffer-size)))
1740
7ad938e7
JPW
1741(define-ibuffer-column mode
1742 (:inline t
f0b31589 1743 :header-mouse-map ibuffer-mode-header-map
7ad938e7
JPW
1744 :props
1745 ('mouse-face 'highlight
1746 'keymap ibuffer-mode-name-map
1747 'help-echo "mouse-2: filter by this mode"))
23eabff6 1748 (format-mode-line mode-name nil nil (current-buffer)))
25d2f683 1749
34a4faa0
JPW
1750(define-ibuffer-column process
1751 (:summarizer
1752 (lambda (strings)
1753 (let ((total (length (delete "" strings))))
1754 (cond ((zerop total) "No processes")
1755 ((= 1 total) "1 process")
1756 (t (format "%d processes" total))))))
96777edb
CW
1757 (ibuffer-aif (get-buffer-process buffer)
1758 (format "(%s %s)" it (process-status it))
34a4faa0
JPW
1759 ""))
1760
1761(define-ibuffer-column filename
1762 (:summarizer
1763 (lambda (strings)
1764 (let ((total (length (delete "" strings))))
1765 (cond ((zerop total) "No files")
1766 ((= 1 total) "1 file")
1767 (t (format "%d files" total))))))
25d2f683
CW
1768 (let ((directory-abbrev-alist ibuffer-directory-abbrev-alist))
1769 (abbreviate-file-name
9d458edc 1770 (or (ibuffer-buffer-file-name) ""))))
25d2f683 1771
34a4faa0
JPW
1772(define-ibuffer-column filename-and-process
1773 (:name "Filename/Process"
d5794180 1774 :header-mouse-map ibuffer-filename/process-header-map
34a4faa0
JPW
1775 :summarizer
1776 (lambda (strings)
1777 (setq strings (delete "" strings))
1778 (let ((procs 0)
1779 (files 0))
1780 (dolist (string strings)
1781 (if (string-match "\\(\?:\\`(\[\[:ascii:\]\]\+)\\)" string)
1782 (progn (setq procs (1+ procs))
1783 (if (< (match-end 0) (length string))
1784 (setq files (1+ files))))
1785 (setq files (1+ files))))
1786 (concat (cond ((zerop files) "No files")
1787 ((= 1 files) "1 file")
1788 (t (format "%d files" files)))
1789 ", "
1790 (cond ((zerop procs) "no processes")
1791 ((= 1 procs) "1 process")
1792 (t (format "%d processes" procs)))))))
fd225d80 1793 (let ((proc (get-buffer-process buffer))
63e0bf5e 1794 (filename (ibuffer-make-column-filename buffer mark)))
fd225d80 1795 (if proc
34a4faa0 1796 (concat (propertize (format "(%s %s)" proc (process-status proc))
545aad2f 1797 'font-lock-face 'italic)
34a4faa0
JPW
1798 (if (> (length filename) 0)
1799 (format " %s" filename)
1800 ""))
fd225d80
CW
1801 filename)))
1802
25d2f683 1803(defun ibuffer-format-column (str width alignment)
972b8f82
JB
1804 (let ((left (make-string (/ width 2) ?\s))
1805 (right (make-string (- width (/ width 2)) ?\s)))
25d2f683
CW
1806 (case alignment
1807 (:right (concat left right str))
1808 (:center (concat left str right))
1809 (t (concat str left right)))))
1810
545aad2f 1811(defun ibuffer-buffer-name-face (buf mark)
fd225d80 1812 (cond ((char-equal mark ibuffer-marked-char)
545aad2f 1813 ibuffer-marked-face)
fd225d80 1814 ((char-equal mark ibuffer-deletion-char)
545aad2f 1815 ibuffer-deletion-face)
fd225d80
CW
1816 (t
1817 (let ((level -1)
fd225d80
CW
1818 result)
1819 (dolist (e ibuffer-fontification-alist result)
1820 (when (and (> (car e) level)
1821 (with-current-buffer buf
545aad2f 1822 (eval (nth 1 e))))
fd225d80 1823 (setq level (car e)
545aad2f 1824 result (nth 2 e))))))))
25d2f683
CW
1825
1826(defun ibuffer-insert-buffer-line (buffer mark format)
1827 "Insert a line describing BUFFER and MARK using FORMAT."
87a6a53a 1828 (ibuffer-assert-ibuffer-mode)
25d2f683 1829 (let ((beg (point)))
25d2f683 1830 (funcall format buffer mark)
cb059426
CW
1831 (put-text-property beg (point) 'ibuffer-properties (list buffer mark)))
1832 (insert "\n"))
25d2f683 1833
cb059426 1834;; This function knows a bit too much of the internals. It would be
b5cd37ea 1835;; nice if it was all abstracted away.
25d2f683 1836(defun ibuffer-redisplay-current ()
87a6a53a 1837 (ibuffer-assert-ibuffer-mode)
25d2f683
CW
1838 (when (eobp)
1839 (forward-line -1))
1840 (beginning-of-line)
cb059426
CW
1841 (let ((curformat (mapcar #'ibuffer-expand-format-entry
1842 (ibuffer-current-format t))))
1843 (ibuffer-clear-summary-columns curformat)
1844 (let ((buf (ibuffer-current-buffer)))
1845 (when buf
1846 (let ((mark (ibuffer-current-mark)))
ed233dd8
CW
1847 (save-excursion
1848 (delete-region (point) (1+ (line-end-position)))
1849 (ibuffer-insert-buffer-line
1850 buf mark
1851 (ibuffer-current-format)))
cb059426
CW
1852 (when ibuffer-shrink-to-minimum-size
1853 (ibuffer-shrink-to-fit)))))))
71296446 1854
25d2f683
CW
1855(defun ibuffer-map-on-mark (mark func)
1856 (ibuffer-map-lines
57c9cc3e 1857 #'(lambda (buf mk)
25d2f683 1858 (if (char-equal mark mk)
57c9cc3e 1859 (funcall func buf mark)
25d2f683
CW
1860 nil))))
1861
b5cd37ea
CW
1862(defun ibuffer-map-lines (function &optional nomodify group)
1863 "Call FUNCTION for each buffer.
4837b516 1864Set the ibuffer modification flag unless NOMODIFY is non-nil.
25d2f683 1865
b5cd37ea
CW
1866If optional argument GROUP is non-nil, then only call FUNCTION on
1867buffers in filtering group GROUP.
1868
4e4a724c
JPW
1869FUNCTION is called with two arguments:
1870the buffer object itself and the current mark symbol."
87a6a53a 1871 (ibuffer-assert-ibuffer-mode)
b5cd37ea
CW
1872 (ibuffer-forward-line 0)
1873 (let* ((orig-target-line (1+ (count-lines (save-excursion
1874 (goto-char (point-min))
1875 (ibuffer-forward-line 0)
1876 (point))
1877 (point))))
1878 (target-line-offset orig-target-line)
1879 (ibuffer-map-lines-total 0)
1880 (ibuffer-map-lines-count 0))
25d2f683 1881 (unwind-protect
57c9cc3e
CW
1882 (progn
1883 (setq buffer-read-only nil)
1884 (goto-char (point-min))
4e4a724c 1885 (ibuffer-forward-line 0 t)
57c9cc3e 1886 (while (and (not (eobp))
b5cd37ea
CW
1887 (not (get-text-property (point) 'ibuffer-summary))
1888 (progn
1889 (ibuffer-forward-line 0 t)
1890 (and (not (eobp))
1891 (not (get-text-property (point) 'ibuffer-summary)))))
57c9cc3e
CW
1892 (let ((result
1893 (if (buffer-live-p (ibuffer-current-buffer))
b5cd37ea
CW
1894 (when (or (null group)
1895 (ibuffer-aif (get-text-property (point) 'ibuffer-filter-group)
1896 (equal group it)))
1897 (save-excursion
1898 (funcall function
1899 (ibuffer-current-buffer)
1900 (ibuffer-current-mark))))
57c9cc3e
CW
1901 ;; Kill the line if the buffer is dead
1902 'kill)))
1903 ;; A given mapping function should return:
1904 ;; `nil' if it chose not to affect the buffer
1905 ;; `kill' means the remove line from the buffer list
1906 ;; `t' otherwise
1907 (incf ibuffer-map-lines-total)
1908 (cond ((null result)
1909 (forward-line 1))
1910 ((eq result 'kill)
1911 (delete-region (line-beginning-position)
1912 (1+ (line-end-position)))
1913 (incf ibuffer-map-lines-count)
1914 (when (< ibuffer-map-lines-total
4e4a724c 1915 orig-target-line)
b5cd37ea 1916 (decf target-line-offset)))
57c9cc3e
CW
1917 (t
1918 (incf ibuffer-map-lines-count)
1919 (forward-line 1)))))
1920 ibuffer-map-lines-count)
25d2f683
CW
1921 (progn
1922 (setq buffer-read-only t)
1923 (unless nomodify
1924 (set-buffer-modified-p nil))
57c9cc3e
CW
1925 (goto-char (point-min))
1926 (ibuffer-forward-line 0)
b5cd37ea 1927 (ibuffer-forward-line (1- target-line-offset))))))
25d2f683
CW
1928
1929(defun ibuffer-get-marked-buffers ()
1930 "Return a list of buffer objects currently marked."
1931 (delq nil
1932 (mapcar #'(lambda (e)
1933 (when (eq (cdr e) ibuffer-marked-char)
1934 (car e)))
1935 (ibuffer-current-state-list))))
1936
d246cabf
CW
1937(defun ibuffer-current-state-list (&optional pos)
1938 "Return a list like (BUF . MARK) of all buffers in an ibuffer.
1939If POS is non-nil, return a list like (BUF MARK POINT), where POINT is
1940the value of point at the beginning of the line for that buffer."
25d2f683
CW
1941 (let ((ibuffer-current-state-list-tmp '()))
1942 ;; ah, if only we had closures. I bet this will mysteriously
1943 ;; break later. Don't blame me.
d246cabf
CW
1944 (if pos
1945 (ibuffer-map-lines-nomodify
1946 #'(lambda (buf mark)
1947 (when (buffer-live-p buf)
1948 (push (list buf mark (point)) ibuffer-current-state-list-tmp))))
1949 (ibuffer-map-lines-nomodify
1950 #'(lambda (buf mark)
1951 (when (buffer-live-p buf)
1952 (push (cons buf mark) ibuffer-current-state-list-tmp)))))
25d2f683
CW
1953 (nreverse ibuffer-current-state-list-tmp)))
1954
851476d4 1955(defun ibuffer-current-buffers-with-marks (curbufs)
25d2f683
CW
1956 "Return a list like (BUF . MARK) of all open buffers."
1957 (let ((bufs (ibuffer-current-state-list)))
1958 (mapcar #'(lambda (buf) (let ((e (assq buf bufs)))
1959 (if e
1960 e
972b8f82 1961 (cons buf ?\s))))
851476d4 1962 curbufs)))
25d2f683
CW
1963
1964(defun ibuffer-buf-matches-predicates (buf predicates)
1965 (let ((hit nil)
1966 (name (buffer-name buf)))
1967 (dolist (pred predicates)
1968 (when (if (stringp pred)
1969 (string-match pred name)
1970 (funcall pred buf))
1971 (setq hit t)))
1972 hit))
71296446 1973
25d2f683
CW
1974(defun ibuffer-filter-buffers (ibuffer-buf last bmarklist all)
1975 (let ((ext-loaded (featurep 'ibuf-ext)))
1976 (delq nil
b5cd37ea
CW
1977 (mapcar
1978 ;; element should be like (BUFFER . MARK)
1979 #'(lambda (e)
1980 (let* ((buf (car e)))
1981 (when
1982 ;; This takes precedence over anything else
1983 (or (and ibuffer-always-show-last-buffer
4e4a724c
JPW
1984 (eq last buf))
1985 (funcall (if ext-loaded
1986 #'ibuffer-ext-visible-p
1987 #'ibuffer-visible-p)
1988 buf all ibuffer-buf))
b5cd37ea
CW
1989 e)))
1990 bmarklist))))
25d2f683
CW
1991
1992(defun ibuffer-visible-p (buf all &optional ibuffer-buf)
1993 (and (or all
1994 (not
1995 (ibuffer-buf-matches-predicates buf ibuffer-maybe-show-predicates)))
1996 (or ibuffer-view-ibuffer
4e4a724c 1997 (and ibuffer-buf
25d2f683
CW
1998 (not (eq ibuffer-buf buf))))))
1999
2000;; This function is a special case; it's not defined by
6081889e 2001;; `define-ibuffer-sorter'.
25d2f683
CW
2002(defun ibuffer-do-sort-by-recency ()
2003 "Sort the buffers by last view time."
2004 (interactive)
2005 (setq ibuffer-sorting-mode 'recency)
e7820654
JPW
2006 (when (eq ibuffer-last-sorting-mode 'recency)
2007 (setq ibuffer-sorting-reversep (not ibuffer-sorting-reversep)))
2008 (ibuffer-update nil t)
2009 (setq ibuffer-last-sorting-mode 'recency))
25d2f683
CW
2010
2011(defun ibuffer-update-format ()
2012 (when (null ibuffer-current-format)
2013 (setq ibuffer-current-format 0))
2014 (when (null ibuffer-formats)
2015 (error "Ibuffer error: no formats!")))
2016
2017(defun ibuffer-switch-format ()
2018 "Switch the current display format."
2019 (interactive)
87a6a53a 2020 (ibuffer-assert-ibuffer-mode)
25d2f683
CW
2021 (unless (consp ibuffer-formats)
2022 (error "Ibuffer error: No formats!"))
2023 (setq ibuffer-current-format
80a06d64 2024 (if (>= ibuffer-current-format (1- (length (ibuffer-current-formats nil))))
25d2f683
CW
2025 0
2026 (1+ ibuffer-current-format)))
2027 (ibuffer-update-format)
2028 (ibuffer-redisplay t))
2029
cb059426 2030(defun ibuffer-update-title-and-summary (format)
87a6a53a 2031 (ibuffer-assert-ibuffer-mode)
25d2f683
CW
2032 ;; Don't do funky font-lock stuff here
2033 (let ((after-change-functions nil))
2034 (if (get-text-property (point-min) 'ibuffer-title)
2035 (delete-region (point-min)
2036 (next-single-property-change
2037 (point-min) 'ibuffer-title)))
2038 (goto-char (point-min))
fd225d80 2039 (add-text-properties
25d2f683
CW
2040 (point)
2041 (progn
2042 (let ((opos (point)))
2043 ;; Insert the title names.
cb059426 2044 (dolist (element format)
25d2f683
CW
2045 (insert
2046 (if (stringp element)
2047 element
2048 (let ((sym (car element))
2049 (min (cadr element))
2050 ;; (max (caddr element))
2051 (align (cadddr element)))
4e4a724c 2052 ;; Ignore a negative min when we're inserting the title
25d2f683
CW
2053 (when (minusp min)
2054 (setq min (- min)))
2055 (let* ((name (or (get sym 'ibuffer-column-name)
2056 (error "Unknown column %s in ibuffer-formats" sym)))
f0b31589
DN
2057 (len (length name))
2058 (hmap (get sym 'header-mouse-map))
2059 (strname (if (< len min)
2060 (ibuffer-format-column name
2061 (- min len)
2062 align)
2063 name)))
2064 (when hmap
2065 (setq
2ead9289 2066 strname
f0b31589
DN
2067 (propertize strname 'mouse-face 'highlight 'keymap hmap)))
2068 strname)))))
fd225d80 2069 (add-text-properties opos (point) `(ibuffer-title-header t))
25d2f683
CW
2070 (insert "\n")
2071 ;; Add the underlines
2072 (let ((str (save-excursion
2073 (forward-line -1)
2074 (beginning-of-line)
2075 (buffer-substring (point) (line-end-position)))))
2076 (apply #'insert (mapcar
2077 #'(lambda (c)
972b8f82 2078 (if (not (or (char-equal c ?\s)
25d2f683
CW
2079 (char-equal c ?\n)))
2080 ?-
972b8f82 2081 ?\s))
25d2f683
CW
2082 str)))
2083 (insert "\n"))
2084 (point))
545aad2f 2085 `(ibuffer-title t font-lock-face ,ibuffer-title-face))
cb059426
CW
2086 ;; Now, insert the summary columns.
2087 (goto-char (point-max))
2088 (if (get-text-property (1- (point-max)) 'ibuffer-summary)
2089 (delete-region (previous-single-property-change
2090 (point-max) 'ibuffer-summary)
2091 (point-max)))
0740098c
JPW
2092 (if ibuffer-display-summary
2093 (add-text-properties
2094 (point)
2095 (progn
2096 (insert "\n")
2097 (dolist (element format)
2098 (insert
2099 (if (stringp element)
972b8f82 2100 (make-string (length element) ?\s)
0740098c
JPW
2101 (let ((sym (car element)))
2102 (let ((min (cadr element))
2103 ;; (max (caddr element))
2104 (align (cadddr element)))
2105 ;; Ignore a negative min when we're inserting the title
2106 (when (minusp min)
2107 (setq min (- min)))
2108 (let* ((summary (if (get sym 'ibuffer-column-summarizer)
2109 (funcall (get sym 'ibuffer-column-summarizer)
2110 (get sym 'ibuffer-column-summary))
2111 (make-string (length (get sym 'ibuffer-column-name))
972b8f82 2112 ?\s)))
0740098c
JPW
2113 (len (length summary)))
2114 (if (< len min)
2115 (ibuffer-format-column summary
2116 (- min len)
2117 align)
2118 summary)))))))
2119 (point))
2120 `(ibuffer-summary t)))))
25d2f683 2121
25d2f683
CW
2122
2123(defun ibuffer-redisplay (&optional silent)
2124 "Redisplay the current list of buffers.
25d2f683
CW
2125This does not show new buffers; use `ibuffer-update' for that.
2126
7ad5b902 2127If optional arg SILENT is non-nil, do not display progress messages."
25d2f683 2128 (interactive)
57c9cc3e 2129 (ibuffer-forward-line 0)
25d2f683
CW
2130 (unless silent
2131 (message "Redisplaying current buffer list..."))
2132 (let ((blist (ibuffer-current-state-list)))
2133 (when (null blist)
2134 (if (and (featurep 'ibuf-ext)
cba63a2d 2135 (or ibuffer-filtering-qualifiers ibuffer-hidden-filter-groups))
25d2f683
CW
2136 (message "No buffers! (note: filtering in effect)")
2137 (error "No buffers!")))
b5cd37ea 2138 (ibuffer-redisplay-engine blist t)
25d2f683 2139 (unless silent
57c9cc3e
CW
2140 (message "Redisplaying current buffer list...done"))
2141 (ibuffer-forward-line 0)))
25d2f683
CW
2142
2143(defun ibuffer-update (arg &optional silent)
2144 "Regenerate the list of all buffers.
957237cb
JPW
2145
2146Prefix arg non-nil means to toggle whether buffers that match
2147`ibuffer-maybe-show-predicates' should be displayed.
25d2f683 2148
7ad5b902 2149If optional arg SILENT is non-nil, do not display progress messages."
25d2f683 2150 (interactive "P")
957237cb
JPW
2151 (if arg
2152 (setq ibuffer-display-maybe-show-predicates
2153 (not ibuffer-display-maybe-show-predicates)))
57c9cc3e 2154 (ibuffer-forward-line 0)
25d2f683
CW
2155 (let* ((bufs (buffer-list))
2156 (blist (ibuffer-filter-buffers
94394914
JPW
2157 (current-buffer)
2158 (if (and
2159 (cadr bufs)
2160 (eq ibuffer-always-show-last-buffer
2161 :nomini)
8e7dbfdb 2162 (minibufferp (cadr bufs)))
da337a28 2163 (caddr bufs)
94394914
JPW
2164 (cadr bufs))
2165 (ibuffer-current-buffers-with-marks bufs)
957237cb 2166 ibuffer-display-maybe-show-predicates)))
25d2f683
CW
2167 (when (null blist)
2168 (if (and (featurep 'ibuf-ext)
2169 ibuffer-filtering-qualifiers)
2170 (message "No buffers! (note: filtering in effect)")
2171 (error "No buffers!")))
2172 (unless silent
2173 (message "Updating buffer list..."))
b5cd37ea 2174 (ibuffer-redisplay-engine blist arg)
25d2f683
CW
2175 (unless silent
2176 (message "Updating buffer list...done")))
2177 (if (eq ibuffer-shrink-to-minimum-size 'onewindow)
2178 (ibuffer-shrink-to-fit t)
2179 (when ibuffer-shrink-to-minimum-size
2180 (ibuffer-shrink-to-fit)))
6d11a78b
SM
2181 (ibuffer-forward-line 0)
2182 ;; I tried to update this automatically from the mode-line-process format,
2183 ;; but changing nil-ness of header-line-format while computing
2184 ;; mode-line-format is asking a bit too much it seems. --Stef
2185 (setq header-line-format
2186 (and ibuffer-use-header-line
2187 ibuffer-filtering-qualifiers
2188 ibuffer-header-line-format)))
25d2f683 2189
b5cd37ea 2190(defun ibuffer-sort-bufferlist (bmarklist)
e19fff38
JB
2191 (unless ibuffer-sorting-functions-alist
2192 ;; make sure the sorting functions are loaded
2193 (require 'ibuf-ext))
b5cd37ea
CW
2194 (let* ((sortdat (assq ibuffer-sorting-mode
2195 ibuffer-sorting-functions-alist))
2196 (func (caddr sortdat)))
2197 (let ((result
2198 ;; actually sort the buffers
2199 (if (and sortdat func)
2200 (sort bmarklist func)
2201 bmarklist)))
2202 ;; perhaps reverse the sorted buffer list
2203 (if ibuffer-sorting-reversep
2204 (nreverse result)
2205 result))))
2206
7fbac645 2207(defun ibuffer-insert-filter-group (name display-name filter-string format bmarklist)
b5cd37ea
CW
2208 (add-text-properties
2209 (point)
2210 (progn
2211 (insert "[ " display-name " ]")
2212 (point))
fd225d80
CW
2213 `(ibuffer-filter-group-name
2214 ,name
545aad2f 2215 font-lock-face ,ibuffer-filter-group-name-face
fd225d80
CW
2216 keymap ,ibuffer-mode-filter-group-map
2217 mouse-face highlight
1cd7affa
JPW
2218 help-echo ,(let ((echo '(if tooltip-mode
2219 "mouse-1: toggle marks in this group\nmouse-2: hide/show this filtering group"
ce3a4c83 2220 "mouse-1: toggle marks mouse-2: hide/show")))
1cd7affa 2221 (if (> (length filter-string) 0)
ce3a4c83
JPW
2222 `(concat ,filter-string
2223 (if tooltip-mode "\n" " ")
2224 ,echo)
1cd7affa 2225 echo))))
b5cd37ea
CW
2226 (insert "\n")
2227 (when bmarklist
2228 (put-text-property
2229 (point)
2230 (progn
2231 (dolist (entry bmarklist)
2232 (ibuffer-insert-buffer-line (car entry) (cdr entry) format))
2233 (point))
2234 'ibuffer-filter-group
2235 name)))
2236
957237cb 2237(defun ibuffer-redisplay-engine (bmarklist &optional ignore)
87a6a53a 2238 (ibuffer-assert-ibuffer-mode)
b5cd37ea
CW
2239 (let* ((--ibuffer-insert-buffers-and-marks-format
2240 (ibuffer-current-format))
2241 (--ibuffer-expanded-format (mapcar #'ibuffer-expand-format-entry
2242 (ibuffer-current-format t)))
2243 (orig (count-lines (point-min) (point)))
2244 ;; Inhibit font-lock caching tricks, since we're modifying the
2245 ;; entire buffer at once
2246 (after-change-functions nil)
2247 (ext-loaded (featurep 'ibuf-ext))
2248 (bgroups (if ext-loaded
2249 (ibuffer-generate-filter-groups bmarklist)
2250 (list (cons "Default" bmarklist)))))
cb059426 2251 (ibuffer-clear-summary-columns --ibuffer-expanded-format)
25d2f683
CW
2252 (unwind-protect
2253 (progn
2254 (setq buffer-read-only nil)
2255 (erase-buffer)
2256 (ibuffer-update-format)
b5cd37ea
CW
2257 (dolist (group (nreverse bgroups))
2258 (let* ((name (car group))
2259 (disabled (and ext-loaded
cba63a2d 2260 (member name ibuffer-hidden-filter-groups)))
b5cd37ea 2261 (bmarklist (cdr group)))
cba63a2d 2262 (unless (and (null bmarklist)
b90a6a12 2263 (not disabled)
cba63a2d
CW
2264 ext-loaded
2265 (null ibuffer-show-empty-filter-groups))
2266 (ibuffer-insert-filter-group
2267 name
2268 (if disabled (concat name " ...") name)
7fbac645
CW
2269 (if ext-loaded
2270 (ibuffer-format-filter-group-data name)
2271 "")
cba63a2d
CW
2272 --ibuffer-insert-buffers-and-marks-format
2273 (if disabled
2274 nil
2275 (ibuffer-sort-bufferlist bmarklist))))))
cb059426 2276 (ibuffer-update-title-and-summary --ibuffer-expanded-format))
25d2f683
CW
2277 (setq buffer-read-only t)
2278 (set-buffer-modified-p ibuffer-did-modification)
2279 (setq ibuffer-did-modification nil)
e600eb79 2280 (goto-char (point-min))
2ead9289 2281 (forward-line orig))))
25d2f683
CW
2282
2283(defun ibuffer-quit ()
2284 "Quit this `ibuffer' session.
4837b516 2285Try to restore the previous window configuration if
4ed1f829 2286`ibuffer-restore-window-config-on-quit' is non-nil."
25d2f683 2287 (interactive)
4ed1f829 2288 (if ibuffer-restore-window-config-on-quit
7ad938e7 2289 (progn
25d2f683
CW
2290 (bury-buffer)
2291 (unless (= (count-windows) 1)
4ed1f829 2292 (set-window-configuration ibuffer-prev-window-config)))
25d2f683
CW
2293 (bury-buffer)))
2294
2295;;;###autoload
2296(defun ibuffer-list-buffers (&optional files-only)
2297 "Display a list of buffers, in another window.
2298If optional argument FILES-ONLY is non-nil, then add a filter for
2299buffers which are visiting a file."
2300 (interactive "P")
2301 (ibuffer t nil (when files-only
2302 '((filename . ".*"))) t))
2303
2304;;;###autoload
2305(defun ibuffer-other-window (&optional files-only)
2306 "Like `ibuffer', but displayed in another window by default.
2307If optional argument FILES-ONLY is non-nil, then add a filter for
2308buffers which are visiting a file."
2309 (interactive "P")
2310 (ibuffer t nil (when files-only
2311 '((filename . ".*")))))
2312
2313;;;###autoload
b5cd37ea 2314(defun ibuffer (&optional other-window-p name qualifiers noselect
fd225d80 2315 shrink filter-groups formats)
972b8f82 2316 "Begin using Ibuffer to edit a list of buffers.
25d2f683
CW
2317Type 'h' after entering ibuffer for more information.
2318
972b8f82
JB
2319All arguments are optional.
2320OTHER-WINDOW-P says to use another window.
2321NAME specifies the name of the buffer (defaults to \"*Ibuffer*\").
2322QUALIFIERS is an initial set of filtering qualifiers to use;
2323 see `ibuffer-filtering-qualifiers'.
2324NOSELECT means don't select the Ibuffer buffer.
2325SHRINK means shrink the buffer to minimal size. The special
2326 value `onewindow' means always use another window.
2327FILTER-GROUPS is an initial set of filtering groups to use;
2328 see `ibuffer-filter-groups'.
2329FORMATS is the value to use for `ibuffer-formats'.
2330 If specified, then the variable `ibuffer-formats' will have
2331 that value locally in this buffer."
25d2f683
CW
2332 (interactive "P")
2333 (when ibuffer-use-other-window
34b8f593 2334 (setq other-window-p t))
4ed1f829 2335 (setq ibuffer-prev-window-config (current-window-configuration))
34a4faa0 2336 (let ((buf (get-buffer-create (or name "*Ibuffer*"))))
25d2f683
CW
2337 (if other-window-p
2338 (funcall (if noselect #'(lambda (buf) (display-buffer buf t)) #'pop-to-buffer) buf)
2339 (funcall (if noselect #'display-buffer #'switch-to-buffer) buf))
2340 (with-current-buffer buf
b5cd37ea
CW
2341 (save-selected-window
2342 ;; We switch to the buffer's window in order to be able
2343 ;; to modify the value of point
fab0d308 2344 (select-window (get-buffer-window buf 0))
34a4faa0
JPW
2345 (or (eq major-mode 'ibuffer-mode)
2346 (ibuffer-mode))
4ed1f829 2347 (setq ibuffer-restore-window-config-on-quit other-window-p)
b5cd37ea
CW
2348 (when shrink
2349 (setq ibuffer-shrink-to-minimum-size shrink))
2350 (when qualifiers
2351 (require 'ibuf-ext)
2352 (setq ibuffer-filtering-qualifiers qualifiers))
2353 (when filter-groups
2354 (require 'ibuf-ext)
cba63a2d 2355 (setq ibuffer-filter-groups filter-groups))
fd225d80
CW
2356 (when formats
2357 (set (make-local-variable 'ibuffer-formats) formats))
b5cd37ea
CW
2358 (ibuffer-update nil)
2359 ;; Skip the group name by default.
2360 (ibuffer-forward-line 0 t)
25d2f683
CW
2361 (unwind-protect
2362 (progn
b5cd37ea 2363 (setq buffer-read-only nil)
7ad5b902 2364 (run-hooks 'ibuffer-hook))
b5cd37ea
CW
2365 (setq buffer-read-only t))
2366 (unless ibuffer-expert
2367 (message "Commands: m, u, t, RET, g, k, S, D, Q; q to quit; h for help"))))))
25d2f683 2368
b23af469 2369(put 'ibuffer-mode 'mode-class 'special)
25d2f683
CW
2370(defun ibuffer-mode ()
2371 "A major mode for viewing a list of buffers.
972b8f82 2372In Ibuffer, you can conveniently perform many operations on the
25d2f683
CW
2373currently open buffers, in addition to filtering your view to a
2374particular subset of them, and sorting by various criteria.
2375
2376Operations on marked buffers:
2377
2378 '\\[ibuffer-do-save]' - Save the marked buffers
2379 '\\[ibuffer-do-view]' - View the marked buffers in this frame.
2380 '\\[ibuffer-do-view-other-frame]' - View the marked buffers in another frame.
2381 '\\[ibuffer-do-revert]' - Revert the marked buffers.
2382 '\\[ibuffer-do-toggle-read-only]' - Toggle read-only state of marked buffers.
2383 '\\[ibuffer-do-delete]' - Kill the marked buffers.
78176075
JL
2384 '\\[ibuffer-do-isearch]' - Do incremental search in the marked buffers.
2385 '\\[ibuffer-do-isearch-regexp]' - Isearch for regexp in the marked buffers.
25d2f683
CW
2386 '\\[ibuffer-do-replace-regexp]' - Replace by regexp in each of the marked
2387 buffers.
2388 '\\[ibuffer-do-query-replace]' - Query replace in each of the marked buffers.
2389 '\\[ibuffer-do-query-replace-regexp]' - As above, with a regular expression.
2390 '\\[ibuffer-do-print]' - Print the marked buffers.
2391 '\\[ibuffer-do-occur]' - List lines in all marked buffers which match
2392 a given regexp (like the function `occur').
2393 '\\[ibuffer-do-shell-command-pipe]' - Pipe the contents of the marked
2394 buffers to a shell command.
2395 '\\[ibuffer-do-shell-command-pipe-replace]' - Replace the contents of the marked
2396 buffers with the output of a shell command.
2397 '\\[ibuffer-do-shell-command-file]' - Run a shell command with the
2398 buffer's file as an argument.
2399 '\\[ibuffer-do-eval]' - Evaluate a form in each of the marked buffers. This
2400 is a very flexible command. For example, if you want to make all
2401 of the marked buffers read only, try using (toggle-read-only 1) as
2402 the input form.
2403 '\\[ibuffer-do-view-and-eval]' - As above, but view each buffer while the form
2404 is evaluated.
2405 '\\[ibuffer-do-kill-lines]' - Remove the marked lines from the *Ibuffer* buffer,
2406 but don't kill the associated buffer.
2407 '\\[ibuffer-do-kill-on-deletion-marks]' - Kill all buffers marked for deletion.
2408
2409Marking commands:
2410
2411 '\\[ibuffer-mark-forward]' - Mark the buffer at point.
2412 '\\[ibuffer-toggle-marks]' - Unmark all currently marked buffers, and mark
2413 all unmarked buffers.
2414 '\\[ibuffer-unmark-forward]' - Unmark the buffer at point.
2415 '\\[ibuffer-unmark-backward]' - Unmark the buffer at point, and move to the
2416 previous line.
2417 '\\[ibuffer-unmark-all]' - Unmark all marked buffers.
2418 '\\[ibuffer-mark-by-mode]' - Mark buffers by major mode.
2419 '\\[ibuffer-mark-unsaved-buffers]' - Mark all \"unsaved\" buffers.
2420 This means that the buffer is modified, and has an associated file.
2421 '\\[ibuffer-mark-modified-buffers]' - Mark all modified buffers,
2422 regardless of whether or not they have an associated file.
2423 '\\[ibuffer-mark-special-buffers]' - Mark all buffers whose name begins and
2424 ends with '*'.
2425 '\\[ibuffer-mark-dissociated-buffers]' - Mark all buffers which have
2426 an associated file, but that file doesn't currently exist.
2427 '\\[ibuffer-mark-read-only-buffers]' - Mark all read-only buffers.
2428 '\\[ibuffer-mark-dired-buffers]' - Mark buffers in `dired' mode.
2429 '\\[ibuffer-mark-help-buffers]' - Mark buffers in `help-mode', `apropos-mode', etc.
2430 '\\[ibuffer-mark-old-buffers]' - Mark buffers older than `ibuffer-old-time'.
2431 '\\[ibuffer-mark-for-delete]' - Mark the buffer at point for deletion.
2432 '\\[ibuffer-mark-by-name-regexp]' - Mark buffers by their name, using a regexp.
2433 '\\[ibuffer-mark-by-mode-regexp]' - Mark buffers by their major mode, using a regexp.
2434 '\\[ibuffer-mark-by-file-name-regexp]' - Mark buffers by their filename, using a regexp.
2435
2436Filtering commands:
2437
2438 '\\[ibuffer-filter-by-mode]' - Add a filter by major mode.
5bc06df9 2439 '\\[ibuffer-filter-by-used-mode]' - Add a filter by major mode now in use.
25d2f683
CW
2440 '\\[ibuffer-filter-by-name]' - Add a filter by buffer name.
2441 '\\[ibuffer-filter-by-content]' - Add a filter by buffer content.
2442 '\\[ibuffer-filter-by-filename]' - Add a filter by filename.
2443 '\\[ibuffer-filter-by-size-gt]' - Add a filter by buffer size.
2444 '\\[ibuffer-filter-by-size-lt]' - Add a filter by buffer size.
2445 '\\[ibuffer-filter-by-predicate]' - Add a filter by an arbitrary Lisp predicate.
2446 '\\[ibuffer-save-filters]' - Save the current filters with a name.
2447 '\\[ibuffer-switch-to-saved-filters]' - Switch to previously saved filters.
2448 '\\[ibuffer-add-saved-filters]' - Add saved filters to current filters.
2449 '\\[ibuffer-or-filter]' - Replace the top two filters with their logical OR.
2450 '\\[ibuffer-pop-filter]' - Remove the top filter.
2451 '\\[ibuffer-negate-filter]' - Invert the logical sense of the top filter.
2452 '\\[ibuffer-decompose-filter]' - Break down the topmost filter.
2453 '\\[ibuffer-filter-disable]' - Remove all filtering currently in effect.
cba63a2d
CW
2454
2455Filter group commands:
2456
2457 '\\[ibuffer-filters-to-filter-group]' - Create filter group from filters.
2458 '\\[ibuffer-pop-filter-group]' - Remove top filter group.
b098e753
CW
2459 '\\[ibuffer-forward-filter-group]' - Move to the next filter group.
2460 '\\[ibuffer-backward-filter-group]' - Move to the previous filter group.
2461 '\\[ibuffer-clear-filter-groups]' - Remove all active filter groups.
2462 '\\[ibuffer-save-filter-groups]' - Save the current groups with a name.
2463 '\\[ibuffer-switch-to-saved-filter-groups]' - Restore previously saved groups.
2464 '\\[ibuffer-delete-saved-filter-groups]' - Delete previously saved groups.
71296446 2465
25d2f683
CW
2466Sorting commands:
2467
2468 '\\[ibuffer-toggle-sorting-mode]' - Rotate between the various sorting modes.
2469 '\\[ibuffer-invert-sorting]' - Reverse the current sorting order.
2470 '\\[ibuffer-do-sort-by-alphabetic]' - Sort the buffers lexicographically.
d5794180 2471 '\\[ibuffer-do-sort-by-filename/process]' - Sort the buffers by the file name.
25d2f683
CW
2472 '\\[ibuffer-do-sort-by-recency]' - Sort the buffers by last viewing time.
2473 '\\[ibuffer-do-sort-by-size]' - Sort the buffers by size.
2474 '\\[ibuffer-do-sort-by-major-mode]' - Sort the buffers by major mode.
2475
2476Other commands:
2477
4c38df30
JPW
2478 '\\[ibuffer-update]' - Regenerate the list of all buffers.
2479 Prefix arg means to toggle whether buffers that match
2480 `ibuffer-maybe-show-predicates' should be displayed.
2481
25d2f683
CW
2482 '\\[ibuffer-switch-format]' - Change the current display format.
2483 '\\[forward-line]' - Move point to the next line.
2484 '\\[previous-line]' - Move point to the previous line.
25d2f683
CW
2485 '\\[ibuffer-quit]' - Bury the Ibuffer buffer.
2486 '\\[describe-mode]' - This help.
2487 '\\[ibuffer-diff-with-file]' - View the differences between this buffer
2488 and its associated file.
2489 '\\[ibuffer-visit-buffer]' - View the buffer on this line.
2490 '\\[ibuffer-visit-buffer-other-window]' - As above, but in another window.
2491 '\\[ibuffer-visit-buffer-other-window-noselect]' - As both above, but don't select
2492 the new window.
2493 '\\[ibuffer-bury-buffer]' - Bury (not kill!) the buffer on this line.
2494
cba63a2d 2495** Information on Filtering:
25d2f683
CW
2496
2497 You can filter your ibuffer view via different critera. Each Ibuffer
2498buffer has its own stack of active filters. For example, suppose you
2499are working on an Emacs Lisp project. You can create an Ibuffer
2500buffer displays buffers in just `emacs-lisp' modes via
2501'\\[ibuffer-filter-by-mode] emacs-lisp-mode RET'. In this case, there
2502is just one entry on the filtering stack.
2503
2504You can also combine filters. The various filtering commands push a
2505new filter onto the stack, and the filters combine to show just
2506buffers which satisfy ALL criteria on the stack. For example, suppose
2507you only want to see buffers in `emacs-lisp' mode, whose names begin
2508with \"gnus\". You can accomplish this via:
2509'\\[ibuffer-filter-by-mode] emacs-lisp-mode RET
2510\\[ibuffer-filter-by-name] ^gnus RET'.
2511
2512Additionally, you can OR the top two filters together with
2513'\\[ibuffer-or-filters]'. To see all buffers in either
2514`emacs-lisp-mode' or `lisp-interaction-mode', type:
2515
2516'\\[ibuffer-filter-by-mode] emacs-lisp-mode RET \\[ibuffer-filter-by-mode] lisp-interaction-mode RET \\[ibuffer-or-filters]'.
2517
2518Filters can also be saved and restored using mnemonic names: see the
2519functions `ibuffer-save-filters' and `ibuffer-switch-to-saved-filters'.
2520
2521To remove the top filter on the stack, use '\\[ibuffer-pop-filter]', and
2522to disable all filtering currently in effect, use
cba63a2d
CW
2523'\\[ibuffer-filter-disable]'.
2524
2525** Filter Groups:
2526
2527Once one has mastered filters, the next logical step up is \"filter
2528groups\". A filter group is basically a named group of buffers which
2529match a filter, which are displayed together in an Ibuffer buffer. To
2530create a filter group, simply use the regular functions to create a
2531filter, and then type '\\[ibuffer-filters-to-filter-group]'.
2532
2533A quick example will make things clearer. Suppose that one wants to
2534group all of one's Emacs Lisp buffers together. To do this, type
2535
2536'\\[ibuffer-filter-by-mode] emacs-lisp-mode RET \\[ibuffer-filters-to-filter-group] RET emacs lisp buffers RET'
2537
2538You may, of course, name the group whatever you want; it doesn't have
2539to be \"emacs lisp buffers\". Filter groups may be composed of any
2540arbitrary combination of filters.
2541
2542Just like filters themselves, filter groups act as a stack. Buffers
2543will not be displayed multiple times if they would be included in
2544multiple filter groups; instead, the first filter group is used. The
2545filter groups are displayed in this order of precedence.
2546
2547You may rearrange filter groups by using the regular
2548'\\[ibuffer-kill-line]' and '\\[ibuffer-yank]' pair. Yanked groups
2549will be inserted before the group at point."
25d2f683
CW
2550 (kill-all-local-variables)
2551 (use-local-map ibuffer-mode-map)
2552 (setq major-mode 'ibuffer-mode)
2553 (setq mode-name "Ibuffer")
23eabff6 2554 ;; Include state info next to the mode name.
e47b4224 2555 (set (make-local-variable 'mode-line-process)
56618a0a
SM
2556 '(" by "
2557 (ibuffer-sorting-mode (:eval (symbol-name ibuffer-sorting-mode))
23eabff6
SM
2558 "view time")
2559 (ibuffer-sorting-reversep " [rev]")
2560 (ibuffer-auto-mode " (Auto)")
2561 ;; Only list the filters if they're not already in the header-line.
2562 (header-line-format
2563 ""
2564 (:eval (if (functionp 'ibuffer-format-qualifier)
2565 (mapconcat 'ibuffer-format-qualifier
2566 ibuffer-filtering-qualifiers ""))))))
6d11a78b
SM
2567 ;; `ibuffer-update' puts this on header-line-format when needed.
2568 (setq ibuffer-header-line-format
2569 ;; Display the part that won't be in the mode-line.
2570 (list* "" mode-name
2571 (mapcar (lambda (elem)
2572 (if (eq (car-safe elem) 'header-line-format)
2573 (nth 2 elem) elem))
2574 mode-line-process)))
23eabff6 2575
25d2f683
CW
2576 (setq buffer-read-only t)
2577 (buffer-disable-undo)
3eda3649 2578 (setq truncate-lines ibuffer-truncate-lines)
25d2f683
CW
2579 ;; This makes things less ugly for Emacs 21 users with a non-nil
2580 ;; `show-trailing-whitespace'.
2581 (setq show-trailing-whitespace nil)
4ba16127
JPW
2582 ;; disable `show-paren-mode' buffer-locally
2583 (if (bound-and-true-p show-paren-mode)
2584 (set (make-local-variable 'show-paren-mode) nil))
25d2f683
CW
2585 (set (make-local-variable 'revert-buffer-function)
2586 #'ibuffer-update)
2587 (set (make-local-variable 'ibuffer-sorting-mode)
2588 ibuffer-default-sorting-mode)
2589 (set (make-local-variable 'ibuffer-sorting-reversep)
2590 ibuffer-default-sorting-reversep)
2591 (set (make-local-variable 'ibuffer-shrink-to-minimum-size)
2592 ibuffer-default-shrink-to-minimum-size)
957237cb
JPW
2593 (set (make-local-variable 'ibuffer-display-maybe-show-predicates)
2594 ibuffer-default-display-maybe-show-predicates)
25d2f683 2595 (set (make-local-variable 'ibuffer-filtering-qualifiers) nil)
cba63a2d
CW
2596 (set (make-local-variable 'ibuffer-filter-groups) nil)
2597 (set (make-local-variable 'ibuffer-filter-group-kill-ring) nil)
2598 (set (make-local-variable 'ibuffer-hidden-filter-groups) nil)
25d2f683
CW
2599 (set (make-local-variable 'ibuffer-compiled-formats) nil)
2600 (set (make-local-variable 'ibuffer-cached-formats) nil)
2601 (set (make-local-variable 'ibuffer-cached-eliding-string) nil)
2602 (set (make-local-variable 'ibuffer-cached-elide-long-columns) nil)
2603 (set (make-local-variable 'ibuffer-current-format) nil)
4ed1f829 2604 (set (make-local-variable 'ibuffer-restore-window-config-on-quit) nil)
25d2f683 2605 (set (make-local-variable 'ibuffer-did-modification) nil)
b5cd37ea
CW
2606 (set (make-local-variable 'ibuffer-tmp-hide-regexps) nil)
2607 (set (make-local-variable 'ibuffer-tmp-show-regexps) nil)
25d2f683
CW
2608 (define-key ibuffer-mode-map [menu-bar edit] 'undefined)
2609 (define-key ibuffer-mode-map [menu-bar operate] (cons "Operate" ibuffer-mode-operate-map))
2610 (ibuffer-update-format)
2611 (when ibuffer-default-directory
2612 (setq default-directory ibuffer-default-directory))
214fee7a 2613 (add-hook 'change-major-mode-hook 'font-lock-defontify nil t)
23eabff6 2614 (run-mode-hooks 'ibuffer-mode-hook))
25d2f683 2615
45a68029
GM
2616\f
2617;;; Start of automatically extracted autoloads.
2618\f
2619;;;### (autoloads (ibuffer-do-occur ibuffer-mark-dired-buffers ibuffer-mark-read-only-buffers
2620;;;;;; ibuffer-mark-special-buffers ibuffer-mark-old-buffers ibuffer-mark-compressed-file-buffers
2621;;;;;; ibuffer-mark-help-buffers ibuffer-mark-dissociated-buffers
2622;;;;;; ibuffer-mark-unsaved-buffers ibuffer-mark-modified-buffers
2623;;;;;; ibuffer-mark-by-mode ibuffer-mark-by-file-name-regexp ibuffer-mark-by-mode-regexp
2624;;;;;; ibuffer-mark-by-name-regexp ibuffer-copy-filename-as-kill
2625;;;;;; ibuffer-diff-with-file ibuffer-jump-to-buffer ibuffer-do-kill-lines
2626;;;;;; ibuffer-backwards-next-marked ibuffer-forward-next-marked
2627;;;;;; ibuffer-add-to-tmp-show ibuffer-add-to-tmp-hide ibuffer-bs-show
2628;;;;;; ibuffer-invert-sorting ibuffer-toggle-sorting-mode ibuffer-switch-to-saved-filters
2629;;;;;; ibuffer-add-saved-filters ibuffer-delete-saved-filters ibuffer-save-filters
2630;;;;;; ibuffer-or-filter ibuffer-negate-filter ibuffer-exchange-filters
2631;;;;;; ibuffer-decompose-filter ibuffer-pop-filter ibuffer-filter-disable
2632;;;;;; ibuffer-switch-to-saved-filter-groups ibuffer-delete-saved-filter-groups
2633;;;;;; ibuffer-save-filter-groups ibuffer-yank-filter-group ibuffer-yank
2634;;;;;; ibuffer-kill-line ibuffer-kill-filter-group ibuffer-jump-to-filter-group
2635;;;;;; ibuffer-clear-filter-groups ibuffer-decompose-filter-group
2636;;;;;; ibuffer-pop-filter-group ibuffer-set-filter-groups-by-mode
2637;;;;;; ibuffer-filters-to-filter-group ibuffer-included-in-filters-p
2638;;;;;; ibuffer-backward-filter-group ibuffer-forward-filter-group
2639;;;;;; ibuffer-toggle-filter-group ibuffer-mouse-toggle-filter-group
2640;;;;;; ibuffer-interactive-filter-by-mode ibuffer-mouse-filter-by-mode
f80aa5bf 2641;;;;;; ibuffer-auto-mode) "ibuf-ext" "ibuf-ext.el" "ae74e74d79fa66e206bef609e5f72d00")
45a68029
GM
2642;;; Generated autoloads from ibuf-ext.el
2643
2644(autoload 'ibuffer-auto-mode "ibuf-ext" "\
2645Toggle use of Ibuffer's auto-update facility.
2646With numeric ARG, enable auto-update if and only if ARG is positive.
2647
2648\(fn &optional ARG)" t nil)
2649
2650(autoload 'ibuffer-mouse-filter-by-mode "ibuf-ext" "\
2651Enable or disable filtering by the major mode chosen via mouse.
2652
2653\(fn EVENT)" t nil)
2654
2655(autoload 'ibuffer-interactive-filter-by-mode "ibuf-ext" "\
2656Enable or disable filtering by the major mode at point.
2657
2658\(fn EVENT-OR-POINT)" t nil)
2659
2660(autoload 'ibuffer-mouse-toggle-filter-group "ibuf-ext" "\
2661Toggle the display status of the filter group chosen with the mouse.
2662
2663\(fn EVENT)" t nil)
2664
2665(autoload 'ibuffer-toggle-filter-group "ibuf-ext" "\
2666Toggle the display status of the filter group on this line.
2667
2668\(fn)" t nil)
2669
2670(autoload 'ibuffer-forward-filter-group "ibuf-ext" "\
2671Move point forwards by COUNT filtering groups.
2672
2673\(fn &optional COUNT)" t nil)
2674
2675(autoload 'ibuffer-backward-filter-group "ibuf-ext" "\
2676Move point backwards by COUNT filtering groups.
2677
2678\(fn &optional COUNT)" t nil)
2679 (autoload 'ibuffer-do-shell-command-pipe "ibuf-ext")
2680 (autoload 'ibuffer-do-shell-command-pipe-replace "ibuf-ext")
2681 (autoload 'ibuffer-do-shell-command-file "ibuf-ext")
2682 (autoload 'ibuffer-do-eval "ibuf-ext")
2683 (autoload 'ibuffer-do-view-and-eval "ibuf-ext")
2684 (autoload 'ibuffer-do-rename-uniquely "ibuf-ext")
2685 (autoload 'ibuffer-do-revert "ibuf-ext")
2686 (autoload 'ibuffer-do-isearch "ibuf-ext")
2687 (autoload 'ibuffer-do-isearch-regexp "ibuf-ext")
2688 (autoload 'ibuffer-do-replace-regexp "ibuf-ext")
2689 (autoload 'ibuffer-do-query-replace "ibuf-ext")
2690 (autoload 'ibuffer-do-query-replace-regexp "ibuf-ext")
2691 (autoload 'ibuffer-do-print "ibuf-ext")
2692
2693(autoload 'ibuffer-included-in-filters-p "ibuf-ext" "\
2694Not documented
2695
2696\(fn BUF FILTERS)" nil nil)
2697
2698(autoload 'ibuffer-filters-to-filter-group "ibuf-ext" "\
2699Make the current filters into a filtering group.
2700
2701\(fn NAME)" t nil)
2702
2703(autoload 'ibuffer-set-filter-groups-by-mode "ibuf-ext" "\
2704Set the current filter groups to filter by mode.
2705
2706\(fn)" t nil)
2707
2708(autoload 'ibuffer-pop-filter-group "ibuf-ext" "\
2709Remove the first filter group.
2710
2711\(fn)" t nil)
2712
2713(autoload 'ibuffer-decompose-filter-group "ibuf-ext" "\
2714Decompose the filter group GROUP into active filters.
2715
2716\(fn GROUP)" t nil)
2717
2718(autoload 'ibuffer-clear-filter-groups "ibuf-ext" "\
2719Remove all filter groups.
2720
2721\(fn)" t nil)
2722
2723(autoload 'ibuffer-jump-to-filter-group "ibuf-ext" "\
2724Move point to the filter group whose name is NAME.
2725
2726\(fn NAME)" t nil)
2727
2728(autoload 'ibuffer-kill-filter-group "ibuf-ext" "\
2729Kill the filter group named NAME.
2730The group will be added to `ibuffer-filter-group-kill-ring'.
2731
2732\(fn NAME)" t nil)
2733
2734(autoload 'ibuffer-kill-line "ibuf-ext" "\
2735Kill the filter group at point.
2736See also `ibuffer-kill-filter-group'.
2737
2738\(fn &optional ARG INTERACTIVE-P)" t nil)
2739
2740(autoload 'ibuffer-yank "ibuf-ext" "\
2741Yank the last killed filter group before group at point.
2742
2743\(fn)" t nil)
2744
2745(autoload 'ibuffer-yank-filter-group "ibuf-ext" "\
2746Yank the last killed filter group before group named NAME.
2747
2748\(fn NAME)" t nil)
2749
2750(autoload 'ibuffer-save-filter-groups "ibuf-ext" "\
2751Save all active filter groups GROUPS as NAME.
2752They are added to `ibuffer-saved-filter-groups'. Interactively,
2753prompt for NAME, and use the current filters.
2754
2755\(fn NAME GROUPS)" t nil)
2756
2757(autoload 'ibuffer-delete-saved-filter-groups "ibuf-ext" "\
2758Delete saved filter groups with NAME.
2759They are removed from `ibuffer-saved-filter-groups'.
2760
2761\(fn NAME)" t nil)
2762
2763(autoload 'ibuffer-switch-to-saved-filter-groups "ibuf-ext" "\
2764Set this buffer's filter groups to saved version with NAME.
2765The value from `ibuffer-saved-filter-groups' is used.
2766
2767\(fn NAME)" t nil)
2768
2769(autoload 'ibuffer-filter-disable "ibuf-ext" "\
2770Disable all filters currently in effect in this buffer.
2771
2772\(fn)" t nil)
2773
2774(autoload 'ibuffer-pop-filter "ibuf-ext" "\
2775Remove the top filter in this buffer.
2776
2777\(fn)" t nil)
2778
2779(autoload 'ibuffer-decompose-filter "ibuf-ext" "\
2780Separate the top compound filter (OR, NOT, or SAVED) in this buffer.
2781
2782This means that the topmost filter on the filtering stack, which must
2783be a complex filter like (OR [name: foo] [mode: bar-mode]), will be
2784turned into two separate filters [name: foo] and [mode: bar-mode].
2785
2786\(fn)" t nil)
2787
2788(autoload 'ibuffer-exchange-filters "ibuf-ext" "\
2789Exchange the top two filters on the stack in this buffer.
2790
2791\(fn)" t nil)
2792
2793(autoload 'ibuffer-negate-filter "ibuf-ext" "\
2794Negate the sense of the top filter in the current buffer.
2795
2796\(fn)" t nil)
2797
2798(autoload 'ibuffer-or-filter "ibuf-ext" "\
2799Replace the top two filters in this buffer with their logical OR.
2800If optional argument REVERSE is non-nil, instead break the top OR
2801filter into parts.
2802
2803\(fn &optional REVERSE)" t nil)
2804
2805(autoload 'ibuffer-save-filters "ibuf-ext" "\
2806Save FILTERS in this buffer with name NAME in `ibuffer-saved-filters'.
2807Interactively, prompt for NAME, and use the current filters.
2808
2809\(fn NAME FILTERS)" t nil)
2810
2811(autoload 'ibuffer-delete-saved-filters "ibuf-ext" "\
2812Delete saved filters with NAME from `ibuffer-saved-filters'.
2813
2814\(fn NAME)" t nil)
2815
2816(autoload 'ibuffer-add-saved-filters "ibuf-ext" "\
2817Add saved filters from `ibuffer-saved-filters' to this buffer's filters.
2818
2819\(fn NAME)" t nil)
2820
2821(autoload 'ibuffer-switch-to-saved-filters "ibuf-ext" "\
2822Set this buffer's filters to filters with NAME from `ibuffer-saved-filters'.
2823
2824\(fn NAME)" t nil)
2825 (autoload 'ibuffer-filter-by-mode "ibuf-ext")
2826 (autoload 'ibuffer-filter-by-used-mode "ibuf-ext")
2827 (autoload 'ibuffer-filter-by-name "ibuf-ext")
2828 (autoload 'ibuffer-filter-by-filename "ibuf-ext")
2829 (autoload 'ibuffer-filter-by-size-gt "ibuf-ext")
2830 (autoload 'ibuffer-filter-by-size-lt "ibuf-ext")
2831 (autoload 'ibuffer-filter-by-content "ibuf-ext")
2832 (autoload 'ibuffer-filter-by-predicate "ibuf-ext")
2833
2834(autoload 'ibuffer-toggle-sorting-mode "ibuf-ext" "\
2835Toggle the current sorting mode.
2836Default sorting modes are:
2837 Recency - the last time the buffer was viewed
2838 Name - the name of the buffer
2839 Major Mode - the name of the major mode of the buffer
2840 Size - the size of the buffer
2841
2842\(fn)" t nil)
2843
2844(autoload 'ibuffer-invert-sorting "ibuf-ext" "\
2845Toggle whether or not sorting is in reverse order.
2846
2847\(fn)" t nil)
2848 (autoload 'ibuffer-do-sort-by-major-mode "ibuf-ext")
2849 (autoload 'ibuffer-do-sort-by-mode-name "ibuf-ext")
2850 (autoload 'ibuffer-do-sort-by-alphabetic "ibuf-ext")
2851 (autoload 'ibuffer-do-sort-by-size "ibuf-ext")
2852 (autoload 'ibuffer-do-sort-by-filename/process "ibuf-ext")
2853
2854(autoload 'ibuffer-bs-show "ibuf-ext" "\
2855Emulate `bs-show' from the bs.el package.
2856
2857\(fn)" t nil)
2858
2859(autoload 'ibuffer-add-to-tmp-hide "ibuf-ext" "\
2860Add REGEXP to `ibuffer-tmp-hide-regexps'.
2861This means that buffers whose name matches REGEXP will not be shown
2862for this Ibuffer session.
2863
2864\(fn REGEXP)" t nil)
2865
2866(autoload 'ibuffer-add-to-tmp-show "ibuf-ext" "\
2867Add REGEXP to `ibuffer-tmp-show-regexps'.
2868This means that buffers whose name matches REGEXP will always be shown
2869for this Ibuffer session.
2870
2871\(fn REGEXP)" t nil)
2872
2873(autoload 'ibuffer-forward-next-marked "ibuf-ext" "\
2874Move forward by COUNT marked buffers (default 1).
2875
2876If MARK is non-nil, it should be a character denoting the type of mark
2877to move by. The default is `ibuffer-marked-char'.
2878
2879If DIRECTION is non-nil, it should be an integer; negative integers
2880mean move backwards, non-negative integers mean move forwards.
2881
2882\(fn &optional COUNT MARK DIRECTION)" t nil)
2883
2884(autoload 'ibuffer-backwards-next-marked "ibuf-ext" "\
2885Move backwards by COUNT marked buffers (default 1).
2886
2887If MARK is non-nil, it should be a character denoting the type of mark
2888to move by. The default is `ibuffer-marked-char'.
2889
2890\(fn &optional COUNT MARK)" t nil)
2891
2892(autoload 'ibuffer-do-kill-lines "ibuf-ext" "\
2893Hide all of the currently marked lines.
2894
2895\(fn)" t nil)
2896
2897(autoload 'ibuffer-jump-to-buffer "ibuf-ext" "\
2898Move point to the buffer whose name is NAME.
2899
2900If called interactively, prompt for a buffer name and go to the
2901corresponding line in the Ibuffer buffer. If said buffer is in a
2902hidden group filter, open it.
2903
2904If `ibuffer-jump-offer-only-visible-buffers' is non-nil, only offer
2905visible buffers in the completion list. Calling the command with
2906a prefix argument reverses the meaning of that variable.
2907
2908\(fn NAME)" t nil)
2909
2910(autoload 'ibuffer-diff-with-file "ibuf-ext" "\
2911View the differences between marked buffers and their associated files.
2912If no buffers are marked, use buffer at point.
2913This requires the external program \"diff\" to be in your `exec-path'.
2914
2915\(fn)" t nil)
2916
2917(autoload 'ibuffer-copy-filename-as-kill "ibuf-ext" "\
2918Copy filenames of marked buffers into the kill ring.
2919
2920The names are separated by a space.
2921If a buffer has no filename, it is ignored.
2922
2923With no prefix arg, use the filename sans its directory of each marked file.
2924With a zero prefix arg, use the complete filename of each marked file.
2925With \\[universal-argument], use the filename of each marked file relative
2926to `ibuffer-default-directory' if non-nil, otherwise `default-directory'.
2927
2928You can then feed the file name(s) to other commands with \\[yank].
2929
2930\(fn &optional ARG)" t nil)
2931
2932(autoload 'ibuffer-mark-by-name-regexp "ibuf-ext" "\
2933Mark all buffers whose name matches REGEXP.
2934
2935\(fn REGEXP)" t nil)
2936
2937(autoload 'ibuffer-mark-by-mode-regexp "ibuf-ext" "\
2938Mark all buffers whose major mode matches REGEXP.
2939
2940\(fn REGEXP)" t nil)
2941
2942(autoload 'ibuffer-mark-by-file-name-regexp "ibuf-ext" "\
2943Mark all buffers whose file name matches REGEXP.
2944
2945\(fn REGEXP)" t nil)
2946
2947(autoload 'ibuffer-mark-by-mode "ibuf-ext" "\
2948Mark all buffers whose major mode equals MODE.
2949
2950\(fn MODE)" t nil)
2951
2952(autoload 'ibuffer-mark-modified-buffers "ibuf-ext" "\
2953Mark all modified buffers.
2954
2955\(fn)" t nil)
2956
2957(autoload 'ibuffer-mark-unsaved-buffers "ibuf-ext" "\
2958Mark all modified buffers that have an associated file.
2959
2960\(fn)" t nil)
2961
2962(autoload 'ibuffer-mark-dissociated-buffers "ibuf-ext" "\
2963Mark all buffers whose associated file does not exist.
2964
2965\(fn)" t nil)
2966
2967(autoload 'ibuffer-mark-help-buffers "ibuf-ext" "\
2968Mark buffers like *Help*, *Apropos*, *Info*.
2969
2970\(fn)" t nil)
2971
2972(autoload 'ibuffer-mark-compressed-file-buffers "ibuf-ext" "\
2973Mark buffers whose associated file is compressed.
2974
2975\(fn)" t nil)
2976
2977(autoload 'ibuffer-mark-old-buffers "ibuf-ext" "\
2978Mark buffers which have not been viewed in `ibuffer-old-time' hours.
2979
2980\(fn)" t nil)
2981
2982(autoload 'ibuffer-mark-special-buffers "ibuf-ext" "\
2983Mark all buffers whose name begins and ends with '*'.
2984
2985\(fn)" t nil)
2986
2987(autoload 'ibuffer-mark-read-only-buffers "ibuf-ext" "\
2988Mark all read-only buffers.
2989
2990\(fn)" t nil)
2991
2992(autoload 'ibuffer-mark-dired-buffers "ibuf-ext" "\
2993Mark all `dired' buffers.
2994
2995\(fn)" t nil)
2996
2997(autoload 'ibuffer-do-occur "ibuf-ext" "\
2998View lines which match REGEXP in all marked buffers.
2999Optional argument NLINES says how many lines of context to display: it
3000defaults to one.
3001
3002\(fn REGEXP &optional NLINES)" t nil)
3003
3004;;;***
3005\f
3006;;; End of automatically extracted autoloads.
3007
3008
25d2f683
CW
3009(provide 'ibuffer)
3010
4e4a724c
JPW
3011(run-hooks 'ibuffer-load-hook)
3012
25d2f683
CW
3013;; Local Variables:
3014;; coding: iso-8859-1
3015;; End:
3016
3017;;; ibuffer.el ends here