emacs-devel
[Top][All Lists]
Advanced

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

Re: First fontification of a buffer happens before font lock is fully in


From: Alan Mackenzie
Subject: Re: First fontification of a buffer happens before font lock is fully initialised.
Date: Thu, 23 Feb 2012 11:39:31 +0000
User-agent: Mutt/1.5.21 (2010-09-15)

Hello, Stefan.

[Quick summary: adding the new parameter ":after-hook" to
define-minor-mode, and adapting font-core/font-lock to use it.]

On Fri, Feb 10, 2012 at 09:27:20AM -0500, Stefan Monnier wrote:
> > + :after-hooks    A single lisp form which is evaluated after the mode hooks
> > +                 have been run.  It should be quoted.

> Don't quote it.

OK

> > !      ,@(when after-hooks `(,(eval after-hooks)))

> And don't call `eval'.

OK2.

> Also, I'd move the after-hooks code to after the 
> customize-mark-as-set&message.

OK3.

Here's an amended patch for easy-mmode.el and a patch for font-core/lock
which uses the :after-hook param.  Should I install it?



=== modified file 'doc/lispref/modes.texi'
*** doc/lispref/modes.texi      2012-02-19 05:54:33 +0000
--- doc/lispref/modes.texi      2012-02-22 20:51:42 +0000
***************
*** 1594,1608 ****
  @var{place} can also be a cons @code{(@var{get} . @var{set})},
  where @var{get} is an expression that returns the current state,
  and @var{set} is a function of one argument (a state) that sets it.
  @end table
  
  Any other keyword arguments are passed directly to the
  @code{defcustom} generated for the variable @var{mode}.
  
! The command named @var{mode} first performs the standard actions such
! as setting the variable named @var{mode} and then executes the
! @var{body} forms, if any.  It finishes by running the mode hook
! variable @address@hidden
  @end defmac
  
    The initial value must be @code{nil} except in cases where (1) the
--- 1594,1613 ----
  @var{place} can also be a cons @code{(@var{get} . @var{set})},
  where @var{get} is an expression that returns the current state,
  and @var{set} is a function of one argument (a state) that sets it.
+ 
+ @item :after-hook @var{after-hook}
+ This defines a single lisp form which is evaluated after the mode hooks
+ have run.  It should not be quoted.
  @end table
  
  Any other keyword arguments are passed directly to the
  @code{defcustom} generated for the variable @var{mode}.
  
! The command named @var{mode} first performs the standard actions such as
! setting the variable named @var{mode} and then executes the @var{body}
! forms, if any.  It then runs the mode hook variable
! @address@hidden and finishes by evaluating any form in
! @code{:after-hook}.
  @end defmac
  
    The initial value must be @code{nil} except in cases where (1) the

=== modified file 'lisp/emacs-lisp/easy-mmode.el'
*** lisp/emacs-lisp/easy-mmode.el       2012-02-07 08:26:54 +0000
--- lisp/emacs-lisp/easy-mmode.el       2012-02-22 20:11:14 +0000
***************
*** 135,140 ****
--- 135,142 ----
                the new state, and sets it.  If you specify a :variable,
                this function does not define a MODE variable (nor any of
                the terms used in :variable).
+ :after-hook     A single lisp form which is evaluated after the mode hooks
+                 have been run.  It should not be quoted.
  
  For example, you could write
    (define-minor-mode foo-mode \"If enabled, foo on you!\"
***************
*** 170,175 ****
--- 172,178 ----
           (setter nil)            ;The function (if any) to set the mode var.
           (modefun mode)          ;The minor mode function name we're defining.
         (require t)
+        (after-hook nil)
         (hook (intern (concat mode-name "-hook")))
         (hook-on (intern (concat mode-name "-on-hook")))
         (hook-off (intern (concat mode-name "-off-hook")))
***************
*** 197,202 ****
--- 200,206 ----
               (setq mode variable)
             (setq mode (car variable))
             (setq setter (cdr variable))))
