(redirected from isearch)

IncrementalSearch

Isearch, that is, incremental search, is the standard way to search in vanilla Emacs. Type ‘C-s’ and start typing a search string – Emacs finds a match to what you’ve typed so far. Change your input, and Emacs adjusts to find the new target. This dynamic, on-the-fly behavior is what is meant by “incremental” search.

Regexp Searches (On Beyond Wildcards)

Searching with regular expressions (regexps) is searching with wildcards (and more). If you aren’t already searching using regexps, then that’s the next thing you should learnNOW!

Try ‘C-M-s’ (forward) or ‘C-M-r’ (backward) – or you can use ‘M-r’ after ‘C-s’ or ‘C-r’ (i.e., during a literal search).

With regexp searching you will need to think a little more, but will do fewer searches for a task, and will be able to more precisely get what you’re searching for.

To learn about regexps, see RegularExpression.

Standard Isearch Keys

You can define your own keymap to extend Isearch with some other key bindings (see MoreIsearchKeys, below), but Isearch already comes with these handy keybindings (and more):

More Isearch Keys: Adding Key Bindings

       (define-key isearch-mode-map (kbd "C-y") 'isearch-yank-kill)
Why? Up until Emacs 24.1, ‘C-y’ in Isearch didn’t do what you might expect: Instead of yanking from the ‘kill-ring’ to the search string, it acts on the current line.
       (defun isearch-yank-sexp ()
         "*Pull next expression from buffer into search string."
         (interactive)
         (isearch-yank-internal (lambda () (forward-sexp 1) (point))))
Bind it to some key of your preference in isearch-mode-map.
       (define-key isearch-mode-map [next]
         'isearch-repeat-forward)
       (define-key isearch-mode-map [prior]
         'isearch-repeat-backward)
    (define-key isearch-mode-map "\C-o" 
          '(lambda ()(interactive)(isearch-process-search-char ?\n)))

Position of the Cursor after Searching

Note that when you type ‘C-r’, isearch goes backwards. When you search backwards, find something, and then end the search, for example by hitting ‘RET’, point is at the beginning of the string you searched. When you search forwards, point is not necessarily at the end of the string you were searching for, but only after the last character that you typed – bad usability! That means that you cannot predict point based on the string you are searching for (and thinking about). You must predict point based on the numbers of characters you typed.

Here is how to change that in your InitFile, courtesy of AdrianKubala:

    (add-hook 'isearch-mode-end-hook 'my-goto-match-beginning)
    (defun my-goto-match-beginning ()
      (when (and isearch-forward isearch-other-end)
        (goto-char isearch-other-end)))
    (defadvice isearch-exit (after my-goto-match-beginning activate)
      "Go to beginning of match."
      (when (and isearch-forward isearch-other-end)
        (goto-char isearch-other-end)))

With this hook, both ‘C-g’ and ‘RET’ exit the search at the begining of the search string. To recover the old behaviour of ‘C-g’ (going back to where you where before starting the search), you can change the hook to (only tested on Emacs 22):

    (defun my-goto-match-beginning ()
      (when (and isearch-forward isearch-other-end (not isearch-mode-end-hook-quit))
        (goto-char isearch-other-end)))

Tip: To get back to where you started the search, just use ‘C-x C-x’. This works because isearch sets the mark at the search start (if point ends up elsewhere after searching).

Note: Emacs 21 currently has a bug in that ‘isearch-mode-end-hook’ is called after ‘C-g’ exits an isearch. That means that if you end a search with ‘C-g’ you cannot use ‘C-x C-x’ to get back to where you were before searching.

Since I submitted that bug, I’ve heard back that it will be corrected in the next GNU Emacs release. – DrewAdams

Another way to get the functionality of jumping to the beginning of the search-term is simply adding a little wrapper function and binding it to a different key. I find C-v a good candidate, you don’t usually want to jump to next page when searching:

    (define-key isearch-mode-map (kbd "C-v") 'my-isearch-forward-to-beginning)
    (defun my-isearch-forward-to-beginning ()
      "Do a forward search and jump to the beginning of the search-term."
      (interactive)
      (isearch-repeat 'forward)
      (goto-char isearch-other-end))

Now you can use C-s to search normally (point at end) and C-v to make point jump to beginning. Alternatively, you can swap these two keys if you prefer the new behaviour more often.

    (define-key isearch-mode-map (kbd "C-s") 'my-isearch-forward-to-beginning)
    (define-key isearch-mode-map (kbd "C-v") 'isearch-repeat-forward)

– Fuco

See also: IsearchOtherEnd.

Feedback During Isearch

Library oneonone.el changes the background color of the (separate) minibuffer frame when you search. Screenshots of the minibuffer frame (normal, followed by isearch):

DrewsEmacsMinibufferFrame DrewsEmacsMinibufferFrameIsearch

Icicles Search: Another Way to Search Incrementally

Besides enhancing Isearch completion (see MoreIsearchKeys, above), Icicles provides an additional, unusual way of searching incrementally that is akin to both isearch and ‘occur’ – but weirder! The explanation is here: Icicles - Search Commands, Overview. Highlights:

“Incremental” has a double meaning here:

Display last searched string in minibuffer prompt

 (add-hook 'isearch-mode-hook (lambda () (interactive)
   (setq isearch-message (concat isearch-message "[ " (car search-ring) " ] "))
   (isearch-search-and-update)))

See Also

Here is some more info about Isearch:

I often search for a string which I want to grab and paste elsewhere: So I want to find it, mark it, and kill it. I can use C-w/C-z to extend the search string (either by word or by sexp), and then I just want to grab is somehow: I think it’s natural to bind it to M-w.

Here’s how:

  (defun isearch-save-and-exit ()
     "Exit search normally. and save the `search-string' on kill-ring."
    (interactive)
    (isearch-done)
    (isearch-clean-overlays)
    (kill-new isearch-string))
 
  (define-key isearch-mode-map    "\M-w" 'isearch-save-and-exit)

SearchAndReplace CategoryRegexp