From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: improving query-replace and query-replace-regexp Date: 01 Jun 2004 19:48:23 -0400 Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: References: <20040528.182035.197345599.wl@gnu.org> <87k6yvorzf.fsf@mail.jurta.org> <20040529213132.GA31322@fencepost> <873c5hd35q.fsf@mail.jurta.org> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1086133849 28921 80.91.224.253 (1 Jun 2004 23:50:49 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Tue, 1 Jun 2004 23:50:49 +0000 (UTC) Cc: wl@gnu.org, emacs-devel@gnu.org, rms@gnu.org, Miles Bader Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Wed Jun 02 01:50:41 2004 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1BVJ1l-0004BQ-00 for ; Wed, 02 Jun 2004 01:50:41 +0200 Original-Received: from lists.gnu.org ([199.232.76.165]) by quimby.gnus.org with esmtp (Exim 3.35 #1 (Debian)) id 1BVJ1l-00089e-00 for ; Wed, 02 Jun 2004 01:50:41 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BVJ21-0006jr-40 for emacs-devel@quimby.gnus.org; Tue, 01 Jun 2004 19:50:57 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1BVJ1l-0006aS-RN for emacs-devel@gnu.org; Tue, 01 Jun 2004 19:50:42 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1BVJ1k-0006Yl-2J for emacs-devel@gnu.org; Tue, 01 Jun 2004 19:50:40 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BVJ1j-0006YM-WD for emacs-devel@gnu.org; Tue, 01 Jun 2004 19:50:40 -0400 Original-Received: from [206.47.199.166] (helo=simmts8-srv.bellnexxia.net) by monty-python.gnu.org with esmtp (Exim 4.34) id 1BVIzY-0000Cl-Uh; Tue, 01 Jun 2004 19:48:25 -0400 Original-Received: from empanada.local ([67.70.165.15]) by simmts8-srv.bellnexxia.net (InterMail vM.5.01.06.05 201-253-122-130-105-20030824) with ESMTP id <20040601234821.OPFL28088.simmts8-srv.bellnexxia.net@empanada.local>; Tue, 1 Jun 2004 19:48:21 -0400 Original-Received: by empanada.local (Postfix, from userid 502) id C34C11C2491; Tue, 1 Jun 2004 19:48:23 -0400 (EDT) Original-To: Juri Linkov In-Reply-To: <873c5hd35q.fsf@mail.jurta.org> Original-Lines: 89 User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3.50 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.4 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:24369 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:24369 > I tried Stefan's implementation and it works fine. I have only one remark: > if the last history item contains newlines, it may confuse users because > it displays only the closing square bracket at the minibuffer prompt. Good point. How about the version below instead? Stefan --- orig/lisp/replace.el +++ mod/lisp/replace.el @@ -1,6 +1,6 @@ ;;; replace.el --- replace commands for Emacs -;; Copyright (C) 1985, 86, 87, 92, 94, 96, 1997, 2000, 2001, 2002 +;; Copyright (C) 1985, 86, 87, 92, 94, 96, 1997, 2000, 2001, 02, 03, 2004 ;; Free Software Foundation, Inc. ;; Maintainer: FSF @@ -69,17 +69,32 @@ (defun query-replace-read-args (string regexp-flag &optional noerror) (unless noerror (barf-if-buffer-read-only)) - (let (from to) + (let ((lastfrom (car (symbol-value query-replace-from-history-variable))) + (lastto (car (symbol-value query-replace-to-history-variable))) + from to) (if query-replace-interactive (setq from (car (if regexp-flag regexp-search-ring search-ring))) + (if (equal lastfrom lastto) + ;; Typically, this is because the two histlists are shared. + (setq lastfrom + (cadr (symbol-value query-replace-from-history-variable)))) ;; The save-excursion here is in case the user marks and copies ;; a region in order to specify the minibuffer input. ;; That should not clobber the region for the query-replace itself. (save-excursion - (setq from (read-from-minibuffer (format "%s: " string) + (setq from (read-from-minibuffer + (if (null lastto) + (format "%s: " string) + (format "%s [%s -> %s]: " string + (mapconcat 'isearch-text-char-description + lastfrom "") + (mapconcat 'isearch-text-char-description + lastto ""))) nil nil nil query-replace-from-history-variable nil t))) + (if (and lastto (zerop (length from))) + (setq from lastfrom to lastto) ;; Warn if user types \n or \t, but don't reject the input. (if (string-match "\\\\[nt]" from) (let ((match (match-string 0 from))) @@ -88,12 +103,13 @@ (message "Note: `\\n' here doesn't match a newline; to do that, type C-q C-j instead")) ((string= match "\\t") (message "Note: `\\t' here doesn't match a tab; to do that, just type TAB"))) - (sit-for 2)))) + (sit-for 2))))) + (unless to (save-excursion (setq to (read-from-minibuffer (format "%s %s with: " string from) nil nil nil - query-replace-to-history-variable from t))) + query-replace-to-history-variable from t)))) (list from to current-prefix-arg))) (defun query-replace (from-string to-string &optional delimited start end) @@ -842,7 +858,6 @@ (let ((matches 0) ;; count of matched lines (lines 1) ;; line count (matchbeg 0) - (matchend 0) (origpt nil) (begpt nil) (endpt nil) @@ -862,8 +877,7 @@ (setq origpt (point)) (when (setq endpt (re-search-forward regexp nil t)) (setq matches (1+ matches)) ;; increment match count - (setq matchbeg (match-beginning 0) - matchend (match-end 0)) + (setq matchbeg (match-beginning 0)) (setq begpt (save-excursion (goto-char matchbeg) (line-beginning-position)))