1

Inspired by this answer, I have written the following function to perform a query-replace inside a math environment, but it does not work.

Edit. If you execute the function, the query-search tries to find all occurrences of string1, not necessarily those in math expressions, in other words texmathp is ignored.

Any hint to correct the code is welcomed.

(defun my-query-replace-in-math (string1 string2)
  (interactive "Mfrom-string: \nMto-string: ")
  (while (and (query-replace string1 string2) (texmathp))))
3
  • What does "it does not work" mean? Elaborate. Show us details.
    – phils
    Sep 12, 2019 at 12:46
  • @phils some explanations were added.
    – Name
    Sep 12, 2019 at 12:55
  • Use isearch-filter-predicate to ignore matches that don't satisfy texmathp. See the doc for that variable.
    – Drew
    Sep 12, 2019 at 14:15

1 Answer 1

3

As suggested by @Drew, this can be achieved by setting isearch-filter-predicate appropriately. Indeed, the docstring for query-replace includes:

C-h f query-replace

...

Ignore read-only matches if ‘query-replace-skip-read-only’ is non-nil, ignore hidden matches if ‘search-invisible’ is nil, and ignore more matches using ‘isearch-filter-predicate’.

Here's a proposal allowing to toggle between "normal" and "math only" query replace:

(defun isearch-filter-visible-and-texmath (beg end)
  "Possible value for isearch-filter-predicate."
  (and (isearch-filter-visible beg end)
       (save-excursion (goto-char beg) (texmathp))))

(defun toggle-query-replace-in-maths ()
  "Toggle restricting query-replace to TeX math content."
  (interactive)
  (setq-local isearch-filter-predicate
              (if (eq isearch-filter-predicate #'isearch-filter-visible)
                  (progn
                    (message "Query replace now only in math")
                    #'isearch-filter-visible-and-texmath)
                (progn
                  (message "Query replace back to normal")
                  #'isearch-filter-visible))))

Note that setq-local is used so that the change is buffer local (it probably does not make sense for non tex buffers, anyway).

I don't find it totally satisfactory, since it will break other changes that could have been done to isearch-filter-predicate. Maybe someone will propose something better!

4
  • Thank you for devoting time to provide this answer. I may have some comments after testing.
    – Name
    Sep 14, 2019 at 14:45
  • It is interesting that, when toggle-query-replace-in-maths in enabled, one can also do an isearch-forward (C-s) in math. The only inconvenience is that, when something is found, the entire equation from its beginning until the found term is highlighted. To see what I mean do a C-s for n in $A_{n}(X_1,\ldots,X_n)=0$, then press C-s again.
    – Name
    Sep 15, 2019 at 15:02
  • @Name isearch-forward being affected is not unexpected, given the name of the variable, but the highliting is indeed annoying. This needs more investigation!
    – JeanPierre
    Sep 18, 2019 at 19:30
  • I've been struggling with this problem for a long time and I was very happy to find this very elegant solution! Thank you very much!! However I found a litthe glitch, probably within texmathp, which prevents proper behavior when replacing within a construct I often use in TeX, namely $$ long equation $$$$ long equation continued $$. The second math environment is not recognized as such, unless I use a space between the 4.th and 5.th dollar sign.
    – Ruy
    Oct 8, 2022 at 1:44

Your Answer

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

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