diff options
| author | João Távora | 2019-07-12 19:27:53 +0100 |
|---|---|---|
| committer | João Távora | 2019-12-04 23:38:06 +0100 |
| commit | 5b45c269cda09fe46e110adb6f6767040f4ade59 (patch) | |
| tree | 0a6cd49204b36d878db339d145d331ab10eb8f5d | |
| parent | 0e774d4f355b4f12a625da5ca9602d1ba876bcc1 (diff) | |
| download | emacs-5b45c269cda09fe46e110adb6f6767040f4ade59.tar.gz emacs-5b45c269cda09fe46e110adb6f6767040f4ade59.zip | |
New jit-lock-antiblink-grace feature
* lisp/jit-lock.el (jit-lock-antiblink-grace): New defcustom.
(jit-lock--antiblink-line-beginning-position)
(jit-lock--antiblink-string-or-comment): New variables
(jit-lock--antiblink-post-command): New helper.
(jit-lock-mode): Tweak post-command-hook and
jit-lock-context-timer.
* etc/NEWS: Mention jit-lock-antiblink-grace
| -rw-r--r-- | etc/NEWS | 7 | ||||
| -rw-r--r-- | lisp/jit-lock.el | 75 |
2 files changed, 81 insertions, 1 deletions
| @@ -626,6 +626,13 @@ If the region is active, the command joins all the lines in the | |||
| 626 | region. When there's no active region, the command works on the | 626 | region. When there's no active region, the command works on the |
| 627 | current and the previous or the next line, as before. | 627 | current and the previous or the next line, as before. |
| 628 | 628 | ||
| 629 | --- | ||
| 630 | ** New customizable variable 'jit-lock-antiblink-grace'. | ||
| 631 | When typing strings, this helps avoid "blinking", an oscillation | ||
| 632 | between string and non-string fontification. The variable holds a | ||
| 633 | number of seconds (default is 2) before a potentially unwanted | ||
| 634 | fontification starts. Set to nil to get back the old behavior. | ||
| 635 | |||
| 629 | 636 | ||
| 630 | * Changes in Specialized Modes and Packages in Emacs 27.1 | 637 | * Changes in Specialized Modes and Packages in Emacs 27.1 |
| 631 | 638 | ||
diff --git a/lisp/jit-lock.el b/lisp/jit-lock.el index 48998a81fe7..a17224e4bd0 100644 --- a/lisp/jit-lock.el +++ b/lisp/jit-lock.el | |||
| @@ -123,6 +123,20 @@ The value of this variable is used when JIT Lock mode is turned on." | |||
| 123 | :type '(number :tag "seconds") | 123 | :type '(number :tag "seconds") |
| 124 | :group 'jit-lock) | 124 | :group 'jit-lock) |
| 125 | 125 | ||
| 126 | (defcustom jit-lock-antiblink-grace 2 | ||
| 127 | "Grace period after which to refontify due to unterminated strings. | ||
| 128 | If nil, no grace period is given. Otherwise, a newly created | ||
| 129 | unterminated string is fontified only to the end of the current | ||
| 130 | line, after which the system waits this many seconds of idle time | ||
| 131 | before deciding the string is multi-line and fontifying the | ||
| 132 | remaining lines. When typing strings, this helps avoid | ||
| 133 | \"blinking\", an unwanted oscillation between string and | ||
| 134 | non-string fontification." | ||
| 135 | :type '(choice (const :tag "never" nil) | ||
| 136 | (number :tag "seconds")) | ||
| 137 | :group 'jit-lock | ||
| 138 | :version "27.1") | ||
| 139 | |||
| 126 | (defcustom jit-lock-defer-time nil ;; 0.25 | 140 | (defcustom jit-lock-defer-time nil ;; 0.25 |
| 127 | "Idle time after which deferred fontification should take place. | 141 | "Idle time after which deferred fontification should take place. |
| 128 | If nil, fontification is not deferred. | 142 | If nil, fontification is not deferred. |
| @@ -157,6 +171,13 @@ If nil, contextual fontification is disabled.") | |||
| 157 | "List of buffers with pending deferred fontification.") | 171 | "List of buffers with pending deferred fontification.") |
| 158 | (defvar jit-lock-stealth-buffers nil | 172 | (defvar jit-lock-stealth-buffers nil |
| 159 | "List of buffers that are being fontified stealthily.") | 173 | "List of buffers that are being fontified stealthily.") |
| 174 | |||
| 175 | (defvar jit-lock--antiblink-grace-timer nil | ||
| 176 | "Idle timer for fontifying unterminated string or comment, or nil.") | ||
| 177 | (defvar jit-lock--antiblink-line-beginning-position (make-marker) | ||
| 178 | "Last line beginning position after last command (a marker).") | ||
| 179 | (defvar jit-lock--antiblink-string-or-comment nil | ||
| 180 | "Non-nil if in string or comment after last command (a boolean).") | ||
| 160 | 181 | ||
| 161 | ;;; JIT lock mode | 182 | ;;; JIT lock mode |
| 162 | 183 | ||
| @@ -232,7 +253,10 @@ If you need to debug code run from jit-lock, see `jit-lock-debug-mode'." | |||
| 232 | (unless jit-lock-context-timer | 253 | (unless jit-lock-context-timer |
| 233 | (setq jit-lock-context-timer | 254 | (setq jit-lock-context-timer |
| 234 | (run-with-idle-timer jit-lock-context-time t | 255 | (run-with-idle-timer jit-lock-context-time t |
| 235 | 'jit-lock-context-fontify))) | 256 | (lambda () |
| 257 | (unless jit-lock--antiblink-grace-timer | ||
| 258 | (jit-lock-context-fontify)))))) | ||
| 259 | (add-hook 'post-command-hook 'jit-lock--antiblink-post-command nil t) | ||
| 236 | (setq jit-lock-context-unfontify-pos | 260 | (setq jit-lock-context-unfontify-pos |
| 237 | (or jit-lock-context-unfontify-pos (point-max)))) | 261 | (or jit-lock-context-unfontify-pos (point-max)))) |
| 238 | 262 | ||
| @@ -669,6 +693,55 @@ will take place when text is fontified stealthily." | |||
| 669 | ;; buffer, only jit-lock-context-* will re-fontify it. | 693 | ;; buffer, only jit-lock-context-* will re-fontify it. |
| 670 | (min jit-lock-context-unfontify-pos jit-lock-start)))))) | 694 | (min jit-lock-context-unfontify-pos jit-lock-start)))))) |
| 671 | 695 | ||
| 696 | (defun jit-lock--antiblink-post-command () | ||
| 697 | (let* ((new-l-b-p (copy-marker (line-beginning-position))) | ||
| 698 | (l-b-p-2 (line-beginning-position 2)) | ||
| 699 | (same-line | ||
| 700 | (and jit-lock-antiblink-grace | ||
| 701 | (not (= new-l-b-p l-b-p-2)) | ||
| 702 | (eq (marker-buffer jit-lock--antiblink-line-beginning-position) | ||
| 703 | (current-buffer)) | ||
| 704 | (= new-l-b-p jit-lock--antiblink-line-beginning-position))) | ||
| 705 | (new-s-o-c | ||
| 706 | (and same-line | ||
| 707 | (nth 8 (save-excursion (syntax-ppss l-b-p-2)))))) | ||
| 708 | (cond (;; Opened a new multiline string... | ||
| 709 | (and same-line | ||
| 710 | (null jit-lock--antiblink-string-or-comment) new-s-o-c) | ||
| 711 | (setq jit-lock--antiblink-grace-timer | ||
| 712 | (run-with-idle-timer jit-lock-antiblink-grace nil | ||
| 713 | (lambda () | ||
| 714 | (jit-lock-context-fontify) | ||
| 715 | (setq jit-lock--antiblink-grace-timer | ||
| 716 | nil))))) | ||
| 717 | (;; Closed an unterminated multiline string. | ||
| 718 | (and same-line | ||
| 719 | (null new-s-o-c) jit-lock--antiblink-string-or-comment) | ||
| 720 | ;; Kill the grace timer, might already have run and died. | ||
| 721 | ;; Don't refontify immediately: it adds an unreasonable | ||
| 722 | ;; delay to a well-behaved operation. Leave it for the | ||
| 723 | ;; `jit-lock-context-timer' as usual. | ||
| 724 | (when jit-lock--antiblink-grace-timer | ||
| 725 | (cancel-timer jit-lock--antiblink-grace-timer) | ||
| 726 | (setq jit-lock--antiblink-grace-timer nil))) | ||
| 727 | (same-line | ||
| 728 | ;; In same line, but no state change, leave everything as it was | ||
| 729 | ) | ||
| 730 | (t | ||
| 731 | ;; Left the line somehow or customized feature away, etc | ||
| 732 | ;; kill timer if running, resume normal operation. | ||
| 733 | (when jit-lock--antiblink-grace-timer | ||
| 734 | ;; Do refontify immediately, adding a small delay. This | ||
| 735 | ;; makes sense because it remark somehow that we are | ||
| 736 | ;; leaving the unstable state. | ||
| 737 | (jit-lock-context-fontify) | ||
| 738 | (cancel-timer jit-lock--antiblink-grace-timer) | ||
| 739 | (setq jit-lock--antiblink-grace-timer nil)))) | ||
| 740 | ;; Update variables (and release the marker) | ||
| 741 | (set-marker jit-lock--antiblink-line-beginning-position nil) | ||
| 742 | (setq jit-lock--antiblink-line-beginning-position new-l-b-p | ||
| 743 | jit-lock--antiblink-string-or-comment new-s-o-c))) | ||
| 744 | |||
| 672 | (provide 'jit-lock) | 745 | (provide 'jit-lock) |
| 673 | 746 | ||
| 674 | ;;; jit-lock.el ends here | 747 | ;;; jit-lock.el ends here |