-;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+;; Copyright (C) 2000, 2001, 2002, 2003, 2004,
+;; 2005, 2006, 2007 Free Software Foundation, Inc.
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; your option) any later version.
;; This program is distributed in the hope that it will be useful, but
;; your option) any later version.
;; This program is distributed in the hope that it will be useful, but
;; You should have received a copy of the GNU General Public License
;; along with this program ; see the file COPYING. If not, write to
;; 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.
-(require 'font-lock)
-
-;;; 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)))))
+(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)
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."
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."
-(defcustom ibuffer-formats '((mark modified read-only " " (name 16 16 :left :elide)
- " " (size 6 -1 :right)
- " " (mode 16 16 :right :elide) " " filename-and-process)
+(defcustom ibuffer-formats '((mark modified read-only " " (name 18 18 :left :elide)
+ " " (size 9 -1 :right)
+ " " (mode 16 16 :left :elide) " " filename-and-process)
- (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))
- (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
"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
evaluates to non-nil, then FACE will be put on the buffer name. The
element with the highest PRIORITY takes precedence.
evaluates to non-nil, then FACE will be put on the buffer name. The
element with the highest PRIORITY takes precedence.
(defcustom ibuffer-truncate-lines t
"If non-nil, do not display continuation lines."
:type 'boolean
(defcustom ibuffer-truncate-lines t
"If non-nil, do not display continuation lines."
:type 'boolean
-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)
view of the buffers."
:type '(choice (const :tag "Last view time" :value recency)
(const :tag "Lexicographic" :value alphabetic)
- "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."
(defcustom ibuffer-maybe-show-predicates `(,(lambda (buf)
(and (string-match "^ " (buffer-name buf))
(null buffer-file-name))))
(defcustom ibuffer-maybe-show-predicates `(,(lambda (buf)
(and (string-match "^ " (buffer-name buf))
(null buffer-file-name))))
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.
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."
- "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)
`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-use-header-line (boundp 'header-line-format)
"If non-nil, display a header line containing current filters."
:type 'boolean
:group 'ibuffer)
(defcustom ibuffer-default-directory nil
(defcustom ibuffer-use-header-line (boundp 'header-line-format)
"If non-nil, display a header line containing current filters."
:type 'boolean
:group 'ibuffer)
(defcustom ibuffer-default-directory nil
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'."
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'."
- "Hooks run upon entry into `ibuffer-mode'."
+ "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-load-hook nil
+ "Hook run when Ibuffer is loaded."
(defvar ibuffer-mode-map nil)
(defvar ibuffer-mode-operate-map nil)
(defvar ibuffer-mode-groups-popup nil)
(defvar ibuffer-mode-map nil)
(defvar ibuffer-mode-operate-map nil)
(defvar ibuffer-mode-groups-popup nil)
(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 "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 "DEL") 'ibuffer-unmark-backward)
(define-key map (kbd "M-DEL") 'ibuffer-unmark-all)
(define-key map (kbd "* *") 'ibuffer-unmark-all)
(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 "* /") '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 "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)
(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)
;; immediate operations
(define-key map (kbd "n") 'ibuffer-forward-line)
(define-key map (kbd "<down>") 'ibuffer-forward-line)
(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 "/ 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)
(define-key map (kbd "q") 'ibuffer-quit)
(define-key map (kbd "h") 'describe-mode)
(define-key map (kbd "?") 'describe-mode)
(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 "% 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)
(define-key map (kbd "C-t") 'ibuffer-visit-tags-table)
(define-key map (kbd "|") 'ibuffer-do-shell-command-pipe)
(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 "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)
(define-key map (kbd "k") 'ibuffer-do-kill-lines)
(define-key map (kbd "w") 'ibuffer-copy-filename-as-kill)
(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 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 invert-sorting]
'(menu-item "Reverse sorting order" ibuffer-invert-sorting))
(define-key-after map [menu-bar view sort toggle-sorting-mode]
(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]
(cdr ibuffer-filtering-qualifiers))))
(define-key-after map [menu-bar view filter save-filters]
'(menu-item "Save current filters permanently..." ibuffer-save-filters
(cdr ibuffer-filtering-qualifiers))))
(define-key-after map [menu-bar view filter save-filters]
'(menu-item "Save current filters permanently..." ibuffer-save-filters
: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
: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-filtering-qualifiers)))
(define-key-after groups-map [forward-filter-group]
'(menu-item "Move point to the next 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"
(define-key-after groups-map [backward-filter-group]
'(menu-item "Move point to the previous filter group"
ibuffer-backward-filter-group))
(define-key-after groups-map [backward-filter-group]
'(menu-item "Move point to the previous filter group"
ibuffer-backward-filter-group))
'(menu-item "Restore permanently saved filters..."
ibuffer-switch-to-saved-filter-groups
:enable (and (featurep 'ibuf-ext) ibuffer-saved-filter-groups)
'(menu-item "Restore permanently saved filters..."
ibuffer-switch-to-saved-filter-groups
:enable (and (featurep 'ibuf-ext) ibuffer-saved-filter-groups)
(define-key-after groups-map [delete-saved-filter-groups]
'(menu-item "Delete permanently saved filter groups..."
ibuffer-delete-saved-filter-groups
(define-key-after groups-map [delete-saved-filter-groups]
'(menu-item "Delete permanently saved filter groups..."
ibuffer-delete-saved-filter-groups
'(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 "Toggle Auto Mode" ibuffer-auto-mode
:help "Attempt to automatically update the Ibuffer buffer"))
(define-key-after map [menu-bar view customize]
(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-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-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 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 mark-by-name-regexp]
'(menu-item "Mark by buffer name (regexp)..." ibuffer-mark-by-name-regexp
:help "Mark buffers whose name matches a regexp"))
(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"))
(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"))
(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 (copy-keymap groups-map))))
(define-key ibuffer-mode-groups-popup [kill-filter-group]
(setq ibuffer-mode-map map
ibuffer-mode-operate-map operate-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)))
+ '(menu-item "Kill filter group"
+ ibuffer-kill-line
+ :enable (and (featurep 'ibuf-ext)
+ ibuffer-filter-groups)))
- '(menu-item "Yank last killed filter group"
- ibuffer-yank
- :enable (and (featurep 'ibuf-ext) ibuffer-filter-group-kill-ring)))
-
-(defvar ibuffer-name-map nil)
-(unless ibuffer-name-map
+ '(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)))
(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)
(let ((map (make-sparse-keymap)))
(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)
(let ((map (make-sparse-keymap)))
(define-key map [(mouse-2)] 'ibuffer-mouse-filter-by-mode)
(define-key map (kbd "RET") 'ibuffer-interactive-filter-by-mode)
(let ((map (make-sparse-keymap)))
(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-header-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [(mouse-1)] 'ibuffer-do-sort-by-major-mode)
+ map))
(let ((map (make-sparse-keymap)))
(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)
(let ((map (make-sparse-keymap)))
(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)
-(defvar ibuffer-delete-window-on-quit nil
- "Whether or not to delete the window upon exiting `ibuffer'.")
+(defvar ibuffer-restore-window-config-on-quit nil
+ "If non-nil, restore previous window configuration upon exiting `ibuffer'.")
+
+(defvar ibuffer-prev-window-config nil
+ "Window configuration before starting Ibuffer.")
(defvar ibuffer-sorting-functions-alist nil
"An alist of functions which describe how to sort buffers.
(defvar ibuffer-sorting-functions-alist nil
"An alist of functions which describe how to sort buffers.
(let ((mark (ibuffer-current-mark)))
(setq buffer-read-only nil)
(if (eq mark ibuffer-marked-char)
(let ((mark (ibuffer-current-mark)))
(setq buffer-read-only nil)
(if (eq mark ibuffer-marked-char)
- ;; hm. we could probably do this in a better fashion
- (ibuffer-unmark-all ?\r)
- (save-excursion
- (goto-char eventpt)
- (ibuffer-set-mark ibuffer-marked-char))
- (save-excursion
- (popup-menu ibuffer-mode-operate-map)))))
+ ;; hm. we could probably do this in a better fashion
+ (ibuffer-unmark-all ?\r)
+ (save-excursion
+ (goto-char eventpt)
+ (ibuffer-set-mark ibuffer-marked-char))
+ (save-excursion
+ (popup-menu ibuffer-mode-operate-map)))))
(defun ibuffer-backward-line (&optional arg skip-group-names)
"Move backwards ARG lines, wrapping around the list if necessary."
(interactive "P")
(defun ibuffer-backward-line (&optional arg skip-group-names)
"Move backwards ARG lines, wrapping around the list if necessary."
(interactive "P")
(defun ibuffer-forward-line (&optional arg skip-group-names)
"Move forward ARG lines, wrapping around the list if necessary."
(interactive "P")
(defun ibuffer-forward-line (&optional arg skip-group-names)
"Move forward ARG lines, wrapping around the list if necessary."
(interactive "P")
(1+ (length marked-bufs)))))
(mapcar (if (eq type 'other-frame)
#'(lambda (buf)
(let ((curframe (selected-frame)))
(1+ (length marked-bufs)))))
(mapcar (if (eq type 'other-frame)
#'(lambda (buf)
(let ((curframe (selected-frame)))
(defun ibuffer-buffer-names-with-mark (mark)
(let ((ibuffer-buffer-names-with-mark-result nil))
(ibuffer-map-lines-nomodify
(defun ibuffer-buffer-names-with-mark (mark)
(let ((ibuffer-buffer-names-with-mark-result nil))
(ibuffer-map-lines-nomodify
"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")
"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")
(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")
(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-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)
(ibuffer-aif (get-text-property (point) 'ibuffer-filter-group-name)
(progn
(require 'ibuf-ext)
(ibuffer-mark-on-buffer #'identity mark it))
(defun ibuffer-current-format (&optional uncompiledp)
(or ibuffer-current-format
(setq ibuffer-current-format 0))
(defun ibuffer-current-format (&optional uncompiledp)
(or ibuffer-current-format
(setq ibuffer-current-format 0))
- (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)))
(defun ibuffer-compile-make-eliding-form (strvar elide from-end-p)
(let ((ellipsis (propertize ibuffer-eliding-string 'font-lock-face 'bold)))
(defun ibuffer-compile-make-eliding-form (strvar elide from-end-p)
(let ((ellipsis (propertize ibuffer-eliding-string 'font-lock-face 'bold)))
`(substring ,strvar 0 ,maxvar)))
(defun ibuffer-compile-make-format-form (strvar widthform alignment)
`(substring ,strvar 0 ,maxvar)))
(defun ibuffer-compile-make-format-form (strvar widthform alignment)
;; into our generated code. Otherwise, we just
;; generate a call to the column function.
(ibuffer-aif (assq sym ibuffer-inline-columns)
;; into our generated code. Otherwise, we just
;; generate a call to the column function.
(ibuffer-aif (assq sym ibuffer-inline-columns)
;; 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)
;; 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)))
- (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)))))
(defun ibuffer-recompile-formats ()
"Recompile `ibuffer-formats'."
(interactive)
(setq ibuffer-compiled-formats
(defun ibuffer-recompile-formats ()
"Recompile `ibuffer-formats'."
(interactive)
(setq ibuffer-compiled-formats
(when (boundp 'ibuffer-filter-format-alist)
(setq ibuffer-compiled-filter-formats
(mapcar #'(lambda (entry)
(when (boundp 'ibuffer-filter-format-alist)
(setq ibuffer-compiled-filter-formats
(mapcar #'(lambda (entry)
(ibuffer-awhen (and (consp form)
(get (car form) 'ibuffer-column-summarizer))
(put (car form) 'ibuffer-column-summary nil))))
(ibuffer-awhen (and (consp form)
(get (car form) 'ibuffer-column-summarizer))
(put (car form) 'ibuffer-column-summary nil))))
(not (equal ibuffer-cached-eliding-string ibuffer-eliding-string))
(eql 0 ibuffer-cached-elide-long-columns)
(not (eql ibuffer-cached-elide-long-columns
(not (equal ibuffer-cached-eliding-string ibuffer-eliding-string))
(eql 0 ibuffer-cached-elide-long-columns)
(not (eql ibuffer-cached-elide-long-columns
(ibuffer-recompile-formats)
(setq ibuffer-cached-formats ibuffer-formats
ibuffer-cached-eliding-string ibuffer-eliding-string
(ibuffer-recompile-formats)
(setq ibuffer-cached-formats ibuffer-formats
ibuffer-cached-eliding-string ibuffer-eliding-string
(when ext-loaded
(setq ibuffer-cached-filter-formats ibuffer-filter-format-alist))
(message "Formats have changed, recompiling...done"))))
(when ext-loaded
(setq ibuffer-cached-filter-formats ibuffer-filter-format-alist))
(message "Formats have changed, recompiling...done"))))
-(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"))
+(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))))))
-
-(define-ibuffer-column size (:inline 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-number string))
+ total)))
+ (format "%.0f" total))))
-(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"))
-(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))))))
- "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))))))
-(define-ibuffer-column filename-and-process (:name "Filename/Process")
+(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)))))))
(ibuffer-current-format)))
(when ibuffer-shrink-to-minimum-size
(ibuffer-shrink-to-fit)))))))
(ibuffer-current-format)))
(when ibuffer-shrink-to-minimum-size
(ibuffer-shrink-to-fit)))))))
If optional argument GROUP is non-nil, then only call FUNCTION on
buffers in filtering group GROUP.
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."
(1+ (line-end-position)))
(incf ibuffer-map-lines-count)
(when (< ibuffer-map-lines-total
(1+ (line-end-position)))
(incf ibuffer-map-lines-count)
(when (< ibuffer-map-lines-total
(defun ibuffer-filter-buffers (ibuffer-buf last bmarklist all)
(let ((ext-loaded (featurep 'ibuf-ext)))
(delq nil
(defun ibuffer-filter-buffers (ibuffer-buf last bmarklist all)
(let ((ext-loaded (featurep 'ibuf-ext)))
(delq nil
(defun ibuffer-do-sort-by-recency ()
"Sort the buffers by last view time."
(interactive)
(setq ibuffer-sorting-mode 'recency)
(defun ibuffer-do-sort-by-recency ()
"Sort the buffers by last view time."
(interactive)
(setq ibuffer-sorting-mode 'recency)
- (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
- (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)))))
font-lock-face ,ibuffer-filter-group-name-face
keymap ,ibuffer-mode-filter-group-map
mouse-face highlight
font-lock-face ,ibuffer-filter-group-name-face
keymap ,ibuffer-mode-filter-group-map
mouse-face highlight
- help-echo ,(concat filter-string "mouse-1: toggle marks in this group\nmouse-2: hide/show this filtering group ")))
+ 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))))
(assert (eq major-mode 'ibuffer-mode))
(let* ((--ibuffer-insert-buffers-and-marks-format
(ibuffer-current-format))
(assert (eq major-mode 'ibuffer-mode))
(let* ((--ibuffer-insert-buffers-and-marks-format
(ibuffer-current-format))
-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."
- (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))
(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))
- (select-window (get-buffer-window buf))
- (unless (eq major-mode 'ibuffer-mode)
- (ibuffer-mode)
- (setq need-update t))
- (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)
currently open buffers, in addition to filtering your view to a
particular subset of them, and sorting by various criteria.
currently open buffers, in addition to filtering your view to a
particular subset of them, and sorting by various criteria.
'\\[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.
'\\[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.
'\\[ibuffer-switch-format]' - Change the current display format.
'\\[forward-line]' - Move point to the next line.
'\\[previous-line]' - Move point to the previous line.
'\\[ibuffer-switch-format]' - Change the current display format.
'\\[forward-line]' - Move point to the next line.
'\\[previous-line]' - Move point to the previous line.
'\\[ibuffer-quit]' - Bury the Ibuffer buffer.
'\\[describe-mode]' - This help.
'\\[ibuffer-diff-with-file]' - View the differences between this buffer
'\\[ibuffer-quit]' - Bury the Ibuffer buffer.
'\\[describe-mode]' - This help.
'\\[ibuffer-diff-with-file]' - View the differences between this buffer
;; This makes things less ugly for Emacs 21 users with a non-nil
;; `show-trailing-whitespace'.
(setq show-trailing-whitespace nil)
;; This makes things less ugly for Emacs 21 users with a non-nil
;; `show-trailing-whitespace'.
(setq show-trailing-whitespace nil)
ibuffer-default-sorting-reversep)
(set (make-local-variable 'ibuffer-shrink-to-minimum-size)
ibuffer-default-shrink-to-minimum-size)
ibuffer-default-sorting-reversep)
(set (make-local-variable 'ibuffer-shrink-to-minimum-size)
ibuffer-default-shrink-to-minimum-size)
(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)
(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)
(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-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-modification) nil)
(set (make-local-variable 'ibuffer-tmp-hide-regexps) nil)
(set (make-local-variable 'ibuffer-tmp-show-regexps) 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)
(when ibuffer-default-directory
(setq default-directory ibuffer-default-directory))
(add-hook 'change-major-mode-hook 'font-lock-defontify nil t)
(when ibuffer-default-directory
(setq default-directory ibuffer-default-directory))
(add-hook 'change-major-mode-hook 'font-lock-defontify nil t)