emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/focus 74e0a30f08 2/3: Delay updating the focus until Emacs


From: ELPA Syncer
Subject: [nongnu] elpa/focus 74e0a30f08 2/3: Delay updating the focus until Emacs is idle
Date: Tue, 28 May 2024 07:00:30 -0400 (EDT)

branch: elpa/focus
commit 74e0a30f08b17d91be0df6ef0a974f80f51cff75
Author: Florian Rommel <mail@florommel.de>
Commit: Florian Rommel <mail@florommel.de>

    Delay updating the focus until Emacs is idle
    
    This improves responsiveness, especially during scrolling.
---
 focus.el | 50 +++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 41 insertions(+), 9 deletions(-)

diff --git a/focus.el b/focus.el
index bf403b46ce..df330c59f9 100644
--- a/focus.el
+++ b/focus.el
@@ -63,6 +63,15 @@ In order for changes to take effect, reenable `focus-mode'."
   :type 'number
   :group 'focus)
 
+(defcustom focus-update-idle-delay nil
+  "Delay (in seconds) before updating the focus after each command.
+The default value of nil results in an immediate update.
+Increase this value if you experience performance issues."
+  :type '(choice (const  :tag "Immediate update" nil)
+                 (const  :tag "Delayed update (0.1s)" 0.1)
+                 (number :tag "Custom delay"))
+  :group 'focus)
+
 (defface focus-unfocused
   '((t :inherit shadow))
   "The face that overlays the unfocused area."
@@ -98,6 +107,9 @@ In order for changes to take effect, reenable `focus-mode'."
 The timer calls `focus-read-only-hide-cursor' after
 `focus-read-only-blink-seconds' seconds.")
 
+(defvar-local focus-update-timer nil
+  "Timer started from `focus-update'")
+
 (defun focus-get-thing ()
   "Return the current thing, based on `focus-mode-to-thing'.
 
@@ -120,16 +132,29 @@ This also sets `focus-current-thing-cache' to the current 
thing."
              (cons beg end)))
           (t (bounds-of-thing-at-point thing)))))
 
-(defun focus-move-focus ()
+(defun focus-move-focus (buffer)
   "Move the focused section according to `focus-bounds'.
 
 If `focus-mode' is enabled, this command fires after each
 command."
-  (with-current-buffer focus-buffer
+  (with-current-buffer buffer
+    (setq focus-update-timer nil)
     (let* ((bounds (focus-bounds)))
       (when bounds
         (focus-move-overlays (car bounds) (cdr bounds))))))
 
+(defun focus-update ()
+  "Trigger an update of the focus.
+
+When `focus-update-idle-delay' is non-nil, start update after the
+specified idle delay."
+  (if focus-update-idle-delay
+      (unless focus-update-timer
+        (setq focus-update-timer
+              (run-with-idle-timer focus-update-idle-delay nil
+                                   #'focus-move-focus focus-buffer)))
+    (focus-move-focus focus-buffer)))
+
 (defun focus-move-overlays (low high)
   "Move the overlays to highlight the region between LOW and HIGH."
   (move-overlay focus-pre-overlay (point-min) low)
@@ -141,7 +166,7 @@ command."
 
 It sets the `focus-pre-overlay', `focus-min-overlay', and
 `focus-post-overlay' to overlays; these are invisible until
-`focus-move-focus' is run.  It adds `focus-move-focus' to
+`focus-update' is run.  It adds `focus-update' to
 `post-command-hook'."
   (unless (or focus-pre-overlay focus-post-overlay)
     (setq focus-pre-overlay  (make-overlay (point-min) (point-min))
@@ -151,8 +176,9 @@ It sets the `focus-pre-overlay', `focus-min-overlay', and
     (overlay-put focus-mid-overlay 'face 'focus-focused)
     (mapc (lambda (o) (overlay-put o 'face 'focus-unfocused))
           (list focus-pre-overlay focus-post-overlay))
-    (add-hook 'post-command-hook 'focus-move-focus nil t)
-    (setq focus-current-thing-cache nil)
+    (setq focus-current-thing-cache nil
+          focus-update-timer nil)
+    (add-hook 'post-command-hook 'focus-update nil t)
     (add-hook 'change-major-mode-hook 'focus-terminate nil t)))
 
 (defun focus-terminate ()
@@ -160,12 +186,15 @@ It sets the `focus-pre-overlay', `focus-min-overlay', and
 
 The overlays pointed to by `focus-pre-overlay',
 `focus-mid-overlay' and `focus-post-overlay' are deleted, and
-`focus-move-focus' is removed from `post-command-hook'."
+`focus-update' is removed from `post-command-hook'."
   (when (and focus-pre-overlay focus-post-overlay)
     (mapc 'delete-overlay
           (list focus-pre-overlay focus-mid-overlay focus-post-overlay))
-    (remove-hook 'post-command-hook 'focus-move-focus t)
+    (remove-hook 'post-command-hook 'focus-update t)
+    (when focus-update-timer
+      (cancel-timer focus-update-timer))
     (setq focus-current-thing-cache nil
+          focus-update-timer nil
           focus-pre-overlay nil
           focus-mid-overlay nil
           focus-post-overlay nil)))
@@ -194,13 +223,16 @@ default is overwritten.  This function simply helps set 
the
   (when (bound-and-true-p focus-mode)
     (when (region-active-p)
       (focus-move-overlays (region-beginning) (region-end)))
-    (remove-hook 'post-command-hook 'focus-move-focus t)))
+    (when focus-update-timer
+      (cancel-timer focus-update-timer))
+    (setq focus-update-timer nil)
+    (remove-hook 'post-command-hook 'focus-update t)))
 
 (defun focus-unpin ()
   "Unpin the focused section."
   (interactive)
   (when (bound-and-true-p focus-mode)
-    (add-hook 'post-command-hook 'focus-move-focus nil t)))
+    (add-hook 'post-command-hook 'focus-update nil t)))
 
 (defun focus-next-thing (&optional n)
   "Move the point to the middle of the Nth next thing."



reply via email to

[Prev in Thread] Current Thread [Next in Thread]