Initiating interactive regexp search programmatically

256 Views Asked by At

I'd like to define a command that initiates an isearch-forward-regexp with a predefined regexp.

Say I want to find all occurrences of either "aaa" or "bbb". The regexp which I can enter interactively with isearch-forward-regexp is \\(aaa\\|bbb\\)

Is there any way to do this without entering the regexp interactively? I've tried things like this:

(defun my-search ()
(interactive)
(isearch-mode t t)
(isearch-yank-string "\\(aaa\\|bbb\\)"))

but this approach doesn't seem to work because there doesn't seem to be any way to define a string in emacs that evaluates to \\(aaa\\|bbb\\) when yanked into isearch.

For instance "\\(aaa" evaluates to (aaa, but "\\\\(aaa" evaluates to \\\\(aaa. There doesn't seem to be a way to evaluate to a single backslash.

Is there a way of doing what I want?

1

There are 1 best solutions below

6
On

This command should do what I think you are asking for:

(defun foo (regexp) 
  (interactive (list (read-regexp "Regexp: ")))
  (isearch-mode t t)
  (let ((isearch-regexp  nil))
    (isearch-yank-string regexp)))

For example: M-x foo RET, then enter \(aaa\|bbb\) RET.

If you call it from Lisp instead of interactively then just provide the regexp you want as a string. For example:

(foo "\\(aaa\\|bbb\\)")

Note that isearch-yank-string does this:

(if isearch-regexp (setq string (regexp-quote string)))

That's why foo binds isearch-regexp to nil around the call to isearch-yank-string: to prevent quoting regexp special chars in the string.