[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
igrep-find-replace.el --- igrep interface for query-replace
From: |
Kevin A. Burton |
Subject: |
igrep-find-replace.el --- igrep interface for query-replace |
Date: |
29 Oct 2001 19:06:57 -0800 |
User-agent: |
Gnus/5.0808 (Gnus v5.8.8) Emacs/21.1 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
... Modernization and misc bug fixes.
;;; igrep-find-replace.el --- igrep interface for query-replace
;; $Id: igrep-find-query-replace.el,v 1.4 2001/10/26 06:19:59 burton Exp $
;; Copyright (C) 2000-2003 Free Software Foundation, Inc.
;; Copyright (C) 2000-2003 Kevin A. Burton (address@hidden)
;; Author: Kevin A. Burton (address@hidden)
;; Maintainer: Kevin A. Burton (address@hidden)
;; Location: http://relativity.yi.org
;; Keywords:
;; Version: 1.0.0
;; This file is [not yet] part of GNU Emacs.
;; This program is free software; you can redistribute it and/or modify it under
;; the terms of the GNU General Public License as published by the Free Software
;; Foundation; either version 2 of the License, or any later version.
;;
;; This program is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
;; details.
;;
;; You should have received a copy of the GNU General Public License along with
;; this program; if not, write to the Free Software Foundation, Inc., 59 Temple
;; Place - Suite 330, Boston, MA 02111-1307, USA.
;;; Commentary:
;;
;; This is a utility for igrep. It allows you to run igrep-find and
;; 'query-replace' within all matched files. This allows you to make major
;; changes to multiple files at once.
;;
;; The interface behaves just like 'igrep' and 'query-replace' and shouldn't
;; confuse the user with any new UI metaphor.
;;
;;; History
;; - Sat Oct 27 2001 08:32 PM (address@hidden): we are now using an
;; 'overlay-arrow' in the igrep buffer.
;;
;; - Sat Oct 27 2001 07:15 PM (address@hidden): message stating that
;; igrep-find-query-will start when igrep finishes.
;;
;; - Thu Oct 25 2001 01:15 AM (address@hidden): need a "y or n" question
;; on the query prompt.
;;
;;; TODO:
;;
;;
;;; HIGH PRIORITY...
;; - when the file buffer (not the *igrep* buffer) shows the match near the end
;; of beginning of the buffer, center the window so that it is more obvious
what
;; we are replacing.
;;
;; - is there an easy function to do this? maybe -recenter or something?
;;
;;
;; - Make sure that the it is obvious what buffer we are in in the *igrep*
;; buffer.
;;
;; - use the secondary selection face to highlight the current line (in the
;; *igrep* buffer) I am replacing.
;;
;; - support the ability to replace multi-line text..
;;
;;
;; - we need to display a NICE message if no matches were found.
;;; LOW PRIORITY...
;; - implement igrep-query-replace as well as igrep-find-query-replace. Any
;; other functions I should implement?? agrep, fgrep, etc?
;;
;; - for some reason I am getting this error:
;;
;; error in process sentinel: Args out of range: 0, 6 [2 times]
;;
;; - Use an italic overlay to highlight the current line/file.
;;
;; - In long buffers, keep the current line near the top of the buffer.
(require 'igrep)
;;; Code:
(defvar ifqr-from nil "String to search and replace from.")
(make-variable-buffer-local 'ifqr-from)
(defvar ifqr-with nil "String to search and replace with.")
(make-variable-buffer-local 'ifqr-with)
(defvar ifqr-replacement-count 0 "Number of replacements for the last
`query-replace'.")
(defvar ifqr-text-buffer-name "*ifqr-text*" "Buffer used for reading and writing
text/multiline string")
(defvar ifqr-text-replace-from nil "Search for the given text.")
(defvar ifqr-text-replace-with nil "Replace the given text.")
(defvar ifqr-text-replace-var-name nil "Var name to set.")
(defvar ifqr-text-replace-function nil "Function to eval after completion.")
(defface ifqr-line-overlay-face nil "Overlay used to highlight the current
match.")
(set-face-background 'ifqr-line-overlay-face (face-background
'secondary-selection))
(defvar ifqr-line-overlay (make-overlay 0 0) "Overlay used to highlight this
match.")
(defun igrep-find-query-replace(replace-from replace-with files)
"Use igrep-find to query and replace strings within buffers."
(interactive
(let(from to files)
(setq from (read-string "Query replace: "))
(setq to (read-string (format "Query replace %s with: " from )))
(setq files (igrep-read-files))
(list from to files)))
(delete-other-windows)
(let ((igrep-find t)
igrep-args
filename
process)
(setq igrep-args (list "grep" replace-from files))
;;run igrep-find...
(igrep (elt igrep-args 0)
(elt igrep-args 1)
(elt igrep-args 2))
(message "igrep-find-query-replace will start when igrep finishes...")
;;get the process created by igrep
(setq process (get-process "igrep"))
;;if the process is nil... it exited quickly... process the output.
(if process
;; use a process sentinel to find it.
(progn
;;update buffer local variables for from/width
(save-excursion
(set-buffer (process-buffer process))
(setq ifqr-from replace-from)
(setq ifqr-with replace-with))
(set-process-sentinel process 'ifqr-sentinel))
;;this should never happen... I think... maybe we shouldn't signal an
;;error though.
(error "Unable to find process"))))
(defun ifqr-do()
"Do the query/replace after igrep has ran saving. Show the number of
replacements when complete. "
;;reset the count
(setq ifqr-replacement-count 0)
(let(filename line-number replace-from replace-with quit)
(set-buffer "*igrep*")
(display-buffer "*igrep*")
;;get the local replacement vars..
(setq replace-from ifqr-from)
(setq replace-with ifqr-with)
(beginning-of-buffer)
(forward-line 2)
(ifqr-highlight-line (point))
;;navigate forward though the igrep buffer.
(while (and (not quit)
(re-search-forward "\\(^/[^:]+\\):\\([0-9]+\\):" nil t))
(ifqr-highlight-line (point))
(setq filename (match-string 1))
(setq line-number (string-to-number (match-string 2)))
(setq quit (ifqr-do-replace filename line-number replace-from
replace-with))
;;return to the igrep buffer just in case.
(set-buffer "*igrep*")
(forward-line 1)
(beginning-of-line)))
(message "Replaced %i occurrences...done" ifqr-replacement-count))
(defun ifqr-do-replace(filename line-number replace-from replace-with)
"Do a replacement on the given line number, keep doing until we are complete.
If the user select 'q' (for quit) return true, else nil. "
;;valid options are y/n/q
(let(source-buffer result)
(setq source-buffer (find-file-noselect filename))
(set-window-buffer (other-window 0) source-buffer)
(set-buffer source-buffer)
(goto-line line-number)
(beginning-of-buffer)
(assert (search-forward replace-from nil t)
nil (format "Could not find %s" replace-from))
;;highlight the match...
(ifqr-highlight (match-beginning 0) (match-end 0))
;;if an error is signaled... catch it... this can happen from mouse
;;events/etc..
(condition-case nil
(progn
;;should we replace
(if (yes-or-no-p (format "Query replacing '%s' with '%s' in %s: "
replace-from replace-with filename))
(progn
(replace-match replace-with)
;;increment the match count...
(setq ifqr-replacement-count (1+ ifqr-replacement-count))
;;important to save the buffer when we are done.
(save-buffer))))
nil)
result))
(defun ifqr-highlight(region-start region-end)
"Setup the mark within the given region."
(goto-char region-start)
(push-mark nil t t)
(goto-char region-end))
(defun ifqr-sentinel(process event)
"Process sentinel which detects if the igrep process is done."
(if (and (string-equal (process-name process) "igrep")
(string-match "^finished\n$" event))
(ifqr-do)
(message "")))
(defun igrep-find-query-replace-text()
"Run query replace on long/text strings."
(interactive)
(ifqr-text-step-1))
(defun ifqr-text-step-1()
"Get the from variable."
(ifqr-read-text-string 'ifqr-text-replace-from
'ifqr-text-step-2
"(Step one) Enter the text you would like to search
for."))
(defun ifqr-text-step-2()
(ifqr-read-text-string 'ifqr-text-replace-with
'ifqr-text-do
"(Step two) Enter the text you would like to use as a
replacement."))
(defun ifqr-read-text-string(var-name function message)
"Read a text string from a buffer."
(setq ifqr-text-replace-var-name var-name)
(setq ifqr-text-replace-function function)
(save-excursion
(set-buffer (get-buffer-create ifqr-text-buffer-name))
(erase-buffer)
(insert (format "//REPLACE-TEXT: %s\n" message))
(ifqr-text-entry-mode))
(pop-to-buffer ifqr-text-buffer-name)
(message message))
(defun ifqr-read-text-complete()
"Complete text entry and continue."
(interactive)
(ifqr-text-cleanse-buffer)
(delete-window (get-buffer-window ifqr-text-buffer-name))
(funcall ifqr-text-replace-function))
(defun ifqr-text-cleanse-buffer()
(save-excursion
(set-buffer ifqr-text-buffer-name)
(beginning-of-buffer)
(while (re-search-forward "^//REPLACE-TEXT: .*$" nil t)
(delete-region (match-beginning 0)
(1+ (match-end 0))))))
(defun ifqr-highlight-line(point)
"Highlight the current line so that people know what the heck is going on..."
(interactive
(list
(point)))
(save-excursion
(set-buffer "*igrep*")
(let(begin end)
(goto-char point)
(setq begin (point-at-bol))
(setq end (1+ (point-at-eol)))
;;update the Emacs 21 arrow...
(let(m)
(setq m (make-marker))
(set-marker m begin)
(setq overlay-arrow-position m))
(move-overlay ifqr-line-overlay begin end (current-buffer))
(overlay-put ifqr-line-overlay 'face 'ifqr-line-overlay-face)
(overlay-put ifqr-line-overlay 'window (selected-window))
(overlay-put ifqr-line-overlay 'priority 1)))
(let((redisplay-dont-pause t))
(sit-for 0)
(redraw-frame (selected-frame))))
(define-derived-mode ifqr-text-entry-mode fundamental-mode "IGrepTextEntry"
"Major mode with key bindings to jump to files."
(interactive)
(font-lock-mode 1))
;;comments
(font-lock-add-keywords 'ifqr-text-entry-mode '(("^//.*$"
(0 'font-lock-comment-face
t))))
(define-key ifqr-text-entry-mode-map "\C-c\C-c" 'ifqr-read-text-complete)
(provide 'igrep-find-query-replace)
;;; igrep-find-replace.el ends here
- --
Need a good Engineer? Hire me! ( Java | P2P | XML | Linux | Open Source )
http://relativity.yi.org/bio/
Kevin A. Burton ( address@hidden, address@hidden, address@hidden )
Location - San Francisco, CA, Cell - 415.595.9965
Jabber - address@hidden, Web - http://relativity.yi.org
,@b=map{xB8,unxb8,chr($_^$a[--$h+84])address@hidden;s/...$/1$&/;$d=
unxV,xb25,$_;$b=73;$e=256|(ord$b[4])<<9|ord$b[3];$d=$d>>8^($f=($t=255)&($d
>>12^$d>>4^$d^$d/8))<<17,$e=$e>>8^($t&($g=($q=$e>>14&7^$e)^$q*8^$q<<6))<<9
,$_=(map{$_%16or$t^=$c^=($m=(11,10,116,100,11,122,20,100)[$_/16%8])&110;$t
^=(72,@z=(64,72,$a^=12*($_%16-2?0:$m&17)),$b^=$_%64?12:0,@z)[$_%8]}(16..271))
[$_]^(($h>>=8)+=$f+(~$g&$t))address@hidden"C*",@a}';s/x/pack+/g;eval
-- Perl version of DeCSS.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: Get my public key at: http://relativity.yi.org/pgpkey.txt
iD8DBQE73hlRAwM6xb2dfE0RApNUAKCwSQScEaCr4LkSXlzdCyRuXBE4uwCfee4+
Wgvxb3E6FqwCfGw1oWh+ZCE=
=CoWw
-----END PGP SIGNATURE-----
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- igrep-find-replace.el --- igrep interface for query-replace,
Kevin A. Burton <=