From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: storm@cua.dk (Kim F. Storm) Newsgroups: gmane.emacs.devel Subject: Doing search and replace via *grep* buffer Date: Thu, 15 Feb 2007 13:11:20 +0100 Message-ID: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1171541477 16597 80.91.229.12 (15 Feb 2007 12:11:17 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Thu, 15 Feb 2007 12:11:17 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Feb 15 13:11:00 2007 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1HHfRz-0001cB-JR for ged-emacs-devel@m.gmane.org; Thu, 15 Feb 2007 13:10:59 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HHfRz-0007uc-12 for ged-emacs-devel@m.gmane.org; Thu, 15 Feb 2007 07:10:59 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1HHfRm-0007s7-1K for emacs-devel@gnu.org; Thu, 15 Feb 2007 07:10:46 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1HHfRl-0007rv-As for emacs-devel@gnu.org; Thu, 15 Feb 2007 07:10:45 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HHfRl-0007rs-7f for emacs-devel@gnu.org; Thu, 15 Feb 2007 07:10:45 -0500 Original-Received: from pfepc.post.tele.dk ([195.41.46.237]) by monty-python.gnu.org with esmtp (Exim 4.52) id 1HHfRk-0002oN-Mt for emacs-devel@gnu.org; Thu, 15 Feb 2007 07:10:45 -0500 Original-Received: from kfs-l.imdomain.dk.cua.dk (0x503e2644.bynxx19.adsl-dhcp.tele.dk [80.62.38.68]) by pfepc.post.tele.dk (Postfix) with SMTP id D918A8A0032 for ; Thu, 15 Feb 2007 13:10:38 +0100 (CET) User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.93 (gnu/linux) X-detected-kernel: Linux 2.6, seldom 2.4 (older, 4) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:66418 Archived-At: Here is a small patch which provides a very handy search and replace functionality via the normal grep interfaces (including lgrep/rgrep). It requires that grep regexp highlighting works (I suppose most modern grep programs do that). Here is an example of its use, replacing _some_ occurrences of the identifier `oldtext' with `newtext': First use rgrep to search for oldtext in all .c and .h files: M-x rgrep RET oldtext RET ch RET RET Then in the *grep* buffer, move to the first instance which you want to replace (use `n' or C-n). Then hit / and type the replacement text: / newtext RET Now, still in the *grep* buffer, move to the next instance you want to modify, and just hit . to repeat the replacement, for example: n n . n . n . n n n . (I suppose VI users will find this very familiar). *** grep.el 14 Feb 2007 12:54:20 +0100 1.69 --- grep.el 15 Feb 2007 12:46:01 +0100 *************** *** 185,192 **** --- 185,195 ---- (define-key map "\r" 'compile-goto-error) ;; ? (define-key map "n" 'next-error-no-select) (define-key map "p" 'previous-error-no-select) + (define-key map "o" 'grep-goto-error-no-select) (define-key map "{" 'compilation-previous-file) (define-key map "}" 'compilation-next-file) + (define-key map "/" 'grep-replace-match) + (define-key map "." 'grep-repeat-replace-match) (define-key map "\t" 'compilation-next-error) (define-key map [backtab] 'compilation-previous-error) *************** *** 790,795 **** --- 793,831 ---- (if (eq next-error-last-buffer (current-buffer)) (setq default-directory dir))))))) + (defun grep-goto-error-no-select () + "Display currently grep match in other window." + (interactive) + (save-selected-window + (compile-goto-error))) + + (defvar grep-last-replace-string nil) + + (defun grep-replace-match-internal () + (when compilation-highlight-overlay + (let ((start (overlay-start compilation-highlight-overlay))) + (goto-char start) + (undo-boundary) + (delete-region start (overlay-end compilation-highlight-overlay)) + (insert grep-last-replace-string) + (move-overlay compilation-highlight-overlay start (point))))) + + (defun grep-replace-match (string) + "Replace current grep match with string STRING." + (interactive "sReplace with: ") + (save-selected-window + (setq grep-last-replace-string string) + (let ((next-error-highlight + (if (numberp next-error-highlight) next-error-highlight 0.01)) + (next-error-hook '(grep-replace-match-internal))) + (compile-goto-error)))) + + (defun grep-repeat-replace-match () + "Replace current grep match with last match replace string." + (interactive) + (if (not grep-last-replace-string) + (call-interactively 'grep-replace-match) + (grep-replace-match grep-last-replace-string))) + (provide 'grep) -- Kim F. Storm http://www.cua.dk