summaryrefslogtreecommitdiff
path: root/lisp/isearch.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/isearch.el')
-rw-r--r--lisp/isearch.el452
1 files changed, 243 insertions, 209 deletions
diff --git a/lisp/isearch.el b/lisp/isearch.el
index b58ca8a6f70..922ab0f6ad4 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -26,7 +26,7 @@
;; Instructions
-;; For programmed use of isearch-mode, e.g. calling (isearch-forward),
+;; For programmed use of isearch-mode, e.g. calling `isearch-forward',
;; isearch-mode behaves modally and does not return until the search
;; is completed. It uses a recursive-edit to behave this way.
@@ -46,7 +46,7 @@
;; exits and searches in the last search direction.
;; Exiting immediately from isearch uses isearch-edit-string instead
-;; of nonincremental-search, if search-nonincremental-instead is non-nil.
+;; of nonincremental-search, if `search-nonincremental-instead' is non-nil.
;; The name of this option should probably be changed if we decide to
;; keep the behavior. No point in forcing nonincremental search until
;; the last possible moment.
@@ -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.")
@@ -210,6 +233,7 @@ called with the positions of the start and the end of the text
matched by Isearch and replace commands. If this function
returns nil, Isearch and replace commands will continue searching
without stopping at resp. replacing this match.
+This function is expected to be careful not to clobber the match data.
If you use `add-function' to modify this variable, you can use the
`isearch-message-prefix' advice property to specify the prefix string
@@ -381,7 +405,7 @@ A value of nil means highlight all matches shown on the screen."
(integer :tag "Some"))
:group 'lazy-highlight)
-(defcustom lazy-highlight-buffer-max-at-a-time 20
+(defcustom lazy-highlight-buffer-max-at-a-time 200 ; 20 (bug#48581)
"Maximum matches to highlight at a time (for `lazy-highlight-buffer').
Larger values may reduce Isearch's responsiveness to user input;
smaller values make matches highlight slowly.
@@ -389,7 +413,7 @@ A value of nil means highlight all matches in the buffer."
:type '(choice (const :tag "All" nil)
(integer :tag "Some"))
:group 'lazy-highlight
- :version "27.1")
+ :version "28.1")
(defcustom lazy-highlight-buffer nil
"Controls the lazy-highlighting of the full buffer.
@@ -460,11 +484,11 @@ and doesn't remove full-buffer highlighting after a search."
(make-help-screen isearch-help-for-help-internal
(purecopy "Type a help option: [bkm] or ?")
"You have typed %THIS-KEY%, the help character. Type a Help option:
-\(Type \\<help-map>\\[help-quit] to exit the Help command.)
+\(Type \\<isearch-help-map>\\[help-quit] to exit the Help command.)
-b Display all Isearch key bindings.
-k KEYS Display full documentation of Isearch key sequence.
-m Display documentation of Isearch mode.
+\\[isearch-describe-bindings] Display all Isearch key bindings.
+\\[isearch-describe-key] KEYS Display full documentation of Isearch key sequence.
+\\[isearch-describe-mode] Display documentation of Isearch mode.
You can't type here other help keys available in the global help map,
but outside of this help window when you type them in Isearch mode,
@@ -527,159 +551,6 @@ This is like `describe-bindings', but displays only Isearch keys."
'(isearch-tmm-menubar tmm-menubar menu-bar-open mouse-minor-mode-menu)
"List of commands that can open a menu during Isearch.")
-(defvar isearch-menu-bar-yank-map
- (let ((map (make-sparse-keymap)))
- (define-key map [isearch-yank-pop]
- '(menu-item "Previous kill" isearch-yank-pop-only
- :help "Replace previous yanked kill on search string"))
- (define-key map [isearch-yank-kill]
- '(menu-item "Current kill" isearch-yank-kill
- :help "Append current kill to search string"))
- (define-key map [isearch-yank-until-char]
- '(menu-item "Until char..." isearch-yank-until-char
- :help "Yank from point to specified character into search string"))
- (define-key map [isearch-yank-line]
- '(menu-item "Rest of line" isearch-yank-line
- :help "Yank the rest of the current line on search string"))
- (define-key map [isearch-yank-symbol-or-char]
- '(menu-item "Symbol/char"
- isearch-yank-symbol-or-char
- :help "Yank next symbol or char on search string"))
- (define-key map [isearch-yank-word-or-char]
- '(menu-item "Word/char"
- isearch-yank-word-or-char
- :help "Yank next word or char on search string"))
- (define-key map [isearch-yank-char]
- '(menu-item "Char" isearch-yank-char
- :help "Yank char at point on search string"))
- map))
-
-(defvar isearch-menu-bar-map
- (let ((map (make-sparse-keymap "Isearch")))
- (define-key map [isearch-complete]
- '(menu-item "Complete current search string" isearch-complete
- :help "Complete current search string over search history"))
- (define-key map [isearch-complete-separator]
- '(menu-item "--"))
- (define-key map [isearch-query-replace-regexp]
- '(menu-item "Replace search string as regexp" isearch-query-replace-regexp
- :help "Replace matches for current search string as regexp"))
- (define-key map [isearch-query-replace]
- '(menu-item "Replace search string" isearch-query-replace
- :help "Replace matches for current search string"))
- (define-key map [isearch-occur]
- '(menu-item "Show all matches for search string" isearch-occur
- :help "Show all matches for current search string"))
- (define-key map [isearch-highlight-regexp]
- '(menu-item "Highlight all matches for search string"
- isearch-highlight-regexp
- :help "Highlight all matches for current search string"))
- (define-key map [isearch-search-replace-separator]
- '(menu-item "--"))
- (define-key map [isearch-transient-input-method]
- '(menu-item "Turn on transient input method"
- isearch-transient-input-method
- :help "Turn on transient input method for search"))
- (define-key map [isearch-toggle-specified-input-method]
- '(menu-item "Turn on specific input method"
- isearch-toggle-specified-input-method
- :help "Turn on specific input method for search"))
- (define-key map [isearch-toggle-input-method]
- '(menu-item "Toggle input method" isearch-toggle-input-method
- :help "Toggle input method for search"))
- (define-key map [isearch-input-method-separator]
- '(menu-item "--"))
- (define-key map [isearch-char-by-name]
- '(menu-item "Search for char by name" isearch-char-by-name
- :help "Search for character by name"))
- (define-key map [isearch-quote-char]
- '(menu-item "Search for literal char" isearch-quote-char
- :help "Search for literal char"))
- (define-key map [isearch-special-char-separator]
- '(menu-item "--"))
- (define-key map [isearch-toggle-word]
- '(menu-item "Word matching" isearch-toggle-word
- :help "Word matching"
- :button (:toggle
- . (eq isearch-regexp-function 'word-search-regexp))))
- (define-key map [isearch-toggle-symbol]
- '(menu-item "Symbol matching" isearch-toggle-symbol
- :help "Symbol matching"
- :button (:toggle
- . (eq isearch-regexp-function
- 'isearch-symbol-regexp))))
- (define-key map [isearch-toggle-regexp]
- '(menu-item "Regexp matching" isearch-toggle-regexp
- :help "Regexp matching"
- :button (:toggle . isearch-regexp)))
- (define-key map [isearch-toggle-invisible]
- '(menu-item "Invisible text matching" isearch-toggle-invisible
- :help "Invisible text matching"
- :button (:toggle . isearch-invisible)))
- (define-key map [isearch-toggle-char-fold]
- '(menu-item "Character folding matching" isearch-toggle-char-fold
- :help "Character folding matching"
- :button (:toggle
- . (eq isearch-regexp-function
- 'char-fold-to-regexp))))
- (define-key map [isearch-toggle-case-fold]
- '(menu-item "Case folding matching" isearch-toggle-case-fold
- :help "Case folding matching"
- :button (:toggle . isearch-case-fold-search)))
- (define-key map [isearch-toggle-lax-whitespace]
- '(menu-item "Lax whitespace matching" isearch-toggle-lax-whitespace
- :help "Lax whitespace matching"
- :button (:toggle . isearch-lax-whitespace)))
- (define-key map [isearch-toggle-separator]
- '(menu-item "--"))
- (define-key map [isearch-yank-menu]
- `(menu-item "Yank on search string" ,isearch-menu-bar-yank-map))
- (define-key map [isearch-edit-string]
- '(menu-item "Edit current search string" isearch-edit-string
- :help "Edit current search string"))
- (define-key map [isearch-ring-retreat]
- '(menu-item "Edit previous search string" isearch-ring-retreat
- :help "Edit previous search string in Isearch history"))
- (define-key map [isearch-ring-advance]
- '(menu-item "Edit next search string" isearch-ring-advance
- :help "Edit next search string in Isearch history"))
- (define-key map [isearch-del-char]
- '(menu-item "Delete last char from search string" isearch-del-char
- :help "Delete last character from search string"))
- (define-key map [isearch-delete-char]
- '(menu-item "Undo last input item" isearch-delete-char
- :help "Undo the effect of the last Isearch command"))
- (define-key map [isearch-end-of-buffer]
- '(menu-item "Go to last match" isearch-end-of-buffer
- :help "Go to last occurrence of current search string"))
- (define-key map [isearch-beginning-of-buffer]
- '(menu-item "Go to first match" isearch-beginning-of-buffer
- :help "Go to first occurrence of current search string"))
- (define-key map [isearch-repeat-backward]
- '(menu-item "Repeat search backward" isearch-repeat-backward
- :help "Repeat current search backward"))
- (define-key map [isearch-repeat-forward]
- '(menu-item "Repeat search forward" isearch-repeat-forward
- :help "Repeat current search forward"))
- (define-key map [isearch-nonincremental]
- '(menu-item "Nonincremental search" isearch-exit
- :help "Start nonincremental search"
- :visible (string-equal isearch-string "")))
- (define-key map [isearch-exit]
- '(menu-item "Finish search" isearch-exit
- :help "Finish search leaving point where it is"
- :visible (not (string-equal isearch-string ""))))
- (define-key map [isearch-abort]
- '(menu-item "Remove characters not found" isearch-abort
- :help "Quit current search"
- :visible (not isearch-success)))
- (define-key map [isearch-cancel]
- `(menu-item "Cancel search" isearch-cancel
- :help "Cancel current search and return to starting point"
- :filter ,(lambda (binding)
- (if isearch-success 'isearch-abort binding))))
- map))
-
;; Note: Before adding more key bindings to this map, please keep in
;; mind that any unbound key exits Isearch and runs the command bound
;; to it in the local or global map. So in effect every key unbound
@@ -795,13 +666,116 @@ This is like `describe-bindings', but displays only Isearch keys."
;; The key translations defined in the C-x 8 prefix should add
;; characters to the search string. See iso-transl.el.
(define-key map "\C-x8\r" 'isearch-char-by-name)
-
- (define-key map [menu-bar search-menu]
- (list 'menu-item "Isearch" isearch-menu-bar-map))
-
map)
"Keymap for `isearch-mode'.")
+(easy-menu-define isearch-menu-bar-map isearch-mode-map
+ "Menu for `isearch-mode'."
+ '("Isearch"
+ ["Cancel search" isearch-cancel
+ :help "Cancel current search and return to starting point"
+ :filter (lambda (binding)
+ (if isearch-success 'isearch-abort binding))]
+ ["Remove characters not found" isearch-abort
+ :help "Quit current search"
+ :visible (not isearch-success)]
+ ["Finish search" isearch-exit
+ :help "Finish search leaving point where it is"
+ :visible (not (string-equal isearch-string ""))]
+ ["Nonincremental search" isearch-exit
+ :help "Start nonincremental search"
+ :visible (string-equal isearch-string "")]
+ ["Repeat search forward" isearch-repeat-forward
+ :help "Repeat current search forward"]
+ ["Repeat search backward" isearch-repeat-backward
+ :help "Repeat current search backward"]
+ ["Go to first match" isearch-beginning-of-buffer
+ :help "Go to first occurrence of current search string"]
+ ["Go to last match" isearch-end-of-buffer
+ :help "Go to last occurrence of current search string"]
+ ["Undo last input item" isearch-delete-char
+ :help "Undo the effect of the last Isearch command"]
+ ["Delete last char from search string" isearch-del-char
+ :help "Delete last character from search string"]
+ ["Edit next search string" isearch-ring-advance
+ :help "Edit next search string in Isearch history"]
+ ["Edit previous search string" isearch-ring-retreat
+ :help "Edit previous search string in Isearch history"]
+ ["Edit current search string" isearch-edit-string
+ :help "Edit current search string"]
+ ("Yank on search string"
+ ["Char" isearch-yank-char
+ :help "Yank char at point on search string"]
+ ["Word/char"
+ isearch-yank-word-or-char
+ :help "Yank next word or char on search string"]
+ ["Symbol/char"
+ isearch-yank-symbol-or-char
+ :help "Yank next symbol or char on search string"]
+ ["Rest of line" isearch-yank-line
+ :help "Yank the rest of the current line on search string"]
+ ["Until char..." isearch-yank-until-char
+ :help "Yank from point to specified character into search string"]
+ ["Current kill" isearch-yank-kill
+ :help "Append current kill to search string"]
+ ["Previous kill" isearch-yank-pop-only
+ :help "Replace previous yanked kill on search string"])
+ "---"
+ ["Lax whitespace matching" isearch-toggle-lax-whitespace
+ :help "Lax whitespace matching"
+ :style toggle
+ :selected isearch-lax-whitespace]
+ ["Case folding matching" isearch-toggle-case-fold
+ :help "Case folding matching"
+ :style toggle
+ :selected isearch-case-fold-search]
+ ["Character folding matching" isearch-toggle-char-fold
+ :help "Character folding matching"
+ :style toggle
+ :selected (eq isearch-regexp-function
+ 'char-fold-to-regexp)]
+ ["Invisible text matching" isearch-toggle-invisible
+ :help "Invisible text matching"
+ :style toggle
+ :selected isearch-invisible]
+ ["Regexp matching" isearch-toggle-regexp
+ :help "Regexp matching"
+ :style toggle
+ :selected isearch-regexp]
+ ["Symbol matching" isearch-toggle-symbol
+ :help "Symbol matching"
+ :style toggle
+ :selected (eq isearch-regexp-function
+ 'isearch-symbol-regexp)]
+ ["Word matching" isearch-toggle-word
+ :help "Word matching"
+ :style toggle
+ :selected (eq isearch-regexp-function 'word-search-regexp)]
+ "---"
+ ["Search for literal char" isearch-quote-char
+ :help "Search for literal char"]
+ ["Search for char by name" isearch-char-by-name
+ :help "Search for character by name"]
+ "---"
+ ["Toggle input method" isearch-toggle-input-method
+ :help "Toggle input method for search"]
+ ["Turn on specific input method" isearch-toggle-specified-input-method
+ :help "Turn on specific input method for search"]
+ ["Turn on transient input method" isearch-transient-input-method
+ :help "Turn on transient input method for search"]
+ "---"
+ ["Highlight all matches for search string" isearch-highlight-regexp
+ :help "Highlight all matches for current search string"]
+ ["Show all matches for search string" isearch-occur
+ :help "Show all matches for current search string"]
+ ["Replace search string" isearch-query-replace
+ :help "Replace matches for current search string"]
+ ["Replace search string as regexp" isearch-query-replace-regexp
+ :help "Replace matches for current search string as regexp"]
+ "---"
+ ["Complete current search string" isearch-complete
+ :help "Complete current search string over search history"]))
+
(defvar isearch-tool-bar-old-map nil
"Variable holding the old local value of `tool-bar-map', if any.")
@@ -999,12 +973,13 @@ Each element is an `isearch--state' struct where the slots are
(defvar-local isearch-mode nil) ;; Name of the minor mode, if non-nil.
(define-key global-map "\C-s" 'isearch-forward)
-(define-key esc-map "\C-s" 'isearch-forward-regexp)
+(define-key esc-map "\C-s" 'isearch-forward-regexp)
(define-key global-map "\C-r" 'isearch-backward)
-(define-key esc-map "\C-r" 'isearch-backward-regexp)
-(define-key search-map "w" 'isearch-forward-word)
-(define-key search-map "_" 'isearch-forward-symbol)
-(define-key search-map "." 'isearch-forward-symbol-at-point)
+(define-key esc-map "\C-r" 'isearch-backward-regexp)
+(define-key search-map "w" 'isearch-forward-word)
+(define-key search-map "_" 'isearch-forward-symbol)
+(define-key search-map "." 'isearch-forward-symbol-at-point)
+(define-key search-map "\M-." 'isearch-forward-thing-at-point)
;; Entry points to isearch-mode.
@@ -1184,6 +1159,42 @@ positive, or search for ARGth symbol backward if ARG is negative."
(isearch-push-state)
(isearch-update)))))
+(defcustom isearch-forward-thing-at-point '(region url symbol sexp)
+ "A list of symbols to try to get the \"thing\" at point.
+Each element of the list should be one of the symbols supported by
+`bounds-of-thing-at-point'. This variable is used by the command
+`isearch-forward-thing-at-point' to yank the initial \"thing\"
+as text to the search string."
+ :type '(repeat (symbol :tag "Thing symbol"))
+ :version "28.1")
+
+(defun isearch-forward-thing-at-point ()
+ "Do incremental search forward for the \"thing\" found near point.
+Like ordinary incremental search except that the \"thing\" found at point
+is added to the search string initially. The \"thing\" is defined by
+`bounds-of-thing-at-point'. You can customize the variable
+`isearch-forward-thing-at-point' to define a list of symbols to try
+to find a \"thing\" at point. For example, when the list contains
+the symbol `region' and the region is active, then text from the
+active region is added to the search string."
+ (interactive)
+ (isearch-forward nil 1)
+ (let ((bounds (seq-some (lambda (thing)
+ (bounds-of-thing-at-point thing))
+ isearch-forward-thing-at-point)))
+ (cond
+ (bounds
+ (when (use-region-p)
+ (deactivate-mark))
+ (when (< (car bounds) (point))
+ (goto-char (car bounds)))
+ (isearch-yank-string
+ (buffer-substring-no-properties (car bounds) (cdr bounds))))
+ (t
+ (setq isearch-error "No thing at point")
+ (isearch-push-state)
+ (isearch-update)))))
+
;; isearch-mode only sets up incremental search for the minor mode.
;; All the work is done by the isearch-mode commands.
@@ -1364,7 +1375,8 @@ The last thing is to trigger a new round of lazy highlighting."
;; the X coordinate it returns is 1 pixel beyond
;; the last visible one.
(>= (car visible-p)
- (* (window-max-chars-per-line) (frame-char-width))))
+ (* (window-max-chars-per-line) (frame-char-width)))
+ (< (car visible-p) 0))
(set-window-hscroll (selected-window) current-scroll))))
(if isearch-other-end
(if (< isearch-other-end (point)) ; isearch-forward?
@@ -1499,7 +1511,7 @@ REGEXP if non-nil says use the regexp search ring."
(apply 'propertize string properties))
(defun isearch-update-from-string-properties (string)
- "Update isearch properties from the isearch string"
+ "Update isearch properties from the isearch STRING."
(when (plist-member (text-properties-at 0 string) 'isearch-case-fold-search)
(setq isearch-case-fold-search
(get-text-property 0 'isearch-case-fold-search string)))
@@ -1877,14 +1889,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))
@@ -1894,7 +1907,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)
@@ -1909,13 +1923,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))
@@ -1934,10 +1961,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)))
@@ -1955,10 +1984,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)))
@@ -2508,7 +2539,7 @@ If search string is empty, just beep."
"Read a string from the `kill-ring' and append it to the search string."
(interactive)
(with-isearch-suspended
- (let ((string (read-from-kill-ring)))
+ (let ((string (read-from-kill-ring "Yank from kill-ring: ")))
(if (and isearch-case-fold-search
(eq 'not-yanks search-upper-case))
(setq string (downcase string)))
@@ -2536,7 +2567,7 @@ minibuffer to read a string from the `kill-ring' as `yank-pop' does."
Unlike `isearch-yank-pop', when this command is called not immediately
after a `isearch-yank-kill' or a `isearch-yank-pop-only', it only pops
the last killed string instead of activating the minibuffer to read
-a string from the `kill-ring' as `yank-pop' does. The prefix arg C-u
+a string from the `kill-ring' as `yank-pop' does. The prefix arg \\[universal-argument]
always reads a string from the `kill-ring' using the minibuffer."
(interactive "P")
(cond
@@ -2569,7 +2600,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
@@ -2695,7 +2728,7 @@ With argument, add COUNT copies of the character."
string ""))))))))
(defun isearch-search-and-update ()
- ;; Do the search and update the display.
+ "Do the search and update the display."
(when (or isearch-success
;; Unsuccessful regexp search may become successful by
;; addition of characters which make isearch-string valid
@@ -3227,7 +3260,7 @@ If there is no completion possible, say so and continue searching."
;; Message string
(defun isearch-message (&optional c-q-hack ellipsis)
- ;; Generate and print the message string.
+ "Generate and print the message string."
;; N.B.: This function should always be called with point at the
;; search point, because in certain (rare) circumstances, undesired
@@ -3356,7 +3389,7 @@ the word mode."
(defun isearch-lazy-count-format (&optional suffix-p)
"Format the current match number and the total number of matches.
-When SUFFIX-P is non-nil, the returned string is indended for
+When SUFFIX-P is non-nil, the returned string is intended for
isearch-message-suffix prompt. Otherwise, for isearch-message-prefix."
(let ((format-string (if suffix-p
lazy-count-suffix-format
@@ -3474,14 +3507,13 @@ Optional third argument, if t, means if fail just return nil (no error).
(when pos1
;; When using multiple buffers isearch, switch to the new buffer here,
;; because `save-excursion' above doesn't allow doing it inside funcall.
- (if (and multi-isearch-next-buffer-current-function
- (buffer-live-p multi-isearch-current-buffer))
- (switch-to-buffer multi-isearch-current-buffer))
+ (when multi-isearch-next-buffer-current-function
+ (multi-isearch-switch-buffer))
(goto-char pos1)
pos1)))
(defun isearch-search ()
- ;; Do the search with the current search string.
+ "Do the search with the current search string."
(if (and (eq isearch-case-fold-search t) search-upper-case)
(setq isearch-case-fold-search
(isearch-no-upper-case-p isearch-string isearch-regexp)))
@@ -3498,11 +3530,14 @@ Optional third argument, if t, means if fail just return nil (no error).
;; Clear RETRY unless the search predicate says
;; to skip this search hit.
(if (or (not isearch-success)
- (bobp) (eobp)
- (= (match-beginning 0) (match-end 0))
(funcall isearch-filter-predicate
(match-beginning 0) (match-end 0)))
- (setq retry nil)))
+ (setq retry nil)
+ ;; Advance point on empty matches before retrying
+ (when (= (match-beginning 0) (match-end 0))
+ (if (if isearch-forward (eobp) (bobp))
+ (setq retry nil isearch-success nil)
+ (forward-char (if isearch-forward 1 -1))))))
(setq isearch-just-started nil)
(when isearch-success
(setq isearch-other-end
@@ -3538,10 +3573,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))
@@ -4013,7 +4048,6 @@ Attempt to do the search exactly the way the pending Isearch would."
;; Clear RETRY unless the search predicate says
;; to skip this search hit.
(if (or (not success)
- (= (point) bound) ; like (bobp) (eobp) in `isearch-search'.
(= (match-beginning 0) (match-end 0))
(funcall isearch-filter-predicate
(match-beginning 0) (match-end 0)))
@@ -4127,13 +4161,13 @@ Attempt to do the search exactly the way the pending Isearch would."
"Update highlighting of other matches in the full buffer."
(let ((max lazy-highlight-buffer-max-at-a-time)
(looping t)
- nomore window-start window-end
- (opoint (point)))
+ nomore opoint window-start window-end)
(with-local-quit
(save-selected-window
(if (and (window-live-p isearch-lazy-highlight-window)
(not (memq (selected-window) isearch-lazy-highlight-window-group)))
(select-window isearch-lazy-highlight-window))
+ (setq opoint (point))
(setq window-start (window-group-start))
(setq window-end (window-group-end))
(save-excursion