views:

72

answers:

2

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...

A: 

The easiest way to patch around this would probably be to write a little elisp function.

something like:

(defun auctex-query-replace-regexp (first second replace)
  (interactive "Mfirst:\nMsecond:\nM:replace:")
  (while (re-search-forward (concat first "[ 
]*" second))
    (replace-match replace)))

Stick it in your .emacs, put point on the last ), and evaluate with C-x C-e

Bind it to a key either globally with global-set-key, or mode-specific with add-hook.

note that the character class consists of a literal space and then a literal newline, inserted with C-o or C-q C-j

This is a pretty simple example. Improving it is left as an excersize for the reader ;)

jeremiahd
+3  A: 

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.

Jim Blandy
This is a way nicer solution than mine. I am almost constantly being shown previously unknown nooks and crannies in emacs, and I like that :)
jeremiahd