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