diff options
Diffstat (limited to 'lisp/isearch.el')
-rw-r--r-- | lisp/isearch.el | 101 |
1 files changed, 95 insertions, 6 deletions
diff --git a/lisp/isearch.el b/lisp/isearch.el index 96168f94bd5..91aaa66a5b5 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -4410,14 +4410,17 @@ LAX-WHITESPACE: The value of `isearch-lax-whitespace' and (let ((unwind (make-symbol "minibuffer-lazy-highlight--unwind")) (after-change (make-symbol "minibuffer-lazy-highlight--after-change")) (display-count (make-symbol "minibuffer-lazy-highlight--display-count")) + (buffer (current-buffer)) overlay) (fset unwind (lambda () - (remove-function isearch-filter-predicate filter) + (when filter + (with-current-buffer buffer + (remove-function (local 'isearch-filter-predicate) filter))) (remove-hook 'lazy-count-update-hook display-count) (when overlay (delete-overlay overlay)) - (remove-hook 'after-change-functions after-change) - (remove-hook 'minibuffer-exit-hook unwind) + (remove-hook 'after-change-functions after-change t) + (remove-hook 'minibuffer-exit-hook unwind t) (let ((lazy-highlight-cleanup cleanup)) (lazy-highlight-cleanup)))) (fset after-change @@ -4441,16 +4444,102 @@ LAX-WHITESPACE: The value of `isearch-lax-whitespace' and (format minibuffer-lazy-count-format isearch-lazy-count-total))))) (lambda () - (add-hook 'minibuffer-exit-hook unwind) - (add-hook 'after-change-functions after-change) + (add-hook 'minibuffer-exit-hook unwind nil t) + (add-hook 'after-change-functions after-change nil t) (when minibuffer-lazy-count-format (setq overlay (make-overlay (point-min) (point-min) (current-buffer) t)) (add-hook 'lazy-count-update-hook display-count)) (when filter - (add-function :after-while isearch-filter-predicate filter)) + (with-current-buffer buffer + (add-function :after-while (local 'isearch-filter-predicate) filter))) (funcall after-change nil nil nil))))) +(defun isearch-search-fun-in-text-property (property &optional search-fun) + "Return the function to search inside text that has the specified PROPERTY. +The function will limit the search for matches only inside text which has +this property in the current buffer. +Optional argument SEARCH-FUN provides the function to search text, and +defaults to the value of `isearch-search-fun-default'." + (lambda (string &optional bound noerror count) + (let* ((old (point)) + ;; Check if point is already on the property. + (beg (when (get-text-property + (if isearch-forward old (max (1- old) (point-min))) + property) + old)) + end found (i 0) + (subregexp + (and isearch-regexp + (save-match-data + (catch 'subregexp + (while (string-match "\\^\\|\\$" string i) + (setq i (match-end 0)) + (when (subregexp-context-p string (match-beginning 0)) + ;; The ^/$ is not inside a char-range or escaped. + (throw 'subregexp t)))))))) + ;; Otherwise, try to search for the next property. + (unless beg + (setq beg (if isearch-forward + (next-single-property-change old property) + (previous-single-property-change old property))) + (when beg (goto-char beg))) + ;; Non-nil `beg' means there are more properties. + (while (and beg (not found)) + ;; Search for the end of the current property. + (setq end (if isearch-forward + (next-single-property-change beg property) + (previous-single-property-change beg property))) + ;; Handle ^/$ specially by matching in a temporary buffer. + (if subregexp + (let* ((prop-beg + (if (or (if isearch-forward (bobp) (eobp)) + (null (get-text-property + (+ (point) (if isearch-forward -1 0)) + property))) + ;; Already at the beginning of the field. + beg + ;; Get the real beginning of the field when + ;; the search was started in the middle. + (if isearch-forward + (previous-single-property-change beg property) + (next-single-property-change beg property)))) + (substring (buffer-substring prop-beg end)) + (offset (if isearch-forward prop-beg end)) + match-data) + (with-temp-buffer + (insert substring) + (goto-char (- beg offset -1)) + ;; Apply ^/$ regexp on the whole extracted substring. + (setq found (funcall + (or search-fun (isearch-search-fun-default)) + string (and bound (max (point-min) + (min (point-max) + (- bound offset -1)))) + noerror count)) + ;; Adjust match data as if it's matched in original buffer. + (when found + (setq found (+ found offset -1) + match-data (mapcar (lambda (m) (+ m offset -1)) + (match-data))))) + (when match-data (set-match-data match-data))) + (setq found (funcall + (or search-fun (isearch-search-fun-default)) + string (if bound (if isearch-forward + (min bound end) + (max bound end)) + end) + noerror count))) + ;; Get the next text property. + (unless found + (setq beg (if isearch-forward + (next-single-property-change end property) + (previous-single-property-change end property))) + (when beg (goto-char beg)))) + (unless found (goto-char old)) + found))) + + (defun isearch-resume (string regexp word forward message case-fold) "Resume an incremental search. STRING is the string or regexp searched for. |