+       (:after-hook (setq after-hook (pop body)))
        (t (push keyw extra-keywords) (push (pop body) extra-keywords))))
  
      (setq keymap-sym (if (and keymap (symbolp keymap)) keymap
***************
*** 275,281 ****
                                (not (equal ,last-message
                                            (current-message))))
                     (message ,(format "%s %%sabled" pretty-name)
!                             (if ,mode "en" "dis"))))))
         (force-mode-line-update)
         ;; Return the new setting.
         ,mode)
--- 279,286 ----
                                (not (equal ,last-message
                                            (current-message))))
                     (message ,(format "%s %%sabled" pretty-name)
!                             (if ,mode "en" "dis")))))
!          ,@(when after-hook `(,after-hook)))
         (force-mode-line-update)
         ;; Return the new setting.
         ,mode)

=== modified file 'lisp/font-core.el'
*** lisp/font-core.el   2012-01-19 07:21:25 +0000
--- lisp/font-core.el   2012-02-23 11:10:32 +0000
***************
*** 138,143 ****
--- 138,144 ----
  your own function which is called when `font-lock-mode' is toggled via
  `font-lock-function'. "
    nil nil nil
+   :after-hook (if font-lock-mode (font-lock-initial-fontify))
    ;; Don't turn on Font Lock mode if we don't have a display (we're running a
    ;; batch job) or if the buffer is invisible (the name starts with a space).
    (when (or noninteractive (eq (aref (buffer-name) 0) ?\s))

=== modified file 'lisp/font-lock.el'
*** lisp/font-lock.el   2012-02-10 15:59:29 +0000
--- lisp/font-lock.el   2012-02-23 11:15:14 +0000
***************
*** 629,649 ****
    ;; Shut up the byte compiler.
    (defvar font-lock-face-attributes)) ; Obsolete but respected if set.
  
  (defun font-lock-mode-internal (arg)
    ;; Turn on Font Lock mode.
    (when arg
      (add-hook 'after-change-functions 'font-lock-after-change-function t t)
      (font-lock-set-defaults)
!     (font-lock-turn-on-thing-lock)
!     ;; Fontify the buffer if we have to.
!     (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size)))
!       (cond (font-lock-fontified
!            nil)
!           ((or (null max-size) (> max-size (buffer-size)))
!            (font-lock-fontify-buffer))
!           (font-lock-verbose
!            (message "Fontifying %s...buffer size greater than 
font-lock-maximum-size"
!                     (buffer-name))))))
    ;; Turn off Font Lock mode.
    (unless font-lock-mode
      (remove-hook 'after-change-functions 'font-lock-after-change-function t)
--- 629,652 ----
    ;; Shut up the byte compiler.
    (defvar font-lock-face-attributes)) ; Obsolete but respected if set.
  
+ (defun font-lock-initial-fontify ()
+   ;; The first fontification after turning the mode on.  This must
+   ;;  only be called after the mode hooks have been run.
+   (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size)))
+     (cond (font-lock-fontified
+          nil)
+         ((or (null max-size) (> max-size (buffer-size)))
+          (font-lock-fontify-buffer))
+         (font-lock-verbose
+          (message "Fontifying %s...buffer size greater than 
font-lock-maximum-size"
+                   (buffer-name))))))
+ 
  (defun font-lock-mode-internal (arg)
    ;; Turn on Font Lock mode.
    (when arg
      (add-hook 'after-change-functions 'font-lock-after-change-function t t)
      (font-lock-set-defaults)
!     (font-lock-turn-on-thing-lock))
    ;; Turn off Font Lock mode.
    (unless font-lock-mode
      (remove-hook 'after-change-functions 'font-lock-after-change-function t)



>         Stefan

-- 
Alan Mackenzie (Nuremberg, Germany).



reply via email to

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