From 3194f1ccd99cfd13ddaf621d6e7f1e1aa1645165 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Mon, 7 Dec 2015 15:12:15 +0000 Subject: [PATCH] Further progress making Isearch, Ispell, Replace work with Follow Mode. * lisp/follow.el: (follow-mode): Remove references to sit*-for-function, which no longer exists. Add follow-post-command-hook to three special purpose hooks at setup, and remove them at tear down. * lisp/isearch.el: (isearch-update): invoke isearch-update-post-hook before isearch-lazy-highlight-new-loop. (isearch-lazy-highlight-new-loop): Restore this function to what it previously was, merging the functionality of isearch-lazy-highlight-maybe-new-loop into it. (isearch-lazy-highlight-maybe-new-loop): function removed. * lisp/replace.el: (replace-update-post-hook): New hook variable. (perform-replace): Add second (nil) argument to looking-back. Invoke replace-update-post-hook before calling replace-highlight. * lisp/textmodes/ispell.el: (ispell-update-post-hook): New hook variable. (ispell-command-loop): invoke ispell-update-post-hook. Add GROUP argument to call of pos-visible-in-window-p. (ispell-display-buffer): Place *Choices* window at the top of the last window in a window group. --- lisp/follow.el | 10 +++++++--- lisp/isearch.el | 31 +++++++++++-------------------- lisp/replace.el | 8 ++++++-- lisp/textmodes/ispell.el | 20 +++++++++++++++++--- 4 files changed, 41 insertions(+), 28 deletions(-) diff --git a/lisp/follow.el b/lisp/follow.el index 2cbf0f2b93d..609b29f7ccd 100644 --- a/lisp/follow.el +++ b/lisp/follow.el @@ -423,6 +423,9 @@ Keys specific to Follow mode: (add-hook 'post-command-hook 'follow-post-command-hook t) (add-hook 'window-size-change-functions 'follow-window-size-change t) (add-hook 'after-change-functions 'follow-after-change nil t) + (add-hook 'isearch-update-post-hook 'follow-post-command-hook nil t) + (add-hook 'replace-update-post-hook 'follow-post-command-hook nil t) + (add-hook 'ispell-update-post-hook 'follow-post-command-hook nil t) (setq window-start-group-function 'follow-window-start) (setq window-end-group-function 'follow-window-end) @@ -431,8 +434,7 @@ Keys specific to Follow mode: (setq pos-visible-in-window-p-group-function 'follow-pos-visible-in-window-p) (setq selected-window-group-function 'follow-all-followers) - (setq move-to-window-line-group-function 'follow-move-to-window-line) - (setq sit*-for-function 'follow-sit-for)) + (setq move-to-window-line-group-function 'follow-move-to-window-line)) ;; Remove globally-installed hook functions only if there is no ;; other Follow mode buffer. @@ -445,7 +447,6 @@ Keys specific to Follow mode: (remove-hook 'post-command-hook 'follow-post-command-hook) (remove-hook 'window-size-change-functions 'follow-window-size-change))) - (kill-local-variable 'sit*-for-function) (kill-local-variable 'move-to-window-line-group-function) (kill-local-variable 'selected-window-group-function) (kill-local-variable 'pos-visible-in-window-p-group-function) @@ -454,6 +455,9 @@ Keys specific to Follow mode: (kill-local-variable 'window-end-group-function) (kill-local-variable 'window-start-group-function) + (remove-hook 'ispell-update-post-hook 'follow-post-command-hook t) + (remove-hook 'replace-update-post-hook 'follow-post-command-hook t) + (remove-hook 'isearch-update-post-hook 'follow-post-command-hook t) (remove-hook 'after-change-functions 'follow-after-change t) (remove-hook 'compilation-filter-hook 'follow-align-compilation-windows t))) diff --git a/lisp/isearch.el b/lisp/isearch.el index 12ded02345f..8e9a686dca0 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -961,7 +961,8 @@ used to set the value of `isearch-regexp-function'." (defun isearch-update () "This is called after every isearch command to update the display. -The last thing it does is to run `isearch-update-post-hook'." +The second last thing it does is to run `isearch-update-post-hook'. +The last thing is to trigger a new round of lazy highlighting." (unless (eq (current-buffer) isearch--current-buffer) (when (buffer-live-p isearch--current-buffer) (with-current-buffer isearch--current-buffer @@ -1018,12 +1019,12 @@ The last thing it does is to run `isearch-update-post-hook'." (setq ;; quit-flag nil not for isearch-mode isearch-adjusted nil isearch-yank-flag nil) - (when isearch-lazy-highlight - (isearch-lazy-highlight-new-loop)) ;; We must prevent the point moving to the end of composition when a ;; part of the composition has just been searched. (setq disable-point-adjustment t) - (run-hooks 'isearch-update-post-hook)) + (run-hooks 'isearch-update-post-hook) + (when isearch-lazy-highlight + (isearch-lazy-highlight-new-loop))) (defun isearch-done (&optional nopush edit) "Exit Isearch mode. @@ -3068,21 +3069,7 @@ is nil. This function is called when exiting an incremental search if "22.1") (defun isearch-lazy-highlight-new-loop (&optional beg end) - "Set an idle timer, which will trigger a new `lazy-highlight' loop. -BEG and END specify the bounds within which highlighting should -occur. This is called when `isearch-update' is invoked (which -can cause the search string to change or the window(s) to -scroll). It is also used by other Emacs features. Do not start -the loop when we are executing a keyboard macro." - (setq isearch-lazy-highlight-start-limit beg - isearch-lazy-highlight-end-limit end) - (when (null executing-kbd-macro) - (setq isearch-lazy-highlight-timer - (run-with-idle-timer lazy-highlight-initial-delay nil - 'isearch-lazy-highlight-maybe-new-loop)))) - -(defun isearch-lazy-highlight-maybe-new-loop () - "If needed cleanup any previous `lazy-highlight' loop and begin a new one. + "Cleanup any previous `lazy-highlight' loop and begin a new one. BEG and END specify the bounds within which highlighting should occur. 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 @@ -3118,6 +3105,8 @@ by other Emacs features." ;; It used to check for `(not isearch-error)' here, but actually ;; lazy-highlighting might find matches to highlight even when ;; `isearch-error' is non-nil. (Bug#9918) + (setq isearch-lazy-highlight-start-limit beg + isearch-lazy-highlight-end-limit end) (setq isearch-lazy-highlight-window (selected-window) isearch-lazy-highlight-window-group (selected-window-group) isearch-lazy-highlight-window-start (window-start nil t) @@ -3140,7 +3129,9 @@ by other Emacs features." isearch-lazy-highlight-regexp-function isearch-regexp-function isearch-lazy-highlight-forward isearch-forward) (unless (equal isearch-string "") - (isearch-lazy-highlight-update)))) + (setq isearch-lazy-highlight-timer + (run-with-idle-timer lazy-highlight-initial-delay nil + 'isearch-lazy-highlight-update))))) (defun isearch-lazy-highlight-search () "Search ahead for the next or previous match, for lazy highlighting. diff --git a/lisp/replace.el b/lisp/replace.el index 54b3a71bda2..d48f4f3fdf9 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -2011,6 +2011,9 @@ passed in. If LITERAL is set, no checking is done, anyway." (when backward (goto-char (nth 0 match-data))) noedit) +(defvar replace-update-post-hook nil + "Function(s) to call after query-replace has found a match in the buffer.") + (defvar replace-search-function nil "Function to use when searching for strings to replace. It is used by `query-replace' and `replace-string', and is called @@ -2264,7 +2267,7 @@ It must return a string." (and nonempty-match (or (not regexp-flag) (and (if backward - (looking-back search-string) + (looking-back search-string nil) (looking-at search-string)) (let ((match (match-data))) (and (/= (nth 0 match) (nth 1 match)) @@ -2318,7 +2321,8 @@ It must return a string." ;; `real-match-data'. (while (not done) (set-match-data real-match-data) - (replace-highlight + (run-hooks 'replace-update-post-hook) ; Before `replace-highlight'. + (replace-highlight (match-beginning 0) (match-end 0) start end search-string regexp-flag delimited-flag case-fold-search backward) diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index fe27f0f158c..7d5bb6dbc59 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -2248,6 +2248,11 @@ If so, ask if it needs to be saved." (setq ispell-pdict-modified-p nil)) +(defvar ispell-update-post-hook nil + "A normal hook invoked from the ispell command loop. +It is called once per iteration, before displaying a prompt to +the user.") + (defun ispell-command-loop (miss guess word start end) "Display possible corrections from list MISS. GUESS lists possibly valid affix construction of WORD. @@ -2315,8 +2320,10 @@ Global `ispell-quit' set to start location to continue spell session." count (ispell-int-char (1+ count)))) (setq count (ispell-int-char (- count ?0 skipped)))) + (run-hooks 'ispell-update-post-hook) + ;; ensure word is visible - (if (not (pos-visible-in-window-p end)) + (if (not (pos-visible-in-window-p end nil nil t)) (sit-for 0)) ;; Display choices for misspelled word. @@ -2844,13 +2851,20 @@ Also position fit window to BUFFER and select it." (prog1 (condition-case nil (split-window - nil (- ispell-choices-win-default-height) 'above) + ;; Chose the last of a window group, since + ;; otherwise, the lowering of another window's + ;; TL corner would cause the logical order of + ;; the windows to be changed. + (car (last (selected-window-group))) + (- ispell-choices-win-default-height) 'above) (error nil)) (modify-frame-parameters frame '((unsplittable . t)))))) (and (not unsplittable) (condition-case nil (split-window - nil (- ispell-choices-win-default-height) 'above) + ;; See comment above. + (car (last (selected-window-group))) + (- ispell-choices-win-default-height) 'above) (error nil))) (display-buffer buffer)))) (if (not window)