From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel Subject: Re: First fontification of a buffer happens before font lock is fully initialised. Date: Sat, 4 Feb 2012 12:03:19 +0000 Message-ID: <20120204120319.GC3347@acm.acm> References: <20120125124804.GB3638@acm.acm> <20120125182651.GA3624@acm.acm> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1328357028 31469 80.91.229.3 (4 Feb 2012 12:03:48 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sat, 4 Feb 2012 12:03:48 +0000 (UTC) Cc: Hannu Koivisto , emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Feb 04 13:03:47 2012 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1RteLH-0000LX-OM for ged-emacs-devel@m.gmane.org; Sat, 04 Feb 2012 13:03:44 +0100 Original-Received: from localhost ([::1]:33051 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RteLH-0001r2-1w for ged-emacs-devel@m.gmane.org; Sat, 04 Feb 2012 07:03:43 -0500 Original-Received: from eggs.gnu.org ([140.186.70.92]:55914) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RteLE-0001qu-6D for emacs-devel@gnu.org; Sat, 04 Feb 2012 07:03:41 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RteLB-00010l-6D for emacs-devel@gnu.org; Sat, 04 Feb 2012 07:03:40 -0500 Original-Received: from colin.muc.de ([193.149.48.1]:18335 helo=mail.muc.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RteLA-0000zn-Nn for emacs-devel@gnu.org; Sat, 04 Feb 2012 07:03:37 -0500 Original-Received: (qmail 33397 invoked by uid 3782); 4 Feb 2012 12:03:34 -0000 Original-Received: from acm.muc.de (pD95566C4.dip.t-dialin.net [217.85.102.196]) by colin.muc.de (tmda-ofmipd) with ESMTP; Sat, 04 Feb 2012 13:03:26 +0100 Original-Received: (qmail 12731 invoked by uid 1000); 4 Feb 2012 12:03:19 -0000 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 193.149.48.1 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:148159 Archived-At: 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).