* Font-lock: Major mode should be able to specify region to fontify.
@ 2002-05-10 19:32 Alan Mackenzie
2002-05-10 21:31 ` Stefan Monnier
2002-05-10 22:40 ` Kim F. Storm
0 siblings, 2 replies; 3+ messages in thread
From: Alan Mackenzie @ 2002-05-10 19:32 UTC (permalink / raw)
Currently, when a buffer change occurs, the region which font-lock
refontifies is rigidly constrained to the smallest set of complete lines
which enclose the changed region. Also, there is an implicit assumption
in font-lock that a buffer change can _never_ cause refontification
earlier in the buffer. This works well most of the time, but isn't
always satisfactory.
For example, in awk-mode I want to give an unmatched string/regexp
delimiter font-lock-warning-face. This works well as long as the string
isn't continued to another line. In the following,
1 "A string which \
2 straddles \
3 several \
4 lines
^
point.
the " on line 1 currently has warning-face, since it's unmatched. As
soon as the user types in the closing " on line 4, I want to refontify
the " on line 1 to string-face. Should any of the \s be deleted, then
_both_ "s would get warning-face, and the tail of the string would lose
the string-face.
To do this requires that awk-mode can tell font-lock to fontify lines 1
to 4, rather than just line 4 which it currently does.
I have implemented this feature in font-lock.el (and friends) by creating
a new abnormal hook variable which, if set, is called by one of the
font-lock after-change functions. Here is the patch. The context-diff
is based on the source files from Emacs 21.1.
;;;;;; Changelog entry
2002-05-10 Alan Mackenzie <acm@muc.de>
The following set of changes allows a major mode dynamically to
specify the region to fontify after a buffer change. (fast-lock.el
doesn't need changing.)
* font-lock.el
New abnormal hook before-font-lock-after-change-function,
New function font-lock-run-before-after-change-hook.
Changed font-lock-after-change-function.
* jit-lock.el
Changed jit-lock-after-change
* lazy-lock.el
Changed lazy-lock-defer-line-after-change and
lazy-lock-defer-rest-after-change.
;;;;;; End of Changelog entry
;;;;;; Patch
diff -c -x ChangeLog -x Makefile -x README /usr/src/packages/BUILD/emacs-21.1/lisp/font-lock.el NEW/font-lock.el
*** /usr/src/packages/BUILD/emacs-21.1/lisp/font-lock.el Wed Sep 5 13:36:29 2001
--- NEW/font-lock.el Fri May 10 19:24:25 2002
***************
*** 1260,1270 ****
'(face nil syntax-table nil font-lock-multiline nil)
'(face nil font-lock-multiline nil)))))
;; Called when any modification is made to buffer text.
(defun font-lock-after-change-function (beg end old-len)
! (let ((inhibit-point-motion-hooks t))
(save-excursion
(save-match-data
;; Rescan between start of lines enclosing the region.
(font-lock-fontify-region
(progn (goto-char beg) (beginning-of-line) (point))
--- 1260,1309 ----
'(face nil syntax-table nil font-lock-multiline nil)
'(face nil font-lock-multiline nil)))))
+ (defvar before-font-lock-after-change-function nil
+ "If set to a function, this can specify the region to fontify after a change.
+
+ This variable is a buffer-local abnormal hook whose value, if set, should be a
+ single function. The function gets called from the active font-lock
+ after-change function, and is intended to allow a major mode to calculate for
+ itself the region to be fontified after a buffer change.
+
+ The function is given three parameters, the standard BEG, END and OLD-LEN from
+ after-change-functions. It should return either a cons of the beginning and end
+ buffer-positions \(in that order\) of the region to fontify, or nil (in which
+ case the default region will be used).")
+ (make-variable-buffer-local 'before-font-lock-after-change-function)
+
+ (defun font-lock-run-before-after-change-hook (beg end old-len)
+ "Run the hook function, if any, in before-font-lock-after-change-function,
+ returning its value (a cons of beg and end), if it's valid, else nil.
+
+ BEG END and OLD-LEN are the three parameters supplied by
+ after-change-functions."
+ (cond ((null before-font-lock-after-change-function) nil)
+ ((not (functionp before-font-lock-after-change-function))
+ (message "before-font-lock-after-change-function's value is not a \
+ function in buffer %S"
+ (buffer-name))
+ nil)
+ (t (let ((region (funcall before-font-lock-after-change-function beg end old-len)))
+ (cond ((null region) nil)
+ ((or (not (consp region))
+ (not (wholenump (car region))) (not (wholenump (cdr region)))
+ (not (<= (car region) (cdr region))))
+ (message "before-font-lock-after-change-function returned %S. \
+ This isn't a cons \(beg.end\), with beg and end numbers, and beg <= end")
+ nil)
+ (t region))))))
+
;; Called when any modification is made to buffer text.
(defun font-lock-after-change-function (beg end old-len)
! (let ((inhibit-point-motion-hooks t) region)
(save-excursion
(save-match-data
+ ;; Does the major mode have its own ideas about the region to fontify?
+ (setq region (font-lock-run-before-after-change-hook beg end old-len))
+ (if region (setq beg (car region) end (cdr region)))
;; Rescan between start of lines enclosing the region.
(font-lock-fontify-region
(progn (goto-char beg) (beginning-of-line) (point))
diff -c -x ChangeLog -x Makefile -x README /usr/src/packages/BUILD/emacs-21.1/lisp/jit-lock.el NEW/jit-lock.el
*** /usr/src/packages/BUILD/emacs-21.1/lisp/jit-lock.el Mon Jul 16 12:22:58 2001
--- NEW/jit-lock.el Fri May 10 18:59:36 2002
***************
*** 426,431 ****
--- 426,434 ----
(when jit-lock-mode
(save-excursion
(with-buffer-prepared-for-jit-lock
+ ;; Does the major mode have its own ideas about the region to fontify?
+ (let ((region (font-lock-run-before-after-change-hook start end old-len)))
+ (if region (setq start (car region) end (cdr region))))
;; It's important that the `fontified' property be set from the
;; beginning of the line, else font-lock will properly change the
;; text's face, but the display will have been done already and will
diff -c -x ChangeLog -x Makefile -x README /usr/src/packages/BUILD/emacs-21.1/lisp/lazy-lock.el NEW/lazy-lock.el
*** /usr/src/packages/BUILD/emacs-21.1/lisp/lazy-lock.el Thu Aug 16 14:25:15 2001
--- NEW/lazy-lock.el Fri May 10 19:00:47 2002
***************
*** 771,776 ****
--- 771,779 ----
(save-buffer-state nil
(unless (memq (current-buffer) lazy-lock-buffers)
(push (current-buffer) lazy-lock-buffers))
+ ;; Does the major mode have its own ideas about what to fontify?
+ (let ((region (font-lock-run-before-after-change-hook beg end old-len)))
+ (if region (setq beg (car region) end (cdr region))))
(remove-text-properties (max (1- beg) (point-min))
(min (1+ end) (point-max))
'(lazy-lock nil))))
***************
*** 784,789 ****
--- 787,795 ----
(push (current-buffer) lazy-lock-buffers))
(save-restriction
(widen)
+ ;; Does the major mode have its own ideas about what to fontify?
+ (let ((region (font-lock-run-before-after-change-hook beg end old-len)))
+ (if region (setq beg (car region) end (cdr region))))
(remove-text-properties (max (1- beg) (point-min))
(point-max)
'(lazy-lock nil)))))
;;;;;; end of patch.
--
Alan Mackenzie (Munich, Germany)
Email: aacm@muuc.dee; to decode, wherever there is a repeated letter
(like "aa"), remove half of them (leaving, say, "a").
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Font-lock: Major mode should be able to specify region to fontify.
2002-05-10 19:32 Font-lock: Major mode should be able to specify region to fontify Alan Mackenzie
@ 2002-05-10 21:31 ` Stefan Monnier
2002-05-10 22:40 ` Kim F. Storm
1 sibling, 0 replies; 3+ messages in thread
From: Stefan Monnier @ 2002-05-10 21:31 UTC (permalink / raw)
>>>>> "Alan" == Alan Mackenzie <none@example.invalid> writes:
> I have implemented this feature in font-lock.el (and friends) by creating
> a new abnormal hook variable which, if set, is called by one of the
> font-lock after-change functions. Here is the patch. The context-diff
> is based on the source files from Emacs 21.1.
Please use the latest CVS code as a base, whenever possible.
As for other solutions to your problem:
1 - use font-lock-multiline (but this is a bit expensive)
2 - use jit-lock-defer-multiline (see the CVS' etc/NEWS file)
Solution 2 was written specifically for this kind of case.
Stefan
PS: Your changelog entries don't look right. They should look like
* filename (functionname, varname, othername): blabla.
(morefunctionchanged): blabli.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Font-lock: Major mode should be able to specify region to fontify.
2002-05-10 19:32 Font-lock: Major mode should be able to specify region to fontify Alan Mackenzie
2002-05-10 21:31 ` Stefan Monnier
@ 2002-05-10 22:40 ` Kim F. Storm
1 sibling, 0 replies; 3+ messages in thread
From: Kim F. Storm @ 2002-05-10 22:40 UTC (permalink / raw)
none@example.invalid (Alan Mackenzie) writes:
> I have implemented this feature in font-lock.el (and friends) by creating
> a new abnormal hook variable which, if set, is called by one of the
> font-lock after-change functions. Here is the patch. The context-diff
> is based on the source files from Emacs 21.1.
> * font-lock.el
> New abnormal hook before-font-lock-after-change-function,
> New function font-lock-run-before-after-change-hook.
> Changed font-lock-after-change-function.
I think your patch is ok as such, but I found the naming of the
font-lock-run-before-after-change-hook function rather confusing
(ending in -hook).
Maybe font-lock-get-buffer-specific-region is a better name?
Also, the name of the hook function variable should start with font-lock-,
and it's name really doesn't tell anything about what it does.
IMO, a better name would be font-lock-buffer-specific-region-function.
As a proof of concept, do you have code (using this) for awk-mode to fix the
problem you wanted to solve?
--
Kim F. Storm http://www.cua.dk
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2002-05-10 22:40 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-05-10 19:32 Font-lock: Major mode should be able to specify region to fontify Alan Mackenzie
2002-05-10 21:31 ` Stefan Monnier
2002-05-10 22:40 ` Kim F. Storm
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.