Automatically wrapping I-search?

2020-02-21 04:54发布

问题:

In Vim I can :set wrapscan so that when I do an incremental search, the cursor jumps to the first match whether the first match is above or below the cursor.

In Emacs, if I start a search via C-s, the search fails saying Failing I-search if the first match is above the cursor. If I hit C-s again it then wraps the search, saying Wrapped I-search. How do I wrap and jump the cursor by default as in Vim, without having to C-s a second time?

回答1:

The easiest way to do this is to use the following defadvice:

(defadvice isearch-repeat (after isearch-no-fail activate)
  (unless isearch-success
    (ad-disable-advice 'isearch-repeat 'after 'isearch-no-fail)
    (ad-activate 'isearch-repeat)
    (isearch-repeat (if isearch-forward 'forward))
    (ad-enable-advice 'isearch-repeat 'after 'isearch-no-fail)
    (ad-activate 'isearch-repeat)))

When Isearch fails, it immediately tries again with wrapping. Note that it is important to temporarily disable this defadvice to prevent an infinite loop when there are no matches.



回答2:

Jurta's answer got most of the way there. This is the wanted behavior:

;; Prevents issue where you have to press backspace twice when
;; trying to remove the first character that fails a search
(define-key isearch-mode-map [remap isearch-delete-char] 'isearch-del-char)

(defadvice isearch-search (after isearch-no-fail activate)
  (unless isearch-success
    (ad-disable-advice 'isearch-search 'after 'isearch-no-fail)
    (ad-activate 'isearch-search)
    (isearch-repeat (if isearch-forward 'forward))
    (ad-enable-advice 'isearch-search 'after 'isearch-no-fail)
    (ad-activate 'isearch-search)))


标签: search emacs