25

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 ?

3
  • "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
    Commented May 29, 2015 at 5:04
  • @T.Verron I am convinced now, you are right.
    – Name
    Commented May 29, 2015 at 7:43
  • There's a clever way of doing this in this answer. Commented Oct 14, 2022 at 8:41

1 Answer 1

16
(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, if case-replace and case-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))
19
  • 1
    It 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. Commented May 28, 2015 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
    Commented May 28, 2015 at 21:03
  • 1
    Thanks! Not sure why I didn't find query-replace-map before. Commented May 28, 2015 at 21:13
  • 1
    I've filed that bug report now (#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
    Commented May 28, 2015 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
    Commented May 28, 2015 at 21:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.