From: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: Richard Stallman <rms@gnu.org>, emacs-devel@gnu.org
Subject: Re: Last steps for pretesting (font-lock-extend-region-function)
Date: Thu, 20 Apr 2006 19:34:34 -0400 [thread overview]
Message-ID: <87psjbon3b.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <Pine.LNX.3.96.1060420212130.271D-100000@acm.acm> (Alan Mackenzie's message of "Thu, 20 Apr 2006 22:40:38 +0000 (GMT)")
>> IIRC part (i) needs more than an after-change-function: it also needs
>> a before-change-function.
> That would depend on the major mode, I think. AWK mode needs a
> before-change function. The CC Mode replacement for (setq
> font-lock-lines-before 2) will not need a b-c function.
Simulating font-lock-lines-before only needs an `extend-region' hook in
font-lock-default-fontify-region, a subject about which we already agree.
> However, using the f-l-multiline property approach instead will also need
> a before-change function for exactly the same reasons
That's news to me. Could you explain the scenario you have in mind?
> - or else it will require the major mode to maintain the f-l-multiline
> property permanently.
The font-lock-multiline property is removed by font-lock-unfontify-region
and it is expected that it gets re-added (if needed) every time you fontify
a piece of text. It's never seemed to be a big deal.
No before-change-function in sight.
>> And (again IIRC) it's the part that can already be solved by placing
>> (from one of the font-lock-keywords rules) a font-lock-multiline
>> property.
> I'm not sure. Can a font-lock-keyword rule get access to after-change's
> OLD-LEN in an reasonable fashion?
What for? The font-lock-multiline it needs to add is for use by the next
font-lock round. It says: "next time you fontify this area, make sure you
refontify this piece atomically".
> If a change consists of yanking 20k of text into a buffer, the Major Mode
> must not splat font-lock-multiline onto 20k + 20 bytes, since this would
> defeat the purpose of JIT lock (fontifying a bit at a time).
The font-lock-multiline property is added not to the whole fontified text,
but just to a particular region of text that matched a pattern (a
"keyword"). I think you're absolutely right: I have to document it because
you seem to completely misunderstand it.
> Could you please document the font-lock-multiline mechanism immediately,
> including details on how best to access the after-change-functions's
> OLD-LEN, and details of how and where to hook in the "(put-text-property a
> b 'font-lock-multiline t)" call. Either that, or tell me where to find
> an example of this text property being used, preferably one which uses
> OLD-LEN.
AFAIK the OLD-LEN is never needed. See font-lock.el for an example of code
that sets font-lock-multiline property: if a regexp matches several lines,
it puts the font-lock-multiline property on the wholse matched text (this
is only done if the font-lock-multiline variable is set).
> Or, perhaps you could recode the following AWK Mode fragment into an
> equivalent which uses f-l-multiline instead of f-l-expand-region
> function. PLEASE!
I'll try to, although I'd need to see the font-lock-keywords part (where
I'll have to add the code).
> #########################################################################
> (defvar c-awk-old-EOLL 0)
> (make-variable-buffer-local 'c-awk-old-EOLL)
> ;; End of logical line following the region which is about to be changed. Set
> ;; in c-awk-before-change and used in c-awk-font-lock-extend-region.
> (defun c-awk-before-change (beg end)
> ;; This function is called exclusively from the before-change-functions hook.
> ;; It does two things: Finds the end of the (logical) line on which END lies,
> ;; and clears c-awk-NL-prop text properties from this point onwards.
> (save-restriction
> (save-excursion
> (setq c-awk-old-EOLL (c-awk-end-of-logical-line end))
> (c-save-buffer-state nil
> (c-awk-clear-NL-props end (point-max))))))
> (add-hook 'before-change-functions c-awk-before-change nil t)
> (defun c-awk-end-of-change-region (beg end old-len)
> ;; Find the end of the region which needs to be font-locked after a change.
> ;; This is the end of the logical line on which the change happened, either
> ;; as it was before the change, or as it is now, whichever is later.
> ;; N.B. point is left undefined.
> (max (+ (- c-awk-old-EOLL old-len) (- end beg))
> (c-awk-end-of-logical-line end)))
> (defun c-awk-font-lock-extend-region (beg end old-len)
> (cons (c-awk-beginning-of-logical-line beg)
> (if old-len
> ;; From an after-change-function
> (c-awk-end-of-change-region beg end old-len)
> ;; From a fontifying routine
> (c-awk-end-of-logical-line end))))
> (setq font-lock-extend-region-function 'c-awk-font-lock-extend-region)
> #########################################################################
IIUC, something like the following should do:
(defun c-awk-font-lock-extend-region (beg end)
(cons (c-awk-beginning-of-logical-line beg)
(c-awk-end-of-logical-line end)))
(setq font-lock-extend-region-function 'c-awk-font-lock-extend-region)
(defconst c-awk-font-lock-keywords
'(...
(".*\\\\\n.*"
(0 (progn (put-text-property (match-beginning 0) (match-end 0)
'font-lock-multiline t)
nil)))
...))
although I suspect that you already have a font-lock-keyword that matches
something akin to ".*\\\\\n.*" where you can add the put-text-property.
>> Here is the problems I see with your proposal:
>> - an `extend-region' hook in font-lock-fontify-region is needed
> It is indeed. It is a simple patch, and I am ready and willing to write
> it, both for font-core.el and modes.texi. I do first ask that it's
> accepted in principle, though.
It's completely accepted. I just hope we can call it
"font-lock-extend-region-function".
>> - the font-lock-multiline property should be enough in all cases to make
>> it unnecessary to use an after-change-function hook.
> f-l-extend-region-function also makes a (separate) after-change-f hook
> unnecessary.
Which f-l-extend-region-function? The one called from after-change-f?
Then it's what I meant by "an after-change-function hook". The fact that
it's not called directly from a-c-f but via f-t-a-c-f is not very
important for this discussion.
>> - an after-change-function is expensive, and even more when it comes bundled
>> with a before-change-function, and even more so when compared to
>> code that's only run during font-locking.
> Huh? Font Locking _is_ expensive.
Yup, but (thanks to jit-lock) it's not executed after each and every
buffer modification.
> A before-change function need not be expensive (e.g. c-awk-before-change,
> see above), and calling it is not expensive.
The code will have probably the same cost whether it's called from a-c-f or
from font-lock, but in one case it'll be called (much) more often.
> I suspect that using the f-l-multiline property will absolutely mandate an
> extra after-change function - how else can it access OLD-LEN?
Why would it need OLD-LEN?
Stefan
next prev parent reply other threads:[~2006-04-20 23:34 UTC|newest]
Thread overview: 80+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-04-17 0:56 Last steps for pretesting Richard Stallman
2006-04-17 8:01 ` Ramprasad B
2006-04-17 8:37 ` Eli Zaretskii
2006-04-18 1:42 ` Richard Stallman
2006-04-19 3:54 ` Ramprasad B
2006-04-19 15:40 ` Richard Stallman
2006-04-20 5:23 ` Ramprasad B
2006-04-18 17:31 ` Bill Wohler
2006-04-19 17:02 ` Alan Mackenzie
2006-04-19 21:23 ` Stefan Monnier
2006-04-19 21:30 ` David Kastrup
2006-04-20 21:35 ` Stefan Monnier
2006-04-20 21:37 ` David Kastrup
2006-04-20 21:44 ` Stefan Monnier
2006-04-20 21:46 ` David Kastrup
2006-04-20 22:50 ` Alan Mackenzie
2006-04-19 22:43 ` Last steps for pretesting (font-lock-extend-region-function) Alan Mackenzie
2006-04-20 9:13 ` Alan Mackenzie
2006-04-20 17:46 ` Stefan Monnier
2006-04-20 18:12 ` Alan Mackenzie
2006-04-20 20:58 ` Stefan Monnier
2006-04-20 22:40 ` Alan Mackenzie
2006-04-20 23:34 ` Stefan Monnier [this message]
2006-04-21 7:58 ` Alan Mackenzie
2006-04-21 12:18 ` Stefan Monnier
2006-04-21 19:51 ` Alan Mackenzie
2006-04-21 22:28 ` Stefan Monnier
2006-04-24 19:28 ` Alan Mackenzie
2006-04-24 21:06 ` Stefan Monnier
2006-04-25 6:21 ` Ralf Angeli
2006-04-25 10:53 ` Alan Mackenzie
2006-04-25 18:37 ` Ralf Angeli
2006-04-25 22:00 ` Alan Mackenzie
2006-04-26 6:14 ` Ralf Angeli
2006-04-25 19:26 ` Stefan Monnier
2006-04-25 20:10 ` font-lock-multiline for cc-awk Stefan Monnier
2006-04-26 7:37 ` Alan Mackenzie
2006-04-26 13:55 ` Stefan Monnier
2006-04-25 19:23 ` Last steps for pretesting (font-lock-extend-region-function) Stefan Monnier
2006-04-25 20:18 ` Stefan Monnier
2006-04-25 11:33 ` Alan Mackenzie
2006-04-25 11:59 ` David Kastrup
2006-04-25 12:33 ` Stefan Monnier
2006-04-25 14:07 ` Alan Mackenzie
2006-04-25 16:05 ` Stefan Monnier
2006-04-25 16:09 ` Stefan Monnier
2006-04-25 21:52 ` Alan Mackenzie
2006-04-25 21:49 ` Alan Mackenzie
2006-04-26 4:50 ` Stefan Monnier
2006-04-24 21:20 ` Stefan Monnier
2006-04-25 7:45 ` Alan Mackenzie
2006-04-25 12:12 ` Stefan Monnier
2006-04-25 21:15 ` Alan Mackenzie
2006-04-26 4:33 ` Stefan Monnier
2006-04-26 8:30 ` Alan Mackenzie
2006-04-26 13:36 ` Stefan Monnier
2006-04-24 21:33 ` Stefan Monnier
2006-04-25 7:27 ` Alan Mackenzie
2006-04-25 12:03 ` Stefan Monnier
2006-04-25 13:14 ` Alan Mackenzie
2006-04-26 0:22 ` Miles Bader
2006-04-25 4:39 ` Tomas Zerolo
2006-04-25 19:02 ` Ralf Angeli
2006-04-25 19:30 ` Stefan Monnier
2006-04-25 20:12 ` Ralf Angeli
2006-04-25 20:26 ` Stefan Monnier
2006-04-25 20:58 ` Ralf Angeli
2006-04-25 21:11 ` Stefan Monnier
2006-04-25 22:30 ` Alan Mackenzie
2006-04-26 4:25 ` Stefan Monnier
2006-04-26 7:44 ` Alan Mackenzie
2006-04-25 22:16 ` Alan Mackenzie
2006-04-26 4:36 ` Stefan Monnier
2006-04-21 23:14 ` Drew Adams
2006-04-19 22:53 ` Last steps for pretesting (true file names in load-history?) Alan Mackenzie
2006-04-20 1:14 ` Last steps for pretesting Richard Stallman
2006-04-24 17:52 ` Richard Stallman
2006-04-20 10:54 ` Reiner Steib
2006-04-21 0:10 ` Richard Stallman
2006-04-21 5:46 ` David Kastrup
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
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87psjbon3b.fsf-monnier+emacs@gnu.org \
--to=monnier@iro.umontreal.ca \
--cc=emacs-devel@gnu.org \
--cc=rms@gnu.org \
/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 public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).