;;; ibuffer.el --- operate on buffers like dired
-;; Copyright (C) 2000, 2001, 2002, 2003, 2004 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>
;; 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 '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 18 18 :left :elide)
(defcustom ibuffer-fontification-alist
`((10 buffer-read-only font-lock-constant-face)
- (15 (string-match "^*" (buffer-name)) font-lock-keyword-face)
- (20 (and (string-match "^ " (buffer-name))
+ (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)
- (25 (memq major-mode ibuffer-help-buffer-modes) font-lock-comment-face)
- (30 (eq major-mode 'dired-mode) font-lock-function-name-face))
+ (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
(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."
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
(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."
:type 'boolean
:type '(repeat function)
:group 'ibuffer)
+(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)
-(defvaralias 'ibuffer-hooks 'ibuffer-hook)
+(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)
-(defvaralias 'ibuffer-mode-hooks 'ibuffer-mode-hook)
+(define-obsolete-variable-alias 'ibuffer-mode-hooks
+ 'ibuffer-mode-hook "22.1")
(defcustom ibuffer-load-hook nil
"Hook run when Ibuffer is loaded."
(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)
(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-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 map (kbd "RET") 'ibuffer-interactive-filter-by-mode)
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-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)))
(define-key map [(mouse-1)] 'ibuffer-mouse-toggle-mark)
(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.
(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)))
(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)))
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."
(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)))))
((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))
(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
"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))
(defun ibuffer-compile-make-eliding-form (strvar elide from-end-p)
(let ((ellipsis (propertize ibuffer-eliding-string 'font-lock-face 'bold)))
- (if (or elide ibuffer-elide-long-columns)
+ (if (or elide (with-no-warnings ibuffer-elide-long-columns))
`(if (> strlen 5)
,(if from-end-p
`(concat ,ellipsis
`(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))
'(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)
(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))
(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"))))
(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
(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-int string))
+ (+ (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
(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
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))
(mapcar #'(lambda (buf) (let ((e (assq buf bufs)))
(if e
e
- (cons buf ? ))))
+ (cons buf ?\s))))
curbufs)))
(defun ibuffer-buf-matches-predicates (buf predicates)
(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))))))
+ (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
(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))
(dolist (element format)
(insert
(if (stringp element)
- (make-string (length element) ? )
+ (make-string (length element) ?\s)
(let ((sym (car element)))
(let ((min (cadr element))
;; (max (caddr element))
(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
(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.
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
(caddr bufs)
(cadr bufs))
(ibuffer-current-buffers-with-marks bufs)
- arg)))
+ ibuffer-display-maybe-show-predicates)))
(when (null blist)
(if (and (featurep 'ibuf-ext)
ibuffer-filtering-qualifiers)
'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))
`ibuffer-restore-window-config-on-quit' is non-nil."
(interactive)
(if ibuffer-restore-window-config-on-quit
- (progn
+ (progn
(bury-buffer)
(unless (= (count-windows) 1)
(set-window-configuration ibuffer-prev-window-config)))
;;;###autoload
(defun ibuffer (&optional other-window-p name qualifiers noselect
shrink filter-groups formats)
- "Begin using `ibuffer' to edit a list of buffers.
+ "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'.
-Optional argument FORMATS is the value to use for `ibuffer-formats'.
-If specified, then the variable `ibuffer-formats' will have that value
-locally in this buffer."
+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))
(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))
+ (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)
(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.
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)
(when ibuffer-default-directory
(setq default-directory ibuffer-default-directory))
(add-hook 'change-major-mode-hook 'font-lock-defontify nil t)
- (run-hooks 'ibuffer-mode-hook)
+ (run-mode-hooks 'ibuffer-mode-hook)
;; called after mode hooks to allow the user to add filters
(ibuffer-update-mode-name))