all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Kaushal <kaushal.modi@gmail.com>
To: Drew Adams <drew.adams@oracle.com>, Juri Linkov <juri@linkov.net>
Cc: 20687@debbugs.gnu.org
Subject: bug#20687: 25.0.50; `perform-replace' should invoke a key that you have bound in `query-replace-map'
Date: Wed, 03 Jun 2015 03:35:15 +0000	[thread overview]
Message-ID: <CAFyQvY038fk87ecRuKLFctOEZd6gEaAHvpBfYHOQ6HV=aFK6cA@mail.gmail.com> (raw)
In-Reply-To: <f0a2bf44-165c-4125-8985-87fb17e31087@default>

[-- Attachment #1: Type: text/plain, Size: 10524 bytes --]

In that case, the patch becomes much more complicated.

We have to modify the query-replace-map in replace.el itself as we cannot
access the internal variables required to printed this message in
isearch-style with (sit-for 1):

(message query-replace-in-progress-message
                                    (query-replace-descr from-string)
                                    (query-replace-descr
replacement-presentation)
                                    query-message-momentary)

Here: from-string, replacement-presentation are internal variables and
cannot be used in a function defined outside that (cond ..) form. So the
earlier approach to define a function externally to toggle the case and to
bind that to query-replace-map from outside does not apply (if we want to
flash the case fold toggle info momentarily as done in isearch). Even the
replacement-presentation was in a (let .. ) form not accessible to the
(cond ..) form and so I moved it to an outer (let ..) form as seen in the
below patch.

I tested this out and the M-c and M-r bindings work great. It now also
gives clear info on what the user should expect after that binding is used.
Please give it a try.

I have still kept this line

 (def (call-interactively def)) ; User-defined key, invoke it.

as it could be useful to bind any other function from outside that does not
need internal variables.

--- replace.el 2015-06-02 23:21:42.631715000 -0400
+++ replace-editted.el 2015-06-02 23:32:47.754001000 -0400
@@ -1834,6 +1834,8 @@
     (define-key map [M-next] 'scroll-other-window)
     (define-key map [?\C-\M-\S-v] 'scroll-other-window-down)
     (define-key map [M-prior] 'scroll-other-window-down)
+    (define-key map "\M-c" 'toggle-query-case)
+    (define-key map "\M-r" 'toggle-replace-preserve-case)
     ;; Binding ESC would prohibit the M-v binding.  Instead, callers
     ;; should check for ESC specially.
     ;; (define-key map "\e" 'exit-prefix)
@@ -2100,12 +2102,14 @@
          ;; (match-data); otherwise it is t if a match is possible at
point.
          (match-again t)

-         (message
+         (query-replace-in-progress-message
           (if query-flag
               (apply 'propertize
                      (substitute-command-keys
-                      "Query replacing %s with %s:
(\\<query-replace-map>\\[help] for help) ")
-                     minibuffer-prompt-properties))))
+                      (concat "Query replacing %s with %s: "
+                              "(\\<query-replace-map>\\[help] for help) %s
"))
+                     minibuffer-prompt-properties)))
+         (query-message-momentary ""))

     ;; If region is active, in Transient Mark mode, operate on region.
     (if backward
@@ -2251,7 +2255,7 @@
                          noedit real-match-data backward)
                         replace-count (1+ replace-count)))
               (undo-boundary)
-              (let (done replaced key def)
+              (let (done replaced key def replacement-presentation)
                 ;; Loop reading commands until one of them sets done,
                 ;; which means it has finished handling this
                 ;; occurrence.  Any command that sets `done' should
@@ -2266,17 +2270,18 @@
                    regexp-flag delimited-flag case-fold-search backward)
                   ;; Bind message-log-max so we don't fill up the message
log
                   ;; with a bunch of identical messages.
-                  (let ((message-log-max nil)
-                        (replacement-presentation
-                         (if query-replace-show-replacement
-                             (save-match-data
-                               (set-match-data real-match-data)
-                               (match-substitute-replacement
next-replacement
-                                                             nocasify
literal))
-                           next-replacement)))
-                    (message message
+                  (let ((message-log-max nil))
+                    (setq replacement-presentation
+                          (if query-replace-show-replacement
+                              (save-match-data
+                                (set-match-data real-match-data)
+                                (match-substitute-replacement
next-replacement
+                                                              nocasify
literal))
+                            next-replacement))
+                    (message query-replace-in-progress-message
                              (query-replace-descr from-string)
-                             (query-replace-descr
replacement-presentation)))
+                             (query-replace-descr replacement-presentation)
+                             query-message-momentary))
                   (setq key (read-event))
                   ;; Necessary in case something happens during read-event
                   ;; that clobbers the match data.
@@ -2404,6 +2409,51 @@
                          (replace-dehighlight)
                          (save-excursion (recursive-edit))
                          (setq replaced t))
+
+                        ((eq def 'toggle-query-case)
+                         (setq case-fold-search (not case-fold-search))
+                         (let ((message-log-max nil)
+                               (query-message-momentary
+                                (concat "["
+                                        (if case-fold-search
+                                            "case insensitive search"
+                                          "Case Sensitive Search")
+                                        "]")))
+                           (message query-replace-in-progress-message
+                                    (query-replace-descr from-string)
+                                    (query-replace-descr
replacement-presentation)
+                                    query-message-momentary)
+                           (sit-for 1)))
+
+                        ((eq def 'toggle-replace-preserve-case)
+                         (let ((message-log-max nil)
+                               (nocasify-value-reason "")
+                               query-message-momentary)
+                           (setq nocasify (not nocasify))
+                           (cond
+                            ((null case-fold-search)
+                             (setq nocasify nil)
+                             (setq nocasify-value-reason ", as
case-fold-search is nil"))
+                            ((null (isearch-no-upper-case-p from-string
regexp-flag))
+                             (setq nocasify nil)
+                             (setq nocasify-value-reason ", as FROM-STRING
has an upper case char."))
+                            ((null (isearch-no-upper-case-p
next-replacement regexp-flag))
+                             (setq nocasify t)
+                             (setq nocasify-value-reason ", as REPLACEMENT
has an upper case char.")))
+                           (setq query-message-momentary
+                                 (concat "[Replaced text case will "
+                                         (if nocasify "NOT " "")
+                                         "be preserved"
+                                         nocasify-value-reason
+                                         "]"))
+                           (message query-replace-in-progress-message
+                                    (query-replace-descr from-string)
+                                    (query-replace-descr
replacement-presentation)
+                                    query-message-momentary)
+                           (sit-for 1.5)))
+
+                        (def (call-interactively def)) ; User-defined key,
invoke it.
+
                         ;; Note: we do not need to treat `exit-prefix'
                         ;; specially here, since we reread
                         ;; any unrecognized character.


On Tue, Jun 2, 2015 at 6:51 PM Drew Adams <drew.adams@oracle.com> wrote:

> > > +                  ;; Show whether `case-fold-search' is `t' or `nil'
> > > +                  (if case-fold-search "[case] " "[CaSe] ")
> >
> > Maybe we should use the same message about case-folding like in
> > isearch?
>
> The msg should somehow indicate that what is involved here is (only)
> case-sensitivity wrt FROM (i.e., wrt search, not replacement).  Not
> sure what the best way to do that would be.
>
> IOW, there is more than one use of case sensitivity here, unlike
> the case for search.  There is what `case-fold-search' controls (the
> search), and there is what `case-replace' controls (the replacement).
> And then there is what happens for the replacement according to the
> case of FROM.
>
> ---
>
> BTW, we might consider binding a key to toggle case sensitivity for
> search as part of this bug fix (i.e., not just fixing `perform-replace'
> so it respects keys that user might bind).  In that case, maybe the
> same key we use in Isearch (`M-c') would be a good choice.
>
> ---
>
> BTW2, I think that Emacs manual node `Replacement and Case' is confusing.
> The first three paragraphs (2/3 of the node), for instance:
>
>  If the first argument of a replace command is all lower case, the
>  command ignores case while searching for occurrences to
>  replace--provided `case-fold-search' is non-`nil'.  If
>  `case-fold-search' is set to `nil', case is always significant in all
>  searches.
>
>   An upper-case letter anywhere in the incremental search string makes
>   the search case-sensitive.  Thus, searching for `Foo' does not find
>   `foo' or `FOO'.  This applies to regular expression search as well as
>   to string search.  The effect ceases if you delete the upper-case
>   letter from the search string.
>
>   If you set the variable `case-fold-search' to `nil', then all
>   letters must match exactly, including case.  This is a per-buffer
>   variable; altering the variable normally affects only the current
>   buffer, unless you change its default value.  *Note Locals::.  This
>   variable applies to nonincremental searches also, including those
>   performed by the replace commands (*note Replace::) and the minibuffer
>   history matching commands (*note Minibuffer History::).
>
> These paragraphs really say only that the search part of replace commands
> acts normally: `case-fold-search' governs.  They should be removed or
> changed to say just that.  Leaving them as they are just confuses readers,
> IMO.
>

[-- Attachment #2: Type: text/html, Size: 13185 bytes --]

  reply	other threads:[~2015-06-03  3:35 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-28 21:12 bug#20687: 25.0.50; `perform-replace' should invoke a key that you have bound in `query-replace-map' Drew Adams
2015-06-01 20:53 ` Juri Linkov
2015-06-01 21:11   ` Drew Adams
2015-06-02 22:01     ` Juri Linkov
2015-06-02 22:12       ` Drew Adams
2020-09-17 18:11       ` Lars Ingebrigtsen
2015-06-02 13:08 ` Kaushal
2015-06-02 22:02   ` Juri Linkov
2015-06-02 22:50     ` Drew Adams
2015-06-03  3:35       ` Kaushal [this message]
2015-06-03  4:39         ` Drew Adams
2015-06-03  5:10           ` Kaushal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAFyQvY038fk87ecRuKLFctOEZd6gEaAHvpBfYHOQ6HV=aFK6cA@mail.gmail.com' \
    --to=kaushal.modi@gmail.com \
    --cc=20687@debbugs.gnu.org \
    --cc=drew.adams@oracle.com \
    --cc=juri@linkov.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.