Function: isearch-fallback
isearch-fallback is a byte-compiled function defined in isearch.el.gz.
Signature
(isearch-fallback WANT-BACKSLASH &optional ALLOW-INVALID TO-BARRIER)
Documentation
Return point to previous successful match to allow regexp liberalization.
Respects C-s (isearch-repeat-forward) and C-r (isearch-repeat-backward) by stopping at isearch-barrier as needed.
Do nothing if a backslash is escaping the liberalizing character. If WANT-BACKSLASH is non-nil, invert this behavior (for \} and \|).
Do nothing if regexp has recently been invalid unless optional ALLOW-INVALID non-nil.
If optional TO-BARRIER non-nil, ignore previous matches and go exactly to the barrier.
Source Code
;; Defined in /usr/src/emacs/lisp/isearch.el.gz
(defun isearch-fallback (want-backslash &optional allow-invalid to-barrier)
"Return point to previous successful match to allow regexp liberalization.
\\<isearch-mode-map>
Respects \\[isearch-repeat-forward] and \\[isearch-repeat-backward] by \
stopping at `isearch-barrier' as needed.
Do nothing if a backslash is escaping the liberalizing character.
If WANT-BACKSLASH is non-nil, invert this behavior (for \\} and \\|).
Do nothing if regexp has recently been invalid unless optional
ALLOW-INVALID non-nil.
If optional TO-BARRIER non-nil, ignore previous matches and go exactly
to the barrier."
;; (eq (not a) (not b)) makes all non-nil values equivalent
(when (and isearch-regexp (eq (not (isearch-backslash isearch-string))
(not want-backslash))
;; We have to check 2 stack frames because the last might be
;; invalid just because of a backslash.
(or (not isearch-error)
(not (isearch--state-error (cadr isearch-cmds)))
allow-invalid))
(if to-barrier
(progn (goto-char isearch-barrier)
(setq isearch-adjusted t))
(let* ((stack isearch-cmds)
(previous (cdr stack)) ; lookbelow in the stack
(frame (car stack)))
;; Walk down the stack looking for a valid regexp (as of course only
;; they can be the previous successful match); this conveniently
;; removes all bracket-sets and groups that might be in the way, as
;; well as partial \{\} constructs that the code below leaves behind.
;; Also skip over postfix operators -- though horrid,
;; 'ab?\{5,6\}+\{1,2\}*' is perfectly valid.
(while (and previous
(or (isearch--state-error frame)
(let* ((string (isearch--state-string frame))
(lchar (aref string (1- (length string)))))
;; The operators aren't always operators; check
;; backslashes. This doesn't handle the case of
;; operators at the beginning of the regexp not
;; being special, but then we should fall back to
;; the barrier anyway because it's all optional.
(if (isearch-backslash
(isearch--state-string (car previous)))
(eq lchar ?\})
(memq lchar '(?* ?? ?+))))))
(setq stack previous previous (cdr previous) frame (car stack)))
(when stack
;; `stack' now refers the most recent valid regexp that is not at
;; all optional in its last term. Now dig one level deeper and find
;; what matched before that.
(let ((last-other-end
(or (and (car previous)
(isearch--state-other-end (car previous)))
isearch-barrier)))
(goto-char (if isearch-forward
(max last-other-end isearch-barrier)
(min last-other-end isearch-barrier)))
(setq isearch-adjusted t)))))))