emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] scratch/jit-lock-antiblink 7ad83a6: New jit-lock-antiblink


From: João Távora
Subject: [Emacs-diffs] scratch/jit-lock-antiblink 7ad83a6: New jit-lock-antiblink-grace feature
Date: Fri, 12 Jul 2019 14:30:38 -0400 (EDT)

branch: scratch/jit-lock-antiblink
commit 7ad83a6a89745b1e528352f2c0de9766a7b58a2f
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>

    New jit-lock-antiblink-grace feature
    
    * lisp/jit-lock.el (jit-lock-antiblink-grace): New user-visible variable.
    (jit-lock--antiblink-grace-timer, jit-lock--antiblink-l-l-b)
    (jit-lock--antiblink-i-s-o-c): New helpers.
    (jit-lock-mode): Tweak post-command-hook and
    jit-lock-context-timer.
    (jit-lock--antiblink-post-command): New helper.
---
 lisp/jit-lock.el | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 74 insertions(+), 1 deletion(-)

diff --git a/lisp/jit-lock.el b/lisp/jit-lock.el
index 48998a8..7ae79f0 100644
--- a/lisp/jit-lock.el
+++ b/lisp/jit-lock.el
@@ -123,6 +123,15 @@ The value of this variable is used when JIT Lock mode is 
turned on."
   :type '(number :tag "seconds")
   :group 'jit-lock)
 
+(defcustom jit-lock-antiblink-grace 2
+  "Like `jit-lock-context-time' but for unterminated multiline strings.
+If the user has just opened an unterminated string at EOL, give
+him/her some grace time before deciding it is a multi-line string
+and fontifying accordingly, do so only if the user stares idle at
+that string for more than this many seconds."
+  :type '(number :tag "seconds")
+  :group 'jit-lock)
+
 (defcustom jit-lock-defer-time nil ;; 0.25
   "Idle time after which deferred fontification should take place.
 If nil, fontification is not deferred.
@@ -157,6 +166,15 @@ If nil, contextual fontification is disabled.")
   "List of buffers with pending deferred fontification.")
 (defvar jit-lock-stealth-buffers nil
   "List of buffers that are being fontified stealthily.")
+
+(defvar jit-lock--antiblink-grace-timer nil
+  "Idle timer for fontifying unterminated string or comment, or nil")
+(defvar jit-lock--antiblink-l-l-b (make-marker)
+  "Last line beginning (l-l-b) position after last command (a marker).")
+(defvar jit-lock--antiblink-i-s-o-c nil
+  "In string or comment (i-s-o-c) after last command (a boolean).")
+
+
 
 ;;; JIT lock mode
 
@@ -232,7 +250,10 @@ If you need to debug code run from jit-lock, see 
`jit-lock-debug-mode'."
       (unless jit-lock-context-timer
         (setq jit-lock-context-timer
               (run-with-idle-timer jit-lock-context-time t
-                                   'jit-lock-context-fontify)))
+                                   (lambda ()
+                                     (unless jit-lock--antiblink-grace-timer
+                                       (jit-lock-context-fontify))))))
+      (add-hook 'post-command-hook 'jit-lock--antiblink-post-command nil t)
       (setq jit-lock-context-unfontify-pos
             (or jit-lock-context-unfontify-pos (point-max))))
 
@@ -669,6 +690,58 @@ will take place when text is fontified stealthily."
               ;; buffer, only jit-lock-context-* will re-fontify it.
               (min jit-lock-context-unfontify-pos jit-lock-start))))))
 
+(defun jit-lock--antiblink-post-command ()
+  (let* ((new-l-l-b (set-marker (make-marker) (line-beginning-position)))
+         (new-i-s-o-c
+          (nth 8 (save-excursion (syntax-ppss (line-end-position)))))
+         (same-line
+          (and jit-lock-antiblink-grace
+               (eq (marker-buffer jit-lock--antiblink-l-l-b) (current-buffer))
+               (= new-l-l-b jit-lock--antiblink-l-l-b))))
+    (cond (;; opened a new multiline string...
+           (and same-line
+
+                (null jit-lock--antiblink-i-s-o-c) new-i-s-o-c)
+           ;; assert that the grace timer is null and schedule it
+           (when jit-lock--antiblink-grace-timer
+             (display-warning
+              'font-lock :level
+              "`jit-lock--antiblink-grace-timer' not null" :warning))
+           (setq jit-lock--antiblink-grace-timer
+                 (run-with-idle-timer jit-lock-antiblink-grace nil
+                                      (lambda ()
+                                        (jit-lock-context-fontify)
+                                        (setq jit-lock--antiblink-grace-timer 
nil)))))
+          (;; closed an unterminated multiline string.
+           (and same-line
+                (null new-i-s-o-c) jit-lock--antiblink-i-s-o-c)
+           ;; Kill the grace timer, might already have run and died.
+           ;; Don't refontify immediately: it adds an unreasonable
+           ;; delay to a well-behaved operation.  Leave it for the
+           ;; `jit-lock-context-timer' as usual.
+           (when jit-lock--antiblink-grace-timer
+             (cancel-timer jit-lock--antiblink-grace-timer)
+             (setq jit-lock--antiblink-grace-timer nil))
+
+           )
+          (same-line
+           ;; in same line, but no state change, leave everything as it was
+           )
+          (t
+           ;; left the line somehow or customized feature away, etc
+           ;; kill timer if running, resume normal operation.
+           (when jit-lock--antiblink-grace-timer
+             ;; Do refontify immediately, adding a small delay.  This
+             ;; is per Lars' request, and it makes sense because we
+             ;; should remark somehow that we are leaving the unstable
+             ;; state.
+             (jit-lock-context-fontify)
+             (cancel-timer jit-lock--antiblink-grace-timer)
+             (setq jit-lock--antiblink-grace-timer nil))))
+    ;; update variables
+    (setq jit-lock--antiblink-l-l-b   new-l-l-b
+          jit-lock--antiblink-i-s-o-c new-i-s-o-c)))
+
 (provide 'jit-lock)
 
 ;;; jit-lock.el ends here



reply via email to

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