aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuri Linkov2025-05-28 20:15:21 +0300
committerJuri Linkov2025-05-28 20:15:21 +0300
commit295f73d23d337593959ec7d73ecbcfa61a732f0f (patch)
tree7f9f0f5ae02cbde042c67e0e41008b69117efbb6
parent6279a9e8ef701c2eef8c198b7b26f235bb41f2b0 (diff)
downloademacs-295f73d23d337593959ec7d73ecbcfa61a732f0f.tar.gz
emacs-295f73d23d337593959ec7d73ecbcfa61a732f0f.zip
* lisp/isearch.el (search-within-boundaries): Optimize (bug#78520).
For non-subregexp case, search for the first match and continue from its position. This avoids unnecessary scan for all text properties until the first match. When nothing is found, skip the entire body.
-rw-r--r--lisp/isearch.el41
1 files changed, 27 insertions, 14 deletions
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 6b759f4ad3e..68519b7a820 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -4610,9 +4610,7 @@ defaults to the value of `isearch-search-fun-default' when nil."
4610(defun search-within-boundaries ( search-fun get-fun next-fun 4610(defun search-within-boundaries ( search-fun get-fun next-fun
4611 string &optional bound noerror count) 4611 string &optional bound noerror count)
4612 (let* ((old (point)) 4612 (let* ((old (point))
4613 ;; Check if point is already on the property. 4613 beg end found skip (i 0)
4614 (beg (when (funcall get-fun old) old))
4615 end found (i 0)
4616 (subregexp 4614 (subregexp
4617 (and isearch-regexp 4615 (and isearch-regexp
4618 (save-match-data 4616 (save-match-data
@@ -4622,18 +4620,33 @@ defaults to the value of `isearch-search-fun-default' when nil."
4622 (when (subregexp-context-p string (match-beginning 0)) 4620 (when (subregexp-context-p string (match-beginning 0))
4623 ;; The ^/$ is not inside a char-range or escaped. 4621 ;; The ^/$ is not inside a char-range or escaped.
4624 (throw 'subregexp t)))))))) 4622 (throw 'subregexp t))))))))
4625 ;; Otherwise, try to search for the next property. 4623
4626 (unless beg 4624 ;; Optimization for non-subregexp case to set the initial position
4627 (setq beg (funcall next-fun old)) 4625 ;; on the first match assuming there is no need to check boundaries
4628 (when beg 4626 ;; for a search string/regexp without anchors (bug#78520).
4629 (if (or (null bound) 4627 (unless subregexp
4630 (if isearch-forward 4628 (save-match-data
4631 (< beg bound) 4629 (if (funcall (or search-fun (isearch-search-fun-default))
4632 (> beg bound))) 4630 string bound noerror count)
4633 (goto-char beg) 4631 (goto-char (if isearch-forward (match-beginning 0) (match-end 0)))
4634 (setq beg nil)))) 4632 (setq skip t))))
4633
4634 (unless skip
4635 ;; Check if point is already on the property.
4636 (setq beg (when (funcall get-fun (point)) (point)))
4637 ;; Otherwise, try to search for the next property.
4638 (unless beg
4639 (setq beg (funcall next-fun (point)))
4640 (when beg
4641 (if (or (null bound)
4642 (if isearch-forward
4643 (< beg bound)
4644 (> beg bound)))
4645 (goto-char beg)
4646 (setq beg nil)))))
4647
4635 ;; Non-nil `beg' means there are more properties. 4648 ;; Non-nil `beg' means there are more properties.
4636 (while (and beg (not found)) 4649 (while (and beg (not found) (not skip))
4637 ;; Search for the end of the current property. 4650 ;; Search for the end of the current property.
4638 (setq end (funcall next-fun beg)) 4651 (setq end (funcall next-fun beg))
4639 ;; Handle ^/$ specially by matching in a temporary buffer. 4652 ;; Handle ^/$ specially by matching in a temporary buffer.