comparison lisp/ibuffer.el @ 44830:ce8cb080a127

(ibuffer-filter-group-name-face): New. (ibuffer-mode-map): Bind and add menu entries for most new functions; also, bind the arrow keys to the movement functions. (ibuffer-mode-filter-group-map): New. (ibuffer-mouse-toggle-mark): Handle group names. (ibuffer-mouse-visit-buffer): Error if the current buffer is killed. (ibuffer-skip-properties): New function. (ibuffer-backward-line, ibuffer-forward-line): Optionally skip group names. Also, handle new properties. (ibuffer-visit-buffer, ibuffer-visit-buffer-other-window): Move error handling to `ibuffer-current-buffer'. (ibuffer-visit-buffer-other-frame, ibuffer-bury-buffer): Ditto. (ibuffer-visit-tags-table, ibuffer-do-view-1): Ditto. (ibuffer-toggle-marks): Add optional group argument. (ibuffer-mark-interactive): Skip group names. (ibuffer-current-buffer): Clean up error handling. (ibuffer-fontify-region-function): Fontify group names. (ibuffer-map-lines): Add extra group argument. Handle it. (ibuffer-current-filter-groups): New function. (ibuffer-redisplay): Handle hidden filtering groups. (ibuffer-sort-bufferlist): New function, taken from `ibuffer-insert-buffers-and-marks'. (ibuffer-insert-filter-group): New function. (ibuffer-redisplay-engine): Renamed from `ibuffer-insert-buffers-and-marks'. Handle new filtering groups. (ibuffer): Add filter-groups argument. Handle it. Use `save-selected-window'. (ibuffer-mode): Make `ibuffer-filtering-groups' and `ibuffer-hidden-filtering-groups' buffer-local.
author Colin Walters <walters@gnu.org>
date Wed, 24 Apr 2002 23:27:28 +0000
parents b9d6590397ef
children 6cd35f994b33
comparison
equal deleted inserted replaced
44829:771798f69a5c 44830:ce8cb080a127
4 4
5 ;; Author: Colin Walters <walters@verbum.org> 5 ;; Author: Colin Walters <walters@verbum.org>
6 ;; Created: 8 Sep 2000 6 ;; Created: 8 Sep 2000
7 ;; Keywords: buffer, convenience 7 ;; Keywords: buffer, convenience
8 8
9 ;; This file is not currently part of GNU Emacs. 9 ;; This file is part of GNU Emacs.
10 10
11 ;; This program is free software; you can redistribute it and/or 11 ;; This program is free software; you can redistribute it and/or
12 ;; modify it under the terms of the GNU General Public License as 12 ;; modify it under the terms of the GNU General Public License as
13 ;; published by the Free Software Foundation; either version 2, or (at 13 ;; published by the Free Software Foundation; either version 2, or (at
14 ;; your option) any later version. 14 ;; your option) any later version.
310 :type 'face 310 :type 'face
311 :group 'ibuffer) 311 :group 'ibuffer)
312 312
313 (defcustom ibuffer-title-face 'font-lock-type-face 313 (defcustom ibuffer-title-face 'font-lock-type-face
314 "Face used for the title string." 314 "Face used for the title string."
315 :type 'face
316 :group 'ibuffer)
317
318 (defcustom ibuffer-filter-group-name-face 'bold
319 "Face used for displaying filtering group names."
315 :type 'face 320 :type 'face
316 :group 'ibuffer) 321 :group 'ibuffer)
317 322
318 (defcustom ibuffer-directory-abbrev-alist nil 323 (defcustom ibuffer-directory-abbrev-alist nil
319 "An alist of file name abbreviations like `directory-abbrev-alist'." 324 "An alist of file name abbreviations like `directory-abbrev-alist'."
362 (define-key map (kbd "k") 'ibuffer-mark-for-delete) 367 (define-key map (kbd "k") 'ibuffer-mark-for-delete)
363 (define-key map (kbd "x") 'ibuffer-do-kill-on-deletion-marks) 368 (define-key map (kbd "x") 'ibuffer-do-kill-on-deletion-marks)
364 369
365 ;; immediate operations 370 ;; immediate operations
366 (define-key map (kbd "n") 'ibuffer-forward-line) 371 (define-key map (kbd "n") 'ibuffer-forward-line)
372 (define-key map (kbd "<down>") 'ibuffer-forward-line)
367 (define-key map (kbd "SPC") 'forward-line) 373 (define-key map (kbd "SPC") 'forward-line)
368 (define-key map (kbd "p") 'ibuffer-backward-line) 374 (define-key map (kbd "p") 'ibuffer-backward-line)
375 (define-key map (kbd "<up>") 'ibuffer-forward-line)
369 (define-key map (kbd "M-}") 'ibuffer-forward-next-marked) 376 (define-key map (kbd "M-}") 'ibuffer-forward-next-marked)
370 (define-key map (kbd "M-{") 'ibuffer-backwards-next-marked) 377 (define-key map (kbd "M-{") 'ibuffer-backwards-next-marked)
371 (define-key map (kbd "l") 'ibuffer-redisplay) 378 (define-key map (kbd "l") 'ibuffer-redisplay)
372 (define-key map (kbd "g") 'ibuffer-update) 379 (define-key map (kbd "g") 'ibuffer-update)
373 (define-key map "`" 'ibuffer-switch-format) 380 (define-key map "`" 'ibuffer-switch-format)
396 (define-key map (kbd "/ p") 'ibuffer-pop-filter) 403 (define-key map (kbd "/ p") 'ibuffer-pop-filter)
397 (define-key map (kbd "/ !") 'ibuffer-negate-filter) 404 (define-key map (kbd "/ !") 'ibuffer-negate-filter)
398 (define-key map (kbd "/ t") 'ibuffer-exchange-filters) 405 (define-key map (kbd "/ t") 'ibuffer-exchange-filters)
399 (define-key map (kbd "/ TAB") 'ibuffer-exchange-filters) 406 (define-key map (kbd "/ TAB") 'ibuffer-exchange-filters)
400 (define-key map (kbd "/ o") 'ibuffer-or-filter) 407 (define-key map (kbd "/ o") 'ibuffer-or-filter)
408 (define-key map (kbd "/ g") 'ibuffer-filters-to-filter-group)
409 (define-key map (kbd "/ P") 'ibuffer-pop-filter-group)
401 (define-key map (kbd "/ /") 'ibuffer-filter-disable) 410 (define-key map (kbd "/ /") 'ibuffer-filter-disable)
411
412 (define-key map (kbd "M-n") 'ibuffer-forward-filter-group)
413 (define-key map (kbd "<right>") 'ibuffer-forward-filter-group)
414 (define-key map (kbd "M-p") 'ibuffer-backward-filter-group)
415 (define-key map (kbd "<left>") 'ibuffer-backward-filter-group)
416 (define-key map (kbd "M-j") 'ibuffer-jump-to-filter-group)
402 417
403 (define-key map (kbd "q") 'ibuffer-quit) 418 (define-key map (kbd "q") 'ibuffer-quit)
404 (define-key map (kbd "h") 'describe-mode) 419 (define-key map (kbd "h") 'describe-mode)
405 (define-key map (kbd "?") 'describe-mode) 420 (define-key map (kbd "?") 'describe-mode)
406 421
537 '(menu-item "Add to permanently saved filters..." ibuffer-add-saved-filters 552 '(menu-item "Add to permanently saved filters..." ibuffer-add-saved-filters
538 :help "Include current filters in an already saved stack")) 553 :help "Include current filters in an already saved stack"))
539 (define-key-after map [menu-bar view filter delete-saved-filters] 554 (define-key-after map [menu-bar view filter delete-saved-filters]
540 '(menu-item "Delete permanently saved filters..." ibuffer-delete-saved-filters 555 '(menu-item "Delete permanently saved filters..." ibuffer-delete-saved-filters
541 :help "Remove stack of filters from saved list")) 556 :help "Remove stack of filters from saved list"))
557 (define-key-after map [menu-bar view filter-groups]
558 (cons "Filter Groups" (make-sparse-keymap "Filter Groups")))
559 (define-key-after map [menu-bar view filter-groups filters-to-filter-group]
560 '(menu-item "Make current filters into filter group"
561 ibuffer-filters-to-filter-group))
562 (define-key-after map [menu-bar view filter-groups pop-filter-group]
563 '(menu-item "Remove top filter group"
564 ibuffer-pop-filter-group))
565 (define-key-after map [menu-bar view filter-groups filters-to-filter-group]
566 '(menu-item "Create filter group from current filters"
567 ibuffer-filters-to-filter-group))
568
542 (define-key-after map [menu-bar view dashes2] 569 (define-key-after map [menu-bar view dashes2]
543 '("--")) 570 '("--"))
544 (define-key-after map [menu-bar view diff-with-file] 571 (define-key-after map [menu-bar view diff-with-file]
545 '(menu-item "Diff with file" ibuffer-diff-with-file 572 '(menu-item "Diff with file" ibuffer-diff-with-file
546 :help "View the differences between this buffer and its file")) 573 :help "View the differences between this buffer and its file"))
673 (set-keymap-parent map ibuffer-mode-map) 700 (set-keymap-parent map ibuffer-mode-map)
674 (define-key map [(mouse-2)] 'ibuffer-mouse-filter-by-mode) 701 (define-key map [(mouse-2)] 'ibuffer-mouse-filter-by-mode)
675 (define-key map (kbd "RET") 'ibuffer-interactive-filter-by-mode) 702 (define-key map (kbd "RET") 'ibuffer-interactive-filter-by-mode)
676 (setq ibuffer-mode-name-map map))) 703 (setq ibuffer-mode-name-map map)))
677 704
705 (defvar ibuffer-mode-filter-group-map nil)
706 (unless ibuffer-mode-filter-group-map
707 (let ((map (make-sparse-keymap)))
708 (set-keymap-parent map ibuffer-mode-map)
709 (define-key map [(mouse-1)] 'ibuffer-mouse-toggle-mark)
710 (define-key map [(mouse-2)] 'ibuffer-mouse-toggle-filter-group)
711 (define-key map (kbd "RET") 'ibuffer-toggle-filter-group)
712 (setq ibuffer-mode-filter-group-map map)))
713
678 ;; quiet the byte-compiler 714 ;; quiet the byte-compiler
679 (defvar ibuffer-mode-operate-menu nil) 715 (defvar ibuffer-mode-operate-menu nil)
680 (defvar ibuffer-mode-mark-menu nil) 716 (defvar ibuffer-mode-mark-menu nil)
681 (defvar ibuffer-mode-view-menu nil) 717 (defvar ibuffer-mode-view-menu nil)
682 718
727 763
728 (defun ibuffer-mouse-toggle-mark (event) 764 (defun ibuffer-mouse-toggle-mark (event)
729 "Toggle the marked status of the buffer chosen with the mouse." 765 "Toggle the marked status of the buffer chosen with the mouse."
730 (interactive "e") 766 (interactive "e")
731 (unwind-protect 767 (unwind-protect
732 (save-excursion 768 (let ((pt (save-excursion
733 (mouse-set-point event) 769 (mouse-set-point event)
734 (let ((mark (ibuffer-current-mark))) 770 (point))))
735 (setq buffer-read-only nil) 771 (ibuffer-aif (get-text-property (point) 'ibuffer-filter-group-name)
736 (if (eq mark ibuffer-marked-char) 772 (ibuffer-toggle-marks it)
737 (ibuffer-set-mark ? ) 773 (goto-char pt)
738 (ibuffer-set-mark ibuffer-marked-char)))) 774 (let ((mark (ibuffer-current-mark)))
775 (setq buffer-read-only nil)
776 (if (eq mark ibuffer-marked-char)
777 (ibuffer-set-mark ? )
778 (ibuffer-set-mark ibuffer-marked-char)))))
739 (setq buffer-read-only t))) 779 (setq buffer-read-only t)))
740 780
741 (defun ibuffer-find-file (file &optional wildcards) 781 (defun ibuffer-find-file (file &optional wildcards)
742 "Like `find-file', but default to the directory of the buffer at point." 782 "Like `find-file', but default to the directory of the buffer at point."
743 (interactive 783 (interactive
754 "Visit the buffer chosen with the mouse." 794 "Visit the buffer chosen with the mouse."
755 (interactive "e") 795 (interactive "e")
756 (switch-to-buffer 796 (switch-to-buffer
757 (save-excursion 797 (save-excursion
758 (mouse-set-point event) 798 (mouse-set-point event)
759 (ibuffer-current-buffer)))) 799 (ibuffer-current-buffer t))))
760 800
761 (defun ibuffer-mouse-popup-menu (event) 801 (defun ibuffer-mouse-popup-menu (event)
762 "Display a menu of operations." 802 "Display a menu of operations."
763 (interactive "e") 803 (interactive "e")
764 (let ((origline (count-lines (point-min) (point)))) 804 (let ((origline (count-lines (point-min) (point))))
775 (save-excursion 815 (save-excursion
776 (popup-menu ibuffer-mode-operate-map)))) 816 (popup-menu ibuffer-mode-operate-map))))
777 (progn 817 (progn
778 (setq buffer-read-only t) 818 (setq buffer-read-only t)
779 (goto-line (1+ origline)))))) 819 (goto-line (1+ origline))))))
780 820
781 (defun ibuffer-backward-line (&optional arg) 821 (defun ibuffer-skip-properties (props direction)
822 (while (and (not (eobp))
823 (let ((hit nil))
824 (dolist (prop props hit)
825 (when (get-text-property (point) prop)
826 (setq hit t)))))
827 (forward-line direction)
828 (beginning-of-line)))
829
830 (defun ibuffer-backward-line (&optional arg skip-group-names)
782 "Move backwards ARG lines, wrapping around the list if necessary." 831 "Move backwards ARG lines, wrapping around the list if necessary."
783 (interactive "P") 832 (interactive "P")
784 (unless arg 833 (unless arg
785 (setq arg 1)) 834 (setq arg 1))
786 (beginning-of-line) 835 (beginning-of-line)
787 (while (> arg 0) 836 (while (> arg 0)
788 (forward-line -1) 837 (forward-line -1)
789 (when (get-text-property (point) 'ibuffer-title) 838 (when (or (get-text-property (point) 'ibuffer-title)
839 (and skip-group-names
840 (get-text-property (point) 'ibuffer-filter-group-name)))
790 (goto-char (point-max)) 841 (goto-char (point-max))
791 (beginning-of-line)) 842 (beginning-of-line))
792 (while (get-text-property (point) 'ibuffer-summary) 843 (ibuffer-skip-properties (append '(ibuffer-summary)
793 (forward-line -1) 844 (when skip-group-names
794 (beginning-of-line)) 845 '(ibuffer-filter-group-name)))
846 -1)
795 ;; Handle the special case of no buffers. 847 ;; Handle the special case of no buffers.
796 (when (get-text-property (point) 'ibuffer-title) 848 (when (get-text-property (point) 'ibuffer-title)
797 (forward-line 1) 849 (forward-line 1)
798 (setq arg 1)) 850 (setq arg 1))
799 (decf arg))) 851 (decf arg)))
800 852
801 (defun ibuffer-forward-line (&optional arg) 853 (defun ibuffer-forward-line (&optional arg skip-group-names)
802 "Move forward ARG lines, wrapping around the list if necessary." 854 "Move forward ARG lines, wrapping around the list if necessary."
803 (interactive "P") 855 (interactive "P")
804 (unless arg 856 (unless arg
805 (setq arg 1)) 857 (setq arg 1))
806 (beginning-of-line) 858 (beginning-of-line)
807 (when (or (eobp) 859 (when (or (eobp)
808 (get-text-property (point) 'ibuffer-summary)) 860 (get-text-property (point) 'ibuffer-summary))
809 (goto-char (point-min))) 861 (goto-char (point-min)))
810 (when (get-text-property (point) 'ibuffer-title) 862 (when (or (get-text-property (point) 'ibuffer-title)
811 (if (> arg 0) 863 (and skip-group-names
812 (decf arg)) 864 (get-text-property (point) 'ibuffer-filter-group-name)))
813 (while (get-text-property (point) 'ibuffer-title) 865 (when (> arg 0)
814 (forward-line 1))) 866 (decf arg))
867 (ibuffer-skip-properties (append '(ibuffer-title)
868 (when skip-group-names
869 '(ibuffer-filter-group-name)))
870 1))
815 (if (< arg 0) 871 (if (< arg 0)
816 (ibuffer-backward-line (- arg)) 872 (ibuffer-backward-line (- arg))
817 (while (> arg 0) 873 (while (> arg 0)
818 (forward-line 1) 874 (forward-line 1)
819 (when (or (eobp) 875 (when (or (eobp)
820 (get-text-property (point) 'ibuffer-summary)) 876 (get-text-property (point) 'ibuffer-summary))
821 (goto-char (point-min))) 877 (goto-char (point-min)))
822 (while (get-text-property (point) 'ibuffer-title) 878 (decf arg)
823 (forward-line 1)) 879 (ibuffer-skip-properties (append '(ibuffer-title)
824 (decf arg)))) 880 (when skip-group-names
881 '(ibuffer-filter-group-name)))
882 1))))
825 883
826 (defun ibuffer-visit-buffer (&optional single) 884 (defun ibuffer-visit-buffer (&optional single)
827 "Visit the buffer on this line. 885 "Visit the buffer on this line.
828 886
829 If optional argument SINGLE is non-nil, then also ensure there is only 887 If optional argument SINGLE is non-nil, then also ensure there is only
830 one window." 888 one window."
831 (interactive "P") 889 (interactive "P")
832 (let ((buf (ibuffer-current-buffer))) 890 (let ((buf (ibuffer-current-buffer t)))
833 (if (bufferp buf)
834 (unless (buffer-live-p buf)
835 (error "Buffer %s has been killed!" buf))
836 (error "No buffer on this line"))
837 (bury-buffer (current-buffer)) 891 (bury-buffer (current-buffer))
838 (switch-to-buffer buf) 892 (switch-to-buffer buf)
839 (when single 893 (when single
840 (delete-other-windows)))) 894 (delete-other-windows))))
841 895
842 (defun ibuffer-visit-buffer-other-window (&optional noselect) 896 (defun ibuffer-visit-buffer-other-window (&optional noselect)
843 "Visit the buffer on this line in another window." 897 "Visit the buffer on this line in another window."
844 (interactive) 898 (interactive)
845 (let ((buf (ibuffer-current-buffer))) 899 (let ((buf (ibuffer-current-buffer t)))
846 (unless (buffer-live-p buf)
847 (error "Buffer %s has been killed!" buf))
848 (bury-buffer (current-buffer)) 900 (bury-buffer (current-buffer))
849 (if noselect 901 (if noselect
850 (let ((curwin (selected-window))) 902 (let ((curwin (selected-window)))
851 (pop-to-buffer buf) 903 (pop-to-buffer buf)
852 (select-window curwin)) 904 (select-window curwin))
858 (ibuffer-visit-buffer-other-window t)) 910 (ibuffer-visit-buffer-other-window t))
859 911
860 (defun ibuffer-visit-buffer-other-frame () 912 (defun ibuffer-visit-buffer-other-frame ()
861 "Visit the buffer on this line in another frame." 913 "Visit the buffer on this line in another frame."
862 (interactive) 914 (interactive)
863 (let ((buf (ibuffer-current-buffer))) 915 (let ((buf (ibuffer-current-buffer t)))
864 (unless (buffer-live-p buf)
865 (error "Buffer %s has been killed!" buf))
866 (bury-buffer (current-buffer)) 916 (bury-buffer (current-buffer))
867 (switch-to-buffer-other-frame buf))) 917 (switch-to-buffer-other-frame buf)))
868 918
869 (defun ibuffer-visit-buffer-1-window () 919 (defun ibuffer-visit-buffer-1-window ()
870 "Visit the buffer on this line, and delete other windows." 920 "Visit the buffer on this line, and delete other windows."
872 (ibuffer-visit-buffer t)) 922 (ibuffer-visit-buffer t))
873 923
874 (defun ibuffer-bury-buffer () 924 (defun ibuffer-bury-buffer ()
875 "Bury the buffer on this line." 925 "Bury the buffer on this line."
876 (interactive) 926 (interactive)
877 (let ((buf (ibuffer-current-buffer)) 927 (let ((buf (ibuffer-current-buffer t))
878 (line (+ 1 (count-lines 1 (point))))) 928 (line (+ 1 (count-lines 1 (point)))))
879 (unless (buffer-live-p buf)
880 (error "Buffer %s has been killed!" buf))
881 (bury-buffer buf) 929 (bury-buffer buf)
882 (ibuffer-update nil t) 930 (ibuffer-update nil t)
883 (goto-line line))) 931 (goto-line line)))
884 932
885 (defun ibuffer-visit-tags-table () 933 (defun ibuffer-visit-tags-table ()
886 "Visit the tags table in the buffer on this line. See `visit-tags-table'." 934 "Visit the tags table in the buffer on this line. See `visit-tags-table'."
887 (interactive) 935 (interactive)
888 (let ((file (buffer-file-name (ibuffer-current-buffer)))) 936 (let ((file (buffer-file-name (ibuffer-current-buffer t))))
889 (if file 937 (if file
890 (visit-tags-table file) 938 (visit-tags-table file)
891 (error "Specified buffer has no file")))) 939 (error "Specified buffer has no file"))))
892 940
893 (defun ibuffer-do-view (&optional other-frame) 941 (defun ibuffer-do-view (&optional other-frame)
904 (ibuffer-do-view-1 (if other-frame 'other-frame 'horizontally))) 952 (ibuffer-do-view-1 (if other-frame 'other-frame 'horizontally)))
905 953
906 (defun ibuffer-do-view-1 (type) 954 (defun ibuffer-do-view-1 (type)
907 (let ((marked-bufs (ibuffer-get-marked-buffers))) 955 (let ((marked-bufs (ibuffer-get-marked-buffers)))
908 (when (null marked-bufs) 956 (when (null marked-bufs)
909 (setq marked-bufs (list (ibuffer-current-buffer)))) 957 (setq marked-bufs (list (ibuffer-current-buffer t))))
910 (unless (and (eq type 'other-frame) 958 (unless (and (eq type 'other-frame)
911 (not ibuffer-expert) 959 (not ibuffer-expert)
912 (> (length marked-bufs) 3) 960 (> (length marked-bufs) 3)
913 (not (y-or-n-p (format "Really create a new frame for %s buffers? " 961 (not (y-or-n-p (format "Really create a new frame for %s buffers? "
914 (length marked-bufs))))) 962 (length marked-bufs)))))
1096 (when (not (char-equal mark ? )) 1144 (when (not (char-equal mark ? ))
1097 (ibuffer-set-mark-1 ? )) 1145 (ibuffer-set-mark-1 ? ))
1098 t))))) 1146 t)))))
1099 (ibuffer-redisplay t)) 1147 (ibuffer-redisplay t))
1100 1148
1101 (defun ibuffer-toggle-marks () 1149 (defun ibuffer-toggle-marks (&optional group)
1102 "Toggle which buffers are marked. 1150 "Toggle which buffers are marked.
1103 In other words, unmarked buffers become marked, and marked buffers 1151 In other words, unmarked buffers become marked, and marked buffers
1104 become unmarked." 1152 become unmarked."
1105 (interactive) 1153 (interactive)
1106 (let ((count 1154 (let ((count
1111 nil) 1159 nil)
1112 ((eq mark ? ) 1160 ((eq mark ? )
1113 (ibuffer-set-mark-1 ibuffer-marked-char) 1161 (ibuffer-set-mark-1 ibuffer-marked-char)
1114 t) 1162 t)
1115 (t 1163 (t
1116 nil)))))) 1164 nil)))
1165 nil group)))
1117 (message "%s buffers marked" count)) 1166 (message "%s buffers marked" count))
1118 (ibuffer-redisplay t)) 1167 (ibuffer-redisplay t))
1119 1168
1120 (defun ibuffer-mark-forward (arg) 1169 (defun ibuffer-mark-forward (arg)
1121 "Mark the buffer on this line, and move forward ARG lines." 1170 "Mark the buffer on this line, and move forward ARG lines."
1134 1183
1135 (defun ibuffer-mark-interactive (arg mark movement) 1184 (defun ibuffer-mark-interactive (arg mark movement)
1136 (assert (eq major-mode 'ibuffer-mode)) 1185 (assert (eq major-mode 'ibuffer-mode))
1137 (unless arg 1186 (unless arg
1138 (setq arg 1)) 1187 (setq arg 1))
1139 (ibuffer-forward-line 0) 1188 (ibuffer-forward-line 0 t)
1140 (let ((inhibit-read-only t)) 1189 (let ((inhibit-read-only t))
1141 (while (> arg 0) 1190 (while (> arg 0)
1142 (ibuffer-set-mark mark) 1191 (ibuffer-set-mark mark)
1143 (ibuffer-forward-line movement) 1192 (ibuffer-forward-line movement t)
1144 (setq arg (1- arg))))) 1193 (setq arg (1- arg)))))
1145 1194
1146 (defun ibuffer-set-mark (mark) 1195 (defun ibuffer-set-mark (mark)
1147 (assert (eq major-mode 'ibuffer-mode)) 1196 (assert (eq major-mode 'ibuffer-mode))
1148 (let ((inhibit-read-only t)) 1197 (let ((inhibit-read-only t))
1169 (ibuffer-mark-interactive arg ibuffer-deletion-char -1)) 1218 (ibuffer-mark-interactive arg ibuffer-deletion-char -1))
1170 1219
1171 (defun ibuffer-current-buffer (&optional must-be-live) 1220 (defun ibuffer-current-buffer (&optional must-be-live)
1172 (let ((buf (car (get-text-property (line-beginning-position) 1221 (let ((buf (car (get-text-property (line-beginning-position)
1173 'ibuffer-properties)))) 1222 'ibuffer-properties))))
1174 (when (and must-be-live 1223 (when must-be-live
1175 (not (buffer-live-p buf))) 1224 (if (bufferp buf)
1176 (error "Buffer %s has been killed!" buf)) 1225 (unless (buffer-live-p buf)
1226 (error (substitute-command-keys "Buffer %s has been killed; use `\\[ibuffer-update]' to update") buf))
1227 (error "No buffer on this line")))
1177 buf)) 1228 buf))
1178 1229
1179 (defun ibuffer-active-formats-name () 1230 (defun ibuffer-active-formats-name ()
1180 (if (boundp 'ibuffer-filter-format-alist) 1231 (if (boundp 'ibuffer-filter-format-alist)
1181 (let ((ret nil)) 1232 (let ((ret nil))
1431 (put (car form) 'ibuffer-column-summary nil)))) 1482 (put (car form) 'ibuffer-column-summary nil))))
1432 1483
1433 (defun ibuffer-check-formats () 1484 (defun ibuffer-check-formats ()
1434 (when (null ibuffer-formats) 1485 (when (null ibuffer-formats)
1435 (error "No formats!")) 1486 (error "No formats!"))
1436 (when (or (null ibuffer-compiled-formats) 1487 (let ((ext-loaded (featurep 'ibuf-ext)))
1437 (null ibuffer-cached-formats) 1488 (when (or (null ibuffer-compiled-formats)
1438 (not (eq ibuffer-cached-formats ibuffer-formats)) 1489 (null ibuffer-cached-formats)
1439 (null ibuffer-cached-eliding-string) 1490 (not (eq ibuffer-cached-formats ibuffer-formats))
1440 (not (equal ibuffer-cached-eliding-string ibuffer-eliding-string)) 1491 (null ibuffer-cached-eliding-string)
1441 (eql 0 ibuffer-cached-elide-long-columns) 1492 (not (equal ibuffer-cached-eliding-string ibuffer-eliding-string))
1442 (not (eql ibuffer-cached-elide-long-columns 1493 (eql 0 ibuffer-cached-elide-long-columns)
1443 ibuffer-elide-long-columns)) 1494 (not (eql ibuffer-cached-elide-long-columns
1444 (not (eq ibuffer-cached-filter-formats 1495 ibuffer-elide-long-columns))
1445 ibuffer-filter-format-alist)) 1496 (and ext-loaded
1446 (and ibuffer-filter-format-alist 1497 (not (eq ibuffer-cached-filter-formats
1447 (null ibuffer-compiled-filter-formats))) 1498 ibuffer-filter-format-alist))
1448 (message "Formats have changed, recompiling...") 1499 (and ibuffer-filter-format-alist
1449 (ibuffer-recompile-formats) 1500 (null ibuffer-compiled-filter-formats))))
1450 (setq ibuffer-cached-formats ibuffer-formats 1501 (message "Formats have changed, recompiling...")
1451 ibuffer-cached-eliding-string ibuffer-eliding-string 1502 (ibuffer-recompile-formats)
1452 ibuffer-cached-elide-long-columns ibuffer-elide-long-columns 1503 (setq ibuffer-cached-formats ibuffer-formats
1453 ibuffer-cached-filter-formats ibuffer-filter-format-alist) 1504 ibuffer-cached-eliding-string ibuffer-eliding-string
1454 (message "Formats have changed, recompiling...done"))) 1505 ibuffer-cached-elide-long-columns ibuffer-elide-long-columns)
1506 (when ext-loaded
1507 (setq ibuffer-cached-filter-formats ibuffer-filter-format-alist))
1508 (message "Formats have changed, recompiling...done"))))
1455 1509
1456 (defvar ibuffer-inline-columns nil) 1510 (defvar ibuffer-inline-columns nil)
1457 1511
1458 (define-ibuffer-column mark (:name " " :inline t) 1512 (define-ibuffer-column mark (:name " " :inline t)
1459 (string mark)) 1513 (string mark))
1514 (goto-char beg) 1568 (goto-char beg)
1515 (beginning-of-line) 1569 (beginning-of-line)
1516 (while (< (point) end) 1570 (while (< (point) end)
1517 (if (get-text-property (point) 'ibuffer-title-header) 1571 (if (get-text-property (point) 'ibuffer-title-header)
1518 (put-text-property (point) (line-end-position) 'face ibuffer-title-face) 1572 (put-text-property (point) (line-end-position) 'face ibuffer-title-face)
1519 (unless (or (get-text-property (point) 'ibuffer-title) 1573 (if (get-text-property (point) 'ibuffer-filter-group-name)
1520 (get-text-property (point) 'ibuffer-summary)) 1574 (put-text-property (point) (line-end-position) 'face
1521 (multiple-value-bind (buf mark) 1575 ibuffer-filter-group-name-face)
1522 (get-text-property (point) 'ibuffer-properties) 1576 (unless (or (get-text-property (point) 'ibuffer-title)
1523 (let* ((namebeg (next-single-property-change (point) 'ibuffer-name-column 1577 (get-text-property (point) 'ibuffer-summary))
1524 nil (line-end-position))) 1578 (multiple-value-bind (buf mark)
1525 (nameend (next-single-property-change namebeg 'ibuffer-name-column 1579 (get-text-property (point) 'ibuffer-properties)
1526 nil (line-end-position)))) 1580 (let* ((namebeg (next-single-property-change (point) 'ibuffer-name-column
1527 (put-text-property namebeg 1581 nil (line-end-position)))
1528 nameend 1582 (nameend (next-single-property-change namebeg 'ibuffer-name-column
1529 'face 1583 nil (line-end-position))))
1530 (cond ((char-equal mark ibuffer-marked-char) 1584 (put-text-property namebeg
1531 ibuffer-marked-face) 1585 nameend
1532 ((char-equal mark ibuffer-deletion-char) 1586 'face
1533 ibuffer-deletion-face) 1587 (cond ((char-equal mark ibuffer-marked-char)
1534 (t 1588 ibuffer-marked-face)
1535 (let ((level -1) 1589 ((char-equal mark ibuffer-deletion-char)
1536 result) 1590 ibuffer-deletion-face)
1537 (dolist (e ibuffer-fontification-alist result) 1591 (t
1538 (when (and (> (car e) level) 1592 (let ((level -1)
1539 (with-current-buffer buf 1593 result)
1540 (eval (cadr e)))) 1594 (dolist (e ibuffer-fontification-alist result)
1541 (setq level (car e) 1595 (when (and (> (car e) level)
1542 result 1596 (with-current-buffer buf
1543 (if (symbolp (caddr e)) 1597 (eval (cadr e))))
1544 (if (facep (caddr e)) 1598 (setq level (car e)
1545 (caddr e) 1599 result
1546 (symbol-value (caddr e))))))))))))))) 1600 (if (symbolp (caddr e))
1601 (if (facep (caddr e))
1602 (caddr e)
1603 (symbol-value (caddr e))))))))))))))))
1547 (forward-line 1)))) 1604 (forward-line 1))))
1548 (when verbose (message "Fontifying...done"))) 1605 (when verbose (message "Fontifying...done")))
1549 1606
1550 (defun ibuffer-unfontify-region-function (beg end) 1607 (defun ibuffer-unfontify-region-function (beg end)
1551 (let ((inhibit-read-only t)) 1608 (let ((inhibit-read-only t))
1558 (funcall format buffer mark) 1615 (funcall format buffer mark)
1559 (put-text-property beg (point) 'ibuffer-properties (list buffer mark))) 1616 (put-text-property beg (point) 'ibuffer-properties (list buffer mark)))
1560 (insert "\n")) 1617 (insert "\n"))
1561 1618
1562 ;; This function knows a bit too much of the internals. It would be 1619 ;; This function knows a bit too much of the internals. It would be
1563 ;; nice if it was all abstracted away into 1620 ;; nice if it was all abstracted away.
1564 ;; `ibuffer-insert-buffers-and-marks'.
1565 (defun ibuffer-redisplay-current () 1621 (defun ibuffer-redisplay-current ()
1566 (assert (eq major-mode 'ibuffer-mode)) 1622 (assert (eq major-mode 'ibuffer-mode))
1567 (when (eobp) 1623 (when (eobp)
1568 (forward-line -1)) 1624 (forward-line -1))
1569 (beginning-of-line) 1625 (beginning-of-line)
1586 #'(lambda (buf mk) 1642 #'(lambda (buf mk)
1587 (if (char-equal mark mk) 1643 (if (char-equal mark mk)
1588 (funcall func buf mark) 1644 (funcall func buf mark)
1589 nil)))) 1645 nil))))
1590 1646
1591 (defun ibuffer-map-lines (function &optional nomodify) 1647 (defun ibuffer-map-lines (function &optional nomodify group)
1592 "Call FUNCTION for each buffer in an ibuffer. 1648 "Call FUNCTION for each buffer.
1593 Don't set the ibuffer modification flag iff NOMODIFY is non-nil. 1649 Don't set the ibuffer modification flag iff NOMODIFY is non-nil.
1650
1651 If optional argument GROUP is non-nil, then only call FUNCTION on
1652 buffers in filtering group GROUP.
1594 1653
1595 FUNCTION is called with four arguments: the buffer object itself, the 1654 FUNCTION is called with four arguments: the buffer object itself, the
1596 current mark symbol, and the beginning and ending line positions." 1655 current mark symbol, and the beginning and ending line positions."
1597 (assert (eq major-mode 'ibuffer-mode)) 1656 (assert (eq major-mode 'ibuffer-mode))
1598 (let ((orig-target-line (count-lines (point-min) 1657 (ibuffer-forward-line 0)
1599 (line-beginning-position))) 1658 (let* ((orig-target-line (1+ (count-lines (save-excursion
1600 (target-buf-count 0) 1659 (goto-char (point-min))
1601 (ibuffer-map-lines-total 0) 1660 (ibuffer-forward-line 0)
1602 (ibuffer-map-lines-count 0)) 1661 (point))
1662 (point))))
1663 (target-line-offset orig-target-line)
1664 (ibuffer-map-lines-total 0)
1665 (ibuffer-map-lines-count 0))
1603 (unwind-protect 1666 (unwind-protect
1604 (progn 1667 (progn
1605 (setq buffer-read-only nil) 1668 (setq buffer-read-only nil)
1606 (goto-char (point-min)) 1669 (goto-char (point-min))
1607 (ibuffer-forward-line 0) 1670 (ibuffer-forward-line 0 t)
1608 (setq orig-target-line (1+ (- orig-target-line
1609 (count-lines (point-min) (point))))
1610 target-buf-count orig-target-line)
1611 (while (and (not (eobp)) 1671 (while (and (not (eobp))
1612 (not (get-text-property (point) 'ibuffer-summary))) 1672 (not (get-text-property (point) 'ibuffer-summary))
1673 (progn
1674 (ibuffer-forward-line 0 t)
1675 (and (not (eobp))
1676 (not (get-text-property (point) 'ibuffer-summary)))))
1613 (let ((result 1677 (let ((result
1614 (if (buffer-live-p (ibuffer-current-buffer)) 1678 (if (buffer-live-p (ibuffer-current-buffer))
1615 (save-excursion 1679 (when (or (null group)
1616 (funcall function 1680 (ibuffer-aif (get-text-property (point) 'ibuffer-filter-group)
1617 (ibuffer-current-buffer) 1681 (equal group it)))
1618 (ibuffer-current-mark))) 1682 (save-excursion
1683 (funcall function
1684 (ibuffer-current-buffer)
1685 (ibuffer-current-mark))))
1619 ;; Kill the line if the buffer is dead 1686 ;; Kill the line if the buffer is dead
1620 'kill))) 1687 'kill)))
1621 ;; A given mapping function should return: 1688 ;; A given mapping function should return:
1622 ;; `nil' if it chose not to affect the buffer 1689 ;; `nil' if it chose not to affect the buffer
1623 ;; `kill' means the remove line from the buffer list 1690 ;; `kill' means the remove line from the buffer list
1629 (delete-region (line-beginning-position) 1696 (delete-region (line-beginning-position)
1630 (1+ (line-end-position))) 1697 (1+ (line-end-position)))
1631 (incf ibuffer-map-lines-count) 1698 (incf ibuffer-map-lines-count)
1632 (when (< ibuffer-map-lines-total 1699 (when (< ibuffer-map-lines-total
1633 orig-target-line) 1700 orig-target-line)
1634 (decf target-buf-count))) 1701 (decf target-line-offset)))
1635 (t 1702 (t
1636 (incf ibuffer-map-lines-count) 1703 (incf ibuffer-map-lines-count)
1637 (forward-line 1))))) 1704 (forward-line 1)))))
1638 ibuffer-map-lines-count) 1705 ibuffer-map-lines-count)
1639 (progn 1706 (progn
1640 (setq buffer-read-only t) 1707 (setq buffer-read-only t)
1641 (unless nomodify 1708 (unless nomodify
1642 (set-buffer-modified-p nil)) 1709 (set-buffer-modified-p nil))
1643 (goto-char (point-min)) 1710 (goto-char (point-min))
1644 (ibuffer-forward-line 0) 1711 (ibuffer-forward-line 0)
1645 (ibuffer-forward-line (1- target-buf-count)))))) 1712 (ibuffer-forward-line (1- target-line-offset))))))
1646 1713
1647 (defun ibuffer-get-marked-buffers () 1714 (defun ibuffer-get-marked-buffers ()
1648 "Return a list of buffer objects currently marked." 1715 "Return a list of buffer objects currently marked."
1649 (delq nil 1716 (delq nil
1650 (mapcar #'(lambda (e) 1717 (mapcar #'(lambda (e)
1668 #'(lambda (buf mark) 1735 #'(lambda (buf mark)
1669 (when (buffer-live-p buf) 1736 (when (buffer-live-p buf)
1670 (push (cons buf mark) ibuffer-current-state-list-tmp))))) 1737 (push (cons buf mark) ibuffer-current-state-list-tmp)))))
1671 (nreverse ibuffer-current-state-list-tmp))) 1738 (nreverse ibuffer-current-state-list-tmp)))
1672 1739
1740 (defun ibuffer-current-filter-groups ()
1741 (save-excursion
1742 (goto-char (point-min))
1743 (let ((pos nil)
1744 (result nil))
1745 (while (and (not (eobp))
1746 (setq pos (next-single-property-change
1747 (point) 'ibuffer-filter-group-name)))
1748 (goto-char pos)
1749 (push (cons (get-text-property (point) 'ibuffer-filter-group-name)
1750 pos)
1751 result)
1752 (goto-char (next-single-property-change
1753 pos 'ibuffer-filter-group-name)))
1754 (nreverse result))))
1755
1673 (defun ibuffer-current-buffers-with-marks (curbufs) 1756 (defun ibuffer-current-buffers-with-marks (curbufs)
1674 "Return a list like (BUF . MARK) of all open buffers." 1757 "Return a list like (BUF . MARK) of all open buffers."
1675 (let ((bufs (ibuffer-current-state-list))) 1758 (let ((bufs (ibuffer-current-state-list)))
1676 (mapcar #'(lambda (buf) (let ((e (assq buf bufs))) 1759 (mapcar #'(lambda (buf) (let ((e (assq buf bufs)))
1677 (if e 1760 (if e
1690 hit)) 1773 hit))
1691 1774
1692 (defun ibuffer-filter-buffers (ibuffer-buf last bmarklist all) 1775 (defun ibuffer-filter-buffers (ibuffer-buf last bmarklist all)
1693 (let ((ext-loaded (featurep 'ibuf-ext))) 1776 (let ((ext-loaded (featurep 'ibuf-ext)))
1694 (delq nil 1777 (delq nil
1695 (mapcar 1778 (mapcar
1696 ;; element should be like (BUFFER . MARK) 1779 ;; element should be like (BUFFER . MARK)
1697 #'(lambda (e) 1780 #'(lambda (e)
1698 (let* ((buf (car e))) 1781 (let* ((buf (car e)))
1699 (when 1782 (when
1700 ;; This takes precedence over anything else 1783 ;; This takes precedence over anything else
1701 (or (and ibuffer-always-show-last-buffer 1784 (or (and ibuffer-always-show-last-buffer
1702 (eq last buf)) 1785 (eq last buf))
1703 (funcall (if ext-loaded 1786 (funcall (if ext-loaded
1704 #'ibuffer-ext-visible-p 1787 #'ibuffer-ext-visible-p
1705 #'ibuffer-visible-p) 1788 #'ibuffer-visible-p)
1706 buf all ibuffer-buf)) 1789 buf all ibuffer-buf))
1707 e))) 1790 e)))
1708 bmarklist)))) 1791 bmarklist))))
1709 1792
1710 (defun ibuffer-visible-p (buf all &optional ibuffer-buf) 1793 (defun ibuffer-visible-p (buf all &optional ibuffer-buf)
1711 (and (or all 1794 (and (or all
1712 (not 1795 (not
1713 (ibuffer-buf-matches-predicates buf ibuffer-maybe-show-predicates))) 1796 (ibuffer-buf-matches-predicates buf ibuffer-maybe-show-predicates)))
1862 (unless silent 1945 (unless silent
1863 (message "Redisplaying current buffer list...")) 1946 (message "Redisplaying current buffer list..."))
1864 (let ((blist (ibuffer-current-state-list))) 1947 (let ((blist (ibuffer-current-state-list)))
1865 (when (null blist) 1948 (when (null blist)
1866 (if (and (featurep 'ibuf-ext) 1949 (if (and (featurep 'ibuf-ext)
1867 ibuffer-filtering-qualifiers) 1950 (or ibuffer-filtering-qualifiers ibuffer-hidden-filtering-groups))
1868 (message "No buffers! (note: filtering in effect)") 1951 (message "No buffers! (note: filtering in effect)")
1869 (error "No buffers!"))) 1952 (error "No buffers!")))
1870 (ibuffer-insert-buffers-and-marks blist t) 1953 (ibuffer-redisplay-engine blist t)
1871 (ibuffer-update-mode-name) 1954 (ibuffer-update-mode-name)
1872 (unless silent 1955 (unless silent
1873 (message "Redisplaying current buffer list...done")) 1956 (message "Redisplaying current buffer list...done"))
1874 (ibuffer-forward-line 0))) 1957 (ibuffer-forward-line 0)))
1875 1958
1901 ibuffer-filtering-qualifiers) 1984 ibuffer-filtering-qualifiers)
1902 (message "No buffers! (note: filtering in effect)") 1985 (message "No buffers! (note: filtering in effect)")
1903 (error "No buffers!"))) 1986 (error "No buffers!")))
1904 (unless silent 1987 (unless silent
1905 (message "Updating buffer list...")) 1988 (message "Updating buffer list..."))
1906 (ibuffer-insert-buffers-and-marks blist 1989 (ibuffer-redisplay-engine blist arg)
1907 arg)
1908 (ibuffer-update-mode-name) 1990 (ibuffer-update-mode-name)
1909 (unless silent 1991 (unless silent
1910 (message "Updating buffer list...done"))) 1992 (message "Updating buffer list...done")))
1911 (if (eq ibuffer-shrink-to-minimum-size 'onewindow) 1993 (if (eq ibuffer-shrink-to-minimum-size 'onewindow)
1912 (ibuffer-shrink-to-fit t) 1994 (ibuffer-shrink-to-fit t)
1913 (when ibuffer-shrink-to-minimum-size 1995 (when ibuffer-shrink-to-minimum-size
1914 (ibuffer-shrink-to-fit))) 1996 (ibuffer-shrink-to-fit)))
1915 (ibuffer-forward-line 0)) 1997 (ibuffer-forward-line 0))
1916 1998
1917 (defun ibuffer-insert-buffers-and-marks (bmarklist &optional all) 1999 (defun ibuffer-sort-bufferlist (bmarklist)
2000 (let* ((sortdat (assq ibuffer-sorting-mode
2001 ibuffer-sorting-functions-alist))
2002 (func (caddr sortdat)))
2003 (let ((result
2004 ;; actually sort the buffers
2005 (if (and sortdat func)
2006 (sort bmarklist func)
2007 bmarklist)))
2008 ;; perhaps reverse the sorted buffer list
2009 (if ibuffer-sorting-reversep
2010 (nreverse result)
2011 result))))
2012
2013 (defun ibuffer-insert-filter-group (name display-name format bmarklist)
2014 (add-text-properties
2015 (point)
2016 (progn
2017 (insert "[ " display-name " ]")
2018 (point))
2019 `(ibuffer-filter-group-name ,name keymap ,ibuffer-mode-filter-group-map
2020 mouse-face highlight
2021 help-echo "mouse-1: toggle marks in this group\nmouse-2: hide/show this filtering group "))
2022 (insert "\n")
2023 (when bmarklist
2024 (put-text-property
2025 (point)
2026 (progn
2027 (dolist (entry bmarklist)
2028 (ibuffer-insert-buffer-line (car entry) (cdr entry) format))
2029 (point))
2030 'ibuffer-filter-group
2031 name)))
2032
2033 (defun ibuffer-redisplay-engine (bmarklist &optional all)
1918 (assert (eq major-mode 'ibuffer-mode)) 2034 (assert (eq major-mode 'ibuffer-mode))
1919 (let ((--ibuffer-insert-buffers-and-marks-format 2035 (let* ((--ibuffer-insert-buffers-and-marks-format
1920 (ibuffer-current-format)) 2036 (ibuffer-current-format))
1921 (--ibuffer-expanded-format (mapcar #'ibuffer-expand-format-entry 2037 (--ibuffer-expanded-format (mapcar #'ibuffer-expand-format-entry
1922 (ibuffer-current-format t))) 2038 (ibuffer-current-format t)))
1923 (orig (count-lines (point-min) (point))) 2039 (orig (count-lines (point-min) (point)))
1924 ;; Inhibit font-lock caching tricks, since we're modifying the 2040 ;; Inhibit font-lock caching tricks, since we're modifying the
1925 ;; entire buffer at once 2041 ;; entire buffer at once
1926 (after-change-functions nil)) 2042 (after-change-functions nil)
2043 (ext-loaded (featurep 'ibuf-ext))
2044 (bgroups (if ext-loaded
2045 (ibuffer-generate-filter-groups bmarklist)
2046 (list (cons "Default" bmarklist)))))
1927 (ibuffer-clear-summary-columns --ibuffer-expanded-format) 2047 (ibuffer-clear-summary-columns --ibuffer-expanded-format)
1928 (unwind-protect 2048 (unwind-protect
1929 (progn 2049 (progn
1930 (setq buffer-read-only nil) 2050 (setq buffer-read-only nil)
1931 (erase-buffer) 2051 (erase-buffer)
1932 (ibuffer-update-format) 2052 (ibuffer-update-format)
1933 (let ((entries 2053 (dolist (group (nreverse bgroups))
1934 (let* ((sortdat (assq ibuffer-sorting-mode 2054 (let* ((name (car group))
1935 ibuffer-sorting-functions-alist)) 2055 (disabled (and ext-loaded
1936 (func (caddr sortdat))) 2056 (member name ibuffer-hidden-filtering-groups)))
1937 (let ((result 2057 (bmarklist (cdr group)))
1938 ;; actually sort the buffers 2058 (ibuffer-insert-filter-group
1939 (if (and sortdat func) 2059 name
1940 (sort bmarklist func) 2060 (if disabled (concat name " ...") name)
1941 bmarklist))) 2061 --ibuffer-insert-buffers-and-marks-format
1942 ;; perhaps reverse the sorted buffer list 2062 (if disabled
1943 (if ibuffer-sorting-reversep 2063 nil
1944 (nreverse result) 2064 (ibuffer-sort-bufferlist bmarklist)))))
1945 result)))))
1946 (dolist (entry entries)
1947 (ibuffer-insert-buffer-line
1948 (car entry)
1949 (cdr entry)
1950 --ibuffer-insert-buffers-and-marks-format)))
1951 (ibuffer-update-title-and-summary --ibuffer-expanded-format)) 2065 (ibuffer-update-title-and-summary --ibuffer-expanded-format))
1952 (setq buffer-read-only t) 2066 (setq buffer-read-only t)
1953 (set-buffer-modified-p ibuffer-did-modification) 2067 (set-buffer-modified-p ibuffer-did-modification)
1954 (setq ibuffer-did-modification nil) 2068 (setq ibuffer-did-modification nil)
1955 (goto-line (1+ orig))))) 2069 (goto-line (1+ orig)))))
1982 (interactive "P") 2096 (interactive "P")
1983 (ibuffer t nil (when files-only 2097 (ibuffer t nil (when files-only
1984 '((filename . ".*"))))) 2098 '((filename . ".*")))))
1985 2099
1986 ;;;###autoload 2100 ;;;###autoload
1987 (defun ibuffer (&optional other-window-p name qualifiers noselect shrink) 2101 (defun ibuffer (&optional other-window-p name qualifiers noselect
2102 shrink filter-groups)
1988 "Begin using `ibuffer' to edit a list of buffers. 2103 "Begin using `ibuffer' to edit a list of buffers.
1989 Type 'h' after entering ibuffer for more information. 2104 Type 'h' after entering ibuffer for more information.
1990 2105
1991 Optional argument OTHER-WINDOW-P says to use another window. 2106 Optional argument OTHER-WINDOW-P says to use another window.
1992 Optional argument NAME specifies the name of the buffer; it defaults 2107 Optional argument NAME specifies the name of the buffer; it defaults
1993 to \"*Ibuffer*\". 2108 to \"*Ibuffer*\".
1994 Optional argument QUALIFIERS is an initial set of filtering qualifiers 2109 Optional argument QUALIFIERS is an initial set of filtering qualifiers
1995 to use; see `ibuffer-filtering-qualifiers'. 2110 to use; see `ibuffer-filtering-qualifiers'.
1996 Optional argument NOSELECT means don't select the Ibuffer buffer. 2111 Optional argument NOSELECT means don't select the Ibuffer buffer.
1997 Optional argument SHRINK means shrink the buffer to minimal size. The 2112 Optional argument SHRINK means shrink the buffer to minimal size. The
1998 special value `onewindow' means always use another window." 2113 special value `onewindow' means always use another window.
2114 Optional argument FILTER-GROUPS is an initial set of filtering
2115 groups to use; see `ibuffer-filtering-groups'."
1999 (interactive "P") 2116 (interactive "P")
2000
2001 ;; The individual functions are lazy-loaded, via byte-compile-dynamic,
2002 ;; so we may as well load the file unconditionally now.
2003 (require 'ibuf-ext)
2004
2005 (when ibuffer-use-other-window 2117 (when ibuffer-use-other-window
2006 (setq other-window-p t)) 2118 (setq other-window-p t))
2007 (let* ((buf (get-buffer-create (or name "*Ibuffer*"))) 2119 (let* ((buf (get-buffer-create (or name "*Ibuffer*")))
2008 (already-in (eq (current-buffer) buf)) 2120 (already-in (eq (current-buffer) buf))
2009 (need-update nil)) 2121 (need-update nil))
2010 (if other-window-p 2122 (if other-window-p
2011 (funcall (if noselect #'(lambda (buf) (display-buffer buf t)) #'pop-to-buffer) buf) 2123 (funcall (if noselect #'(lambda (buf) (display-buffer buf t)) #'pop-to-buffer) buf)
2012 (funcall (if noselect #'display-buffer #'switch-to-buffer) buf)) 2124 (funcall (if noselect #'display-buffer #'switch-to-buffer) buf))
2013 (with-current-buffer buf 2125 (with-current-buffer buf
2014 (let ((owin (selected-window))) 2126 (save-selected-window
2127 ;; We switch to the buffer's window in order to be able
2128 ;; to modify the value of point
2129 (select-window (get-buffer-window buf))
2130 (unless (eq major-mode 'ibuffer-mode)
2131 (ibuffer-mode)
2132 (setq need-update t))
2133 (when (ibuffer-use-fontification)
2134 (require 'font-lock))
2135 (setq ibuffer-delete-window-on-quit other-window-p)
2136 (when shrink
2137 (setq ibuffer-shrink-to-minimum-size shrink))
2138 (when qualifiers
2139 (require 'ibuf-ext)
2140 (setq ibuffer-filtering-qualifiers qualifiers))
2141 (when filter-groups
2142 (require 'ibuf-ext)
2143 (setq ibuffer-filtering-groups filter-groups))
2144 (ibuffer-update nil)
2145 ;; Skip the group name by default.
2146 (ibuffer-forward-line 0 t)
2015 (unwind-protect 2147 (unwind-protect
2016 (progn 2148 (progn
2017 ;; We switch to the buffer's window in order to be able 2149 (setq buffer-read-only nil)
2018 ;; to modify the value of point 2150 (run-hooks 'ibuffer-hooks))
2019 (select-window (get-buffer-window buf)) 2151 (setq buffer-read-only t))
2020 (unless (eq major-mode 'ibuffer-mode) 2152 (unless ibuffer-expert
2021 (ibuffer-mode) 2153 (message "Commands: m, u, t, RET, g, k, S, D, Q; q to quit; h for help"))))))
2022 (setq need-update t))
2023 (when (ibuffer-use-fontification)
2024 (require 'font-lock))
2025 (setq ibuffer-delete-window-on-quit other-window-p)
2026 (when shrink
2027 (setq ibuffer-shrink-to-minimum-size shrink))
2028 (when qualifiers
2029 (setq ibuffer-filtering-qualifiers qualifiers))
2030 (ibuffer-update nil)
2031 (unwind-protect
2032 (progn
2033 (setq buffer-read-only nil)
2034 (run-hooks 'ibuffer-hooks))
2035 (setq buffer-read-only t))
2036 (unless ibuffer-expert
2037 (message "Commands: m, u, t, RET, g, k, S, D, Q; q to quit; h for help")))
2038 (select-window owin))))))
2039 2154
2040 (put 'ibuffer-mode 'mode-class 'special) 2155 (put 'ibuffer-mode 'mode-class 'special)
2041 (defun ibuffer-mode () 2156 (defun ibuffer-mode ()
2042 "A major mode for viewing a list of buffers. 2157 "A major mode for viewing a list of buffers.
2043 In ibuffer, you can conveniently perform many operations on the 2158 In ibuffer, you can conveniently perform many operations on the
2197 (set (make-local-variable 'ibuffer-sorting-reversep) 2312 (set (make-local-variable 'ibuffer-sorting-reversep)
2198 ibuffer-default-sorting-reversep) 2313 ibuffer-default-sorting-reversep)
2199 (set (make-local-variable 'ibuffer-shrink-to-minimum-size) 2314 (set (make-local-variable 'ibuffer-shrink-to-minimum-size)
2200 ibuffer-default-shrink-to-minimum-size) 2315 ibuffer-default-shrink-to-minimum-size)
2201 (set (make-local-variable 'ibuffer-filtering-qualifiers) nil) 2316 (set (make-local-variable 'ibuffer-filtering-qualifiers) nil)
2317 (set (make-local-variable 'ibuffer-filtering-groups) nil)
2318 (set (make-local-variable 'ibuffer-hidden-filtering-groups) nil)
2202 (set (make-local-variable 'ibuffer-compiled-formats) nil) 2319 (set (make-local-variable 'ibuffer-compiled-formats) nil)
2203 (set (make-local-variable 'ibuffer-cached-formats) nil) 2320 (set (make-local-variable 'ibuffer-cached-formats) nil)
2204 (set (make-local-variable 'ibuffer-cached-eliding-string) nil) 2321 (set (make-local-variable 'ibuffer-cached-eliding-string) nil)
2205 (set (make-local-variable 'ibuffer-cached-elide-long-columns) nil) 2322 (set (make-local-variable 'ibuffer-cached-elide-long-columns) nil)
2206 (set (make-local-variable 'ibuffer-current-format) nil) 2323 (set (make-local-variable 'ibuffer-current-format) nil)
2207 (set (make-local-variable 'ibuffer-did-modifiction) nil) 2324 (set (make-local-variable 'ibuffer-did-modifiction) nil)
2208 (set (make-local-variable 'ibuffer-delete-window-on-quit) nil) 2325 (set (make-local-variable 'ibuffer-delete-window-on-quit) nil)
2209 (set (make-local-variable 'ibuffer-did-modification) nil) 2326 (set (make-local-variable 'ibuffer-did-modification) nil)
2210 (when (featurep 'ibuf-ext) 2327 (set (make-local-variable 'ibuffer-tmp-hide-regexps) nil)
2211 (set (make-local-variable 'ibuffer-tmp-hide-regexps) nil) 2328 (set (make-local-variable 'ibuffer-tmp-show-regexps) nil)
2212 (set (make-local-variable 'ibuffer-tmp-show-regexps) nil))
2213 (define-key ibuffer-mode-map [menu-bar edit] 'undefined) 2329 (define-key ibuffer-mode-map [menu-bar edit] 'undefined)
2214 (define-key ibuffer-mode-map [menu-bar operate] (cons "Operate" ibuffer-mode-operate-map)) 2330 (define-key ibuffer-mode-map [menu-bar operate] (cons "Operate" ibuffer-mode-operate-map))
2215 (ibuffer-update-format) 2331 (ibuffer-update-format)
2216 (when ibuffer-default-directory 2332 (when ibuffer-default-directory
2217 (setq default-directory ibuffer-default-directory)) 2333 (setq default-directory ibuffer-default-directory))