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 --]
next prev parent 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.