all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Alan Mackenzie <acm@muc.de>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: Hannu Koivisto <azure@iki.fi>, emacs-devel@gnu.org
Subject: Re: First fontification of a buffer happens before font lock is fully initialised.
Date: Sat, 4 Feb 2012 12:03:19 +0000	[thread overview]
Message-ID: <20120204120319.GC3347@acm.acm> (raw)
In-Reply-To: <jwvfwf31c3y.fsf-monnier+emacs@gnu.org>

Hello, Stefan

On Wed, Jan 25, 2012 at 08:43:48PM -0500, Stefan Monnier wrote:
> >> > This situation was found and analysed by Hannu Koivisto after CC Mode
> >> > crashed for this reason on a C++ buffer.  Why it doesn't happen for
> >> > every CC Mode buffer is not yet clear.
> >> I think the behavior depends on the use of font-lock-support-mode.
> >> With jit-lock, fontification takes place after running the mode-hook,
> >> whereas without it, fontification takes place before.
> > Surely this cannot be

> I'm pretty sure this is the source of the difference.

> > the hooks are run at the end of the define-minor-mode expansion no
> > matter what.

> Yes, but fontification can take place even later, depending on
> font-lock-support-mode.

> > Surely the hooks are not being run twice.

> No, indeed, they should only be run once.

> > Though I admit I haven't tracked down the stages in initialising
> > jit-lock-mode.

> jit-lock postpones fontification to whenever the text is actually
> displayed, i.e. much later than initialization; it may very well never
> fontify any part of the text at all, if the buffer is never displayed.

> > So do you agree that the code should be changed so that
> > fontification always happens after running the mode-hook?

> Yes, I agree.  This was the behavior in Emacs-20, and is also the
> behavior with jit-lock (i.e. the default behavior).  I'm not sure what's
> the best way to get that result, tho: adding yet-another keyword to
> define-minor-mode is something I'd rather avoid.

I can only see one other way to deal with this: that is to write
`font-lock-mode' explicitly; or rather, expand the macro by hand, tidy it
up, and move the `run-hooks'.

I've done this in the patch below.  To see the difference between before
and after, do

emacs -Q
M-: (setq font-lock-support-mode nil)
C-c C-f random.c

Before the change, an error is thrown.  After the change, it works.
Should I commit this patch?



=== modified file 'lisp/font-core.el'
*** lisp/font-core.el	2012-01-19 07:21:25 +0000
--- lisp/font-core.el	2012-02-04 11:59:45 +0000
***************
*** 87,93 ****
  ;; The mode for which font-lock was initialized, or nil if none.
  (defvar font-lock-major-mode)
  
! (define-minor-mode font-lock-mode
    "Toggle syntax highlighting in this buffer (Font Lock mode).
  With a prefix argument ARG, enable Font Lock mode if ARG is
  positive, and disable it otherwise.  If called from Lisp, enable
--- 87,100 ----
  ;; The mode for which font-lock was initialized, or nil if none.
  (defvar font-lock-major-mode)
  
! (defvar font-lock-mode nil
!   "Non-nil if Font-Lock mode is enabled.
! Use the command `font-lock-mode' to change this variable.")
! (make-variable-buffer-local 'font-lock-mode)
! 
! ;; Note: `define-minor-mode' cannot be used here, since the mode hooks
! ;; need to be run before the first fontification of a buffer.
! (defun font-lock-mode (&optional arg)
    "Toggle syntax highlighting in this buffer (Font Lock mode).
  With a prefix argument ARG, enable Font Lock mode if ARG is
  positive, and disable it otherwise.  If called from Lisp, enable
***************
*** 137,152 ****
  The above is the default behavior of `font-lock-mode'; you may specify
  your own function which is called when `font-lock-mode' is toggled via
  `font-lock-function'. "
!   nil nil nil
!   ;; 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))
!     (setq font-lock-mode nil))
!   (funcall font-lock-function font-lock-mode)
!   ;; Arrange to unfontify this buffer if we change major mode later.
!   (if font-lock-mode
!       (add-hook 'change-major-mode-hook 'font-lock-change-mode nil t)
!     (remove-hook 'change-major-mode-hook 'font-lock-change-mode t)))
  
  ;; Get rid of fontification for the old major mode.
  ;; We do this when changing major modes.
--- 144,185 ----
  The above is the default behavior of `font-lock-mode'; you may specify
  your own function which is called when `font-lock-mode' is toggled via
  `font-lock-function'. "
!   (interactive (list (or current-prefix-arg 'toggle)))
!   (let ((last-message (current-message)))
!     (setq font-lock-mode
! 	  (cond ((eq arg 'toggle)
! 		 (not font-lock-mode))
! 		(arg (> (prefix-numeric-value arg) 0))
! 		(t (if (null font-lock-mode)
! 		       t
! 		     (message "Toggling %s off; better pass an explicit argument."
! 			      'font-lock-mode)
! 		     nil))))
! 
!     (when (or noninteractive (eq (aref (buffer-name) 0) 32))
!       (setq font-lock-mode nil))
! 
!     (if font-lock-mode
! 	(add-hook 'change-major-mode-hook 'font-lock-change-mode nil t)
!       (remove-hook 'change-major-mode-hook 'font-lock-change-mode t))
!     (run-hooks 'font-lock-mode-hook
! 	       (if font-lock-mode
! 		   'font-lock-mode-on-hook
! 		 'font-lock-mode-off-hook))
!     (funcall font-lock-function font-lock-mode)
!    (if (called-interactively-p 'any)
! 	(progn nil
! 	       (unless (and (current-message)
! 			    (not (equal last-message (current-message))))
! 		 (message "Font-Lock mode %sabled"
! 			  (if font-lock-mode "en" "dis"))))))
! 
!   (force-mode-line-update) font-lock-mode)
! 
! :autoload-end
! (add-minor-mode 'font-lock-mode nil
! 		(if (boundp 'font-lock-mode-map)
! 		    font-lock-mode-map))
  
  ;; Get rid of fontification for the old major mode.
  ;; We do this when changing major modes.



>         Stefan

-- 
Alan Mackenzie (Nuremberg, Germany).



  parent reply	other threads:[~2012-02-04 12:03 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-25 12:48 First fontification of a buffer happens before font lock is fully initialised Alan Mackenzie
2012-01-25 17:46 ` Stefan Monnier
2012-01-25 18:26   ` Alan Mackenzie
2012-01-25 19:22     ` Hannu Koivisto
2012-01-25 20:22       ` Alan Mackenzie
2012-01-26  1:43     ` Stefan Monnier
2012-01-26 10:58       ` Alan Mackenzie
2012-02-04 12:03       ` Alan Mackenzie [this message]
2012-02-06  1:39         ` Stefan Monnier
2012-02-07 10:10           ` Alan Mackenzie
2012-02-07 18:02             ` Stefan Monnier
2012-02-08 21:43               ` Alan Mackenzie
2012-02-10 14:27                 ` Stefan Monnier
2012-02-23 11:39                   ` Alan Mackenzie
2012-02-23 14:34                     ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120204120319.GC3347@acm.acm \
    --to=acm@muc.de \
    --cc=azure@iki.fi \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.