]> code.delx.au - gnu-emacs/blobdiff - lisp/ibuffer.el
(ibuffer-compressed-file-name-regexp): Avoid loading
[gnu-emacs] / lisp / ibuffer.el
index 5ae9fad222c386842df53c9942a3b338e0badb7f..4b1069b26c1e055f6cc6989ee741362993880d1f 100644 (file)
@@ -1,8 +1,10 @@
 ;;; ibuffer.el --- operate on buffers like dired
 
-;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+;; Copyright (C) 2000, 2001, 2002, 2003, 2004,
+;;   2005, 2006 Free Software Foundation, Inc.
 
 ;; Author: Colin Walters <walters@verbum.org>
+;; Maintainer: John Paul Wallington <jpw@gnu.org>
 ;; Created: 8 Sep 2000
 ;; Keywords: buffer, convenience
 
@@ -20,8 +22,8 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with this program ; see the file COPYING.  If not, write to
-;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
   (require 'ibuf-macs)
   (require 'dired))
 
-;;; Compatibility
-(eval-and-compile
-  (if (fboundp 'window-list)
-      (defun ibuffer-window-list ()
-       (window-list nil 'nomini))
-    (defun ibuffer-window-list ()
-      (let ((ibuffer-window-list-result nil))
-       (walk-windows #'(lambda (win) (push win ibuffer-window-list-result)) 'nomini)
-       (nreverse ibuffer-window-list-result))))
-
-  (cond ((boundp 'global-font-lock-mode)
-        (defsubst ibuffer-use-fontification ()
-          (when (boundp 'font-lock-mode)
-            font-lock-mode)))
-       ((boundp 'font-lock-auto-fontify)
-        (defsubst ibuffer-use-fontification ()
-          font-lock-auto-fontify))
-       (t
-        (defsubst ibuffer-use-fontification ()
-          nil))))
+(require 'font-core)
+
+;; These come from ibuf-ext.el, which can not be require'd at compile time
+;; because it has a recursive dependency on ibuffer.el
+(defvar ibuffer-auto-mode)
+(defvar ibuffer-cached-filter-formats)
+(defvar ibuffer-compiled-filter-formats)
+(defvar ibuffer-filter-format-alist)
+(defvar ibuffer-filter-group-kill-ring)
+(defvar ibuffer-filter-groups)
+(defvar ibuffer-filtering-qualifiers)
+(defvar ibuffer-hidden-filter-groups)
+(defvar ibuffer-inline-columns)
+(defvar ibuffer-show-empty-filter-groups)
+(defvar ibuffer-tmp-hide-regexps)
+(defvar ibuffer-tmp-show-regexps)
 
 (defgroup ibuffer nil
   "An advanced replacement for `buffer-menu'.
 Ibuffer allows you to operate on buffers in a manner much like Dired.
 Operations include sorting, marking by regular expression, and
 the ability to filter the displayed buffers by various criteria."
+  :version "22.1"
   :group 'convenience)
 
-(defcustom ibuffer-formats '((mark modified read-only " " (name 16 16 :left :elide)
-                                  " " (size 6 -1 :right)
-                                  " " (mode 16 16 :right :elide) " " filename)
+(defcustom ibuffer-formats '((mark modified read-only " " (name 18 18 :left :elide)
+                                  " " (size 9 -1 :right)
+                                  " " (mode 16 16 :right :elide) " " filename-and-process)
                             (mark " " (name 16 -1) " " filename))
   "A list of ways to display buffer lines.
 
@@ -142,17 +141,26 @@ elisp byte-compiler."
   :group 'ibuffer)
 
 (defcustom ibuffer-fontification-alist
-  `((10 buffer-read-only font-lock-reference-face)
-    (15 (string-match "^*" (buffer-name)) font-lock-keyword-face)
-    (20 (string-match "^ " (buffer-name)) font-lock-warning-face)
-    (25 (memq major-mode ibuffer-help-buffer-modes) font-lock-comment-face)
-    (30 (eq major-mode 'dired-mode) font-lock-function-name-face))
+  `((10 buffer-read-only font-lock-constant-face)
+    (15 (and buffer-file-name
+            (string-match ibuffer-compressed-file-name-regexp
+                          buffer-file-name))
+       font-lock-doc-face)
+    (20 (string-match "^*" (buffer-name)) font-lock-keyword-face)
+    (25 (and (string-match "^ " (buffer-name))
+            (null buffer-file-name))
+       italic)
+    (30 (memq major-mode ibuffer-help-buffer-modes) font-lock-comment-face)
+    (35 (eq major-mode 'dired-mode) font-lock-function-name-face))
   "An alist describing how to fontify buffers.
 Each element should be of the form (PRIORITY FORM FACE), where
 PRIORITY is an integer, FORM is an arbitrary form to evaluate in the
 buffer, and FACE is the face to use for fontification.  If the FORM
 evaluates to non-nil, then FACE will be put on the buffer name.  The
-element with the highest PRIORITY takes precedence."
+element with the highest PRIORITY takes precedence.
+
+If you change this variable, you must kill the Ibuffer buffer and
+recreate it for the change to take effect."
   :type '(repeat
          (list (integer :tag "Priority")
                (sexp :tag "Test Form")
@@ -160,7 +168,7 @@ element with the highest PRIORITY takes precedence."
   :group 'ibuffer)
 
 (defcustom ibuffer-use-other-window nil
-  "If non-nil, display the Ibuffer in another window by default."
+  "If non-nil, display Ibuffer in another window by default."
   :type 'boolean
   :group 'ibuffer)
 
@@ -170,6 +178,11 @@ element with the highest PRIORITY takes precedence."
   :group 'ibuffer)
 (defvar ibuffer-shrink-to-minimum-size nil)
 
+(defcustom ibuffer-display-summary t
+  "If non-nil, summarize Ibuffer columns."
+  :type 'boolean
+  :group 'ibuffer)
+
 (defcustom ibuffer-truncate-lines t
   "If non-nil, do not display continuation lines."
   :type 'boolean
@@ -183,8 +196,8 @@ element with the highest PRIORITY takes precedence."
 (defcustom ibuffer-default-sorting-mode 'recency
   "The criteria by which to sort the buffers.
 
-Note that this variable is local to each ibuffer buffer.  Thus, you
-can have multiple ibuffer buffers open, each with a different sorted
+Note that this variable is local to each Ibuffer buffer.  Thus, you
+can have multiple Ibuffer buffers open, each with a different sorted
 view of the buffers."
   :type '(choice (const :tag "Last view time" :value recency)
                 (const :tag "Lexicographic" :value alphabetic)
@@ -200,11 +213,12 @@ view of the buffers."
 (defvar ibuffer-sorting-reversep nil)
 
 (defcustom ibuffer-elide-long-columns nil
-  "If non-nil, then elide column entries which exceed their max length.
-This variable is deprecated; use the :elide argument of
-`ibuffer-formats' to elide just certain columns."
+  "If non-nil, then elide column entries which exceed their max length."
   :type 'boolean
   :group 'ibuffer)
+(make-obsolete-variable 'ibuffer-elide-long-columns
+                        "use the :elide argument of `ibuffer-formats'."
+                        "22.1")
 
 (defcustom ibuffer-eliding-string "..."
   "The string to use for eliding long columns."
@@ -214,19 +228,34 @@ This variable is deprecated; use the :elide argument of
 (defcustom ibuffer-maybe-show-predicates `(,(lambda (buf)
                                              (and (string-match "^ " (buffer-name buf))
                                                   (null buffer-file-name))))
-  "A list of predicates (a regexp or function) for buffers to display conditionally.
+  "A list of predicates for buffers to display conditionally.
+
+A predicate can be a regexp or a function.
 If a regexp, then it will be matched against the buffer's name.
 If a function, it will be called with the buffer as an argument, and
 should return non-nil if this buffer should be shown.
 
-Viewing of buffers hidden because of these predicates is enabled by
-giving a non-nil prefix argument to `ibuffer-update'.  Note that this
-specialized filtering occurs before real filtering."
+Viewing of buffers hidden because of these predicates may be customized
+via `ibuffer-default-display-maybe-show-predicates' and is toggled by
+giving a non-nil prefix argument to `ibuffer-update'.
+Note that this specialized filtering occurs before real filtering."
   :type '(repeat (choice regexp function))
   :group 'ibuffer)
 
+(defcustom ibuffer-default-display-maybe-show-predicates nil
+  "Non-nil means show buffers that match `ibuffer-maybe-show-predicates'."
+  :type 'boolean
+  :group 'ibuffer)
+
+(defvar ibuffer-display-maybe-show-predicates nil)
+
 (defvar ibuffer-current-format nil)
 
+(defcustom ibuffer-movement-cycle t
+  "If non-nil, then forward and backwards movement commands cycle."
+  :type 'boolean
+  :group 'ibuffer)
+
 (defcustom ibuffer-modified-char ?*
   "The character to display for modified buffers."
   :type 'character
@@ -261,22 +290,27 @@ state, size, etc."
   :group 'ibuffer)
 
 (defcustom ibuffer-always-show-last-buffer nil
-  "If non-nil, always display the previous buffer.  This variable
-takes precedence over filtering, and even
+  "If non-nil, always display the previous buffer.
+This variable takes precedence over filtering, and even
 `ibuffer-never-show-predicates'."
   :type '(choice (const :tag "Always" :value t)
                 (const :tag "Never" :value nil)
                 (const :tag "Always except minibuffer" :value :nomini))
   :group 'ibuffer)
 
+(defcustom ibuffer-jump-offer-only-visible-buffers nil
+  "If non-nil, only offer buffers visible in the Ibuffer buffer
+in completion lists of the `ibuffer-jump-to-buffer' command."
+  :type 'boolean
+  :group 'ibuffer)
+
 (defcustom ibuffer-use-header-line (boundp 'header-line-format)
-  "If non-nil, display a header line containing current filters.
-This feature only works on Emacs 21 or later."
+  "If non-nil, display a header line containing current filters."
   :type 'boolean
   :group 'ibuffer)
 
 (defcustom ibuffer-default-directory nil
-  "The default directory to use for a new ibuffer buffer.
+  "The default directory to use for a new Ibuffer buffer.
 If nil, inherit the directory of the buffer in which `ibuffer' was
 called.  Otherwise, this variable should be a string naming a
 directory, like `default-directory'."
@@ -284,19 +318,37 @@ directory, like `default-directory'."
                 string)
   :group 'ibuffer)
 
-(defcustom ibuffer-help-buffer-modes '(help-mode apropos-mode
-                                      Info-mode Info-edit-mode)
+(defcustom ibuffer-help-buffer-modes
+  '(help-mode apropos-mode Info-mode Info-edit-mode)
   "List of \"Help\" major modes."
   :type '(repeat function)
   :group 'ibuffer)
 
-(defcustom ibuffer-hooks nil
-  "Hooks run when `ibuffer' is called."
+(eval-when-compile 
+(defcustom ibuffer-compressed-file-name-regexp
+    (concat "\\.\\("
+           (regexp-opt '("arj" "bgz" "bz2" "gz" "lzh" "taz" "tgz" "zip" "z"))
+           "\\)$")
+  "Regexp to match compressed file names."
+  :type 'regexp
+  :group 'ibuffer))
+
+(defcustom ibuffer-hook nil
+  "Hook run when `ibuffer' is called."
+  :type 'hook
+  :group 'ibuffer)
+(define-obsolete-variable-alias 'ibuffer-hooks
+                                'ibuffer-hook "22.1")
+
+(defcustom ibuffer-mode-hook nil
+  "Hook run upon entry into `ibuffer-mode'."
   :type 'hook
   :group 'ibuffer)
+(define-obsolete-variable-alias 'ibuffer-mode-hooks
+                                'ibuffer-mode-hook "22.1")
 
-(defcustom ibuffer-mode-hooks nil
-  "Hooks run upon entry into `ibuffer-mode'."
+(defcustom ibuffer-load-hook nil
+  "Hook run when Ibuffer is loaded."
   :type 'hook
   :group 'ibuffer)
 
@@ -328,6 +380,7 @@ directory, like `default-directory'."
                       (regexp :tag "To")))
   :group 'ibuffer)
 
+
 (defvar ibuffer-mode-map nil)
 (defvar ibuffer-mode-operate-map nil)
 (defvar ibuffer-mode-groups-popup nil)
@@ -351,6 +404,7 @@ directory, like `default-directory'."
     (define-key map (kbd "u") 'ibuffer-unmark-forward)
     (define-key map (kbd "=") 'ibuffer-diff-with-file)
     (define-key map (kbd "j") 'ibuffer-jump-to-buffer)
+    (define-key map (kbd "M-g") 'ibuffer-jump-to-buffer)
     (define-key map (kbd "DEL") 'ibuffer-unmark-backward)
     (define-key map (kbd "M-DEL") 'ibuffer-unmark-all)
     (define-key map (kbd "* *") 'ibuffer-unmark-all)
@@ -362,13 +416,14 @@ directory, like `default-directory'."
     (define-key map (kbd "* /") 'ibuffer-mark-dired-buffers)
     (define-key map (kbd "* e") 'ibuffer-mark-dissociated-buffers)
     (define-key map (kbd "* h") 'ibuffer-mark-help-buffers)
+    (define-key map (kbd "* z") 'ibuffer-mark-compressed-file-buffers)
     (define-key map (kbd ".") 'ibuffer-mark-old-buffers)
-    
+
     (define-key map (kbd "d") 'ibuffer-mark-for-delete)
     (define-key map (kbd "C-d") 'ibuffer-mark-for-delete-backwards)
     (define-key map (kbd "k") 'ibuffer-mark-for-delete)
     (define-key map (kbd "x") 'ibuffer-do-kill-on-deletion-marks)
-  
+
     ;; immediate operations
     (define-key map (kbd "n") 'ibuffer-forward-line)
     (define-key map (kbd "<down>") 'ibuffer-forward-line)
@@ -391,6 +446,7 @@ directory, like `default-directory'."
     (define-key map (kbd "s m") 'ibuffer-do-sort-by-major-mode)
 
     (define-key map (kbd "/ m") 'ibuffer-filter-by-mode)
+    (define-key map (kbd "/ M") 'ibuffer-filter-by-used-mode)
     (define-key map (kbd "/ n") 'ibuffer-filter-by-name)
     (define-key map (kbd "/ c") 'ibuffer-filter-by-content)
     (define-key map (kbd "/ e") 'ibuffer-filter-by-predicate)
@@ -409,6 +465,7 @@ directory, like `default-directory'."
     (define-key map (kbd "/ o") 'ibuffer-or-filter)
     (define-key map (kbd "/ g") 'ibuffer-filters-to-filter-group)
     (define-key map (kbd "/ P") 'ibuffer-pop-filter-group)
+    (define-key map (kbd "/ D") 'ibuffer-decompose-filter-group)
     (define-key map (kbd "/ /") 'ibuffer-filter-disable)
 
     (define-key map (kbd "M-n") 'ibuffer-forward-filter-group)
@@ -422,7 +479,7 @@ directory, like `default-directory'."
     (define-key map (kbd "/ R") 'ibuffer-switch-to-saved-filter-groups)
     (define-key map (kbd "/ X") 'ibuffer-delete-saved-filter-groups)
     (define-key map (kbd "/ \\") 'ibuffer-clear-filter-groups)
-  
+
     (define-key map (kbd "q") 'ibuffer-quit)
     (define-key map (kbd "h") 'describe-mode)
     (define-key map (kbd "?") 'describe-mode)
@@ -430,7 +487,7 @@ directory, like `default-directory'."
     (define-key map (kbd "% n") 'ibuffer-mark-by-name-regexp)
     (define-key map (kbd "% m") 'ibuffer-mark-by-mode-regexp)
     (define-key map (kbd "% f") 'ibuffer-mark-by-file-name-regexp)
-  
+
     (define-key map (kbd "C-t") 'ibuffer-visit-tags-table)
 
     (define-key map (kbd "|") 'ibuffer-do-shell-command-pipe)
@@ -455,7 +512,7 @@ directory, like `default-directory'."
     (define-key map (kbd "V") 'ibuffer-do-revert)
     (define-key map (kbd "W") 'ibuffer-do-view-and-eval)
     (define-key map (kbd "X") 'ibuffer-do-shell-command-pipe)
-  
+
     (define-key map (kbd "k") 'ibuffer-do-kill-lines)
     (define-key map (kbd "w") 'ibuffer-copy-filename-as-kill)
 
@@ -504,6 +561,8 @@ directory, like `default-directory'."
     (define-key-after map [menu-bar view sort do-sort-by-recency]
       '(menu-item "Sort by view time" ibuffer-do-sort-by-recency
                  :help "Sort by the last time the buffer was displayed"))
+    (define-key-after map [menu-bar view sort dashes]
+      '("--"))
     (define-key-after map [menu-bar view sort invert-sorting]
       '(menu-item "Reverse sorting order" ibuffer-invert-sorting))
     (define-key-after map [menu-bar view sort toggle-sorting-mode]
@@ -514,9 +573,12 @@ directory, like `default-directory'."
       (cons "Filter" (make-sparse-keymap "Filter")))
 
     (define-key-after map [menu-bar view filter filter-disable]
-      '(menu-item "Disable all filtering" ibuffer-filter-disable))
+      '(menu-item "Disable all filtering" ibuffer-filter-disable
+                 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)))
     (define-key-after map [menu-bar view filter filter-by-mode]
       '(menu-item "Add filter by major mode..." ibuffer-filter-by-mode))
+    (define-key-after map [menu-bar view filter filter-by-mode]
+      '(menu-item "Add filter by major mode in use..." ibuffer-filter-by-used-mode))
     (define-key-after map [menu-bar view filter filter-by-name]
       '(menu-item "Add filter by buffer name..." ibuffer-filter-by-name))
     (define-key-after map [menu-bar view filter filter-by-filename]
@@ -530,38 +592,50 @@ directory, like `default-directory'."
     (define-key-after map [menu-bar view filter filter-by-predicate]
       '(menu-item "Add filter by Lisp predicate..." ibuffer-filter-by-predicate))
     (define-key-after map [menu-bar view filter pop-filter]
-      '(menu-item "Remove top filter" ibuffer-pop-filter))
+      '(menu-item "Remove top filter" ibuffer-pop-filter
+                 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)))
     (define-key-after map [menu-bar view filter or-filter]
       '(menu-item "OR top two filters" ibuffer-or-filter
+                 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers
+                              (cdr ibuffer-filtering-qualifiers))
                  :help "Create a new filter which is the logical OR of the top two filters"))
     (define-key-after map [menu-bar view filter negate-filter]
-      '(menu-item "Negate top filter" ibuffer-negate-filter))
+      '(menu-item "Negate top filter" ibuffer-negate-filter
+                 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)))
     (define-key-after map [menu-bar view filter decompose-filter]
       '(menu-item "Decompose top filter" ibuffer-decompose-filter
+                 :enable (and (featurep 'ibuf-ext) (memq (car ibuffer-filtering-qualifiers) '(or saved not)))
                  :help "Break down a complex filter like OR or NOT"))
     (define-key-after map [menu-bar view filter exchange-filters]
-      '(menu-item "Swap top two filters" ibuffer-exchange-filters))
+      '(menu-item "Swap top two filters" ibuffer-exchange-filters
+                 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers
+                              (cdr ibuffer-filtering-qualifiers))))
     (define-key-after map [menu-bar view filter save-filters]
       '(menu-item "Save current filters permanently..." ibuffer-save-filters
+                 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)
                  :help "Use a mnemnonic name to store current filter stack"))
     (define-key-after map [menu-bar view filter switch-to-saved-filters]
       '(menu-item "Restore permanently saved filters..." ibuffer-switch-to-saved-filters
+                 :enable (and (featurep 'ibuf-ext) ibuffer-saved-filters)
                  :help "Replace current filters with a saved stack"))
     (define-key-after map [menu-bar view filter add-saved-filters]
       '(menu-item "Add to permanently saved filters..." ibuffer-add-saved-filters
+                 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)
                  :help "Include already saved stack with current filters"))
     (define-key-after map [menu-bar view filter delete-saved-filters]
       '(menu-item "Delete permanently saved filters..."
-                 ibuffer-delete-saved-filters))
+                 ibuffer-delete-saved-filters
+                 :enable (and (featurep 'ibuf-ext) ibuffer-saved-filters)))
 
     ;; Filter groups
 
     (define-key-after groups-map [filters-to-filter-group]
       '(menu-item "Create filter group from current filters..."
-                 ibuffer-filters-to-filter-group))
+                 ibuffer-filters-to-filter-group
+                 :enable (and (featurep 'ibuf-ext) ibuffer-filtering-qualifiers)))
     (define-key-after groups-map [forward-filter-group]
       '(menu-item "Move point to the next filter group"
-                 ibuffer-forward-filter-group))    
+                 ibuffer-forward-filter-group))
     (define-key-after groups-map [backward-filter-group]
       '(menu-item "Move point to the previous filter group"
                  ibuffer-backward-filter-group))
@@ -579,22 +653,30 @@ directory, like `default-directory'."
     (define-key-after groups-map [pop-filter-group]
       '(menu-item "Remove top filter group"
                  ibuffer-pop-filter-group
-                 :enable (and (featurep 'ibuf-ext) ibuffer-filter-group-kill-ring)))
+                 :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups)))
     (define-key-after groups-map [clear-filter-groups]
       '(menu-item "Remove all filter groups"
                  ibuffer-clear-filter-groups
-                 :enable (and (featurep 'ibuf-ext) ibuffer-filter-group-kill-ring)))
+                 :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups)))
+    (define-key-after groups-map [pop-filter-group]
+      '(menu-item "Decompose filter group..."
+                 ibuffer-pop-filter-group
+                 :help "\"Unmake\" a filter group"
+                 :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups)))
     (define-key-after groups-map [save-filter-groups]
       '(menu-item "Save current filter groups permanently..."
                  ibuffer-save-filter-groups
+                 :enable (and (featurep 'ibuf-ext) ibuffer-filter-groups)
                  :help "Use a mnemnonic name to store current filter groups"))
     (define-key-after groups-map [switch-to-saved-filter-groups]
       '(menu-item "Restore permanently saved filters..."
                  ibuffer-switch-to-saved-filter-groups
-                 :help "Replace current filters with a saved stack"))    
+                 :enable (and (featurep 'ibuf-ext) ibuffer-saved-filter-groups)
+                 :help "Replace current filters with a saved stack"))
     (define-key-after groups-map [delete-saved-filter-groups]
       '(menu-item "Delete permanently saved filter groups..."
-                 ibuffer-delete-saved-filter-groups))
+                 ibuffer-delete-saved-filter-groups
+                 :enable (and (featurep 'ibuf-ext) ibuffer-saved-filter-groups)))
     (define-key-after groups-map [set-filter-groups-by-mode]
       '(menu-item "Set current filter groups to filter by mode"
                  ibuffer-set-filter-groups-by-mode))
@@ -611,8 +693,7 @@ directory, like `default-directory'."
       '(menu-item "Toggle Auto Mode" ibuffer-auto-mode
                  :help "Attempt to automatically update the Ibuffer buffer"))
     (define-key-after map [menu-bar view customize]
-      '(menu-item "Customize Ibuffer" (lambda () (interactive)
-                                       (customize-group 'ibuffer))
+      '(menu-item "Customize Ibuffer" ibuffer-customize
                  :help "Use Custom to customize Ibuffer"))
 
     (define-key-after map [menu-bar mark]
@@ -651,15 +732,18 @@ directory, like `default-directory'."
     (define-key-after map [menu-bar mark mark-help-buffers]
       '(menu-item "Mark help buffers" ibuffer-mark-help-buffers
                  :help "Mark buffers in help-mode"))
+    (define-key-after map [menu-bar mark mark-compressed-file-buffers]
+      '(menu-item "Mark compressed file buffers" ibuffer-mark-compressed-file-buffers
+                 :help "Mark buffers which have a file that is compressed"))
     (define-key-after map [menu-bar mark mark-old-buffers]
       '(menu-item "Mark old buffers" ibuffer-mark-old-buffers
                  :help "Mark buffers which have not been viewed recently"))
     (define-key-after map [menu-bar mark unmark-all]
       '(menu-item "Unmark All" ibuffer-unmark-all))
-    
+
     (define-key-after map [menu-bar mark dashes]
       '("--"))
-      
+
     (define-key-after map [menu-bar mark mark-by-name-regexp]
       '(menu-item "Mark by buffer name (regexp)..." ibuffer-mark-by-name-regexp
                  :help "Mark buffers whose name matches a regexp"))
@@ -717,45 +801,71 @@ directory, like `default-directory'."
     (define-key-after operate-map [do-view-and-eval]
       '(menu-item "Eval (viewing buffer)..." ibuffer-do-view-and-eval
                  :help "Evaluate a Lisp form in each marked buffer while viewing it"))
-    
+
     (setq ibuffer-mode-map map
          ibuffer-mode-operate-map operate-map
-         ibuffer-mode-groups-popup groups-map)))
-(defvar ibuffer-name-map nil)
-(unless ibuffer-name-map
+         ibuffer-mode-groups-popup (copy-keymap groups-map))))
+
+(define-key ibuffer-mode-groups-popup [kill-filter-group]
+  '(menu-item "Kill filter group"
+             ibuffer-kill-line
+             :enable (and (featurep 'ibuf-ext)
+                          ibuffer-filter-groups)))
+(define-key ibuffer-mode-groups-popup [yank-filter-group]
+  '(menu-item "Yank last killed filter group"
+             ibuffer-yank
+             :enable (and (featurep 'ibuf-ext)
+                          ibuffer-filter-group-kill-ring)))
+
+(defvar ibuffer-name-map
   (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map ibuffer-mode-map)
     (define-key map [(mouse-1)] 'ibuffer-mouse-toggle-mark)
     (define-key map [(mouse-2)] 'ibuffer-mouse-visit-buffer)
     (define-key map [down-mouse-3] 'ibuffer-mouse-popup-menu)
-    (setq ibuffer-name-map map)))
+    map))
 
-(defvar ibuffer-mode-name-map nil)
-(unless ibuffer-mode-name-map
+(defvar ibuffer-mode-name-map
   (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map ibuffer-mode-map)
     (define-key map [(mouse-2)] 'ibuffer-mouse-filter-by-mode)
     (define-key map (kbd "RET") 'ibuffer-interactive-filter-by-mode)
-    (setq ibuffer-mode-name-map map)))
+    map))
+
+(defvar ibuffer-name-header-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [(mouse-1)] 'ibuffer-do-sort-by-alphabetic)
+    map))
+
+(defvar ibuffer-size-header-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [(mouse-1)] 'ibuffer-do-sort-by-size)
+    map))
 
-(defvar ibuffer-mode-filter-group-map nil)
-(unless ibuffer-mode-filter-group-map
+(defvar ibuffer-mode-header-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [(mouse-1)] 'ibuffer-do-sort-by-major-mode)
+    map))
+
+(defvar ibuffer-mode-filter-group-map
   (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map ibuffer-mode-map)
     (define-key map [(mouse-1)] 'ibuffer-mouse-toggle-mark)
     (define-key map [(mouse-2)] 'ibuffer-mouse-toggle-filter-group)
     (define-key map (kbd "RET") 'ibuffer-toggle-filter-group)
     (define-key map [down-mouse-3] 'ibuffer-mouse-popup-menu)
-    (setq ibuffer-mode-filter-group-map map)))
+    map))
 
-(defvar ibuffer-mode-hooks nil)
+(defvar ibuffer-restore-window-config-on-quit nil
+  "If non-nil, restore previous window configuration upon exiting `ibuffer'.")
 
-(defvar ibuffer-delete-window-on-quit nil
-  "Whether or not to delete the window upon exiting `ibuffer'.")
+(defvar ibuffer-prev-window-config nil
+  "Window configuration before starting Ibuffer.")
 
 (defvar ibuffer-did-modification nil)
 
+(defvar ibuffer-compiled-formats nil)
+(defvar ibuffer-cached-formats nil)
+(defvar ibuffer-cached-eliding-string nil)
+(defvar ibuffer-cached-elide-long-columns 0)
+
 (defvar ibuffer-sorting-functions-alist nil
   "An alist of functions which describe how to sort buffers.
 
@@ -784,7 +894,7 @@ width and the longest string in LIST."
       (while list
        (dotimes (i (1- columns))
          (insert (concat (car list) (make-string (- max (length (car list)))
-                                                 ? )))
+                                                 ?\s)))
          (setq list (cdr list)))
        (when (not (null list))
          (insert (pop list)))
@@ -807,7 +917,7 @@ width and the longest string in LIST."
          (let ((mark (ibuffer-current-mark)))
            (setq buffer-read-only nil)
            (if (eq mark ibuffer-marked-char)
-               (ibuffer-set-mark ? )
+               (ibuffer-set-mark ?\s)
              (ibuffer-set-mark ibuffer-marked-char)))))
     (setq buffer-read-only t)))
 
@@ -820,8 +930,8 @@ width and the longest string in LIST."
                                    default-directory)
                                default-directory))))
      (list (read-file-name "Find file: " default-directory)
-          current-prefix-arg)))
-  (find-file file (or wildcards (interactive-p))))
+          t)))
+  (find-file file wildcards))
 
 (defun ibuffer-mouse-visit-buffer (event)
   "Visit the buffer chosen with the mouse."
@@ -834,26 +944,26 @@ width and the longest string in LIST."
 (defun ibuffer-mouse-popup-menu (event)
   "Display a menu of operations."
   (interactive "e")
-  (let ((origline (count-lines (point-min) (point))))
+  (let ((eventpt (posn-point (event-end event)))
+       (origpt (point)))
     (unwind-protect
-       (progn
-         (mouse-set-point event)
-         (if (get-text-property (point) 'ibuffer-filter-group-name)
-             (save-excursion 
-               (popup-menu ibuffer-mode-groups-popup))
-           (setq buffer-read-only nil)
+       (if (get-text-property eventpt 'ibuffer-filter-group-name)
+           (progn
+             (goto-char eventpt)
+             (popup-menu ibuffer-mode-groups-popup))
+         (let ((inhibit-read-only t))
            (ibuffer-save-marks
              ;; hm.  we could probably do this in a better fashion
              (ibuffer-unmark-all ?\r)
-             (setq buffer-read-only nil)
-             (ibuffer-set-mark ibuffer-marked-char)
-             (setq buffer-read-only nil)
+             (save-excursion
+               (goto-char eventpt)
+               (ibuffer-set-mark ibuffer-marked-char))
              (save-excursion
                (popup-menu ibuffer-mode-operate-map)))))
-      (progn
-       (setq buffer-read-only t)
-       (goto-line (1+ origline))))))
-  
+      (setq buffer-read-only t)
+      (if (= eventpt (point))
+         (goto-char origpt)))))
+
 (defun ibuffer-skip-properties (props direction)
   (while (and (not (eobp))
              (let ((hit nil))
@@ -863,17 +973,23 @@ width and the longest string in LIST."
     (forward-line direction)
     (beginning-of-line)))
 
+(defun ibuffer-customize ()
+  "Begin customizing Ibuffer interactively."
+  (interactive)
+  (customize-group 'ibuffer))
+
 (defun ibuffer-backward-line (&optional arg skip-group-names)
   "Move backwards ARG lines, wrapping around the list if necessary."
   (interactive "P")
-  (unless arg
-    (setq arg 1))
+  (or arg (setq arg 1))
   (beginning-of-line)
   (while (> arg 0)
     (forward-line -1)
-    (when (or (get-text-property (point) 'ibuffer-title)
-             (and skip-group-names
-                  (get-text-property (point) 'ibuffer-filter-group-name)))
+    (when (and ibuffer-movement-cycle
+              (or (get-text-property (point) 'ibuffer-title)
+                  (and skip-group-names
+                       (get-text-property (point)
+                                          'ibuffer-filter-group-name))))
       (goto-char (point-max))
       (beginning-of-line))
     (ibuffer-skip-properties (append '(ibuffer-summary)
@@ -889,11 +1005,11 @@ width and the longest string in LIST."
 (defun ibuffer-forward-line (&optional arg skip-group-names)
   "Move forward ARG lines, wrapping around the list if necessary."
   (interactive "P")
-  (unless arg
-    (setq arg 1))
+  (or arg (setq arg 1))
   (beginning-of-line)
-  (when (or (eobp)
-           (get-text-property (point) 'ibuffer-summary))
+  (when (and ibuffer-movement-cycle
+            (or (eobp)
+                (get-text-property (point) 'ibuffer-summary)))
     (goto-char (point-min)))
   (when (or (get-text-property (point) 'ibuffer-title)
            (and skip-group-names
@@ -908,8 +1024,9 @@ width and the longest string in LIST."
       (ibuffer-backward-line (- arg))
     (while (> arg 0)
       (forward-line 1)
-      (when (or (eobp)
-               (get-text-property (point) 'ibuffer-summary))
+      (when (and ibuffer-movement-cycle
+                (or (eobp)
+                    (get-text-property (point) 'ibuffer-summary)))
        (goto-char (point-min)))
       (decf arg)
       (ibuffer-skip-properties (append '(ibuffer-title)
@@ -919,7 +1036,6 @@ width and the longest string in LIST."
 
 (defun ibuffer-visit-buffer (&optional single)
   "Visit the buffer on this line.
-
 If optional argument SINGLE is non-nil, then also ensure there is only
 one window."
   (interactive "P")
@@ -996,16 +1112,16 @@ a new window in the current frame, splitting vertically."
                 (> (length marked-bufs) 3)
                 (not (y-or-n-p (format "Really create a new frame for %s buffers? "
                                        (length marked-bufs)))))
-     (set-buffer-modified-p nil)
+      (set-buffer-modified-p nil)
       (delete-other-windows)
       (switch-to-buffer (pop marked-bufs))
       (let ((height (/ (1- (if (eq type 'horizontally) (frame-width)
-                              (frame-height)))
+                            (frame-height)))
                       (1+ (length marked-bufs)))))
        (mapcar (if (eq type 'other-frame)
                    #'(lambda (buf)
                        (let ((curframe (selected-frame)))
-                         (select-frame (new-frame))
+                         (select-frame (make-frame))
                          (switch-to-buffer buf)
                          (select-frame curframe)))
                  #'(lambda (buf)
@@ -1039,12 +1155,12 @@ a new window in the current frame, splitting vertically."
            (ibuffer-columnize-and-insert-list names)
            (goto-char (point-min))
            (setq buffer-read-only t))
-         (let ((lastwin (car (last (ibuffer-window-list)))))
+         (let ((lastwin (car (last (window-list nil 'nomini)))))
            ;; Now attempt to display the buffer...
            (save-window-excursion
              (select-window lastwin)
              ;; The window might be too small to split; in that case,
-            ;; try a few times to increase its size before giving up.
+             ;; try a few times to increase its size before giving up.
              (let ((attempts 0)
                    (trying t))
                (while trying
@@ -1056,11 +1172,11 @@ a new window in the current frame, splitting vertically."
                     ;; Handle a failure
                     (if (or (> (incf attempts) 4)
                             (and (stringp (cadr err))
-              ;; This definitely falls in the ghetto hack category...
+                                 ;; This definitely falls in the
+                                 ;; ghetto hack category...
                                  (not (string-match "too small" (cadr err)))))
                         (apply #'signal err)
                       (enlarge-window 3))))))
-          ;; This part doesn't work correctly sometimes under XEmacs.
              (select-window (next-window))
              (switch-to-buffer buf)
              (unwind-protect
@@ -1077,7 +1193,7 @@ a new window in the current frame, splitting vertically."
 (defun ibuffer-buffer-names-with-mark (mark)
   (let ((ibuffer-buffer-names-with-mark-result nil))
     (ibuffer-map-lines-nomodify
-     #'(lambda (buf mk) 
+     #'(lambda (buf mk)
         (when (char-equal mark mk)
           (push (buffer-name buf)
                 ibuffer-buffer-names-with-mark-result))))
@@ -1093,7 +1209,7 @@ a new window in the current frame, splitting vertically."
   (if all
       (ibuffer-map-lines-nomodify
        #'(lambda (buf mark)
-          (not (char-equal mark ? ))))
+          (not (char-equal mark ?\s))))
     (ibuffer-map-lines-nomodify
      #'(lambda (buf mark)
         (char-equal mark ibuffer-marked-char)))))
@@ -1106,7 +1222,7 @@ a new window in the current frame, splitting vertically."
 (defsubst ibuffer-map-deletion-lines (func)
   (ibuffer-map-on-mark ibuffer-deletion-char func))
 
-(define-ibuffer-op save ()
+(define-ibuffer-op ibuffer-do-save ()
   "Save marked buffers as with `save-buffer'."
   (:complex t
    :opstring "saved"
@@ -1123,19 +1239,19 @@ a new window in the current frame, splitting vertically."
        (save-buffer))))
   t)
 
-(define-ibuffer-op toggle-modified ()
+(define-ibuffer-op ibuffer-do-toggle-modified ()
   "Toggle modification flag of marked buffers."
   (:opstring "(un)marked as modified"
    :modifier-p t)
   (set-buffer-modified-p (not (buffer-modified-p))))
 
-(define-ibuffer-op toggle-read-only ()
+(define-ibuffer-op ibuffer-do-toggle-read-only ()
   "Toggle read only status in marked buffers."
   (:opstring "toggled read only status in"
    :modifier-p t)
   (toggle-read-only))
 
-(define-ibuffer-op delete ()
+(define-ibuffer-op ibuffer-do-delete ()
   "Kill marked buffers as with `kill-this-buffer'."
   (:opstring "killed"
    :active-opstring "kill"
@@ -1146,7 +1262,7 @@ a new window in the current frame, splitting vertically."
       'kill
     nil))
 
-(define-ibuffer-op kill-on-deletion-marks ()
+(define-ibuffer-op ibuffer-do-kill-on-deletion-marks ()
   "Kill buffers marked for deletion as with `kill-this-buffer'."
   (:opstring "killed"
    :active-opstring "kill"
@@ -1167,18 +1283,18 @@ a new window in the current frame, splitting vertically."
      ((char-equal mark ibuffer-marked-char)
       (ibuffer-map-marked-lines
        #'(lambda (buf mark)
-          (ibuffer-set-mark-1 ? )
+          (ibuffer-set-mark-1 ?\s)
           t)))
      ((char-equal mark ibuffer-deletion-char)
       (ibuffer-map-deletion-lines
        #'(lambda (buf mark)
-          (ibuffer-set-mark-1 ? )
+          (ibuffer-set-mark-1 ?\s)
           t)))
      (t
       (ibuffer-map-lines
        #'(lambda (buf mark)
-          (when (not (char-equal mark ? ))
-            (ibuffer-set-mark-1 ? ))
+          (when (not (char-equal mark ?\s))
+            (ibuffer-set-mark-1 ?\s))
           t)))))
   (ibuffer-redisplay t))
 
@@ -1195,9 +1311,9 @@ group."
         (ibuffer-map-lines
          #'(lambda (buf mark)
              (cond ((eq mark ibuffer-marked-char)
-                    (ibuffer-set-mark-1 ? )
+                    (ibuffer-set-mark-1 ?\s)
                     nil)
-                   ((eq mark ? )
+                   ((eq mark ?\s)
                     (ibuffer-set-mark-1 ibuffer-marked-char)
                     t)
                    (t
@@ -1216,24 +1332,23 @@ If point is on a group name, this function operates on that group."
   "Unmark the buffer on this line, and move forward ARG lines.
 If point is on a group name, this function operates on that group."
   (interactive "P")
-  (ibuffer-mark-interactive arg ?  1))
+  (ibuffer-mark-interactive arg ?\s 1))
 
 (defun ibuffer-unmark-backward (arg)
   "Unmark the buffer on this line, and move backward ARG lines.
 If point is on a group name, this function operates on that group."
   (interactive "P")
-  (ibuffer-mark-interactive arg ?  -1))
+  (ibuffer-mark-interactive arg ?\s -1))
 
 (defun ibuffer-mark-interactive (arg mark movement)
   (assert (eq major-mode 'ibuffer-mode))
-  (unless arg
-    (setq arg 1))
+  (or arg (setq arg 1))
   (ibuffer-forward-line 0)
   (ibuffer-aif (get-text-property (point) 'ibuffer-filter-group-name)
       (progn
        (require 'ibuf-ext)
        (ibuffer-mark-on-buffer #'identity mark it))
-    (ibuffer-forward-line 0 t) 
+    (ibuffer-forward-line 0 t)
     (let ((inhibit-read-only t))
       (while (> arg 0)
        (ibuffer-set-mark mark)
@@ -1300,40 +1415,38 @@ If point is on a group name, this function operates on that group."
                  (if uncompiledp
                      ibuffer-filter-format-alist
                    ibuffer-compiled-filter-formats))))))
-       
+
 (defun ibuffer-current-format (&optional uncompiledp)
   (or ibuffer-current-format
       (setq ibuffer-current-format 0))
-  (nth ibuffer-current-format (ibuffer-current-formats uncompiledp)))  
+  (nth ibuffer-current-format (ibuffer-current-formats uncompiledp)))
 
 (defun ibuffer-expand-format-entry (form)
   (if (or (consp form)
          (symbolp form))
-    (let ((sym (intern (concat "ibuffer-make-column-"
-                              (symbol-name (if (consp form)
-                                               (car form)
-                                             form))))))
-      (unless (or (fboundp sym)
-                 (assq sym ibuffer-inline-columns))
-       (error "Unknown column %s in ibuffer-formats" form))
-      (let (min max align elide)
-       (if (consp form)
-           (setq min (or (nth 1 form) 0)
-                 max (or (nth 2 form) -1)
-                 align (or (nth 3 form) :left)
-                 elide (or (nth 4 form) nil))
-         (setq min 0
-               max -1
-               align :left
-               elide nil))
-       (list sym min max align elide)))
+      (let ((sym (intern (concat "ibuffer-make-column-"
+                                (symbol-name (if (consp form)
+                                                 (car form)
+                                               form))))))
+       (unless (or (fboundp sym)
+                   (assq sym ibuffer-inline-columns))
+         (error "Unknown column %s in ibuffer-formats" form))
+       (let (min max align elide)
+         (if (consp form)
+             (setq min (or (nth 1 form) 0)
+                   max (or (nth 2 form) -1)
+                   align (or (nth 3 form) :left)
+                   elide (or (nth 4 form) nil))
+           (setq min 0
+                 max -1
+                 align :left
+                 elide nil))
+         (list sym min max align elide)))
     form))
-  
+
 (defun ibuffer-compile-make-eliding-form (strvar elide from-end-p)
-  (let ((ellipsis (if (ibuffer-use-fontification) 
-                     (propertize ibuffer-eliding-string 'face 'bold)
-                   ibuffer-eliding-string)))
-    (if (or elide ibuffer-elide-long-columns)
+  (let ((ellipsis (propertize ibuffer-eliding-string 'font-lock-face 'bold)))
+    (if (or elide (with-no-warnings ibuffer-elide-long-columns))
        `(if (> strlen 5)
             ,(if from-end-p
                  `(concat ,ellipsis
@@ -1352,8 +1465,8 @@ If point is on a group name, this function operates on that group."
     `(substring ,strvar 0 ,maxvar)))
 
 (defun ibuffer-compile-make-format-form (strvar widthform alignment)
-  (let* ((left `(make-string tmp2 ? ))
-         (right `(make-string (- tmp1 tmp2) ? )))
+  (let* ((left `(make-string tmp2 ?\s))
+        (right `(make-string (- tmp1 tmp2) ?\s)))
     `(progn
        (setq tmp1 ,widthform
             tmp2 (/ tmp1 2))
@@ -1430,19 +1543,19 @@ If point is on a group name, this function operates on that group."
                    ;; into our generated code.  Otherwise, we just
                    ;; generate a call to the column function.
                    (ibuffer-aif (assq sym ibuffer-inline-columns)
-                                (nth 1 it)
-                                `(,sym buffer mark)))
+                       (nth 1 it)
+                     `(,sym buffer mark)))
                   ;; You're not expected to understand this.  Hell, I
                   ;; don't even understand it, and I wrote it five
                   ;; minutes ago.
                   (insertgenfn (ibuffer-aif (get sym 'ibuffer-column-summarizer)
-                                 ;; I really, really wish Emacs Lisp had closures.
-                                 (lambda (arg sym)
-                                   `(insert
-                                     (let ((ret ,arg))
-                                       (put ',sym 'ibuffer-column-summary
-                                            (cons ret (get ',sym 'ibuffer-column-summary)))
-                                       ret)))
+                                   ;; I really, really wish Emacs Lisp had closures.
+                                   (lambda (arg sym)
+                                     `(insert
+                                       (let ((ret ,arg))
+                                         (put ',sym 'ibuffer-column-summary
+                                              (cons ret (get ',sym 'ibuffer-column-summary)))
+                                         ret)))
                                  (lambda (arg sym)
                                    `(insert ,arg))))
                   (mincompform `(< strlen ,(if (integerp min)
@@ -1451,40 +1564,40 @@ If point is on a group name, this function operates on that group."
                   (maxcompform `(> strlen ,(if (integerp max)
                                                max
                                              'max))))
-                (if (or min-used max-used)
-                    ;; The complex case, where we have to limit the
-                    ;; form to a maximum or minimum size.
-                    (progn
-                      (when (and min-used (not (integerp min)))
-                        (push `(min ,min) letbindings))
-                      (when (and max-used (not (integerp max)))
-                        (push `(max ,max) letbindings))
-                      (push 
-                       (if (and min-used max-used)
-                           `(if ,mincompform
-                                ,minform
-                              (if ,maxcompform
-                                  ,maxform))
-                         (if min-used
-                             `(when ,mincompform
-                                ,minform)
-                           `(when ,maxcompform
-                              ,maxform)))
-                       outforms)
-                      (push (append 
-                             `(setq str ,callform)
-                             (when strlen-used
-                               `(strlen (length str))))
-                            outforms)
-                      (setq outforms
-                            (append outforms (list (funcall insertgenfn 'str sym)))))
-                  ;; The simple case; just insert the string.
-                  (push (funcall insertgenfn callform sym) outforms))
-                ;; Finally, return a `let' form which binds the
-                ;; variables in `letbindings', and contains all the
-                ;; code in `outforms'.
-                `(let ,letbindings
-                   ,@outforms)))))
+              (if (or min-used max-used)
+                  ;; The complex case, where we have to limit the
+                  ;; form to a maximum or minimum size.
+                  (progn
+                    (when (and min-used (not (integerp min)))
+                      (push `(min ,min) letbindings))
+                    (when (and max-used (not (integerp max)))
+                      (push `(max ,max) letbindings))
+                    (push
+                     (if (and min-used max-used)
+                         `(if ,mincompform
+                              ,minform
+                            (if ,maxcompform
+                                ,maxform))
+                       (if min-used
+                           `(when ,mincompform
+                              ,minform)
+                         `(when ,maxcompform
+                            ,maxform)))
+                     outforms)
+                    (push (append
+                           `(setq str ,callform)
+                           (when strlen-used
+                             `(strlen (length str))))
+                          outforms)
+                    (setq outforms
+                          (append outforms (list (funcall insertgenfn 'str sym)))))
+                ;; The simple case; just insert the string.
+                (push (funcall insertgenfn callform sym) outforms))
+              ;; Finally, return a `let' form which binds the
+              ;; variables in `letbindings', and contains all the
+              ;; code in `outforms'.
+              `(let ,letbindings
+                 ,@outforms)))))
        result))
     (setq result
          ;; We don't want to unconditionally load the byte-compiler.
@@ -1506,16 +1619,11 @@ If point is on a group name, this function operates on that group."
                                            '(tmp2)))
                              ,@(nreverse result))))))))
 
-(defvar ibuffer-compiled-formats nil)
-(defvar ibuffer-cached-formats nil)
-(defvar ibuffer-cached-eliding-string nil)
-(defvar ibuffer-cached-elide-long-columns 0)
-
 (defun ibuffer-recompile-formats ()
   "Recompile `ibuffer-formats'."
   (interactive)
   (setq ibuffer-compiled-formats
-         (mapcar #'ibuffer-compile-format ibuffer-formats))
+       (mapcar #'ibuffer-compile-format ibuffer-formats))
   (when (boundp 'ibuffer-filter-format-alist)
     (setq ibuffer-compiled-filter-formats
          (mapcar #'(lambda (entry)
@@ -1530,7 +1638,7 @@ If point is on a group name, this function operates on that group."
     (ibuffer-awhen (and (consp form)
                        (get (car form) 'ibuffer-column-summarizer))
       (put (car form) 'ibuffer-column-summary nil))))
-  
+
 (defun ibuffer-check-formats ()
   (when (null ibuffer-formats)
     (error "No formats!"))
@@ -1542,7 +1650,7 @@ If point is on a group name, this function operates on that group."
              (not (equal ibuffer-cached-eliding-string ibuffer-eliding-string))
              (eql 0 ibuffer-cached-elide-long-columns)
              (not (eql ibuffer-cached-elide-long-columns
-                       ibuffer-elide-long-columns))
+                       (with-no-warnings ibuffer-elide-long-columns)))
              (and ext-loaded
                   (not (eq ibuffer-cached-filter-formats
                            ibuffer-filter-format-alist))
@@ -1552,7 +1660,7 @@ If point is on a group name, this function operates on that group."
       (ibuffer-recompile-formats)
       (setq ibuffer-cached-formats ibuffer-formats
            ibuffer-cached-eliding-string ibuffer-eliding-string
-           ibuffer-cached-elide-long-columns ibuffer-elide-long-columns)
+           ibuffer-cached-elide-long-columns (with-no-warnings ibuffer-elide-long-columns))
       (when ext-loaded
        (setq ibuffer-cached-filter-formats ibuffer-filter-format-alist))
       (message "Formats have changed, recompiling...done"))))
@@ -1564,7 +1672,7 @@ If point is on a group name, this function operates on that group."
 
 (define-ibuffer-column read-only (:name "R" :inline t)
   (if buffer-read-only
-      "%"
+      (string ibuffer-read-only-char)
     " "))
 
 (define-ibuffer-column modified (:name "M" :inline t)
@@ -1572,90 +1680,125 @@ If point is on a group name, this function operates on that group."
       (string ibuffer-modified-char)
     " "))
 
-(define-ibuffer-column name (:inline t
-                            :props
-                            ('mouse-face 'highlight 'keymap ibuffer-name-map
-                             'ibuffer-name-column t
-                             'help-echo "mouse-1: mark this buffer\nmouse-2: select this buffer\nmouse-3: operate on this buffer"))
-  (buffer-name))
-  
-(define-ibuffer-column size (:inline t)
+(define-ibuffer-column name
+  (:inline t
+   :header-mouse-map ibuffer-name-header-map
+   :props
+   ('mouse-face 'highlight 'keymap ibuffer-name-map
+               'ibuffer-name-column t
+               'help-echo '(if tooltip-mode
+                               "mouse-1: mark this buffer\nmouse-2: select this buffer\nmouse-3: operate on this buffer"
+                             "mouse-1: mark buffer   mouse-2: select buffer   mouse-3: operate"))
+   :summarizer
+   (lambda (strings)
+     (let ((bufs (length strings)))
+       (cond ((zerop bufs) "No buffers")
+            ((= 1 bufs) "1 buffer")
+            (t (format "%s buffers" bufs))))))
+  (propertize (buffer-name) 'font-lock-face (ibuffer-buffer-name-face buffer mark)))
+
+(define-ibuffer-column size
+  (:inline t
+   :header-mouse-map ibuffer-size-header-map
+   :summarizer
+   (lambda (column-strings)
+     (let ((total 0))
+       (dolist (string column-strings)
+        (setq total
+              ;; like, ewww ...
+              (+ (float (string-to-number string))
+                 total)))
+       (format "%.0f" total))))
   (format "%s" (buffer-size)))
 
-(define-ibuffer-column mode (:inline t
-                            :props
-                            ('mouse-face 'highlight
-                             'keymap ibuffer-mode-name-map
-                             'help-echo "mouse-2: filter by this mode"))
+(define-ibuffer-column mode
+  (:inline t
+   :header-mouse-map ibuffer-mode-header-map
+   :props
+   ('mouse-face 'highlight
+               'keymap ibuffer-mode-name-map
+               'help-echo "mouse-2: filter by this mode"))
   (format "%s" mode-name))
 
-(define-ibuffer-column process ()
+(define-ibuffer-column process
+  (:summarizer
+   (lambda (strings)
+     (let ((total (length (delete "" strings))))
+       (cond ((zerop total) "No processes")
+            ((= 1 total) "1 process")
+            (t (format "%d processes" total))))))
   (ibuffer-aif (get-buffer-process buffer)
       (format "(%s %s)" it (process-status it))
-    "none"))
-
-(define-ibuffer-column filename ()
+    ""))
+
+(define-ibuffer-column filename
+  (:summarizer
+   (lambda (strings)
+     (let ((total (length (delete "" strings))))
+       (cond ((zerop total) "No files")
+            ((= 1 total) "1 file")
+            (t (format "%d files" total))))))
   (let ((directory-abbrev-alist ibuffer-directory-abbrev-alist))
     (abbreviate-file-name
      (or buffer-file-name
         (and (boundp 'dired-directory)
-             dired-directory)
+             (if (stringp dired-directory)
+                 dired-directory
+               (car dired-directory)))
         ""))))
 
+(define-ibuffer-column filename-and-process
+  (:name "Filename/Process"
+   :summarizer
+   (lambda (strings)
+     (setq strings (delete "" strings))
+     (let ((procs 0)
+          (files 0))
+       (dolist (string strings)
+        (if (string-match "\\(\?:\\`(\[\[:ascii:\]\]\+)\\)" string)
+            (progn (setq procs (1+ procs))
+                   (if (< (match-end 0) (length string))
+                       (setq files (1+ files))))
+          (setq files (1+ files))))
+       (concat (cond ((zerop files) "No files")
+                    ((= 1 files) "1 file")
+                    (t (format "%d files" files)))
+              ", "
+              (cond ((zerop procs) "no processes")
+                    ((= 1 procs) "1 process")
+                    (t (format "%d processes" procs)))))))
+  (let ((proc (get-buffer-process buffer))
+       (filename (ibuffer-make-column-filename buffer mark)))
+    (if proc
+       (concat (propertize (format "(%s %s)" proc (process-status proc))
+                           'font-lock-face 'italic)
+               (if (> (length filename) 0)
+                   (format " %s" filename)
+                 ""))
+      filename)))
+
 (defun ibuffer-format-column (str width alignment)
-  (let ((left (make-string (/ width 2) ? ))
-       (right (make-string (- width (/ width 2)) ? )))
+  (let ((left (make-string (/ width 2) ?\s))
+       (right (make-string (- width (/ width 2)) ?\s)))
     (case alignment
       (:right (concat left right str))
       (:center (concat left str right))
       (t (concat str left right)))))
 
-(defun ibuffer-fontify-region-function (beg end &optional verbose)
-  (when verbose (message "Fontifying..."))
-  (let ((inhibit-read-only t))
-    (save-excursion
-      (goto-char beg)
-      (beginning-of-line)
-      (while (< (point) end)
-       (if (get-text-property (point) 'ibuffer-title-header)
-           (put-text-property (point) (line-end-position) 'face ibuffer-title-face)
-         (if (get-text-property (point) 'ibuffer-filter-group-name)
-             (put-text-property (point) (line-end-position) 'face
-                                ibuffer-filter-group-name-face)
-           (unless (or (get-text-property (point) 'ibuffer-title)
-                       (get-text-property (point) 'ibuffer-summary))
-             (multiple-value-bind (buf mark)
-                 (get-text-property (point) 'ibuffer-properties)
-               (let* ((namebeg (next-single-property-change (point) 'ibuffer-name-column
-                                                            nil (line-end-position)))
-                      (nameend (next-single-property-change namebeg 'ibuffer-name-column
-                                                            nil (line-end-position))))
-                 (put-text-property namebeg
-                                    nameend
-                                    'face
-                                    (cond ((char-equal mark ibuffer-marked-char)
-                                           ibuffer-marked-face)
-                                          ((char-equal mark ibuffer-deletion-char)
-                                           ibuffer-deletion-face)
-                                          (t
-                                           (let ((level -1)
-                                                 result)
-                                             (dolist (e ibuffer-fontification-alist result)
-                                               (when (and (> (car e) level)
-                                                          (with-current-buffer buf
-                                                            (eval (cadr e))))
-                                                 (setq level (car e)
-                                                       result
-                                                       (if (symbolp (caddr e))
-                                                           (if (facep (caddr e))
-                                                               (caddr e)
-                                                             (symbol-value (caddr e))))))))))))))))
-       (forward-line 1))))
-  (when verbose (message "Fontifying...done")))
-
-(defun ibuffer-unfontify-region-function (beg end)
-  (let ((inhibit-read-only t))
-    (remove-text-properties beg end '(face nil))))
+(defun ibuffer-buffer-name-face (buf mark)
+  (cond ((char-equal mark ibuffer-marked-char)
+        ibuffer-marked-face)
+       ((char-equal mark ibuffer-deletion-char)
+        ibuffer-deletion-face)
+       (t
+        (let ((level -1)
+              result)
+          (dolist (e ibuffer-fontification-alist result)
+            (when (and (> (car e) level)
+                       (with-current-buffer buf
+                         (eval (nth 1 e))))
+              (setq level (car e)
+                    result (nth 2 e))))))))
 
 (defun ibuffer-insert-buffer-line (buffer mark format)
   "Insert a line describing BUFFER and MARK using FORMAT."
@@ -1685,7 +1828,7 @@ If point is on a group name, this function operates on that group."
             (ibuffer-current-format)))
          (when ibuffer-shrink-to-minimum-size
            (ibuffer-shrink-to-fit)))))))
-   
+
 (defun ibuffer-map-on-mark (mark func)
   (ibuffer-map-lines
    #'(lambda (buf mk)
@@ -1700,8 +1843,8 @@ Don't set the ibuffer modification flag iff NOMODIFY is non-nil.
 If optional argument GROUP is non-nil, then only call FUNCTION on
 buffers in filtering group GROUP.
 
- FUNCTION is called with four arguments: the buffer object itself, the
-current mark symbol, and the beginning and ending line positions."
+FUNCTION is called with two arguments:
+the buffer object itself and the current mark symbol."
   (assert (eq major-mode 'ibuffer-mode))
   (ibuffer-forward-line 0)
   (let* ((orig-target-line (1+ (count-lines (save-excursion
@@ -1716,7 +1859,7 @@ current mark symbol, and the beginning and ending line positions."
        (progn
          (setq buffer-read-only nil)
          (goto-char (point-min))
-         (ibuffer-forward-line 0 t)      
+         (ibuffer-forward-line 0 t)
          (while (and (not (eobp))
                      (not (get-text-property (point) 'ibuffer-summary))
                      (progn
@@ -1746,7 +1889,7 @@ current mark symbol, and the beginning and ending line positions."
                                    (1+ (line-end-position)))
                     (incf ibuffer-map-lines-count)
                     (when (< ibuffer-map-lines-total
-                              orig-target-line)
+                             orig-target-line)
                       (decf target-line-offset)))
                    (t
                     (incf ibuffer-map-lines-count)
@@ -1792,7 +1935,7 @@ the value of point at the beginning of the line for that buffer."
     (mapcar #'(lambda (buf) (let ((e (assq buf bufs)))
                              (if e
                                  e
-                               (cons buf ? ))))
+                               (cons buf ?\s))))
            curbufs)))
 
 (defun ibuffer-buf-matches-predicates (buf predicates)
@@ -1804,7 +1947,7 @@ the value of point at the beginning of the line for that buffer."
              (funcall pred buf))
        (setq hit t)))
     hit))
-  
+
 (defun ibuffer-filter-buffers (ibuffer-buf last bmarklist all)
   (let ((ext-loaded (featurep 'ibuf-ext)))
     (delq nil
@@ -1815,11 +1958,11 @@ the value of point at the beginning of the line for that buffer."
                 (when
                     ;; This takes precedence over anything else
                     (or (and ibuffer-always-show-last-buffer
-                               (eq last buf))
-                          (funcall (if ext-loaded
-                                       #'ibuffer-ext-visible-p
-                                     #'ibuffer-visible-p)
-                                   buf all ibuffer-buf))
+                             (eq last buf))
+                        (funcall (if ext-loaded
+                                     #'ibuffer-ext-visible-p
+                                   #'ibuffer-visible-p)
+                                 buf all ibuffer-buf))
                   e)))
           bmarklist))))
 
@@ -1828,7 +1971,7 @@ the value of point at the beginning of the line for that buffer."
           (not
            (ibuffer-buf-matches-predicates buf ibuffer-maybe-show-predicates)))
        (or ibuffer-view-ibuffer
-          (and ibuffer-buf 
+          (and ibuffer-buf
                (not (eq ibuffer-buf buf))))))
 
 ;; This function is a special case; it's not defined by
@@ -1867,7 +2010,7 @@ the value of point at the beginning of the line for that buffer."
                       (next-single-property-change
                        (point-min) 'ibuffer-title)))
     (goto-char (point-min))
-    (put-text-property
+    (add-text-properties
      (point)
      (progn
        (let ((opos (point)))
@@ -1880,18 +2023,24 @@ the value of point at the beginning of the line for that buffer."
                    (min (cadr element))
                    ;; (max (caddr element))
                    (align (cadddr element)))
-              ;; Ignore a negative min when we're inserting the title
+               ;; Ignore a negative min when we're inserting the title
                (when (minusp min)
                  (setq min (- min)))
                (let* ((name (or (get sym 'ibuffer-column-name)
                                 (error "Unknown column %s in ibuffer-formats" sym)))
-                      (len (length name)))
-                 (if (< len min)
-                     (ibuffer-format-column name
-                                            (- min len)
-                                            align)
-                   name))))))
-        (put-text-property opos (point) 'ibuffer-title-header t)
+                      (len (length name))
+                      (hmap (get sym 'header-mouse-map))
+                      (strname (if (< len min)
+                                   (ibuffer-format-column name
+                                                          (- min len)
+                                                          align)
+                                 name)))
+                 (when hmap
+                   (setq
+                    strname 
+                    (propertize strname 'mouse-face 'highlight 'keymap hmap)))
+                 strname)))))
+        (add-text-properties opos (point) `(ibuffer-title-header t))
         (insert "\n")
         ;; Add the underlines
         (let ((str (save-excursion
@@ -1900,48 +2049,49 @@ the value of point at the beginning of the line for that buffer."
                      (buffer-substring (point) (line-end-position)))))
           (apply #'insert (mapcar
                            #'(lambda (c)
-                               (if (not (or (char-equal c ? )
+                               (if (not (or (char-equal c ?\s)
                                             (char-equal c ?\n)))
                                    ?-
-                                 ? ))
+                                 ?\s))
                            str)))
         (insert "\n"))
        (point))
-     'ibuffer-title t)
+     `(ibuffer-title t font-lock-face ,ibuffer-title-face))
     ;; Now, insert the summary columns.
     (goto-char (point-max))
     (if (get-text-property (1- (point-max)) 'ibuffer-summary)
        (delete-region (previous-single-property-change
                        (point-max) 'ibuffer-summary)
                       (point-max)))
-    (put-text-property
-     (point)
-     (progn
-       (insert "\n")
-       (dolist (element format)
-        (insert
-         (if (stringp element)
-             (make-string (length element) ? )
-           (let ((sym (car element)))
-             (let ((min (cadr element))
-                   ;; (max (caddr element))
-                   (align (cadddr element)))
-               ;; Ignore a negative min when we're inserting the title
-               (when (minusp min)
-                 (setq min (- min)))
-               (let* ((summary (if (get sym 'ibuffer-column-summarizer)
-                                   (funcall (get sym 'ibuffer-column-summarizer)
-                                            (get sym 'ibuffer-column-summary))
-                                 (make-string (length (get sym 'ibuffer-column-name))
-                                              ? )))
-                      (len (length summary)))
-                 (if (< len min)
-                     (ibuffer-format-column summary
-                                            (- min len)
-                                            align)
-                   summary)))))))
-       (point))
-     'ibuffer-summary t)))
+    (if ibuffer-display-summary
+       (add-text-properties
+        (point)
+        (progn
+          (insert "\n")
+          (dolist (element format)
+            (insert
+             (if (stringp element)
+                 (make-string (length element) ?\s)
+               (let ((sym (car element)))
+                 (let ((min (cadr element))
+                       ;; (max (caddr element))
+                       (align (cadddr element)))
+                   ;; Ignore a negative min when we're inserting the title
+                   (when (minusp min)
+                     (setq min (- min)))
+                   (let* ((summary (if (get sym 'ibuffer-column-summarizer)
+                                       (funcall (get sym 'ibuffer-column-summarizer)
+                                                (get sym 'ibuffer-column-summary))
+                                     (make-string (length (get sym 'ibuffer-column-name))
+                                                  ?\s)))
+                          (len (length summary)))
+                     (if (< len min)
+                         (ibuffer-format-column summary
+                                                (- min len)
+                                                align)
+                       summary)))))))
+          (point))
+        `(ibuffer-summary t)))))
 
 (defun ibuffer-update-mode-name ()
   (setq mode-name (format "Ibuffer by %s" (if ibuffer-sorting-mode
@@ -1969,10 +2119,9 @@ the value of point at the beginning of the line for that buffer."
 
 (defun ibuffer-redisplay (&optional silent)
   "Redisplay the current list of buffers.
-
 This does not show new buffers; use `ibuffer-update' for that.
 
-If SILENT is non-`nil', do not generate progress messages."
+If optional arg SILENT is non-nil, do not display progress messages."
   (interactive)
   (ibuffer-forward-line 0)
   (unless silent
@@ -1992,26 +2141,27 @@ If SILENT is non-`nil', do not generate progress messages."
 (defun ibuffer-update (arg &optional silent)
   "Regenerate the list of all buffers.
 
-Display buffers whose name matches one of `ibuffer-maybe-show-predicates'
-iff arg ARG is non-nil.  
+Prefix arg non-nil means to toggle whether buffers that match
+`ibuffer-maybe-show-predicates' should be displayed.
 
-Do not display messages if SILENT is non-nil."
+If optional arg SILENT is non-nil, do not display progress messages."
   (interactive "P")
+  (if arg
+      (setq ibuffer-display-maybe-show-predicates
+           (not ibuffer-display-maybe-show-predicates)))
   (ibuffer-forward-line 0)
   (let* ((bufs (buffer-list))
         (blist (ibuffer-filter-buffers
-               (current-buffer)
-               (if (and
-                    (cadr bufs)
-                    (eq ibuffer-always-show-last-buffer
-                        :nomini)
-                    ;; This is a hack.
-                    (string-match " \\*Minibuf"
-                                  (buffer-name (cadr bufs))))
-                   (caddr bufs)
-                 (cadr bufs))
-               (ibuffer-current-buffers-with-marks bufs)
-               arg)))
+                (current-buffer)
+                (if (and
+                     (cadr bufs)
+                     (eq ibuffer-always-show-last-buffer
+                         :nomini)
+                     (minibufferp (cadr bufs)))
+                    (caddr bufs)
+                  (cadr bufs))
+                (ibuffer-current-buffers-with-marks bufs)
+                ibuffer-display-maybe-show-predicates)))
     (when (null blist)
       (if (and (featurep 'ibuf-ext)
               ibuffer-filtering-qualifiers)
@@ -2043,15 +2193,25 @@ Do not display messages if SILENT is non-nil."
          (nreverse result)
        result))))
 
-(defun ibuffer-insert-filter-group (name display-name format bmarklist)
+(defun ibuffer-insert-filter-group (name display-name filter-string format bmarklist)
   (add-text-properties
    (point)
    (progn
      (insert "[ " display-name " ]")
      (point))
-   `(ibuffer-filter-group-name ,name keymap ,ibuffer-mode-filter-group-map
-                              mouse-face highlight
-                              help-echo "mouse-1: toggle marks in this group\nmouse-2: hide/show this filtering group "))
+   `(ibuffer-filter-group-name
+     ,name
+     font-lock-face ,ibuffer-filter-group-name-face
+     keymap ,ibuffer-mode-filter-group-map
+     mouse-face highlight
+     help-echo ,(let ((echo '(if tooltip-mode
+                                "mouse-1: toggle marks in this group\nmouse-2: hide/show this filtering group"
+                              "mouse-1: toggle marks  mouse-2: hide/show")))
+                 (if (> (length filter-string) 0)
+                     `(concat ,filter-string
+                              (if tooltip-mode "\n" " ")
+                              ,echo)
+                   echo))))
   (insert "\n")
   (when bmarklist
     (put-text-property
@@ -2063,7 +2223,7 @@ Do not display messages if SILENT is non-nil."
      'ibuffer-filter-group
      name)))
 
-(defun ibuffer-redisplay-engine (bmarklist &optional all)
+(defun ibuffer-redisplay-engine (bmarklist &optional ignore)
   (assert (eq major-mode 'ibuffer-mode))
   (let* ((--ibuffer-insert-buffers-and-marks-format
          (ibuffer-current-format))
@@ -2089,11 +2249,15 @@ Do not display messages if SILENT is non-nil."
                                  (member name ibuffer-hidden-filter-groups)))
                   (bmarklist (cdr group)))
              (unless (and (null bmarklist)
+                          (not disabled)
                           ext-loaded
                           (null ibuffer-show-empty-filter-groups))
                (ibuffer-insert-filter-group
                 name
                 (if disabled (concat name " ...") name)
+                (if ext-loaded
+                    (ibuffer-format-filter-group-data name)
+                  "")
                 --ibuffer-insert-buffers-and-marks-format
                 (if disabled
                     nil
@@ -2106,13 +2270,14 @@ Do not display messages if SILENT is non-nil."
 
 (defun ibuffer-quit ()
   "Quit this `ibuffer' session.
-Delete the current window iff `ibuffer-delete-window-on-quit' is non-nil."
+Try to restore the previous window configuration iff
+`ibuffer-restore-window-config-on-quit' is non-nil."
   (interactive)
-  (if ibuffer-delete-window-on-quit
+  (if ibuffer-restore-window-config-on-quit
       (progn
        (bury-buffer)
        (unless (= (count-windows) 1)
-         (delete-window)))
+         (set-window-configuration ibuffer-prev-window-config)))
     (bury-buffer)))
 
 ;;;###autoload
@@ -2135,26 +2300,28 @@ buffers which are visiting a file."
 
 ;;;###autoload
 (defun ibuffer (&optional other-window-p name qualifiers noselect
-                         shrink filter-groups)
-  "Begin using `ibuffer' to edit a list of buffers.
+                         shrink filter-groups formats)
+  "Begin using Ibuffer to edit a list of buffers.
 Type 'h' after entering ibuffer for more information.
 
-Optional argument OTHER-WINDOW-P says to use another window.
-Optional argument NAME specifies the name of the buffer; it defaults
-to \"*Ibuffer*\".
-Optional argument QUALIFIERS is an initial set of filtering qualifiers
-to use; see `ibuffer-filtering-qualifiers'.
-Optional argument NOSELECT means don't select the Ibuffer buffer.
-Optional argument SHRINK means shrink the buffer to minimal size.  The
-special value `onewindow' means always use another window.
-Optional argument FILTER-GROUPS is an initial set of filtering
-groups to use; see `ibuffer-filter-groups'."
+All arguments are optional.
+OTHER-WINDOW-P says to use another window.
+NAME specifies the name of the buffer (defaults to \"*Ibuffer*\").
+QUALIFIERS is an initial set of filtering qualifiers to use;
+  see `ibuffer-filtering-qualifiers'.
+NOSELECT means don't select the Ibuffer buffer.
+SHRINK means shrink the buffer to minimal size.  The special
+  value `onewindow' means always use another window.
+FILTER-GROUPS is an initial set of filtering groups to use;
+  see `ibuffer-filter-groups'.
+FORMATS is the value to use for `ibuffer-formats'.
+  If specified, then the variable `ibuffer-formats' will have
+  that value locally in this buffer."
   (interactive "P")
   (when ibuffer-use-other-window
     (setq other-window-p t))
-  (let* ((buf (get-buffer-create (or name "*Ibuffer*")))
-        (already-in (eq (current-buffer) buf))
-        (need-update nil))
+  (setq ibuffer-prev-window-config (current-window-configuration))
+  (let ((buf (get-buffer-create (or name "*Ibuffer*"))))
     (if other-window-p
        (funcall (if noselect #'(lambda (buf) (display-buffer buf t)) #'pop-to-buffer) buf)
       (funcall (if noselect #'display-buffer #'switch-to-buffer) buf))
@@ -2162,13 +2329,10 @@ groups to use; see `ibuffer-filter-groups'."
       (save-selected-window
        ;; We switch to the buffer's window in order to be able
        ;; to modify the value of point
-       (select-window (get-buffer-window buf))
-       (unless (eq major-mode 'ibuffer-mode)
-         (ibuffer-mode)
-         (setq need-update t))
-       (when (ibuffer-use-fontification)
-         (require 'font-lock))
-       (setq ibuffer-delete-window-on-quit other-window-p)
+       (select-window (get-buffer-window buf 0))
+       (or (eq major-mode 'ibuffer-mode)
+           (ibuffer-mode))
+       (setq ibuffer-restore-window-config-on-quit other-window-p)
        (when shrink
          (setq ibuffer-shrink-to-minimum-size shrink))
        (when qualifiers
@@ -2177,13 +2341,15 @@ groups to use; see `ibuffer-filter-groups'."
        (when filter-groups
          (require 'ibuf-ext)
          (setq ibuffer-filter-groups filter-groups))
+       (when formats
+         (set (make-local-variable 'ibuffer-formats) formats))
        (ibuffer-update nil)
        ;; Skip the group name by default.
        (ibuffer-forward-line 0 t)
        (unwind-protect
            (progn
              (setq buffer-read-only nil)
-             (run-hooks 'ibuffer-hooks))
+             (run-hooks 'ibuffer-hook))
          (setq buffer-read-only t))
        (unless ibuffer-expert
          (message "Commands: m, u, t, RET, g, k, S, D, Q; q to quit; h for help"))))))
@@ -2191,7 +2357,7 @@ groups to use; see `ibuffer-filter-groups'."
 (put 'ibuffer-mode 'mode-class 'special)
 (defun ibuffer-mode ()
   "A major mode for viewing a list of buffers.
-In ibuffer, you can conveniently perform many operations on the
+In Ibuffer, you can conveniently perform many operations on the
 currently open buffers, in addition to filtering your view to a
 particular subset of them, and sorting by various criteria.
 
@@ -2256,6 +2422,7 @@ Marking commands:
 Filtering commands:
 
   '\\[ibuffer-filter-by-mode]' - Add a filter by major mode.
+  '\\[ibuffer-filter-by-used-mode]' - Add a filter by major mode now in use.
   '\\[ibuffer-filter-by-name]' - Add a filter by buffer name.
   '\\[ibuffer-filter-by-content]' - Add a filter by buffer content.
   '\\[ibuffer-filter-by-filename]' - Add a filter by filename.
@@ -2281,7 +2448,7 @@ Filter group commands:
   '\\[ibuffer-save-filter-groups]' - Save the current groups with a name.
   '\\[ibuffer-switch-to-saved-filter-groups]' - Restore previously saved groups.
   '\\[ibuffer-delete-saved-filter-groups]' - Delete previously saved groups.
-    
+
 Sorting commands:
 
   '\\[ibuffer-toggle-sorting-mode]' - Rotate between the various sorting modes.
@@ -2372,12 +2539,9 @@ will be inserted before the group at point."
   ;; This makes things less ugly for Emacs 21 users with a non-nil
   ;; `show-trailing-whitespace'.
   (setq show-trailing-whitespace nil)
-  ;; Dummy font-lock-defaults to make font-lock turn on.  We want this
-  ;; so we know when to enable ibuffer's internal fontification.
-  (set (make-local-variable 'font-lock-defaults)
-       '(nil t nil nil nil
-            (font-lock-fontify-region-function . ibuffer-fontify-region-function)
-            (font-lock-unfontify-region-function . ibuffer-unfontify-region-function)))
+  ;; disable `show-paren-mode' buffer-locally
+  (if (bound-and-true-p show-paren-mode)
+      (set (make-local-variable 'show-paren-mode) nil))
   (set (make-local-variable 'revert-buffer-function)
        #'ibuffer-update)
   (set (make-local-variable 'ibuffer-sorting-mode)
@@ -2386,6 +2550,8 @@ will be inserted before the group at point."
        ibuffer-default-sorting-reversep)
   (set (make-local-variable 'ibuffer-shrink-to-minimum-size)
        ibuffer-default-shrink-to-minimum-size)
+  (set (make-local-variable 'ibuffer-display-maybe-show-predicates)
+       ibuffer-default-display-maybe-show-predicates)
   (set (make-local-variable 'ibuffer-filtering-qualifiers) nil)
   (set (make-local-variable 'ibuffer-filter-groups) nil)
   (set (make-local-variable 'ibuffer-filter-group-kill-ring) nil)
@@ -2395,8 +2561,7 @@ will be inserted before the group at point."
   (set (make-local-variable 'ibuffer-cached-eliding-string) nil)
   (set (make-local-variable 'ibuffer-cached-elide-long-columns) nil)
   (set (make-local-variable 'ibuffer-current-format) nil)
-  (set (make-local-variable 'ibuffer-did-modifiction) nil)
-  (set (make-local-variable 'ibuffer-delete-window-on-quit) nil)
+  (set (make-local-variable 'ibuffer-restore-window-config-on-quit) nil)
   (set (make-local-variable 'ibuffer-did-modification) nil)
   (set (make-local-variable 'ibuffer-tmp-hide-regexps) nil)
   (set (make-local-variable 'ibuffer-tmp-show-regexps) nil)
@@ -2405,14 +2570,18 @@ will be inserted before the group at point."
   (ibuffer-update-format)
   (when ibuffer-default-directory
     (setq default-directory ibuffer-default-directory))
-  (run-hooks 'ibuffer-mode-hooks)
+  (add-hook 'change-major-mode-hook 'font-lock-defontify nil t)
+  (run-mode-hooks 'ibuffer-mode-hook)
   ;; called after mode hooks to allow the user to add filters
   (ibuffer-update-mode-name))
 
 (provide 'ibuffer)
 
+(run-hooks 'ibuffer-load-hook)
+
 ;; Local Variables:
 ;; coding: iso-8859-1
 ;; End:
 
+;;; arch-tag: 72581688-0603-4954-b8cf-837c700f62e8
 ;;; ibuffer.el ends here