[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/idle-highlight-mode 082ce4f5fc 48/59: Fix highlighting vis
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/idle-highlight-mode 082ce4f5fc 48/59: Fix highlighting visible ranges |
Date: |
Thu, 7 Jul 2022 12:00:32 -0400 (EDT) |
branch: elpa/idle-highlight-mode
commit 082ce4f5fce581812967ae7cc76235415e44507d
Author: Campbell Barton <ideasman42@gmail.com>
Commit: Campbell Barton <ideasman42@gmail.com>
Fix highlighting visible ranges
When single buffer has multiple views, visible ranges are now updated.
---
changelog.rst | 1 +
idle-highlight-mode.el | 167 ++++++++++++++++++++++++++++++++-----------------
2 files changed, 112 insertions(+), 56 deletions(-)
diff --git a/changelog.rst b/changelog.rst
index 108db8963f..974683b79e 100644
--- a/changelog.rst
+++ b/changelog.rst
@@ -1,5 +1,6 @@
- In development (2021-08-29)
+ - Fix highlighting with multiple windows sharing one buffer.
- Add ``idle-highlight-exceptions-syntax`` so the characters used in the
syntax-table used can be customized.
- Support setting ``idle-highlight-exceptions`` to a function that takes the
word as an argument.
- Support setting ``idle-highlight-exceptions-face`` to a function that
takes list of faces as an argument.
diff --git a/idle-highlight-mode.el b/idle-highlight-mode.el
index 166706eb25..f337a48fbb 100755
--- a/idle-highlight-mode.el
+++ b/idle-highlight-mode.el
@@ -139,6 +139,41 @@ Argument POS return faces at this point."
(push face faces)))))
faces))
+(defun idle-highlight--merge-overlapping-ranges (ranges)
+ "Destructively modify and return RANGES with overlapping values removed.
+
+Where RANGES is an unordered list of (min . max) cons cells."
+ (cond
+ ((cdr ranges)
+ ;; Simple < sorting of cons cells.
+ (setq ranges
+ (sort
+ ranges
+ (lambda (x y) (or (< (car x) (car y)) (and (= (car x) (car y)) (<
(cdr x) (cdr y)))))))
+ ;; Step over `ranges', de-duplicating & adjusting elements as needed.
+ (let
+ (
+ (ranges-iter ranges)
+ (ranges-next (cdr ranges)))
+ (while ranges-next
+ (let
+ (
+ (head (car ranges-iter))
+ (next (car ranges-next)))
+ (cond
+ ((< (cdr head) (car next))
+ (setq ranges-iter ranges-next)
+ (setq ranges-next (cdr ranges-next)))
+ (t
+ (when (< (cdr head) (cdr next))
+ (setcdr head (cdr next)))
+ (setq ranges-next (cdr ranges-next))
+ (setcdr ranges-iter ranges-next)))))
+ ranges))
+
+ (t ;; No need for complex logic single/empty lists.
+ ranges)))
+
;; ---------------------------------------------------------------------------
;; Internal Context Checking Functions
@@ -192,39 +227,32 @@ Argument POS return faces at this point."
(mapc 'delete-overlay idle-highlight--overlays)
(setq idle-highlight--overlays nil)))
-(defsubst idle-highlight--highlight (target target-beg target-end)
- "Highlight TARGET found between TARGET-BEG and TARGET-END"
+(defun idle-highlight--highlight (target target-beg target-end visible-ranges)
+ "Highlight TARGET found between TARGET-BEG and TARGET-END.
+
+Argument VISIBLE-RANGES is a list of (min . max) ranges to highlight."
(idle-highlight--unhighlight)
(save-excursion
- (let
- (
- (target-regexp (concat "\\<" (regexp-quote target) "\\>"))
- (beg-ex
- (progn
- (goto-char (max (point-min) (min target-beg (window-start))))
- (beginning-of-line)
- (point)))
- (end-ex
- (progn
- (goto-char (min (point-max) (max target-end (window-end))))
- (beginning-of-line)
- (end-of-line)
- (point))))
- (dolist
- (range
- (cond
- (idle-highlight-exclude-point
- (list (cons beg-ex target-beg) (cons target-end end-ex)))
- (t
- (list (cons beg-ex end-ex)))))
- (goto-char (car range))
- (while (re-search-forward target-regexp (cdr range) t)
- (let ((ov (make-overlay (match-beginning 0) (match-end 0))))
- (overlay-put ov 'face 'idle-highlight)
- (push ov idle-highlight--overlays)))))))
-
-(defun idle-highlight--word-at-point ()
- "Highlight the word under the point."
+ (let ((target-regexp (concat "\\<" (regexp-quote target) "\\>")))
+ (dolist (range visible-ranges)
+ (pcase-let ((`(,beg . ,end) range))
+ (goto-char beg)
+ (while (re-search-forward target-regexp end t)
+ (let
+ (
+ (match-beg (match-beginning 0))
+ (match-end (match-end 0)))
+ (unless
+ (and
+ idle-highlight-exclude-point
+ (eq target-beg match-beg)
+ (eq target-end match-end))
+ (let ((ov (make-overlay match-beg match-end)))
+ (overlay-put ov 'face 'idle-highlight)
+ (push ov idle-highlight--overlays))))))))))
+
+(defun idle-highlight--word-at-point (visible-ranges)
+ "Highlight the word under the point across all VISIBLE-RANGES."
(idle-highlight--unhighlight)
(when (idle-highlight--check-symbol-at-point (point))
(let ((target-range (bounds-of-thing-at-point 'symbol)))
@@ -232,7 +260,7 @@ Argument POS return faces at this point."
(pcase-let ((`(,target-beg . ,target-end) target-range))
(let ((target (buffer-substring-no-properties target-beg
target-end)))
(when (idle-highlight--check-word target)
- (idle-highlight--highlight target target-beg target-end))))))))
+ (idle-highlight--highlight target target-beg target-end
visible-ranges))))))))
;; ---------------------------------------------------------------------------
@@ -262,41 +290,68 @@ Argument POS return faces at this point."
(defun idle-highlight--time-callback-or-disable ()
"Callback that run the repeat timer."
- ;; Ensure all other buffers are highlighted on request.
- (let ((is-mode-active (bound-and-true-p idle-highlight-mode)))
+ (let
+ ( ;; Ensure all other buffers are highlighted on request.
+ (is-mode-active (bound-and-true-p idle-highlight-mode))
+ (buf-current (current-buffer))
+ (dirty-buffer-list (list)))
+
;; When this buffer is not in the mode, flush all other buffers.
(cond
(is-mode-active
- ;; Don't update in the window loop to ensure we always
- ;; update the current buffer in the current context.
- (setq idle-highlight--dirty nil))
+ (setq idle-highlight--dirty t))
(t
;; If the timer ran when in another buffer,
;; a previous buffer may need a final refresh, ensure this happens.
(setq idle-highlight--dirty-flush-all t)))
- (when idle-highlight--dirty-flush-all
- ;; Run the mode callback for all other buffers in the queue.
- (dolist (frame (frame-list))
- (dolist (win (window-list frame -1))
- (let ((buf (window-buffer win)))
- (when
- (and
- (buffer-local-value 'idle-highlight-mode buf)
- (buffer-local-value 'idle-highlight--dirty buf))
- (with-selected-frame frame
- (with-selected-window win
- (with-current-buffer buf
- (setq idle-highlight--dirty nil)
- (idle-highlight--word-at-point)))))))))
- ;; Always keep the current buffer dirty
- ;; so navigating away from this buffer will refresh it.
- (if is-mode-active
- (setq idle-highlight--dirty t))
+ ;; Accumulate visible ranges in each buffers `idle-highlight--dirty'
+ ;; value which is temporarily used as a list to store ranges.
+ (dolist (frame (frame-list))
+ (dolist (win (window-list frame -1))
+ (let ((buf (window-buffer win)))
+ (when
+ (cond
+ (idle-highlight--dirty-flush-all
+ (and
+ (buffer-local-value 'idle-highlight-mode buf)
+ (buffer-local-value 'idle-highlight--dirty buf)))
+ (t
+ (eq buf buf-current)))
+
+ (unless (memq buf dirty-buffer-list)
+ (push buf dirty-buffer-list))
+
+ (with-current-buffer buf
+ (when (eq idle-highlight--dirty t)
+ (setq idle-highlight--dirty nil))
+ ;; Push a (min . max) cons cell,
+ ;; expanded to line bounds (to avoid clipping words).
+ (save-excursion
+ (push
+ (cons
+ (progn
+ (goto-char (max (point-min) (window-start win)))
+ (line-beginning-position))
+ (progn
+ (goto-char (min (point-max) (window-end win)))
+ (line-end-position)))
+ idle-highlight--dirty)))))))
+
+ (dolist (buf dirty-buffer-list)
+ (with-current-buffer buf
+ (let ((visible-ranges idle-highlight--dirty))
+ ;; Restore this values status as a boolean.
+ (setq idle-highlight--dirty nil)
+
+ (setq visible-ranges (idle-highlight--merge-overlapping-ranges
visible-ranges))
+ (idle-highlight--word-at-point visible-ranges))))
(cond
(is-mode-active
- (idle-highlight--word-at-point))
+ ;; Always keep the current buffer dirty
+ ;; so navigating away from this buffer will refresh it.
+ (setq idle-highlight--dirty t))
(t ;; Cancel the timer until the current buffer uses this mode again.
(idle-highlight--time-ensure nil)))))
- [nongnu] branch elpa/idle-highlight-mode created (now 5418252a11), ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode 1e0b38c09f 02/59: [Refactor] Save the last highlighted regexp in a variable for easier unhighlighting., ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode 64d6522636 10/59: Fix documentation, ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode 902df81b5a 18/59: Cleanup: deprecation warning using `in-string-p`, ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode c4be332ecb 34/59: readme: move hints into their own section, ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode aa4c7a7ada 40/59: readme: update description, ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode 4714dcafcc 36/59: readme: add default values for settings, ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode 2b627d5d45 24/59: Cleanup: be explicit that this mode isn't global, ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode 20a0fb798c 27/59: Disable the repeating idle timer when the minor mode isn't active, ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode 082ce4f5fc 48/59: Fix highlighting visible ranges,
ELPA Syncer <=
- [nongnu] elpa/idle-highlight-mode 0423fc2b38 55/59: Fix #2 Substrings of identifiers are highlighted, ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode 7401286a4b 01/59: Version 1.0. Initial Commit., ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode df7f6a84f5 07/59: Highlight only when point is on a symbol character., ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode 834d03af77 08/59: Update version to 1.1.2, ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode f360d4e7fe 12/59: [Formatting] Place defcustoms before defvars., ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode 10eda41c22 15/59: Cleanup: use '--' separator for private functions and variables, ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode fa7a82993e 16/59: Cleanup: use defvar-local, ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode 14150dde6b 17/59: Cleanup: quiet checkdoc warnings, ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode 59f5c6ce37 23/59: Add readme, ELPA Syncer, 2022/07/07
- [nongnu] elpa/idle-highlight-mode 2bc509cc28 20/59: Cleanup: byte code compiler warnings, ELPA Syncer, 2022/07/07