From: Po Lu Date: Mon, 17 Feb 2025 08:46:48 +0000 (+0800) Subject: Adapt query-replace and lazy highlighting to text conversion X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e6107d7f571b84ac1ba76de4b889fcb5529042b6;p=emacs.git Adapt query-replace and lazy highlighting to text conversion * lisp/isearch.el (isearch-lazy-highlight-new-loop): Rather call redisplay to guarantee a valid window-start than sit-for, to account for cases where this function is called from an after-change-function bound to a special input event quickly followed by another event that does not modify the buffer. * lisp/progmodes/prog-mode.el (treesit-node-at): Declare function before references. * lisp/replace.el (perform-replace): When querying, suppress text conversion around the input loop. (cherry picked from commit b236a2529dd90c9f506243b594e2a0d33afb0946) --- diff --git a/lisp/isearch.el b/lisp/isearch.el index cb7c107660c..a0e546101a4 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -4058,7 +4058,10 @@ This is called when `isearch-update' is invoked (which can cause the search string to change or the window to scroll). It is also used by other Emacs features." (when (and (null executing-kbd-macro) - (sit-for 0) ;make sure (window-start) is credible + ;; This used to read `(sit-for 0)', but that has proved + ;; unreliable when called from within + ;; after-change-functions bound to certain special events. + (redisplay) ;make sure (window-start) is credible (or (not (equal isearch-string isearch-lazy-highlight-last-string)) (not (memq (selected-window) diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el index 23594f22ad4..0f67fb1585e 100644 --- a/lisp/progmodes/prog-mode.el +++ b/lisp/progmodes/prog-mode.el @@ -146,6 +146,8 @@ instead." (end (progn (forward-sexp 1) (point)))) (indent-region start end nil)))) +(declare-function treesit-node-at "treesit.c") + (defun prog-fill-reindent-defun (&optional argument) "Refill or reindent the paragraph or defun that contains point. diff --git a/lisp/replace.el b/lisp/replace.el index 1966d0c4b56..1ae1881ce98 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -2812,6 +2812,8 @@ and END." (<= end (cdr bounds)))) region-bounds))))) +(defvar overriding-text-conversion-style) + (defun perform-replace (from-string replacements query-flag regexp-flag delimited-flag &optional repeat-count map start end backward region-noncontiguous-p) @@ -2874,10 +2876,13 @@ characters." (limit nil) (region-filter nil) + ;; Disable text conversion during the replacement operation. + (old-text-conversion-style overriding-text-conversion-style) + overriding-text-conversion-style + ;; Data for the next match. If a cons, it has the same format as ;; (match-data); otherwise it is t if a match is possible at point. (match-again t) - (message (if query-flag (apply #'propertize @@ -2932,6 +2937,10 @@ characters." (push-mark) (undo-boundary) + (when query-flag + (setq overriding-text-conversion-style nil) + (when (fboundp 'set-text-conversion-style) + (set-text-conversion-style text-conversion-style))) (unwind-protect ;; Loop finding occurrences that perhaps should be replaced. (while (and keep-going @@ -3348,7 +3357,13 @@ characters." last-was-act-and-show nil)))))) (replace-dehighlight) (when region-filter - (remove-function isearch-filter-predicate region-filter))) + (remove-function isearch-filter-predicate region-filter)) + (when query-flag + ;; Resume text conversion. + (setq overriding-text-conversion-style + old-text-conversion-style) + (when (fboundp 'set-text-conversion-style) + (set-text-conversion-style text-conversion-style)))) (or unread-command-events (message (ngettext "Replaced %d occurrence%s" "Replaced %d occurrences%s"