comparison lisp/ibuf-ext.el @ 88155:d7ddb3e565de

sync with trunk
author Henrik Enberg <henrik.enberg@telia.com>
date Mon, 16 Jan 2006 00:03:54 +0000
parents f90856c1755e
children
comparison
equal deleted inserted replaced
88154:8ce476d3ba36 88155:d7ddb3e565de
1 ;;; ibuf-ext.el --- extensions for ibuffer 1 ;;; ibuf-ext.el --- extensions for ibuffer
2 2
3 ;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. 3 ;; Copyright (C) 2000, 2001, 2002, 2003, 2004,
4 ;; 2005 Free Software Foundation, Inc.
4 5
5 ;; Author: Colin Walters <walters@verbum.org> 6 ;; Author: Colin Walters <walters@verbum.org>
6 ;; Maintainer: John Paul Wallington <jpw@gnu.org> 7 ;; Maintainer: John Paul Wallington <jpw@gnu.org>
7 ;; Created: 2 Dec 2001 8 ;; Created: 2 Dec 2001
8 ;; Keywords: buffer, convenience 9 ;; Keywords: buffer, convenience
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ;; General Public License for more details. 21 ;; General Public License for more details.
21 22
22 ;; You should have received a copy of the GNU General Public License 23 ;; You should have received a copy of the GNU General Public License
23 ;; along with this program ; see the file COPYING. If not, write to 24 ;; along with this program ; see the file COPYING. If not, write to
24 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 25 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02111-1307, USA. 26 ;; Boston, MA 02110-1301, USA.
26 27
27 ;;; Commentary: 28 ;;; Commentary:
28 29
29 ;; These functions should be automatically loaded when called, but you 30 ;; These functions should be automatically loaded when called, but you
30 ;; can explicity (require 'ibuf-ext) in your ~/.emacs to have them 31 ;; can explicity (require 'ibuf-ext) in your ~/.emacs to have them
33 ;;; Code: 34 ;;; Code:
34 35
35 (require 'ibuffer) 36 (require 'ibuffer)
36 37
37 (eval-when-compile 38 (eval-when-compile
38 (require 'derived)
39 (require 'ibuf-macs) 39 (require 'ibuf-macs)
40 (require 'cl)) 40 (require 'cl))
41 41
42 ;;; Utility functions 42 ;;; Utility functions
43 (defun ibuffer-delete-alist (key alist) 43 (defun ibuffer-delete-alist (key alist)
220 (or 220 (or
221 (ibuffer-included-in-filters-p buf ibuffer-filtering-qualifiers) 221 (ibuffer-included-in-filters-p buf ibuffer-filtering-qualifiers)
222 (ibuffer-buf-matches-predicates buf ibuffer-always-show-predicates))))) 222 (ibuffer-buf-matches-predicates buf ibuffer-always-show-predicates)))))
223 223
224 (defun ibuffer-auto-update-changed () 224 (defun ibuffer-auto-update-changed ()
225 (when ibuffer-auto-buffers-changed 225 (when (frame-or-buffer-changed-p 'ibuffer-auto-buffers-changed)
226 (setq ibuffer-auto-buffers-changed nil)
227 (mapcar #'(lambda (buf) 226 (mapcar #'(lambda (buf)
228 (ignore-errors 227 (ignore-errors
229 (with-current-buffer buf 228 (with-current-buffer buf
230 (when (and ibuffer-auto-mode 229 (when (and ibuffer-auto-mode
231 (eq major-mode 'ibuffer-mode)) 230 (eq major-mode 'ibuffer-mode))
241 (error "This buffer is not in Ibuffer mode")) 240 (error "This buffer is not in Ibuffer mode"))
242 (set (make-local-variable 'ibuffer-auto-mode) 241 (set (make-local-variable 'ibuffer-auto-mode)
243 (if arg 242 (if arg
244 (plusp arg) 243 (plusp arg)
245 (not ibuffer-auto-mode))) 244 (not ibuffer-auto-mode)))
246 (defadvice get-buffer-create (after ibuffer-notify-create activate) 245 (frame-or-buffer-changed-p 'ibuffer-auto-buffers-changed)
247 (setq ibuffer-auto-buffers-changed t))
248 (defadvice kill-buffer (after ibuffer-notify-kill activate)
249 (setq ibuffer-auto-buffers-changed t))
250 (add-hook 'post-command-hook 'ibuffer-auto-update-changed) 246 (add-hook 'post-command-hook 'ibuffer-auto-update-changed)
251 (ibuffer-update-mode-name)) 247 (ibuffer-update-mode-name))
252 248
253 ;;;###autoload 249 ;;;###autoload
254 (defun ibuffer-mouse-filter-by-mode (event) 250 (defun ibuffer-mouse-filter-by-mode (event)
259 ;;;###autoload 255 ;;;###autoload
260 (defun ibuffer-interactive-filter-by-mode (event-or-point) 256 (defun ibuffer-interactive-filter-by-mode (event-or-point)
261 "Enable or disable filtering by the major mode at point." 257 "Enable or disable filtering by the major mode at point."
262 (interactive "d") 258 (interactive "d")
263 (if (eventp event-or-point) 259 (if (eventp event-or-point)
264 (mouse-set-point event-or-point) 260 (posn-set-point (event-end event-or-point))
265 (goto-char event-or-point)) 261 (goto-char event-or-point))
266 (let ((buf (ibuffer-current-buffer))) 262 (let ((buf (ibuffer-current-buffer)))
267 (if (assq 'mode ibuffer-filtering-qualifiers) 263 (if (assq 'mode ibuffer-filtering-qualifiers)
268 (setq ibuffer-filtering-qualifiers 264 (setq ibuffer-filtering-qualifiers
269 (ibuffer-delete-alist 'mode ibuffer-filtering-qualifiers)) 265 (ibuffer-delete-alist 'mode ibuffer-filtering-qualifiers))
331 (when (= (point) (point-min)) 327 (when (= (point) (point-min))
332 (goto-char (point-max)) 328 (goto-char (point-max))
333 (ibuffer-backward-filter-group 1)) 329 (ibuffer-backward-filter-group 1))
334 (ibuffer-forward-line 0)) 330 (ibuffer-forward-line 0))
335 331
336 ;;;###autoload (autoload 'ibuffer-do-shell-command-pipe "ibuf-ext.el") 332 ;;;###autoload (autoload 'ibuffer-do-shell-command-pipe "ibuf-ext")
337 (define-ibuffer-op shell-command-pipe (command) 333 (define-ibuffer-op shell-command-pipe (command)
338 "Pipe the contents of each marked buffer to shell command COMMAND." 334 "Pipe the contents of each marked buffer to shell command COMMAND."
339 (:interactive "sPipe to shell command: " 335 (:interactive "sPipe to shell command: "
340 :opstring "Shell command executed on" 336 :opstring "Shell command executed on"
341 :modifier-p nil) 337 :modifier-p nil)
342 (shell-command-on-region 338 (shell-command-on-region
343 (point-min) (point-max) command 339 (point-min) (point-max) command
344 (get-buffer-create "* ibuffer-shell-output*"))) 340 (get-buffer-create "* ibuffer-shell-output*")))
345 341
346 ;;;###autoload (autoload 'ibuffer-do-shell-command-pipe-replace "ibuf-ext.el") 342 ;;;###autoload (autoload 'ibuffer-do-shell-command-pipe-replace "ibuf-ext")
347 (define-ibuffer-op shell-command-pipe-replace (command) 343 (define-ibuffer-op shell-command-pipe-replace (command)
348 "Replace the contents of marked buffers with output of pipe to COMMAND." 344 "Replace the contents of marked buffers with output of pipe to COMMAND."
349 (:interactive "sPipe to shell command (replace): " 345 (:interactive "sPipe to shell command (replace): "
350 :opstring "Buffer contents replaced in" 346 :opstring "Buffer contents replaced in"
351 :active-opstring "replace buffer contents in" 347 :active-opstring "replace buffer contents in"
353 :modifier-p t) 349 :modifier-p t)
354 (with-current-buffer buf 350 (with-current-buffer buf
355 (shell-command-on-region (point-min) (point-max) 351 (shell-command-on-region (point-min) (point-max)
356 command nil t))) 352 command nil t)))
357 353
358 ;;;###autoload (autoload 'ibuffer-do-shell-command-file "ibuf-ext.el") 354 ;;;###autoload (autoload 'ibuffer-do-shell-command-file "ibuf-ext")
359 (define-ibuffer-op shell-command-file (command) 355 (define-ibuffer-op shell-command-file (command)
360 "Run shell command COMMAND separately on files of marked buffers." 356 "Run shell command COMMAND separately on files of marked buffers."
361 (:interactive "sShell command on buffer's file: " 357 (:interactive "sShell command on buffer's file: "
362 :opstring "Shell command executed on" 358 :opstring "Shell command executed on"
363 :modifier-p nil) 359 :modifier-p nil)
366 (if buffer-file-name 362 (if buffer-file-name
367 buffer-file-name 363 buffer-file-name
368 (make-temp-file 364 (make-temp-file
369 (substring (buffer-name) 0 (min 10 (length (buffer-name)))))))))) 365 (substring (buffer-name) 0 (min 10 (length (buffer-name))))))))))
370 366
371 ;;;###autoload (autoload 'ibuffer-do-eval "ibuf-ext.el") 367 ;;;###autoload (autoload 'ibuffer-do-eval "ibuf-ext")
372 (define-ibuffer-op eval (form) 368 (define-ibuffer-op eval (form)
373 "Evaluate FORM in each of the buffers. 369 "Evaluate FORM in each of the buffers.
374 Does not display the buffer during evaluation. See 370 Does not display the buffer during evaluation. See
375 `ibuffer-do-view-and-eval' for that." 371 `ibuffer-do-view-and-eval' for that."
376 (:interactive "xEval in buffers (form): " 372 (:interactive "xEval in buffers (form): "
377 :opstring "evaluated in" 373 :opstring "evaluated in"
378 :modifier-p :maybe) 374 :modifier-p :maybe)
379 (eval form)) 375 (eval form))
380 376
381 ;;;###autoload (autoload 'ibuffer-do-view-and-eval "ibuf-ext.el") 377 ;;;###autoload (autoload 'ibuffer-do-view-and-eval "ibuf-ext")
382 (define-ibuffer-op view-and-eval (form) 378 (define-ibuffer-op view-and-eval (form)
383 "Evaluate FORM while displaying each of the marked buffers. 379 "Evaluate FORM while displaying each of the marked buffers.
384 To evaluate a form without viewing the buffer, see `ibuffer-do-eval'." 380 To evaluate a form without viewing the buffer, see `ibuffer-do-eval'."
385 (:interactive "xEval viewing buffers (form): " 381 (:interactive "xEval viewing buffers (form): "
386 :opstring "evaluated in" 382 :opstring "evaluated in"
391 (progn 387 (progn
392 (switch-to-buffer buf) 388 (switch-to-buffer buf)
393 (eval form)) 389 (eval form))
394 (switch-to-buffer ibuffer-buf)))) 390 (switch-to-buffer ibuffer-buf))))
395 391
396 ;;;###autoload (autoload 'ibuffer-do-rename-uniquely "ibuf-ext.el") 392 ;;;###autoload (autoload 'ibuffer-do-rename-uniquely "ibuf-ext")
397 (define-ibuffer-op rename-uniquely () 393 (define-ibuffer-op rename-uniquely ()
398 "Rename marked buffers as with `rename-uniquely'." 394 "Rename marked buffers as with `rename-uniquely'."
399 (:opstring "renamed" 395 (:opstring "renamed"
400 :modifier-p t) 396 :modifier-p t)
401 (rename-uniquely)) 397 (rename-uniquely))
402 398
403 ;;;###autoload (autoload 'ibuffer-do-revert "ibuf-ext.el") 399 ;;;###autoload (autoload 'ibuffer-do-revert "ibuf-ext")
404 (define-ibuffer-op revert () 400 (define-ibuffer-op revert ()
405 "Revert marked buffers as with `revert-buffer'." 401 "Revert marked buffers as with `revert-buffer'."
406 (:dangerous t 402 (:dangerous t
407 :opstring "reverted" 403 :opstring "reverted"
408 :active-opstring "revert" 404 :active-opstring "revert"
409 :modifier-p :maybe) 405 :modifier-p :maybe)
410 (revert-buffer t t)) 406 (revert-buffer t t))
411 407
412 ;;;###autoload (autoload 'ibuffer-do-replace-regexp "ibuf-ext.el") 408 ;;;###autoload (autoload 'ibuffer-do-replace-regexp "ibuf-ext")
413 (define-ibuffer-op replace-regexp (from-str to-str) 409 (define-ibuffer-op replace-regexp (from-str to-str)
414 "Perform a `replace-regexp' in marked buffers." 410 "Perform a `replace-regexp' in marked buffers."
415 (:interactive 411 (:interactive
416 (let* ((from-str (read-from-minibuffer "Replace regexp: ")) 412 (let* ((from-str (read-from-minibuffer "Replace regexp: "))
417 (to-str (read-from-minibuffer (concat "Replace " from-str 413 (to-str (read-from-minibuffer (concat "Replace " from-str
427 (let ((case-fold-search ibuffer-case-fold-search)) 423 (let ((case-fold-search ibuffer-case-fold-search))
428 (while (re-search-forward from-str nil t) 424 (while (re-search-forward from-str nil t)
429 (replace-match to-str)))) 425 (replace-match to-str))))
430 t)) 426 t))
431 427
432 ;;;###autoload (autoload 'ibuffer-do-query-replace "ibuf-ext.el") 428 ;;;###autoload (autoload 'ibuffer-do-query-replace "ibuf-ext")
433 (define-ibuffer-op query-replace (&rest args) 429 (define-ibuffer-op query-replace (&rest args)
434 "Perform a `query-replace' in marked buffers." 430 "Perform a `query-replace' in marked buffers."
435 (:interactive 431 (:interactive
436 (query-replace-read-args "Query replace" t t) 432 (query-replace-read-args "Query replace" t t)
437 :opstring "replaced in" 433 :opstring "replaced in"
443 (let ((case-fold-search ibuffer-case-fold-search)) 439 (let ((case-fold-search ibuffer-case-fold-search))
444 (goto-char (point-min)) 440 (goto-char (point-min))
445 (apply #'query-replace args))) 441 (apply #'query-replace args)))
446 t)) 442 t))
447 443
448 ;;;###autoload (autoload 'ibuffer-do-query-replace-regexp "ibuf-ext.el") 444 ;;;###autoload (autoload 'ibuffer-do-query-replace-regexp "ibuf-ext")
449 (define-ibuffer-op query-replace-regexp (&rest args) 445 (define-ibuffer-op query-replace-regexp (&rest args)
450 "Perform a `query-replace-regexp' in marked buffers." 446 "Perform a `query-replace-regexp' in marked buffers."
451 (:interactive 447 (:interactive
452 (query-replace-read-args "Query replace regexp" t t) 448 (query-replace-read-args "Query replace regexp" t t)
453 :opstring "replaced in" 449 :opstring "replaced in"
459 (let ((case-fold-search ibuffer-case-fold-search)) 455 (let ((case-fold-search ibuffer-case-fold-search))
460 (goto-char (point-min)) 456 (goto-char (point-min))
461 (apply #'query-replace-regexp args))) 457 (apply #'query-replace-regexp args)))
462 t)) 458 t))
463 459
464 ;;;###autoload (autoload 'ibuffer-do-print "ibuf-ext.el") 460 ;;;###autoload (autoload 'ibuffer-do-print "ibuf-ext")
465 (define-ibuffer-op print () 461 (define-ibuffer-op print ()
466 "Print marked buffers as with `print-buffer'." 462 "Print marked buffers as with `print-buffer'."
467 (:opstring "printed" 463 (:opstring "printed"
468 :modifier-p nil) 464 :modifier-p nil)
469 (print-buffer)) 465 (print-buffer))
554 (setq ibuffer-filter-groups 550 (setq ibuffer-filter-groups
555 (mapcar (lambda (mode) 551 (mapcar (lambda (mode)
556 (cons (format "%s" mode) `((mode . ,mode)))) 552 (cons (format "%s" mode) `((mode . ,mode))))
557 (let ((modes 553 (let ((modes
558 (ibuffer-remove-duplicates 554 (ibuffer-remove-duplicates
559 (mapcar (lambda (buf) (with-current-buffer buf major-mode)) 555 (mapcar (lambda (buf)
556 (with-current-buffer buf major-mode))
560 (buffer-list))))) 557 (buffer-list)))))
561 (if ibuffer-view-ibuffer 558 (if ibuffer-view-ibuffer
562 modes 559 modes
563 (delq 'ibuffer-mode modes))))) 560 (delq 'ibuffer-mode modes)))))
564 (ibuffer-update nil t)) 561 (ibuffer-update nil t))
584 nil t))) 581 nil t)))
585 582
586 ;;;###autoload 583 ;;;###autoload
587 (defun ibuffer-decompose-filter-group (group) 584 (defun ibuffer-decompose-filter-group (group)
588 "Decompose the filter group GROUP into active filters." 585 "Decompose the filter group GROUP into active filters."
589 (interactive (list (ibuffer-read-filter-group-name "Decompose filter group: " t))) 586 (interactive
587 (list (ibuffer-read-filter-group-name "Decompose filter group: " t)))
590 (let ((data (cdr (assoc group ibuffer-filter-groups)))) 588 (let ((data (cdr (assoc group ibuffer-filter-groups))))
591 (setq ibuffer-filter-groups (ibuffer-delete-alist 589 (setq ibuffer-filter-groups (ibuffer-delete-alist
592 group ibuffer-filter-groups) 590 group ibuffer-filter-groups)
593 ibuffer-filtering-qualifiers data)) 591 ibuffer-filtering-qualifiers data))
594 (ibuffer-update nil t)) 592 (ibuffer-update nil t))
618 (nreverse result)))) 616 (nreverse result))))
619 617
620 ;;;###autoload 618 ;;;###autoload
621 (defun ibuffer-jump-to-filter-group (name) 619 (defun ibuffer-jump-to-filter-group (name)
622 "Move point to the filter group whose name is NAME." 620 "Move point to the filter group whose name is NAME."
623 (interactive (list (ibuffer-read-filter-group-name "Jump to filter group: "))) 621 (interactive
622 (list (ibuffer-read-filter-group-name "Jump to filter group: ")))
624 (ibuffer-aif (assoc name (ibuffer-current-filter-groups-with-position)) 623 (ibuffer-aif (assoc name (ibuffer-current-filter-groups-with-position))
625 (goto-char (cdr it)) 624 (goto-char (cdr it))
626 (error "No filter group with name %s" name))) 625 (error "No filter group with name %s" name)))
627 626
628 ;;;###autoload 627 ;;;###autoload
641 (delete name ibuffer-hidden-filter-groups))) 640 (delete name ibuffer-hidden-filter-groups)))
642 (error "No filter group with name \"%s\"" name)) 641 (error "No filter group with name \"%s\"" name))
643 (ibuffer-update nil t)) 642 (ibuffer-update nil t))
644 643
645 ;;;###autoload 644 ;;;###autoload
646 (defun ibuffer-kill-line (&optional arg) 645 (defun ibuffer-kill-line (&optional arg interactive-p)
647 "Kill the filter group at point. 646 "Kill the filter group at point.
648 See also `ibuffer-kill-filter-group'." 647 See also `ibuffer-kill-filter-group'."
649 (interactive "P") 648 (interactive "P\np")
650 (ibuffer-aif (save-excursion 649 (ibuffer-aif (save-excursion
651 (ibuffer-forward-line 0) 650 (ibuffer-forward-line 0)
652 (get-text-property (point) 'ibuffer-filter-group-name)) 651 (get-text-property (point) 'ibuffer-filter-group-name))
653 (progn 652 (progn
654 (ibuffer-kill-filter-group it)) 653 (ibuffer-kill-filter-group it))
655 (funcall (if (interactive-p) #'call-interactively #'funcall) 654 (funcall (if interactive-p #'call-interactively #'funcall)
656 #'kill-line arg))) 655 #'kill-line arg)))
657 656
658 (defun ibuffer-insert-filter-group-before (newgroup group) 657 (defun ibuffer-insert-filter-group-before (newgroup group)
659 (let* ((found nil) 658 (let* ((found nil)
660 (pos (let ((groups (mapcar #'car ibuffer-filter-groups)) 659 (pos (let ((groups (mapcar #'car ibuffer-filter-groups))
665 groups nil) 664 groups nil)
666 (incf res) 665 (incf res)
667 (setq groups (cdr groups)))) 666 (setq groups (cdr groups))))
668 res))) 667 res)))
669 (cond ((not found) 668 (cond ((not found)
670 (setq ibuffer-filter-groups (nconc ibuffer-filter-groups (list newgroup)))) 669 (setq ibuffer-filter-groups
670 (nconc ibuffer-filter-groups (list newgroup))))
671 ((zerop pos) 671 ((zerop pos)
672 (push newgroup ibuffer-filter-groups)) 672 (push newgroup ibuffer-filter-groups))
673 (t 673 (t
674 (let ((cell (nthcdr pos ibuffer-filter-groups))) 674 (let ((cell (nthcdr pos ibuffer-filter-groups)))
675 (setf (cdr cell) (cons (car cell) (cdr cell))) 675 (setf (cdr cell) (cons (car cell) (cdr cell)))
748 ;;;###autoload 748 ;;;###autoload
749 (defun ibuffer-filter-disable () 749 (defun ibuffer-filter-disable ()
750 "Disable all filters currently in effect in this buffer." 750 "Disable all filters currently in effect in this buffer."
751 (interactive) 751 (interactive)
752 (setq ibuffer-filtering-qualifiers nil) 752 (setq ibuffer-filtering-qualifiers nil)
753 (ibuffer-update nil t)) 753 (let ((buf (ibuffer-current-buffer)))
754 (ibuffer-update nil t)
755 (when buf
756 (ibuffer-jump-to-buffer (buffer-name buf)))))
754 757
755 ;;;###autoload 758 ;;;###autoload
756 (defun ibuffer-pop-filter () 759 (defun ibuffer-pop-filter ()
757 "Remove the top filter in this buffer." 760 "Remove the top filter in this buffer."
758 (interactive) 761 (interactive)
759 (when (null ibuffer-filtering-qualifiers) 762 (when (null ibuffer-filtering-qualifiers)
760 (error "No filters in effect")) 763 (error "No filters in effect"))
761 (pop ibuffer-filtering-qualifiers) 764 (pop ibuffer-filtering-qualifiers)
762 (ibuffer-update nil t)) 765 (let ((buf (ibuffer-current-buffer)))
766 (ibuffer-update nil t)
767 (when buf
768 (ibuffer-jump-to-buffer (buffer-name buf)))))
763 769
764 (defun ibuffer-push-filter (qualifier) 770 (defun ibuffer-push-filter (qualifier)
765 "Add QUALIFIER to `ibuffer-filtering-qualifiers'." 771 "Add QUALIFIER to `ibuffer-filtering-qualifiers'."
766 (push qualifier ibuffer-filtering-qualifiers)) 772 (push qualifier ibuffer-filtering-qualifiers))
767 773
834 (progn 840 (progn
835 (when (or (null ibuffer-filtering-qualifiers) 841 (when (or (null ibuffer-filtering-qualifiers)
836 (not (eq 'or (caar ibuffer-filtering-qualifiers)))) 842 (not (eq 'or (caar ibuffer-filtering-qualifiers))))
837 (error "Top filter is not an OR")) 843 (error "Top filter is not an OR"))
838 (let ((lim (pop ibuffer-filtering-qualifiers))) 844 (let ((lim (pop ibuffer-filtering-qualifiers)))
839 (setq ibuffer-filtering-qualifiers (nconc (cdr lim) ibuffer-filtering-qualifiers)))) 845 (setq ibuffer-filtering-qualifiers
846 (nconc (cdr lim) ibuffer-filtering-qualifiers))))
840 (when (< (length ibuffer-filtering-qualifiers) 2) 847 (when (< (length ibuffer-filtering-qualifiers) 2)
841 (error "Need two filters to OR")) 848 (error "Need two filters to OR"))
842 ;; If the second filter is an OR, just add to it. 849 ;; If the second filter is an OR, just add to it.
843 (let ((first (pop ibuffer-filtering-qualifiers)) 850 (let ((first (pop ibuffer-filtering-qualifiers))
844 (second (pop ibuffer-filtering-qualifiers))) 851 (second (pop ibuffer-filtering-qualifiers)))
845 (if (eq 'or (car second)) 852 (if (eq 'or (car second))
846 (push (nconc (list 'or first) (cdr second)) ibuffer-filtering-qualifiers) 853 (push (nconc (list 'or first) (cdr second))
854 ibuffer-filtering-qualifiers)
847 (push (list 'or first second) 855 (push (list 'or first second)
848 ibuffer-filtering-qualifiers)))) 856 ibuffer-filtering-qualifiers))))
849 (ibuffer-update nil t)) 857 (ibuffer-update nil t))
850 858
851 (defun ibuffer-maybe-save-stuff () 859 (defun ibuffer-maybe-save-stuff ()
915 (ibuffer-update nil t)) 923 (ibuffer-update nil t))
916 924
917 (defun ibuffer-format-filter-group-data (filter) 925 (defun ibuffer-format-filter-group-data (filter)
918 (if (equal filter "Default") 926 (if (equal filter "Default")
919 "" 927 ""
920 (concat "Filter: " (mapconcat #'ibuffer-format-qualifier 928 (concat "Filter:" (mapconcat #'ibuffer-format-qualifier
921 (cdr (assq filter ibuffer-filter-groups)) 929 (cdr (assq filter ibuffer-filter-groups))
922 " ") "\n"))) 930 " "))))
923 931
924 (defun ibuffer-format-qualifier (qualifier) 932 (defun ibuffer-format-qualifier (qualifier)
925 (if (eq (car-safe qualifier) 'not) 933 (if (eq (car-safe qualifier) 'not)
926 (concat " [NOT" (ibuffer-format-qualifier-1 (cdr qualifier)) "]") 934 (concat " [NOT" (ibuffer-format-qualifier-1 (cdr qualifier)) "]")
927 (ibuffer-format-qualifier-1 qualifier))) 935 (ibuffer-format-qualifier-1 qualifier)))
959 modes)) 967 modes))
960 968
961 969
962 ;;; Extra operation definitions 970 ;;; Extra operation definitions
963 971
964 ;;;###autoload (autoload 'ibuffer-filter-by-mode "ibuf-ext.el") 972 ;;;###autoload (autoload 'ibuffer-filter-by-mode "ibuf-ext")
965 (define-ibuffer-filter mode 973 (define-ibuffer-filter mode
966 "Toggle current view to buffers with major mode QUALIFIER." 974 "Toggle current view to buffers with major mode QUALIFIER."
967 (:description "major mode" 975 (:description "major mode"
968 :reader 976 :reader
969 (intern 977 (intern
977 (with-current-buffer buf 985 (with-current-buffer buf
978 (symbol-name major-mode)) 986 (symbol-name major-mode))
979 ""))))) 987 "")))))
980 (eq qualifier (with-current-buffer buf major-mode))) 988 (eq qualifier (with-current-buffer buf major-mode)))
981 989
982 ;;;###autoload (autoload 'ibuffer-filter-by-used-mode "ibuf-ext.el") 990 ;;;###autoload (autoload 'ibuffer-filter-by-used-mode "ibuf-ext")
983 (define-ibuffer-filter used-mode 991 (define-ibuffer-filter used-mode
984 "Toggle current view to buffers with major mode QUALIFIER. 992 "Toggle current view to buffers with major mode QUALIFIER.
985 Called interactively, this function allows selection of modes 993 Called interactively, this function allows selection of modes
986 currently used by buffers." 994 currently used by buffers."
987 (:description "major mode in use" 995 (:description "major mode in use"
996 (with-current-buffer buf 1004 (with-current-buffer buf
997 (symbol-name major-mode)) 1005 (symbol-name major-mode))
998 ""))))) 1006 "")))))
999 (eq qualifier (with-current-buffer buf major-mode))) 1007 (eq qualifier (with-current-buffer buf major-mode)))
1000 1008
1001 ;;;###autoload (autoload 'ibuffer-filter-by-name "ibuf-ext.el") 1009 ;;;###autoload (autoload 'ibuffer-filter-by-name "ibuf-ext")
1002 (define-ibuffer-filter name 1010 (define-ibuffer-filter name
1003 "Toggle current view to buffers with name matching QUALIFIER." 1011 "Toggle current view to buffers with name matching QUALIFIER."
1004 (:description "buffer name" 1012 (:description "buffer name"
1005 :reader (read-from-minibuffer "Filter by name (regexp): ")) 1013 :reader (read-from-minibuffer "Filter by name (regexp): "))
1006 (string-match qualifier (buffer-name buf))) 1014 (string-match qualifier (buffer-name buf)))
1007 1015
1008 ;;;###autoload (autoload 'ibuffer-filter-by-filename "ibuf-ext.el") 1016 ;;;###autoload (autoload 'ibuffer-filter-by-filename "ibuf-ext")
1009 (define-ibuffer-filter filename 1017 (define-ibuffer-filter filename
1010 "Toggle current view to buffers with filename matching QUALIFIER." 1018 "Toggle current view to buffers with filename matching QUALIFIER."
1011 (:description "filename" 1019 (:description "filename"
1012 :reader (read-from-minibuffer "Filter by filename (regexp): ")) 1020 :reader (read-from-minibuffer "Filter by filename (regexp): "))
1013 (ibuffer-awhen (buffer-file-name buf) 1021 (ibuffer-awhen (with-current-buffer buf
1022 (or buffer-file-name
1023 (and (boundp 'dired-directory)
1024 (let ((dired-dir
1025 (if (stringp dired-directory)
1026 dired-directory
1027 (car dired-directory))))
1028 (and dired-dir
1029 (expand-file-name dired-dir))))))
1014 (string-match qualifier it))) 1030 (string-match qualifier it)))
1015 1031
1016 ;;;###autoload (autoload 'ibuffer-filter-by-size-gt "ibuf-ext.el") 1032 ;;;###autoload (autoload 'ibuffer-filter-by-size-gt "ibuf-ext")
1017 (define-ibuffer-filter size-gt 1033 (define-ibuffer-filter size-gt
1018 "Toggle current view to buffers with size greater than QUALIFIER." 1034 "Toggle current view to buffers with size greater than QUALIFIER."
1019 (:description "size greater than" 1035 (:description "size greater than"
1020 :reader 1036 :reader
1021 (string-to-number (read-from-minibuffer "Filter by size greater than: "))) 1037 (string-to-number (read-from-minibuffer "Filter by size greater than: ")))
1022 (> (with-current-buffer buf (buffer-size)) 1038 (> (with-current-buffer buf (buffer-size))
1023 qualifier)) 1039 qualifier))
1024 1040
1025 ;;;###autoload (autoload 'ibuffer-filter-by-size-lt "ibuf-ext.el") 1041 ;;;###autoload (autoload 'ibuffer-filter-by-size-lt "ibuf-ext")
1026 (define-ibuffer-filter size-lt 1042 (define-ibuffer-filter size-lt
1027 "Toggle current view to buffers with size less than QUALIFIER." 1043 "Toggle current view to buffers with size less than QUALIFIER."
1028 (:description "size less than" 1044 (:description "size less than"
1029 :reader 1045 :reader
1030 (string-to-number (read-from-minibuffer "Filter by size less than: "))) 1046 (string-to-number (read-from-minibuffer "Filter by size less than: ")))
1031 (< (with-current-buffer buf (buffer-size)) 1047 (< (with-current-buffer buf (buffer-size))
1032 qualifier)) 1048 qualifier))
1033 1049
1034 ;;;###autoload (autoload 'ibuffer-filter-by-content "ibuf-ext.el") 1050 ;;;###autoload (autoload 'ibuffer-filter-by-content "ibuf-ext")
1035 (define-ibuffer-filter content 1051 (define-ibuffer-filter content
1036 "Toggle current view to buffers whose contents match QUALIFIER." 1052 "Toggle current view to buffers whose contents match QUALIFIER."
1037 (:description "content" 1053 (:description "content"
1038 :reader (read-from-minibuffer "Filter by content (regexp): ")) 1054 :reader (read-from-minibuffer "Filter by content (regexp): "))
1039 (with-current-buffer buf 1055 (with-current-buffer buf
1040 (save-excursion 1056 (save-excursion
1041 (goto-char (point-min)) 1057 (goto-char (point-min))
1042 (re-search-forward qualifier nil t)))) 1058 (re-search-forward qualifier nil t))))
1043 1059
1044 ;;;###autoload (autoload 'ibuffer-filter-by-predicate "ibuf-ext.el") 1060 ;;;###autoload (autoload 'ibuffer-filter-by-predicate "ibuf-ext")
1045 (define-ibuffer-filter predicate 1061 (define-ibuffer-filter predicate
1046 "Toggle current view to buffers for which QUALIFIER returns non-nil." 1062 "Toggle current view to buffers for which QUALIFIER returns non-nil."
1047 (:description "predicate" 1063 (:description "predicate"
1048 :reader (read-minibuffer "Filter by predicate (form): ")) 1064 :reader (read-minibuffer "Filter by predicate (form): "))
1049 (with-current-buffer buf 1065 (with-current-buffer buf
1078 (if ibuffer-sorting-reversep 1094 (if ibuffer-sorting-reversep
1079 "reversed" 1095 "reversed"
1080 "normal")) 1096 "normal"))
1081 (ibuffer-redisplay t)) 1097 (ibuffer-redisplay t))
1082 1098
1083 ;;;###autoload (autoload 'ibuffer-do-sort-by-major-mode "ibuf-ext.el") 1099 ;;;###autoload (autoload 'ibuffer-do-sort-by-major-mode "ibuf-ext")
1084 (define-ibuffer-sorter major-mode 1100 (define-ibuffer-sorter major-mode
1085 "Sort the buffers by major modes. 1101 "Sort the buffers by major modes.
1086 Ordering is lexicographic." 1102 Ordering is lexicographic."
1087 (:description "major mode") 1103 (:description "major mode")
1088 (string-lessp (downcase 1104 (string-lessp (downcase
1092 (downcase 1108 (downcase
1093 (symbol-name (with-current-buffer 1109 (symbol-name (with-current-buffer
1094 (car b) 1110 (car b)
1095 major-mode))))) 1111 major-mode)))))
1096 1112
1097 ;;;###autoload (autoload 'ibuffer-do-sort-by-mode-name "ibuf-ext.el") 1113 ;;;###autoload (autoload 'ibuffer-do-sort-by-mode-name "ibuf-ext")
1098 (define-ibuffer-sorter mode-name 1114 (define-ibuffer-sorter mode-name
1099 "Sort the buffers by their mode name. 1115 "Sort the buffers by their mode name.
1100 Ordering is lexicographic." 1116 Ordering is lexicographic."
1101 (:description "major mode name") 1117 (:description "major mode name")
1102 (string-lessp (downcase 1118 (string-lessp (downcase
1106 (downcase 1122 (downcase
1107 (with-current-buffer 1123 (with-current-buffer
1108 (car b) 1124 (car b)
1109 mode-name)))) 1125 mode-name))))
1110 1126
1111 ;;;###autoload (autoload 'ibuffer-do-sort-by-alphabetic "ibuf-ext.el") 1127 ;;;###autoload (autoload 'ibuffer-do-sort-by-alphabetic "ibuf-ext")
1112 (define-ibuffer-sorter alphabetic 1128 (define-ibuffer-sorter alphabetic
1113 "Sort the buffers by their names. 1129 "Sort the buffers by their names.
1114 Ordering is lexicographic." 1130 Ordering is lexicographic."
1115 (:description "buffer name") 1131 (:description "buffer name")
1116 (string-lessp 1132 (string-lessp
1117 (buffer-name (car a)) 1133 (buffer-name (car a))
1118 (buffer-name (car b)))) 1134 (buffer-name (car b))))
1119 1135
1120 ;;;###autoload (autoload 'ibuffer-do-sort-by-size "ibuf-ext.el") 1136 ;;;###autoload (autoload 'ibuffer-do-sort-by-size "ibuf-ext")
1121 (define-ibuffer-sorter size 1137 (define-ibuffer-sorter size
1122 "Sort the buffers by their size." 1138 "Sort the buffers by their size."
1123 (:description "size") 1139 (:description "size")
1124 (< (with-current-buffer (car a) 1140 (< (with-current-buffer (car a)
1125 (buffer-size)) 1141 (buffer-size))
1217 'kill)))) 1233 'kill))))
1218 (message "Killed %s lines" count)))) 1234 (message "Killed %s lines" count))))
1219 1235
1220 ;;;###autoload 1236 ;;;###autoload
1221 (defun ibuffer-jump-to-buffer (name) 1237 (defun ibuffer-jump-to-buffer (name)
1222 "Move point to the buffer whose name is NAME." 1238 "Move point to the buffer whose name is NAME.
1223 (interactive (list nil)) 1239
1224 (let ((table (mapcar #'(lambda (x) 1240 If called interactively, prompt for a buffer name and go to the
1225 (cons (buffer-name (car x)) 1241 corresponding line in the Ibuffer buffer. If said buffer is in a
1226 (caddr x))) 1242 hidden group filter, open it.
1227 (ibuffer-current-state-list t)))) 1243
1228 (when (null table) 1244 If `ibuffer-jump-offer-only-visible-buffers' is non-nil, only offer
1229 (error "No buffers!")) 1245 visible buffers in the completion list. Calling the command with
1230 (when (interactive-p) 1246 a prefix argument reverses the meaning of that variable."
1231 (setq name (completing-read "Jump to buffer: " table nil t))) 1247 (interactive (list
1232 (ibuffer-aif (assoc name table) 1248 (let ((only-visible ibuffer-jump-offer-only-visible-buffers))
1233 (goto-char (cdr it)) 1249 (when current-prefix-arg
1234 (error "No buffer with name %s" name)))) 1250 (setq only-visible (not only-visible)))
1251 (if only-visible
1252 (let ((table (mapcar #'(lambda (x)
1253 (buffer-name (car x)))
1254 (ibuffer-current-state-list))))
1255 (when (null table)
1256 (error "No buffers!"))
1257 (completing-read "Jump to buffer: "
1258 table nil t))
1259 (read-buffer "Jump to buffer: " nil t)))))
1260 (when (not (string= "" name))
1261 (let (buf-point)
1262 ;; Blindly search for our buffer: it is very likely that it is
1263 ;; not in a hidden filter group.
1264 (ibuffer-map-lines #'(lambda (buf marks)
1265 (when (string= (buffer-name buf) name)
1266 (setq buf-point (point))
1267 nil))
1268 t nil)
1269 (when (and
1270 (null buf-point)
1271 (not (null ibuffer-hidden-filter-groups)))
1272 ;; We did not find our buffer. It must be in a hidden filter
1273 ;; group, so go through all hidden filter groups to find it.
1274 (catch 'found
1275 (dolist (group ibuffer-hidden-filter-groups)
1276 (ibuffer-jump-to-filter-group group)
1277 (ibuffer-toggle-filter-group)
1278 (ibuffer-map-lines #'(lambda (buf marks)
1279 (when (string= (buffer-name buf) name)
1280 (setq buf-point (point))
1281 nil))
1282 t group)
1283 (if buf-point
1284 (throw 'found nil)
1285 (ibuffer-toggle-filter-group)))))
1286 (if (null buf-point)
1287 ;; Still not found even though we expanded all hidden filter
1288 ;; groups: that must be because it's hidden by predicate:
1289 ;; we won't bother trying to display it.
1290 (error "No buffer with name %s" name)
1291 (goto-char buf-point)))))
1235 1292
1236 ;;;###autoload 1293 ;;;###autoload
1237 (defun ibuffer-diff-with-file () 1294 (defun ibuffer-diff-with-file ()
1238 "View the differences between this buffer and its associated file. 1295 "View the differences between this buffer and its associated file.
1239 This requires the external program \"diff\" to be in your `exec-path'." 1296 This requires the external program \"diff\" to be in your `exec-path'."
1453 (push buf ibuffer-do-occur-bufs))) 1510 (push buf ibuffer-do-occur-bufs)))
1454 (occur-1 regexp nlines ibuffer-do-occur-bufs))) 1511 (occur-1 regexp nlines ibuffer-do-occur-bufs)))
1455 1512
1456 (provide 'ibuf-ext) 1513 (provide 'ibuf-ext)
1457 1514
1515 ;;; arch-tag: 9af21953-deda-4c30-b76d-f81d9128e76d
1458 ;;; ibuf-ext.el ends here 1516 ;;; ibuf-ext.el ends here