diff options
Diffstat (limited to 'lisp/isearch.el')
-rw-r--r-- | lisp/isearch.el | 92 |
1 files changed, 70 insertions, 22 deletions
diff --git a/lisp/isearch.el b/lisp/isearch.el index 943e24aa563..69fdc9df6d9 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -172,6 +172,29 @@ This allows you to resume earlier Isearch sessions through the command history." :type 'boolean) +(defcustom isearch-wrap-pause t + "Define the behavior of wrapping when there are no more matches. +When `t' (by default), signal an error when no more matches are found. +Then after repeating the search, wrap with `isearch-wrap-function'. +When `no', wrap immediately after reaching the last match. +When `no-ding', wrap immediately without flashing the screen. +When `nil', never wrap, just stop at the last match." + :type '(choice (const :tag "Pause before wrapping" t) + (const :tag "No pause before wrapping" no) + (const :tag "No pause and no flashing" no-ding) + (const :tag "Disable wrapping" nil)) + :version "28.1") + +(defcustom isearch-repeat-on-direction-change nil + "Whether a direction change should move to another match. +When `nil', the default, a direction change moves point to the other +end of the current search match. +When `t', a direction change moves to another search match, if there +is one." + :type '(choice (const :tag "Remain on the same match" nil) + (const :tag "Move to another match" t)) + :version "28.1") + (defvar isearch-mode-hook nil "Function(s) to call after starting up an incremental search.") @@ -1827,14 +1850,15 @@ Use `isearch-exit' to quit without signaling." ;; After taking the last element, adjust ring to previous one. (isearch-ring-adjust1 nil)) ;; If already have what to search for, repeat it. - (or isearch-success - (progn - ;; Set isearch-wrapped before calling isearch-wrap-function - (setq isearch-wrapped t) - (if isearch-wrap-function - (funcall isearch-wrap-function) - (goto-char (if isearch-forward (point-min) (point-max))))))) + (unless (or isearch-success (null isearch-wrap-pause)) + ;; Set isearch-wrapped before calling isearch-wrap-function + (setq isearch-wrapped t) + (if isearch-wrap-function + (funcall isearch-wrap-function) + (goto-char (if isearch-forward (point-min) (point-max)))))) ;; C-s in reverse or C-r in forward, change direction. + (if (and isearch-other-end isearch-repeat-on-direction-change) + (goto-char isearch-other-end)) (setq isearch-forward (not isearch-forward) isearch-success t)) @@ -1844,7 +1868,8 @@ Use `isearch-exit' to quit without signaling." (setq isearch-success t) ;; For the case when count > 1, don't keep intermediate states ;; added to isearch-cmds by isearch-push-state in this loop. - (let ((isearch-cmds isearch-cmds)) + (let ((isearch-cmds isearch-cmds) + (was-success isearch-success)) (while (<= 0 (setq count (1- (or count 1)))) (if (and isearch-success (equal (point) isearch-other-end) @@ -1859,13 +1884,26 @@ Use `isearch-exit' to quit without signaling." (forward-char (if isearch-forward 1 -1)) (isearch-search)) (isearch-search)) - (when (> count 0) - ;; Update isearch-cmds, so if isearch-search fails later, - ;; it can restore old successful state from isearch-cmds. - (isearch-push-state)) - ;; Stop looping on failure. - (when (or (not isearch-success) isearch-error) - (setq count 0))))) + (when (> count 0) + ;; Update isearch-cmds, so if isearch-search fails later, + ;; it can restore old successful state from isearch-cmds. + (isearch-push-state)) + (cond + ;; Wrap immediately and repeat the search again + ((memq isearch-wrap-pause '(no no-ding)) + (if isearch-success + (setq was-success isearch-success) + ;; If failed this time after succeeding last time + (when was-success + (setq was-success nil) + (setq count (1+ count)) ;; Increment to force repeat + (setq isearch-wrapped t) + (if isearch-wrap-function + (funcall isearch-wrap-function) + (goto-char (if isearch-forward (point-min) (point-max))))))) + ;; Stop looping on failure + (t (when (or (not isearch-success) isearch-error) + (setq count 0))))))) (isearch-push-state) (isearch-update)) @@ -1884,10 +1922,12 @@ of the buffer, type \\[isearch-beginning-of-buffer] with a numeric argument." (cond ((< count 0) (isearch-repeat-backward (abs count)) ;; Reverse the direction back - (isearch-repeat 'forward)) + (let ((isearch-repeat-on-direction-change nil)) + (isearch-repeat 'forward))) (t ;; Take into account one iteration to reverse direction - (when (not isearch-forward) (setq count (1+ count))) + (unless isearch-repeat-on-direction-change + (when (not isearch-forward) (setq count (1+ count)))) (isearch-repeat 'forward count)))) (isearch-repeat 'forward))) @@ -1905,10 +1945,12 @@ of the buffer, type \\[isearch-end-of-buffer] with a numeric argument." (cond ((< count 0) (isearch-repeat-forward (abs count)) ;; Reverse the direction back - (isearch-repeat 'backward)) + (let ((isearch-repeat-on-direction-change nil)) + (isearch-repeat 'backward))) (t ;; Take into account one iteration to reverse direction - (when isearch-forward (setq count (1+ count))) + (unless isearch-repeat-on-direction-change + (when isearch-forward (setq count (1+ count)))) (isearch-repeat 'backward count)))) (isearch-repeat 'backward))) @@ -2519,7 +2561,9 @@ Otherwise invoke whatever the calling mouse-2 command sequence is bound to outside of Isearch." (interactive "e") (let ((w (posn-window (event-start click))) - (binding (let ((overriding-terminal-local-map nil)) + (binding (let ((overriding-terminal-local-map nil) + ;; Key search depends on mode (bug#47755) + (isearch-mode nil)) (key-binding (this-command-keys-vector) t)))) (if (and (window-minibuffer-p w) (not (minibuffer-window-active-p w))) ; in echo area @@ -3012,6 +3056,10 @@ See more for options in `search-exit-option'." (goto-char isearch-pre-move-point)) (isearch-search-and-update))) (setq isearch-pre-move-point nil)) + ;; Terminate the search if point has moved to another buffer. + (unless (eq isearch--current-buffer (current-buffer)) + (when (buffer-live-p isearch--current-buffer) + (with-current-buffer isearch--current-buffer (isearch-exit)))) (force-mode-line-update)) (defun isearch-quote-char (&optional count) @@ -3488,10 +3536,10 @@ Optional third argument, if t, means if fail just return nil (no error). ;; stack overflow in regexp search. (setq isearch-error (format "%s" lossage)))) - (if isearch-success - nil + (unless isearch-success ;; Ding if failed this time after succeeding last time. (and (isearch--state-success (car isearch-cmds)) + (not (eq isearch-wrap-pause 'no-ding)) (ding)) (if (functionp (isearch--state-pop-fun (car isearch-cmds))) (funcall (isearch--state-pop-fun (car isearch-cmds)) |