From 6811cdc4de20de54ea52fabcdf18988bab9ccc3e Mon Sep 17 00:00:00 2001 From: Yuki Date: Fri, 21 Sep 2018 18:42:31 +0200 Subject: [PATCH] Draft search highlighting across multiple buffers Provide a pilot version as PoC. No cross-buffer highlighting for substitution in this version. On the way improve overall performance of highlighting by removing `run-at-time` and introducing `window-end` with `update` equal `t`. --- evil-search.el | 81 ++++++++++++++++++++++++++------------------------ evil-vars.el | 10 ------- 2 files changed, 42 insertions(+), 49 deletions(-) diff --git a/evil-search.el b/evil-search.el index 896b3b58b..c906f62e8 100644 --- a/evil-search.el +++ b/evil-search.el @@ -538,19 +538,30 @@ The following properties are supported: "Set the list of active overlays of the highlight HL to OVERLAYS." (aset hl 8 overlays)) +(defun evil-ex-hl-buffers() + "Return buffers to highlight in." + (let ((bufs (list)) buf) + (dolist (win (window-list nil -1 nil)) + (setq buf (window-buffer win)) + (unless (memq buf bufs) + (setq bufs (append bufs (list buf))))) + bufs)) + (defun evil-ex-delete-hl (name) "Remove the highlighting object with a certain NAME." - (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist)))) - (when hl - (mapc #'delete-overlay (evil-ex-hl-overlays hl)) - (setq evil-ex-active-highlights-alist - (assq-delete-all name evil-ex-active-highlights-alist)) - (evil-ex-hl-update-highlights)) - (when (null evil-ex-active-highlights-alist) - (remove-hook 'window-scroll-functions - #'evil-ex-hl-update-highlights-scroll t) - (remove-hook 'window-size-change-functions - #'evil-ex-hl-update-highlights-resize)))) + (dolist (buf (evil-ex-hl-buffers)) + (with-current-buffer buf + (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist)))) + (when hl + (mapc #'delete-overlay (evil-ex-hl-overlays hl)) + (setq evil-ex-active-highlights-alist + (assq-delete-all name evil-ex-active-highlights-alist)) + (evil-ex-hl-update-highlights)) + (when (null evil-ex-active-highlights-alist) + (remove-hook 'window-scroll-functions + #'evil-ex-hl-update-highlights-scroll t) + (remove-hook 'window-size-change-functions + #'evil-ex-hl-update-highlights-resize)))))) (defun evil-ex-hl-active-p (name) "Whether the highlight with a certain NAME is active." @@ -564,7 +575,7 @@ The following properties are supported: (if (zerop (length pattern)) nil pattern)) - (evil-ex-hl-idle-update)))) + (evil-ex-hl-update)))) (defun evil-ex-hl-set-region (name beg end &optional type) "Set minimal and maximal position of highlight NAME to BEG and END." @@ -572,7 +583,7 @@ The following properties are supported: (when hl (evil-ex-hl-set-min hl beg) (evil-ex-hl-set-max hl end) - (evil-ex-hl-idle-update)))) + (evil-ex-hl-update)))) (defun evil-ex-hl-get-max (name) "Return the maximal position of the highlight with name NAME." @@ -599,7 +610,7 @@ The following properties are supported: (list (evil-ex-hl-window hl)))) (let ((beg (max (window-start win) (or (evil-ex-hl-min hl) (point-min)))) - (end (min (window-end win) + (end (min (window-end win t) (or (evil-ex-hl-max hl) (point-max))))) (when (< beg end) (push (cons beg end) ranges)))) @@ -716,28 +727,16 @@ Note that this function ignores the whole-line property of PATTERN." (t (user-error "Unknown search direction: %s" direction))))) -(defun evil-ex-hl-idle-update () - "Triggers the timer to update the highlights in the current buffer." +(defun evil-ex-hl-update () + "Update the highlights in the current buffer." (when (and evil-ex-interactive-search-highlight evil-ex-active-highlights-alist) - (when evil-ex-hl-update-timer - (cancel-timer evil-ex-hl-update-timer)) - (setq evil-ex-hl-update-timer - (run-at-time evil-ex-hl-update-delay nil - #'evil-ex-hl-do-update-highlight - (current-buffer))))) - -(defun evil-ex-hl-do-update-highlight (&optional buffer) - "Timer function for updating the highlights." - (when (buffer-live-p buffer) - (with-current-buffer buffer - (evil-ex-hl-update-highlights))) - (setq evil-ex-hl-update-timer nil)) + (evil-ex-hl-update-highlights))) (defun evil-ex-hl-update-highlights-scroll (win beg) "Update highlights after scrolling in some window." (with-current-buffer (window-buffer win) - (evil-ex-hl-idle-update))) + (evil-ex-hl-update))) (put 'evil-ex-hl-update-highlights-scroll 'permanent-local-hook t) (defun evil-ex-hl-update-highlights-resize (frame) @@ -745,7 +744,7 @@ Note that this function ignores the whole-line property of PATTERN." (let ((buffers (delete-dups (mapcar #'window-buffer (window-list frame))))) (dolist (buf buffers) (with-current-buffer buf - (evil-ex-hl-idle-update))))) + (evil-ex-hl-update))))) (put 'evil-ex-hl-update-highlights-resize 'permanent-local-hook t) ;; interactive search @@ -754,12 +753,12 @@ Note that this function ignores the whole-line property of PATTERN." This function does nothing if `evil-ex-search-interactive' or `evil-ex-search-highlight-all' is nil. " (when (and evil-ex-search-interactive evil-ex-search-highlight-all) - (with-current-buffer (or evil-ex-current-buffer (current-buffer)) - (unless (evil-ex-hl-active-p 'evil-ex-search) - (evil-ex-make-hl 'evil-ex-search - :win (minibuffer-selected-window))) - (if pattern - (evil-ex-hl-change 'evil-ex-search pattern))))) + (dolist (buf (evil-ex-hl-buffers)) + (with-current-buffer buf + (unless (evil-ex-hl-active-p 'evil-ex-search) + (evil-ex-make-hl 'evil-ex-search :win nil)) + (if pattern + (evil-ex-hl-change 'evil-ex-search pattern)))))) (defun evil-ex-search (&optional count) "Search forward or backward COUNT times for the current ex search pattern. @@ -851,7 +850,9 @@ message to be shown. This function does nothing if (evil-ex-search-goto-offset offset) ;; update highlights (when evil-ex-search-highlight-all - (evil-ex-hl-change 'evil-ex-search pattern))) + (dolist (buf (evil-ex-hl-buffers)) + (with-current-buffer buf + (evil-ex-hl-change 'evil-ex-search pattern))))) (t ;; no match (when evil-ex-search-overlay @@ -860,7 +861,9 @@ message to be shown. This function does nothing if (setq evil-ex-search-overlay nil)) ;; no highlights (when evil-ex-search-highlight-all - (evil-ex-hl-change 'evil-ex-search nil)) + (dolist (buf (evil-ex-hl-buffers)) + (with-current-buffer buf + (evil-ex-hl-change 'evil-ex-search nil)))) ;; and go to initial position (goto-char evil-ex-search-start-point))) (when (stringp message) diff --git a/evil-vars.el b/evil-vars.el index d93fc83b4..f877198f0 100644 --- a/evil-vars.el +++ b/evil-vars.el @@ -379,13 +379,6 @@ which causes the parenthesis to be highlighted." :type 'integer :group 'evil) -(defcustom evil-ex-hl-update-delay 0.02 - "Time in seconds of idle before updating search highlighting. -Setting this to a period shorter than that of keyboard's repeat -rate allows highlights to update while scrolling." - :type 'number - :group 'evil) - (defcustom evil-highlight-closing-paren-at-point-states '(not emacs insert replace) "The states in which the closing parenthesis at point should be highlighted. @@ -1843,9 +1836,6 @@ Otherwise the previous command is assumed as substitute.") (evil-define-local-var evil-ex-active-highlights-alist nil "An alist of currently active highlights.") -(evil-define-local-var evil-ex-hl-update-timer nil - "Time used for updating highlights.") - (defvar evil-ex-search-keymap (make-sparse-keymap) "Keymap used in ex-search-mode.") (define-key evil-ex-search-keymap [escape] 'abort-recursive-edit)