When I do M-x query-replace
to replace all occurrences of v
by w
, then it also matches V
(uppercase V
). How to force emacs to only find lowercase v
?
-
"Case-insensitive" is the default behavior, where case doesn't matter in the search. If you want to only match one case, it's "case-sensitive" that you want. (I might miss something too, feel free to rollback the edit if needed) – T. Verron May 29 '15 at 05:04
-
@T.Verron I am convinced now, you are right. – Name May 29 '15 at 07:43
-
There's a clever way of doing this in [this answer](https://emacs.stackexchange.com/a/61410/2246). – Hans Lundmark Oct 14 '22 at 08:41
1 Answers
(customize-set-variable case-fold-search nil)
Or bind that variable (option) in your own command that is otherwise just a wrapper around query-replace
. This has the advantage that it doesn't change the variable value for general use, outside of query-replacing.
See also variable case-replace
, which controls case for the replacement text.
See also C-h f query-replace
, where it says, for example:
Matching is independent of case if
case-fold-search
is non-nil and FROM-STRING has no uppercase letters. Replacement transfers the case pattern of the old text to the new text, ifcase-replace
andcase-fold-search
are non-nil and FROM-STRING has no uppercase
See also the comments below, and Emacs bug #20687, which show how you can patch perform-replace
to let you toggle case folding during query-replace
.
Note too that the existing code for perform-replace
binds case-fold-search
in this way (note the variables on which it depends):
(case-fold-search (if (and case-fold-search search-upper-case)
(isearch-no-upper-case-p from-string regexp-flag)
case-fold-search))

- 75,699
- 9
- 109
- 225
-
1It would have been nice to change `case-fold-search` on the fly as we can do during `isearch` using the `M-c` binding. But unfortunately `query-replace` does have have its mode map. – Kaushal Modi May 28 '15 at 20:38
-
3@kaushalmodi: Normally, it would be as simple as adding a key binding for that to `query-replace-map`: `(defun toggle-case () (interactive) (setq case-fold-search (not case-fold-search)))` and `(define-key query-replace-map "C" 'toggle-case)`. But the handling of keys in that map is hard-coded in `perform-replace`. You might want to `M-x report-emacs-bug`, to get the `perform-replace` code to be more open-ended, so keys can be added to the map. It should at least have a fallback clause that just invokes the cmd bound to the key. – Drew May 28 '15 at 21:03
-
1
-
1I've filed that bug report now (#[20687](http://debbugs.gnu.org/cgi/bugreport.cgi?bug=20687)). The solution is in that bug report: Just modify `perform-replace` to add an additional `cond` clause that invokes the key you've defined in `query-replace-map`. Put the new clause just before the catch-all `t` clause. This is the new clause: `(def (call-interactively def))`. Couldn't be simpler. – Drew May 28 '15 at 21:14
-
`(customize-set-variable case-fold-search nil)` gives the error `customize-set-variable: Attempt to set a constant symbol: nil`. Also I tried both `(setq case-fold-search nil)` and `(setq case-replace nil)`but the query still match the uppercase V. – Name May 28 '15 at 21:45
-
@Name `case-fold-search` is a buffer-local variable. What do you see when you do `C-h v case-fold-search` in the buffer where you are doing the `query-replace`? – Kaushal Modi May 28 '15 at 21:57
-
Your above comment about defining `(defun toggle-case () (interactive) (setq case-fold-search (not case-fold-search)))` solved my problem. When I execute `toggle-case` then I can use case-insensitive query-replace. – Name May 28 '15 at 22:18
-
Thanks **@Drew**! I got a wonderfully [working solution](https://github.com/kaushalmodi/.emacs.d/commit/6636510769fc5f115ea399d906f30ad2395638e4) to toggle the case fold during query-replace. In addition to your suggested patch, I added few more touches to a nice stable solution: [touch-1](https://github.com/kaushalmodi/.emacs.d/blob/6636510769fc5f115ea399d906f30ad2395638e4/setup-files/setup-search.el#L13-L20), [touch-2](https://github.com/kaushalmodi/.emacs.d/blob/6636510769fc5f115ea399d906f30ad2395638e4/elisp/patches/replace-patches.el#L231-L237) – Kaushal Modi May 28 '15 at 22:24
-
@kaushalmodi: After experimenting, consider sending your code as a patch to the same bug report. – Drew May 29 '15 at 00:40
-
@Drew There's only one little issue with this solution; the first match will use the default state of the `perform-replace`-internal value of `case-fold-search`. Once that match is found, only then you get a chance to hit that `C` binding to toggle the case. So for that first match, in most of the cases, you would have to hit `n` to move on to the next possible match that would satisfy the intended case fold condition. We need to get an option to toggle the case BEFORE the first match is searched for.. hope I was able to get the point across. – Kaushal Modi May 29 '15 at 01:43
-
@kaushalmodi: Yes, I know. Not a big deal, IMO. But you are welcome to look for a different solution. IMO, typically a user of this feature will start q-r, realize soon enough if case-folding is not what s?he wants, and toggle it. Often s?he will se multiple hits highlighted and understand immediately, etc. – Drew May 29 '15 at 02:19
-
So is the solution that @Drew submitted as [#20687](https://debbugs.gnu.org/cgi/bugreport.cgi?bug=20687) merged? Don't see it in Emacs 25.1.1, and there hasn't been follow-up in 2 yrs. – Tianxiang Xiong Apr 15 '17 at 00:45
-
@TianxiangXiong: Please consider pinging the bug thread, if you would like progress on this. Maybe some kind soul will take care of it. – Drew Apr 15 '17 at 03:49
-
Would be nice to just make it a command modifier, so if I C-u it performs case-sensitive matching. – Didier A. Apr 18 '19 at 00:49
-
-
@alper: Not sure I understand. Do you mean case sensitivity for matching the file name? That's controlled by the `find` command. You can typically use switch `-iname` instead of `-name`, to get case-insensitive name matching; otherwise it's case-sensitive. – Drew Jun 24 '20 at 15:45
-
@DidierA.: `C-h f query-replace` says that a prefix arg has another behavior: *"In interactive use, the prefix arg (non-nil DELIMITED in non-interactive use), means replace only matches surrounded by word boundaries. A negative prefix arg means replace backward."* – Drew Jun 24 '20 at 15:51
-
I was using `find-name-dired` to make a query change on the all files, I asked as a new question (https://emacs.stackexchange.com/q/59246/18414) to be more clear – alper Jun 24 '20 at 16:19
-
now, years later, a patch was actually merged in Emacs 28, but it's unclear to me how it can actually be used, if at all. I tried with ` (defun anarcat/toggle-case () (interactive) (setq case-fold-search (not case-fold-search)) (message "toggled case-fold-search to %s" case-fold-search)) (define-key query-replace-map (kbd "C") #'anarcat/toggle-case))` and while the (message) call shows the fold-search flipping, it doesn't actually affect the search results. this is really a big inconsistency between query replace and isearch! – anarcat May 19 '23 at 14:18