Search code examples
regexemacsauctex

emacs, auctex and query-replace strings with newline


I use emacs+auctex and auto-fill-mode.

Now sometimes I want to search (and replace) a string containing spaces like "test1 test2". The problem is, that auto-fill-mode replaces space-characters sometimes by newline characters. So search and replace of "test1 test2" does not find those occurrences of this string where auto-fill replaced the whitespace by a newline character.

Any idea how to solve this problem?

I text mode it works to use \s- in query-replace-regexp, i.e. "test1\s-test2" but this does not work in auctex-mode, I don't know why.

Using C-q C-j is very uncomfortable to use, because such cases as "test1 test2" occur very often especially because I want to get the newlines and the spaces in one run, so I have to do something like this:

M-x query-replace-regexp RET

test1[ <-- one space

C-j C-q

]\s-*test2

The last \s-* is because of possible indentations in auctex. This seems not to be very elegant.

By the way if you want to search and replace "test1 test2" is is very annoying to think every time of treating the newline cases specially...


Solution

  • Emacs also has "categories", which are like syntax classes, but a little more flexible. You can use \cX in regular expressions to match a character in category X.

    Here's a function to define an "all-whitespace" category, which includes spaces, newlines, tabs, and form feeds, that you can cite in regular expressions as \cs.

    (defun define-all-whitespace-category (table)
      "Define the 'all-whitespace' category, 's', in the category table TABLE."
      ;; First, clear out any existing definition for category 's'. Otherwise,
      ;; define-category throws an error if one calls this function more than once.
      (aset (char-table-extra-slot table 0) (- ?s ? ) nil)
      ;; Define the new category.
      (define-category ?s "all whitespace
    All whitespace characters, including tab, form feed, and newline"
        table)
      ;; Add characters to it.
      (mapc (lambda (c) (modify-category-entry c ?s table))
            '(?  ?\n ?\f ?\t)))
    
    (define-all-whitespace-category (standard-category-table))
    

    It looks to me like auctex-mode uses the standard category table, so you should be able to use query-replace-regexp with foo\cs+bar in that mode.

    To test it out, you can put point on some character of interest and say:

    M-: (looking-at "\\cs") RET
    

    which will evaluate to t if the character under point is in the all-whitespace category.