X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/7b1019e2781472c793d0bf74e2b9ee17894270b8..73b0cd50031a714347109169ceb8bacae338612a:/lisp/ibuf-ext.el diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el index 6bdaed0a33..55375f1e06 100644 --- a/lisp/ibuf-ext.el +++ b/lisp/ibuf-ext.el @@ -1,12 +1,12 @@ ;;; ibuf-ext.el --- extensions for ibuffer -;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, -;; 2008 Free Software Foundation, Inc. +;; Copyright (C) 2000-2011 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. @@ -91,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" @@ -220,6 +215,16 @@ 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. +With numeric ARG, enable auto-update if and only if ARG is positive." + 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)) @@ -229,20 +234,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." @@ -260,9 +251,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 @@ -410,6 +399,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." @@ -528,10 +535,11 @@ To evaluate a form without viewing the buffer, see `ibuffer-do-eval'." (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) + (values-list + (ibuffer-split-list (lambda (bufmark) + (ibuffer-included-in-filters-p (car bufmark) + filterset)) + bmarklist)) (aset vec i hip-crowd) (incf i) (setq bmarklist lamers)))) @@ -562,7 +570,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 @@ -966,10 +974,7 @@ The list returned will be of the form (\"MODE-NAME\" . MODE-SYMBOL)." (modes) (this-mode)) (while bufs - (setq this-mode - (with-current-buffer - (car bufs) - major-mode) + (setq this-mode (buffer-local-value 'major-mode (car bufs)) bufs (cdr bufs)) (add-to-list 'modes @@ -993,10 +998,9 @@ The list returned will be of the form (\"MODE-NAME\" . MODE-SYMBOL)." t (let ((buf (ibuffer-current-buffer))) (if (and buf (buffer-live-p buf)) - (with-current-buffer buf - (symbol-name major-mode)) + (symbol-name (buffer-local-value 'major-mode buf)) ""))))) - (eq qualifier (with-current-buffer buf major-mode))) + (eq qualifier (buffer-local-value 'major-mode buf))) ;;;###autoload (autoload 'ibuffer-filter-by-used-mode "ibuf-ext") (define-ibuffer-filter used-mode @@ -1012,10 +1016,10 @@ currently used by buffers." t (let ((buf (ibuffer-current-buffer))) (if (and buf (buffer-live-p buf)) - (with-current-buffer buf - (symbol-name major-mode)) + (symbol-name (buffer-local-value + 'major-mode buf)) ""))))) - (eq qualifier (with-current-buffer buf major-mode))) + (eq qualifier (buffer-local-value 'major-mode buf))) ;;;###autoload (autoload 'ibuffer-filter-by-name "ibuf-ext") (define-ibuffer-filter name @@ -1029,18 +1033,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 @@ -1115,13 +1109,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 @@ -1129,9 +1119,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) @@ -1162,10 +1152,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)))))) @@ -1317,15 +1307,69 @@ 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))) + " ")) + proc) + (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) @@ -1380,7 +1424,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) @@ -1433,8 +1478,7 @@ You can then feed the file name(s) to other commands with \\[yank]." "")))))) (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 () @@ -1448,7 +1492,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 @@ -1517,18 +1561,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) @@ -1550,5 +1590,8 @@ defaults to one." (provide 'ibuf-ext) -;; arch-tag: 9af21953-deda-4c30-b76d-f81d9128e76d +;; Local Variables: +;; generated-autoload-file: "ibuffer.el" +;; End: + ;;; ibuf-ext.el ends here