From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.bugs Subject: bug#12526: 24.2.50; `query-replace-interactive' not always respected Date: Thu, 04 Oct 2012 02:38:11 +0300 Organization: JURTA Message-ID: <878vbnnmmc.fsf@mail.jurta.org> References: <877gr8obbs.fsf@mail.jurta.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1349402104 27216 80.91.229.3 (5 Oct 2012 01:55:04 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 5 Oct 2012 01:55:04 +0000 (UTC) Cc: 12526@debbugs.gnu.org To: Dani Moncayo Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Oct 05 03:55:06 2012 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1TJx5M-0005tv-Cp for geb-bug-gnu-emacs@m.gmane.org; Fri, 05 Oct 2012 03:52:16 +0200 Original-Received: from localhost ([::1]:33976 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TJZ3q-0005Sd-Sd for geb-bug-gnu-emacs@m.gmane.org; Wed, 03 Oct 2012 20:13:06 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:44911) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TJZ3n-0005Ry-4e for bug-gnu-emacs@gnu.org; Wed, 03 Oct 2012 20:13:04 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TJZ3l-0003e1-6S for bug-gnu-emacs@gnu.org; Wed, 03 Oct 2012 20:13:03 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:41699) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TJZ3l-0003dw-2C for bug-gnu-emacs@gnu.org; Wed, 03 Oct 2012 20:13:01 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1TJZ3m-00037v-E9 for bug-gnu-emacs@gnu.org; Wed, 03 Oct 2012 20:13:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Juri Linkov Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 04 Oct 2012 00:13:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 12526 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 12526-submit@debbugs.gnu.org id=B12526.134930956311991 (code B ref 12526); Thu, 04 Oct 2012 00:13:02 +0000 Original-Received: (at 12526) by debbugs.gnu.org; 4 Oct 2012 00:12:43 +0000 Original-Received: from localhost ([127.0.0.1]:51950 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TJZ3S-00037K-HU for submit@debbugs.gnu.org; Wed, 03 Oct 2012 20:12:43 -0400 Original-Received: from ps18281.dreamhost.com ([69.163.218.105]:34825 helo=ps18281.dreamhostps.com) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TJZ3P-000376-N0 for 12526@debbugs.gnu.org; Wed, 03 Oct 2012 20:12:41 -0400 Original-Received: from localhost (ps18281.dreamhostps.com [69.163.218.105]) by ps18281.dreamhostps.com (Postfix) with ESMTP id 335BF451CD1A; Wed, 3 Oct 2012 17:12:36 -0700 (PDT) In-Reply-To: (Dani Moncayo's message of "Wed, 3 Oct 2012 12:00:05 +0200") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2.50 (x86_64-pc-linux-gnu) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:65218 Archived-At: >>> Is that feature documented somewhere? >> >> Yes, it is documented in the Info node >> (info "(emacs) Special Isearch") > > Ok, but definitely the docstring of query-replace should be updated, > because currently it is misleading: > If `query-replace-interactive' is non-nil, the last incremental search > string is used as FROM-STRING--you don't have to specify it with the > minibuffer. Thanks for the suggestion. I fixed this docstring in the patch below. > Also, the docstring of `query-replace-interactive' should be update > for the same reason. Since it's easy to do `C-s C-s M-%' to replace the last search string, the option `query-replace-interactive' is useless now and can be declared obsolete. Another reason to remove it is your suggestion below to use `M-% M-n' as its replacement. >> (define-key isearch-mode-map [?\M-%] >> (lambda () >> (interactive) >> (isearch-exit) ;; I'm too lazy to terminate search with RET. >> (call-interactively 'query-replace))) > > This is an ugly solution, IMO. I don't want to define a new command > and bind M-% to it; If you don't want to define a new command, then you can add just one line to your init file: (define-key isearch-mode-map [?\M-%] 'isearch-other-meta-char) > I'd like to set some user-option in my init file so that query-replace > never assumes nothing about the "from" string. If you don't want to use `define-key' for configuration purposes, we might consider using an user option, but not `query-replace-interactive' that is irrelevant for isearch. Such an option has been discussed but not yet implemented. To get an idea how this option could work, please see bug#9706 and its related thread on emacs-devel. With this new option, you will be able to define any command (not only `query-replace') to bypass its isearch keybinding to its original command. > BTW: I think that a much better approach would be to add the last > search string to the list of default arguments, so that, after an > Isearch, I could do `M-% M-n' if I wanted to retrieve that last search > string. Two weeks ago I added the last search string to `C-M-% M-n'. But it's still missing for `M-% M-n'. Thank you for noticing this omission. This is fixed in the patch below. This is another reason to declare `query-replace-interactive' obsolete because now there are two functional replacements for it as is documented in the fixed docstrings. Also I verified that "Query replace (default foo -> bar): RET" still works correctly and empty input redoes the last replace. === modified file 'lisp/replace.el' --- lisp/replace.el 2012-09-25 04:13:02 +0000 +++ lisp/replace.el 2012-10-03 23:38:00 +0000 @@ -62,6 +62,10 @@ (defvar query-replace-defaults nil (defvar query-replace-interactive nil "Non-nil means `query-replace' uses the last search string. That becomes the \"string to replace\".") +(make-obsolete-variable 'query-replace-interactive + "use `M-n' in the minibuffer +that asks for the string to replace, or run `query-replace' +from Isearch by using a key sequence like `C-s C-s M-%'." "24.3") (defcustom query-replace-from-history-variable 'query-replace-history "History list to use for the FROM argument of `query-replace' commands. @@ -125,8 +129,6 @@ (defun query-replace-read-from (prompt r "Query and return the `from' argument of a query-replace operation. The return value can also be a pair (FROM . TO) indicating that the user wants to replace FROM with TO." - (if query-replace-interactive - (car (if regexp-flag regexp-search-ring search-ring)) (let* ((history-add-new-input nil) (prompt (if query-replace-defaults @@ -142,7 +144,8 @@ (defun query-replace-read-from (prompt r (if regexp-flag (read-regexp prompt nil query-replace-from-history-variable) (read-from-minibuffer - prompt nil nil nil query-replace-from-history-variable nil t))))) + prompt nil nil nil query-replace-from-history-variable + (car (if regexp-flag regexp-search-ring search-ring)) t))))) (if (and (zerop (length from)) query-replace-defaults) (cons (car query-replace-defaults) (query-replace-compile-replacement @@ -158,7 +161,7 @@ (defun query-replace-read-from (prompt r ((string= match "\\t") (message "Note: `\\t' here doesn't match a tab; to do that, just type TAB"))) (sit-for 2))) - from)))) + from))) (defun query-replace-compile-replacement (to regexp-flag) "Maybe convert a regexp replacement TO to Lisp. @@ -231,9 +234,11 @@ (defun query-replace (from-string to-str In Transient Mark mode, if the mark is active, operate on the contents of the region. Otherwise, operate from point to the end of the buffer. -If `query-replace-interactive' is non-nil, the last incremental search -string is used as FROM-STRING--you don't have to specify it with the -minibuffer. +Use \\\\[next-history-element] \ +to pull the last incremental search string to the minibuffer +that reads FROM-STRING, or start `query-replace' from +incremental search with a key sequence like `C-s C-s M-%' +to use its current search string as the string to replace. Matching is independent of case if `case-fold-search' is non-nil and FROM-STRING has no uppercase letters. Replacement transfers the case @@ -279,9 +284,11 @@ (defun query-replace-regexp (regexp to-s In Transient Mark mode, if the mark is active, operate on the contents of the region. Otherwise, operate from point to the end of the buffer. -If `query-replace-interactive' is non-nil, the last incremental search -regexp is used as REGEXP--you don't have to specify it with the -minibuffer. +Use \\\\[next-history-element] \ +to pull the last incremental search regexp to the minibuffer +that reads REGEXP, or start `query-replace-regexp' from +incremental search with a key sequence like `C-M-s C-M-s C-M-%' +to use its current search regexp as the regexp to replace. Matching is independent of case if `case-fold-search' is non-nil and REGEXP has no uppercase letters. Replacement transfers the case @@ -364,9 +371,9 @@ (defun query-replace-regexp-eval (regexp In Transient Mark mode, if the mark is active, operate on the contents of the region. Otherwise, operate from point to the end of the buffer. -If `query-replace-interactive' is non-nil, the last incremental search -regexp is used as REGEXP--you don't have to specify it with the -minibuffer. +Use \\\\[next-history-element] \ +to pull the last incremental search regexp to the minibuffer +that reads REGEXP. Preserves case in each replacement if `case-replace' and `case-fold-search' are non-nil and REGEXP has no uppercase letters. @@ -417,19 +424,16 @@ (defun map-query-replace-regexp (regexp Non-interactively, TO-STRINGS may be a list of replacement strings. -If `query-replace-interactive' is non-nil, the last incremental search -regexp is used as REGEXP--you don't have to specify it with the minibuffer. +Use \\\\[next-history-element] \ +to pull the last incremental search regexp to the minibuffer +that reads REGEXP. A prefix argument N says to use each replacement string N times before rotating to the next. Fourth and fifth arg START and END specify the region to operate on." (interactive - (let* ((from (if query-replace-interactive - (car regexp-search-ring) - (read-from-minibuffer "Map query replace (regexp): " - nil nil nil - query-replace-from-history-variable - nil t))) + (let* ((from (read-regexp "Map query replace (regexp): " nil + query-replace-from-history-variable)) (to (read-from-minibuffer (format "Query replace %s with (space-separated strings): " (query-replace-descr from)) @@ -475,9 +479,9 @@ (defun replace-string (from-string to-st only matches surrounded by word boundaries. Fourth and fifth arg START and END specify the region to operate on. -If `query-replace-interactive' is non-nil, the last incremental search -string is used as FROM-STRING--you don't have to specify it with the -minibuffer. +Use \\\\[next-history-element] \ +to pull the last incremental search string to the minibuffer +that reads FROM-STRING. This function is usually the wrong thing to use in a Lisp program. What you probably want is a loop like this: @@ -540,8 +544,9 @@ (defun replace-regexp (regexp to-string text, TO-STRING is actually made a list instead of a string. Use \\[repeat-complex-command] after this command for details. -If `query-replace-interactive' is non-nil, the last incremental search -regexp is used as REGEXP--you don't have to specify it with the minibuffer. +Use \\\\[next-history-element] \ +to pull the last incremental search regexp to the minibuffer +that reads REGEXP. This function is usually the wrong thing to use in a Lisp program. What you probably want is a loop like this: