emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master bc9a6fc: Let jit-lock know the result of font-lock-


From: Stefan Monnier
Subject: [Emacs-diffs] master bc9a6fc: Let jit-lock know the result of font-lock-extend-region-functions.
Date: Tue, 31 Mar 2015 01:33:26 +0000

branch: master
commit bc9a6fcd29cd2e35a34e42f6e8b9492c98c1560f
Author: Stefan Monnier <address@hidden>
Commit: Stefan Monnier <address@hidden>

    Let jit-lock know the result of font-lock-extend-region-functions.
    
    * lisp/jit-lock.el (jit-lock--run-functions): New function.
    (jit-lock-fontify-now): Use it.  Handle fontification bounds more
    precisely in case the backend functions fontify more than requested.
    Don't round up to whole lines since that shouldn't be needed
    any more.
    * lisp/font-lock.el (font-lock-fontify-region-function): Adjust docstring.
    (font-lock-inhibit-thing-lock): Make obsolete.
    (font-lock-default-fontify-region): Return the bounds actually used.
    
    * lisp/emacs-lisp/eieio-base.el (eieio-persistent-validate/fix-slot-value):
    Fix compilation error.
---
 lisp/ChangeLog                |   15 ++++++
 lisp/emacs-lisp/eieio-base.el |    3 +-
 lisp/font-lock.el             |   13 +++--
 lisp/jit-lock.el              |  109 ++++++++++++++++++++++++----------------
 4 files changed, 91 insertions(+), 49 deletions(-)

diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index cad239d..e50c69b 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,18 @@
+2015-03-31  Stefan Monnier  <address@hidden>
+
+       Let jit-lock know the result of font-lock-extend-region-functions.
+       * jit-lock.el (jit-lock--run-functions): New function.
+       (jit-lock-fontify-now): Use it.  Handle fontification bounds more
+       precisely in case the backend functions fontify more than requested.
+       Don't round up to whole lines since that shouldn't be needed
+       any more.
+       * font-lock.el (font-lock-fontify-region-function): Adjust docstring.
+       (font-lock-inhibit-thing-lock): Make obsolete.
+       (font-lock-default-fontify-region): Return the bounds actually used.
+
+       * emacs-lisp/eieio-base.el (eieio-persistent-validate/fix-slot-value):
+       Fix compilation error.
+
 2015-03-30  Artur Malabarba  <address@hidden>
 
        * emacs-lisp/package.el: Reorganize package.el and divide it with
diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el
index c2eab20..2e28036 100644
--- a/lisp/emacs-lisp/eieio-base.el
+++ b/lisp/emacs-lisp/eieio-base.el
@@ -294,7 +294,8 @@ Second, any text properties will be stripped from strings."
   (cond ((consp proposed-value)
         ;; Lists with something in them need special treatment.
         (let* ((slot-idx (- (eieio--slot-name-index class slot)
-                             (eval-when-compile eieio--object-num-slots)))
+                             (eval-when-compile
+                               (length (cl-struct-slot-info 'eieio--object)))))
                 (type (cl--slot-descriptor-type (aref (eieio--class-slots 
class)
                                                       slot-idx)))
                 (classtype (eieio-persistent-slot-type-is-class-p type)))
diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index 6c8392b..96b290e 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -585,11 +585,14 @@ This is normally set via `font-lock-defaults'.")
 This is used when turning off Font Lock mode.
 This is normally set via `font-lock-defaults'.")
 
-(defvar font-lock-fontify-region-function 'font-lock-default-fontify-region
+(defvar font-lock-fontify-region-function #'font-lock-default-fontify-region
   "Function to use for fontifying a region.
 It should take two args, the beginning and end of the region, and an optional
 third arg VERBOSE.  If VERBOSE is non-nil, the function should print status
-messages.  This is normally set via `font-lock-defaults'.")
+messages.  This is normally set via `font-lock-defaults'.
+If it fontifies a larger region, it should ideally return a list of the form
+\(jit-lock-bounds BEG . END) indicating the bounds of the region actually
+fontified.")
 
 (defvar font-lock-unfontify-region-function 'font-lock-default-unfontify-region
   "Function to use for unfontifying a region.
@@ -600,6 +603,7 @@ This is normally set via `font-lock-defaults'.")
   "List of Font Lock mode related modes that should not be turned on.
 Currently, valid mode names are `fast-lock-mode', `jit-lock-mode' and
 `lazy-lock-mode'.  This is normally set via `font-lock-defaults'.")
+(make-obsolete-variable 'font-lock-inhibit-thing-lock nil "25.1")
 
 (defvar-local font-lock-multiline nil
   "Whether font-lock should cater to multiline keywords.
@@ -935,7 +939,7 @@ The value of this variable is used when Font Lock mode is 
turned on."
      ;; Don't fontify eagerly (and don't abort if the buffer is large).
      (set (make-local-variable 'font-lock-fontified) t)
      ;; Use jit-lock.
-     (jit-lock-register 'font-lock-fontify-region
+     (jit-lock-register #'font-lock-fontify-region
                         (not font-lock-keywords-only))
      ;; Tell jit-lock how we extend the region to refontify.
      (add-hook 'jit-lock-after-change-extend-region-functions
@@ -1220,7 +1224,8 @@ This function is the default 
`font-lock-fontify-region-function'."
             (font-lock-fontify-syntactic-keywords-region start end)))
         (unless font-lock-keywords-only
           (font-lock-fontify-syntactically-region beg end loudly))
-        (font-lock-fontify-keywords-region beg end loudly)))))
+        (font-lock-fontify-keywords-region beg end loudly)
+        `(jit-lock-bounds ,beg . ,end)))))
 
 ;; The following must be rethought, since keywords can override fontification.
 ;;    ;; Now scan for keywords, but not if we are inside a comment now.
diff --git a/lisp/jit-lock.el b/lisp/jit-lock.el
index 788646c..d271a44 100644
--- a/lisp/jit-lock.el
+++ b/lisp/jit-lock.el
@@ -351,6 +351,24 @@ is active."
                           (min (point-max) (+ start jit-lock-chunk-size)))
                          'fontified 'defer)))))
 
+(defun jit-lock--run-functions (beg end)
+  (let ((tight-beg nil) (tight-end nil)
+        (loose-beg beg) (loose-end end))
+    (run-hook-wrapped
+     'jit-lock-functions
+     (lambda (fun)
+       (pcase-let*
+           ((res (funcall fun beg end))
+            (`(,this-beg . ,this-end)
+             (if (eq (car-safe res) 'jit-lock-bounds)
+                 (cdr res) (cons beg end))))
+         (setq tight-beg (max tight-beg (or this-beg (point-min))))
+         (setq tight-end (max tight-end (or this-end (point-max))))
+         (setq loose-beg (max loose-beg this-beg))
+         (setq loose-end (max loose-end this-end))
+         nil)))
+    `(,(min tight-beg beg) ,(max tight-end end) ,loose-beg ,loose-end)))
+
 (defun jit-lock-fontify-now (&optional start end)
   "Fontify current buffer from START to END.
 Defaults to the whole buffer.  END can be out of bounds."
@@ -376,54 +394,57 @@ Defaults to the whole buffer.  END can be out of bounds."
           (setq next (or (text-property-any start end 'fontified t)
                          end))
 
-          ;; Decide which range of text should be fontified.
-          ;; The problem is that START and NEXT may be in the
-          ;; middle of something matched by a font-lock regexp.
-          ;; Until someone has a better idea, let's start
-          ;; at the start of the line containing START and
-          ;; stop at the start of the line following NEXT.
-          (goto-char next)  (setq next (line-beginning-position 2))
-          (goto-char start) (setq start (line-beginning-position))
-
-           ;; Make sure the contextual refontification doesn't re-refontify
-           ;; what's already been refontified.
-           (when (and jit-lock-context-unfontify-pos
-                      (< jit-lock-context-unfontify-pos next)
-                      (>= jit-lock-context-unfontify-pos start)
-                      ;; Don't move boundary forward if we have to
-                      ;; refontify previous text.  Otherwise, we risk moving
-                      ;; it past the end of the multiline property and thus
-                      ;; forget about this multiline region altogether.
-                      (not (get-text-property start 
'jit-lock-defer-multiline)))
-             (setq jit-lock-context-unfontify-pos next))
-
           ;; Fontify the chunk, and mark it as fontified.
           ;; We mark it first, to make sure that we don't indefinitely
           ;; re-execute this fontification if an error occurs.
           (put-text-property start next 'fontified t)
-          (condition-case err
-              (run-hook-with-args 'jit-lock-functions start next)
-            ;; If the user quits (which shouldn't happen in normal on-the-fly
-            ;; jit-locking), make sure the fontification will be performed
-            ;; before displaying the block again.
-            (quit (put-text-property start next 'fontified nil)
-                  (funcall 'signal (car err) (cdr err))))
-
-           ;; The redisplay engine has already rendered the buffer up-to
-           ;; `orig-start' and won't notice if the above jit-lock-functions
-           ;; changed the appearance of any part of the buffer prior
-           ;; to that.  So if `start' is before `orig-start', we need to
-           ;; cause a new redisplay cycle after this one so that any changes
-           ;; are properly reflected on screen.
-           ;; To make such repeated redisplay happen less often, we can
-           ;; eagerly extend the refontified region with
-           ;; jit-lock-after-change-extend-region-functions.
-           (when (< start orig-start)
-            (run-with-timer 0 nil #'jit-lock-force-redisplay
-                             (copy-marker start) (copy-marker orig-start)))
-
-          ;; Find the start of the next chunk, if any.
-          (setq start (text-property-any next end 'fontified nil))))))))
+           (pcase-let
+               ;; `tight' is the part we've fully refontified, and `loose'
+               ;; is the part we've partly refontified (some of the
+               ;; functions have refontified it but maybe not all).
+               ((`(,tight-beg ,tight-end ,loose-beg ,loose-end)
+                 (condition-case err
+                     (jit-lock--run-functions start next)
+                   ;; If the user quits (which shouldn't happen in normal
+                   ;; on-the-fly jit-locking), make sure the fontification
+                   ;; will be performed before displaying the block again.
+                   (quit (put-text-property start next 'fontified nil)
+                         (signal (car err) (cdr err))))))
+
+             ;; In case we fontified more than requested, take note.
+             (when (or (< tight-beg start) (> tight-end next))
+               (put-text-property tight-beg tight-end 'fontified t))
+
+             ;; Make sure the contextual refontification doesn't re-refontify
+             ;; what's already been refontified.
+             (when (and jit-lock-context-unfontify-pos
+                        (< jit-lock-context-unfontify-pos tight-end)
+                        (>= jit-lock-context-unfontify-pos tight-beg)
+                        ;; Don't move boundary forward if we have to
+                        ;; refontify previous text.  Otherwise, we risk moving
+                        ;; it past the end of the multiline property and thus
+                        ;; forget about this multiline region altogether.
+                        (not (get-text-property tight-beg
+                                                'jit-lock-defer-multiline)))
+               (setq jit-lock-context-unfontify-pos tight-end))
+
+             ;; The redisplay engine has already rendered the buffer up-to
+             ;; `orig-start' and won't notice if the above jit-lock-functions
+             ;; changed the appearance of any part of the buffer prior
+             ;; to that.  So if `loose-beg' is before `orig-start', we need to
+             ;; cause a new redisplay cycle after this one so that the changes
+             ;; are properly reflected on screen.
+             ;; To make such repeated redisplay happen less often, we can
+             ;; eagerly extend the refontified region with
+             ;; jit-lock-after-change-extend-region-functions.
+             (when (< loose-beg orig-start)
+               (run-with-timer 0 nil #'jit-lock-force-redisplay
+                               (copy-marker loose-beg)
+                               (copy-marker orig-start)))
+
+             ;; Find the start of the next chunk, if any.
+             (setq start
+                   (text-property-any tight-end end 'fontified nil)))))))))
 
 (defun jit-lock-force-redisplay (start end)
   "Force the display engine to re-render START's buffer from START to END.



reply via email to

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