X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/bfab7c6ec74dc55d640ef36f8cb1790a1420f991..c9586acc9719f5af71c61a24b7c5c40eb1b0905f:/lisp/ibuf-ext.el diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el index 8be5a73b5f..146ba61a51 100644 --- a/lisp/ibuf-ext.el +++ b/lisp/ibuf-ext.el @@ -1,34 +1,32 @@ ;;; ibuf-ext.el --- extensions for ibuffer -;; Copyright (C) 2000, 2001, 2002, 2003, 2004, -;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +;; Copyright (C) 2000-2013 Free Software Foundation, Inc. ;; Author: Colin Walters ;; Maintainer: John Paul Wallington ;; Created: 2 Dec 2001 ;; Keywords: buffer, convenience +;; Package: ibuffer ;; This file is part of GNU Emacs. -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 3, or (at -;; your option) any later version. +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. ;; 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., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;; along with GNU Emacs. If not, see . ;;; Commentary: ;; These functions should be automatically loaded when called, but you -;; can explicity (require 'ibuf-ext) in your ~/.emacs to have them +;; can explicitly (require 'ibuf-ext) in your ~/.emacs to have them ;; preloaded. ;;; Code: @@ -37,7 +35,7 @@ (eval-when-compile (require 'ibuf-macs) - (require 'cl)) + (require 'cl-lib)) ;;; Utility functions (defun ibuffer-delete-alist (key alist) @@ -93,11 +91,6 @@ regardless of any active filters in this buffer." (defvar ibuffer-tmp-show-regexps nil "A list of regexps which should match buffer names to always show.") -(defvar ibuffer-auto-mode nil - "If non-nil, Ibuffer auto-mode should be enabled for this buffer. -Do not set this variable directly! Use the function -`ibuffer-auto-mode' instead.") - (defvar ibuffer-auto-buffers-changed nil) (defcustom ibuffer-saved-filters '(("gnus" @@ -222,6 +215,18 @@ Currently, this only applies to `ibuffer-saved-filters' and (ibuffer-included-in-filters-p buf ibuffer-filtering-qualifiers) (ibuffer-buf-matches-predicates buf ibuffer-always-show-predicates))))) +;;;###autoload +(define-minor-mode ibuffer-auto-mode + "Toggle use of Ibuffer's auto-update facility (Ibuffer Auto mode). +With a prefix argument ARG, enable Ibuffer Auto mode if ARG is +positive, and disable it otherwise. If called from Lisp, enable +the mode if ARG is omitted or nil." + nil nil nil + (unless (derived-mode-p 'ibuffer-mode) + (error "This buffer is not in Ibuffer mode")) + (frame-or-buffer-changed-p 'ibuffer-auto-buffers-changed) ; Initialize state vector + (add-hook 'post-command-hook 'ibuffer-auto-update-changed)) + (defun ibuffer-auto-update-changed () (when (frame-or-buffer-changed-p 'ibuffer-auto-buffers-changed) (dolist (buf (buffer-list)) @@ -231,20 +236,6 @@ Currently, this only applies to `ibuffer-saved-filters' and (derived-mode-p 'ibuffer-mode)) (ibuffer-update nil t))))))) -;;;###autoload -(defun ibuffer-auto-mode (&optional arg) - "Toggle use of Ibuffer's auto-update facility. -With numeric ARG, enable auto-update if and only if ARG is positive." - (interactive) - (unless (derived-mode-p 'ibuffer-mode) - (error "This buffer is not in Ibuffer mode")) - (set (make-local-variable 'ibuffer-auto-mode) - (if arg - (plusp arg) - (not ibuffer-auto-mode))) - (frame-or-buffer-changed-p 'ibuffer-auto-buffers-changed) ; Initialize state vector - (add-hook 'post-command-hook 'ibuffer-auto-update-changed)) - ;;;###autoload (defun ibuffer-mouse-filter-by-mode (event) "Enable or disable filtering by the major mode chosen via mouse." @@ -262,9 +253,7 @@ With numeric ARG, enable auto-update if and only if ARG is positive." (if (assq 'mode ibuffer-filtering-qualifiers) (setq ibuffer-filtering-qualifiers (ibuffer-delete-alist 'mode ibuffer-filtering-qualifiers)) - (ibuffer-push-filter (cons 'mode - (with-current-buffer buf - major-mode))))) + (ibuffer-push-filter (cons 'mode (buffer-local-value 'major-mode buf))))) (ibuffer-update nil t)) ;;;###autoload @@ -412,6 +401,24 @@ To evaluate a form without viewing the buffer, see `ibuffer-do-eval'." :modifier-p :maybe) (revert-buffer t t)) +;;;###autoload (autoload 'ibuffer-do-isearch "ibuf-ext") +(define-ibuffer-op ibuffer-do-isearch () + "Perform a `isearch-forward' in marked buffers." + (:interactive () + :opstring "searched in" + :complex t + :modifier-p :maybe) + (multi-isearch-buffers (ibuffer-get-marked-buffers))) + +;;;###autoload (autoload 'ibuffer-do-isearch-regexp "ibuf-ext") +(define-ibuffer-op ibuffer-do-isearch-regexp () + "Perform a `isearch-forward-regexp' in marked buffers." + (:interactive () + :opstring "searched regexp in" + :complex t + :modifier-p :maybe) + (multi-isearch-buffers-regexp (ibuffer-get-marked-buffers))) + ;;;###autoload (autoload 'ibuffer-do-replace-regexp "ibuf-ext") (define-ibuffer-op replace-regexp (from-str to-str) "Perform a `replace-regexp' in marked buffers." @@ -490,32 +497,26 @@ To evaluate a form without viewing the buffer, see `ibuffer-do-eval'." (defun ibuffer-included-in-filter-p-1 (buf filter) (not (not - (case (car filter) - (or + (pcase (car filter) + (`or (memq t (mapcar #'(lambda (x) (ibuffer-included-in-filter-p buf x)) (cdr filter)))) - (saved + (`saved (let ((data (assoc (cdr filter) ibuffer-saved-filters))) (unless data - (ibuffer-filter-disable) + (ibuffer-filter-disable t) (error "Unknown saved filter %s" (cdr filter))) (ibuffer-included-in-filters-p buf (cadr data)))) - (t - (let ((filterdat (assq (car filter) - ibuffer-filtering-alist))) - ;; filterdat should be like (TYPE DESCRIPTION FUNC) - ;; just a sanity check - (unless filterdat - (ibuffer-filter-disable) - (error "Undefined filter %s" (car filter))) - (not - (not - (funcall (caddr filterdat) - buf - (cdr filter)))))))))) + (_ + (pcase-let ((`(,_type ,_desc ,func) + (assq (car filter) ibuffer-filtering-alist))) + (unless func + (ibuffer-filter-disable t) + (error "Undefined filter %s" (car filter))) + (funcall func buf (cdr filter)))))))) (defun ibuffer-generate-filter-groups (bmarklist &optional noempty nodefault) (let ((filter-group-alist (if nodefault @@ -529,13 +530,14 @@ To evaluate a form without viewing the buffer, see `ibuffer-do-eval'." (i 0)) (dolist (filtergroup filter-group-alist) (let ((filterset (cdr filtergroup))) - (multiple-value-bind (hip-crowd lamers) - (ibuffer-split-list (lambda (bufmark) - (ibuffer-included-in-filters-p (car bufmark) - filterset)) - bmarklist) + (cl-multiple-value-bind (hip-crowd lamers) + (cl-values-list + (ibuffer-split-list (lambda (bufmark) + (ibuffer-included-in-filters-p (car bufmark) + filterset)) + bmarklist)) (aset vec i hip-crowd) - (incf i) + (cl-incf i) (setq bmarklist lamers)))) (let (ret) (dotimes (j i ret) @@ -564,7 +566,7 @@ To evaluate a form without viewing the buffer, see `ibuffer-do-eval'." (let ((modes (ibuffer-remove-duplicates (mapcar (lambda (buf) - (with-current-buffer buf major-mode)) + (buffer-local-value 'major-mode buf)) (buffer-list))))) (if ibuffer-view-ibuffer modes @@ -681,7 +683,7 @@ See also `ibuffer-kill-filter-group'." (if (equal (car groups) group) (setq found t groups nil) - (incf res) + (cl-incf res) (setq groups (cdr groups)))) res))) (cond ((not found) @@ -753,19 +755,29 @@ They are removed from `ibuffer-saved-filter-groups'." The value from `ibuffer-saved-filter-groups' is used." (interactive (list - (if (null ibuffer-saved-filter-groups) - (error "No saved filters") - (completing-read "Switch to saved filter group: " - ibuffer-saved-filter-groups nil t)))) + (cond ((null ibuffer-saved-filter-groups) + (error "No saved filters")) + ;; `ibuffer-saved-filter-groups' is a user variable that defaults + ;; to nil. We assume that with one element in this list the user + ;; knows what she wants. See bug#12331. + ((null (cdr ibuffer-saved-filter-groups)) + (caar ibuffer-saved-filter-groups)) + (t + (completing-read "Switch to saved filter group: " + ibuffer-saved-filter-groups nil t))))) (setq ibuffer-filter-groups (cdr (assoc name ibuffer-saved-filter-groups)) ibuffer-hidden-filter-groups nil) (ibuffer-update nil t)) ;;;###autoload -(defun ibuffer-filter-disable () - "Disable all filters currently in effect in this buffer." +(defun ibuffer-filter-disable (&optional delete-filter-groups) + "Disable all filters currently in effect in this buffer. +With optional arg DELETE-FILTER-GROUPS non-nil, delete all filter +group definitions by setting `ibuffer-filter-groups' to nil." (interactive) (setq ibuffer-filtering-qualifiers nil) + (if delete-filter-groups + (setq ibuffer-filter-groups nil)) (let ((buf (ibuffer-current-buffer))) (ibuffer-update nil t) (when buf @@ -798,12 +810,12 @@ turned into two separate filters [name: foo] and [mode: bar-mode]." (when (null ibuffer-filtering-qualifiers) (error "No filters in effect")) (let ((lim (pop ibuffer-filtering-qualifiers))) - (case (car lim) - (or + (pcase (car lim) + (`or (setq ibuffer-filtering-qualifiers (append (cdr lim) ibuffer-filtering-qualifiers))) - (saved + (`saved (let ((data (assoc (cdr lim) ibuffer-saved-filters))) @@ -813,10 +825,10 @@ turned into two separate filters [name: foo] and [mode: bar-mode]." (setq ibuffer-filtering-qualifiers (append (cadr data) ibuffer-filtering-qualifiers)))) - (not + (`not (push (cdr lim) ibuffer-filtering-qualifiers)) - (t + (_ (error "Filter type %s is not compound" (car lim))))) (ibuffer-update nil t)) @@ -948,36 +960,30 @@ Interactively, prompt for NAME, and use the current filters." (ibuffer-format-qualifier-1 qualifier))) (defun ibuffer-format-qualifier-1 (qualifier) - (case (car qualifier) - (saved + (pcase (car qualifier) + (`saved (concat " [filter: " (cdr qualifier) "]")) - (or + (`or (concat " [OR" (mapconcat #'ibuffer-format-qualifier (cdr qualifier) "") "]")) - (t + (_ (let ((type (assq (car qualifier) ibuffer-filtering-alist))) (unless qualifier (error "Ibuffer: bad qualifier %s" qualifier)) (concat " [" (cadr type) ": " (format "%s]" (cdr qualifier))))))) -(defun ibuffer-list-buffer-modes () - "Create an alist of buffer modes currently in use. -The list returned will be of the form (\"MODE-NAME\" . MODE-SYMBOL)." - (let ((bufs (buffer-list)) - (modes) - (this-mode)) - (while bufs - (setq this-mode - (with-current-buffer - (car bufs) - major-mode) - bufs (cdr bufs)) - (add-to-list - 'modes - `(,(symbol-name this-mode) . - ,this-mode))) - modes)) +(defun ibuffer-list-buffer-modes (&optional include-parents) + "Create a completion table of buffer modes currently in use. +If INCLUDE-PARENTS is non-nil then include parent modes." + (let ((modes)) + (dolist (buf (buffer-list)) + (let ((this-mode (buffer-local-value 'major-mode buf))) + (while (and this-mode (not (memq this-mode modes))) + (push this-mode modes) + (setq this-mode (and include-parents + (get this-mode 'derived-mode-parent)))))) + (mapcar #'symbol-name modes))) ;;; Extra operation definitions @@ -987,18 +993,20 @@ The list returned will be of the form (\"MODE-NAME\" . MODE-SYMBOL)." "Toggle current view to buffers with major mode QUALIFIER." (:description "major mode" :reader - (intern - (completing-read "Filter by major mode: " obarray - #'(lambda (e) - (string-match "-mode$" - (symbol-name e))) - t - (let ((buf (ibuffer-current-buffer))) - (if (and buf (buffer-live-p buf)) - (with-current-buffer buf - (symbol-name major-mode)) - ""))))) - (eq qualifier (with-current-buffer buf major-mode))) + (let* ((buf (ibuffer-current-buffer)) + (default (if (and buf (buffer-live-p buf)) + (symbol-name (buffer-local-value + 'major-mode buf))))) + (intern + (completing-read + (if default + (format "Filter by major mode (default %s): " default) + "Filter by major mode: ") + obarray + #'(lambda (e) + (string-match "-mode\\'" (symbol-name e))) + t nil nil default)))) + (eq qualifier (buffer-local-value 'major-mode buf))) ;;;###autoload (autoload 'ibuffer-filter-by-used-mode "ibuf-ext") (define-ibuffer-filter used-mode @@ -1006,18 +1014,29 @@ The list returned will be of the form (\"MODE-NAME\" . MODE-SYMBOL)." Called interactively, this function allows selection of modes currently used by buffers." (:description "major mode in use" + :reader + (let* ((buf (ibuffer-current-buffer)) + (default (if (and buf (buffer-live-p buf)) + (symbol-name (buffer-local-value + 'major-mode buf))))) + (intern + (completing-read + (if default + (format "Filter by major mode (default %s): " default) + "Filter by major mode: ") + (ibuffer-list-buffer-modes) nil t nil nil default)))) + (eq qualifier (buffer-local-value 'major-mode buf))) + +;;;###autoload (autoload 'ibuffer-filter-by-derived-mode "ibuf-ext") +(define-ibuffer-filter derived-mode + "Toggle current view to buffers whose major mode inherits from QUALIFIER." + (:description "derived mode" :reader (intern - (completing-read "Filter by major mode: " - (ibuffer-list-buffer-modes) - nil - t - (let ((buf (ibuffer-current-buffer))) - (if (and buf (buffer-live-p buf)) - (with-current-buffer buf - (symbol-name major-mode)) - ""))))) - (eq qualifier (with-current-buffer buf major-mode))) + (completing-read "Filter by derived mode: " + (ibuffer-list-buffer-modes t) + nil t))) + (with-current-buffer buf (derived-mode-p qualifier))) ;;;###autoload (autoload 'ibuffer-filter-by-name "ibuf-ext") (define-ibuffer-filter name @@ -1031,18 +1050,8 @@ currently used by buffers." "Toggle current view to buffers with filename matching QUALIFIER." (:description "filename" :reader (read-from-minibuffer "Filter by filename (regexp): ")) - (ibuffer-awhen (with-current-buffer buf - (or buffer-file-name - (and (boundp 'dired-directory) - (let ((dired-dir - (if (stringp dired-directory) - dired-directory - (car dired-directory)))) - (and dired-dir - (expand-file-name dired-dir)))) - (and (eq major-mode 'vc-dir-mode) - (bound-and-true-p default-directory)))) - (string-match qualifier it))) + (ibuffer-awhen (buffer-local-value 'buffer-file-name buf) + (string-match qualifier it))) ;;;###autoload (autoload 'ibuffer-filter-by-size-gt "ibuf-ext") (define-ibuffer-filter size-gt @@ -1117,13 +1126,9 @@ Default sorting modes are: Ordering is lexicographic." (:description "major mode") (string-lessp (downcase - (symbol-name (with-current-buffer - (car a) - major-mode))) + (symbol-name (buffer-local-value 'major-mode (car a)))) (downcase - (symbol-name (with-current-buffer - (car b) - major-mode))))) + (symbol-name (buffer-local-value 'major-mode (car b)))))) ;;;###autoload (autoload 'ibuffer-do-sort-by-mode-name "ibuf-ext") (define-ibuffer-sorter mode-name @@ -1131,9 +1136,9 @@ Ordering is lexicographic." Ordering is lexicographic." (:description "major mode name") (string-lessp (downcase - (with-current-buffer - (car a) - (format-mode-line mode-name))) + (with-current-buffer + (car a) + (format-mode-line mode-name))) (downcase (with-current-buffer (car b) @@ -1164,10 +1169,10 @@ Ordering is lexicographic." (string-lessp ;; FIXME: For now just compare the file name and the process name ;; (if it exists). Is there a better way to do this? - (or (buffer-file-name (car a)) + (or (buffer-file-name (car a)) (let ((pr-a (get-buffer-process (car a)))) (and (processp pr-a) (process-name pr-a)))) - (or (buffer-file-name (car b)) + (or (buffer-file-name (car b)) (let ((pr-b (get-buffer-process (car b)))) (and (processp pr-b) (process-name pr-b)))))) @@ -1230,12 +1235,10 @@ mean move backwards, non-negative integers mean move forwards." (setq direction 1)) ;; Skip the title (ibuffer-forward-line 0) - (let ((opos (point)) - curmark) + (let ((opos (point))) (ibuffer-forward-line direction) (while (not (or (= (point) opos) - (eq (setq curmark (ibuffer-current-mark)) - mark))) + (eq (ibuffer-current-mark) mark))) (ibuffer-forward-line direction)) (when (and (= (point) opos) (not (eq (ibuffer-current-mark) mark))) @@ -1258,7 +1261,7 @@ to move by. The default is `ibuffer-marked-char'." (message "No buffers marked; use 'm' to mark a buffer") (let ((count (ibuffer-map-marked-lines - #'(lambda (buf mark) + #'(lambda (_buf _mark) 'kill)))) (message "Killed %s lines" count)))) @@ -1290,7 +1293,7 @@ a prefix argument reverses the meaning of that variable." (let (buf-point) ;; Blindly search for our buffer: it is very likely that it is ;; not in a hidden filter group. - (ibuffer-map-lines #'(lambda (buf marks) + (ibuffer-map-lines #'(lambda (buf _marks) (when (string= (buffer-name buf) name) (setq buf-point (point)) nil)) @@ -1304,7 +1307,7 @@ a prefix argument reverses the meaning of that variable." (dolist (group ibuffer-hidden-filter-groups) (ibuffer-jump-to-filter-group group) (ibuffer-toggle-filter-group) - (ibuffer-map-lines #'(lambda (buf marks) + (ibuffer-map-lines #'(lambda (buf _marks) (when (string= (buffer-name buf) name) (setq buf-point (point)) nil)) @@ -1319,15 +1322,68 @@ a prefix argument reverses the meaning of that variable." (error "No buffer with name %s" name) (goto-char buf-point))))) +(declare-function diff-sentinel "diff" + (code &optional old-temp-file new-temp-file)) + +(defun ibuffer-diff-buffer-with-file-1 (buffer) + (let ((bufferfile (buffer-local-value 'buffer-file-name buffer)) + (tempfile (make-temp-file "buffer-content-"))) + (when bufferfile + (unwind-protect + (progn + (with-current-buffer buffer + (write-region nil nil tempfile nil 'nomessage)) + (let* ((old (expand-file-name bufferfile)) + (new (expand-file-name tempfile)) + (oldtmp (file-local-copy old)) + (newtmp (file-local-copy new)) + (switches diff-switches) + (command + (mapconcat + 'identity + `(,diff-command + ;; Use explicitly specified switches + ,@(if (listp switches) switches (list switches)) + ,@(if (or old new) + (list "-L" (shell-quote-argument old) + "-L" (shell-quote-argument + (format "Buffer %s" (buffer-name buffer))))) + ,(shell-quote-argument (or oldtmp old)) + ,(shell-quote-argument (or newtmp new))) + " "))) + (let ((inhibit-read-only t)) + (insert command "\n") + (diff-sentinel + (call-process shell-file-name nil + (current-buffer) nil + shell-command-switch command)) + (insert "\n"))))) + (sit-for 0) + (when (file-exists-p tempfile) + (delete-file tempfile))))) + ;;;###autoload (defun ibuffer-diff-with-file () - "View the differences between this buffer and its associated file. + "View the differences between marked buffers and their associated files. +If no buffers are marked, use buffer at point. This requires the external program \"diff\" to be in your `exec-path'." (interactive) - (let ((buf (ibuffer-current-buffer))) - (unless (buffer-live-p buf) - (error "Buffer %s has been killed" buf)) - (diff-buffer-with-file buf))) + (require 'diff) + (let ((marked-bufs (ibuffer-get-marked-buffers))) + (when (null marked-bufs) + (setq marked-bufs (list (ibuffer-current-buffer t)))) + (with-current-buffer (get-buffer-create "*Ibuffer Diff*") + (setq buffer-read-only nil) + (buffer-disable-undo (current-buffer)) + (erase-buffer) + (buffer-enable-undo (current-buffer)) + (diff-mode) + (dolist (buf marked-bufs) + (unless (buffer-live-p buf) + (error "Buffer %s has been killed" buf)) + (ibuffer-diff-buffer-with-file-1 buf)) + (setq buffer-read-only t))) + (switch-to-buffer "*Ibuffer Diff*")) ;;;###autoload (defun ibuffer-copy-filename-as-kill (&optional arg) @@ -1353,19 +1409,19 @@ You can then feed the file name(s) to other commands with \\[yank]." (t 'name)))) (ibuffer-map-marked-lines - #'(lambda (buf mark) + #'(lambda (buf _mark) (setq ibuffer-copy-filename-as-kill-result (concat ibuffer-copy-filename-as-kill-result (let ((name (buffer-file-name buf))) (if name - (case type - (full + (pcase type + (`full name) - (relative + (`relative (file-relative-name name (or ibuffer-default-directory default-directory))) - (t + (_ (file-name-nondirectory name))) "")) " ")))) @@ -1374,7 +1430,7 @@ You can then feed the file name(s) to other commands with \\[yank]." (defun ibuffer-mark-on-buffer (func &optional ibuffer-mark-on-buffer-mark group) (let ((count (ibuffer-map-lines - #'(lambda (buf mark) + #'(lambda (buf _mark) (when (funcall func buf) (ibuffer-set-mark-1 (or ibuffer-mark-on-buffer-mark ibuffer-marked-char)) @@ -1382,7 +1438,8 @@ You can then feed the file name(s) to other commands with \\[yank]." nil group))) (ibuffer-redisplay t) - (message "Marked %s buffers" count))) + (unless (eq ibuffer-mark-on-buffer-mark ?\s) + (message "Marked %s buffers" count)))) ;;;###autoload (defun ibuffer-mark-by-name-regexp (regexp) @@ -1420,23 +1477,19 @@ You can then feed the file name(s) to other commands with \\[yank]." (defun ibuffer-mark-by-mode (mode) "Mark all buffers whose major mode equals MODE." (interactive - (list (intern (completing-read "Mark by major mode: " obarray - #'(lambda (e) - ;; kind of a hack... - (and (fboundp e) - (string-match "-mode$" - (symbol-name e)))) - t - (let ((buf (ibuffer-current-buffer))) - (if (and buf (buffer-live-p buf)) - (with-current-buffer buf - (cons (symbol-name major-mode) - 0)) - "")))))) + (let* ((buf (ibuffer-current-buffer)) + (default (if (and buf (buffer-live-p buf)) + (symbol-name (buffer-local-value + 'major-mode buf))))) + (list (intern + (completing-read + (if default + (format "Mark by major mode (default %s): " default) + "Mark by major mode: ") + (ibuffer-list-buffer-modes) nil t nil nil default))))) (ibuffer-mark-on-buffer #'(lambda (buf) - (with-current-buffer buf - (eq major-mode mode))))) + (eq (buffer-local-value 'major-mode buf) mode)))) ;;;###autoload (defun ibuffer-mark-modified-buffers () @@ -1450,7 +1503,7 @@ You can then feed the file name(s) to other commands with \\[yank]." "Mark all modified buffers that have an associated file." (interactive) (ibuffer-mark-on-buffer - #'(lambda (buf) (and (with-current-buffer buf buffer-file-name) + #'(lambda (buf) (and (buffer-local-value 'buffer-file-name buf) (buffer-modified-p buf))))) ;;;###autoload @@ -1497,13 +1550,8 @@ You can then feed the file name(s) to other commands with \\[yank]." (with-current-buffer buf ;; hacked from midnight.el (when buffer-display-time - (let* ((tm (current-time)) - (now (+ (* (float (ash 1 16)) (car tm)) - (float (cadr tm)) (* 0.0000001 (caddr tm)))) - (then (+ (* (float (ash 1 16)) - (car buffer-display-time)) - (float (cadr buffer-display-time)) - (* 0.0000001 (caddr buffer-display-time))))) + (let* ((now (float-time)) + (then (float-time buffer-display-time))) (> (- now then) (* 60 60 ibuffer-old-time)))))))) ;;;###autoload @@ -1519,18 +1567,14 @@ You can then feed the file name(s) to other commands with \\[yank]." "Mark all read-only buffers." (interactive) (ibuffer-mark-on-buffer - #'(lambda (buf) - (with-current-buffer buf - buffer-read-only)))) + #'(lambda (buf) (buffer-local-value 'buffer-read-only buf)))) ;;;###autoload (defun ibuffer-mark-dired-buffers () "Mark all `dired' buffers." (interactive) (ibuffer-mark-on-buffer - #'(lambda (buf) - (with-current-buffer buf - (eq major-mode 'dired-mode))))) + #'(lambda (buf) (eq (buffer-local-value 'major-mode buf) 'dired-mode)))) ;;;###autoload (defun ibuffer-do-occur (regexp &optional nlines) @@ -1546,11 +1590,14 @@ defaults to one." (let ((ibuffer-do-occur-bufs nil)) ;; Accumulate a list of marked buffers (ibuffer-map-marked-lines - #'(lambda (buf mark) + #'(lambda (buf _mark) (push buf ibuffer-do-occur-bufs))) (occur-1 regexp nlines ibuffer-do-occur-bufs))) (provide 'ibuf-ext) -;; arch-tag: 9af21953-deda-4c30-b76d-f81d9128e76d +;; Local Variables: +;; generated-autoload-file: "ibuffer.el" +;; End: + ;;; ibuf-ext.el ends here