[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: address@hidden: modification hooks called only once in c-mode]
From: |
Chong Yidong |
Subject: |
Re: address@hidden: modification hooks called only once in c-mode] |
Date: |
Fri, 10 Aug 2007 20:46:37 -0400 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.1.50 (gnu/linux) |
Richard Stallman <address@hidden> writes:
> Would someone please DTRT, then ack?
> If the fix is simple enough, it should be installed in Emacs 22.
> ....
>
> (defun test-bug-hook (overlay afterp beg end &optional r)
> (message "%s hook called" (if afterp "after" "before")))
>
> (defun test-bug ()
> (let ((beg (point))
> ov)
> (insert "foobar")
> (setq ov (make-overlay beg (point)))
> (overlay-put ov 'face 'highlight)
> (overlay-put ov 'insert-in-front-hooks '(test-bug-hook))))
>
> 1) Create a new buffer in c-mode, evaluate (test-bug), and insert a char
> before the overlay.
>
> Result:
> before hook called
>
> The hook is never called after the change.
The problem is in report_overlay_modification in buffer.c. This
function, which is called both before and after a modification,
compiles a list of modification-hooks to run and executes them. When
called before modification, it first does
last_overlay_modification_hooks_used = 0;
to reset the list of modification hooks to run.
The bug arises when you have an after-change hook that does buffer
changes (in this case, this is c-after-change, which calls
c-invalidate-sws-region-after). The sequence of events is:
1. User issues command to modify the buffer.
2. Before the change is applied, report_overlay_modification is
called. It resets last_overlay_modification_hooks_used to zero,
then compiles a list of hooks to run. This includes both the
insert-in-front hook and the after-change hook.
3. The insert-in-front hook runs.
4. The buffer modification is applies.
5. The after-change hook runs, modifying the buffer elsewhere.
6. This results in report_overlay_modification being called, which
resets last_overlay_modification_hooks_used to zero. The
insert-in-front hook, which was scheduled to run next, gets rubbed
out.
One simple fix is to bind inhibit-modification-hooks in
c-after-change.
A deeper fix would be to make report_overlay_modification check if it
is being called in a modification hook, and take steps to prevent
scheduled hooks from being rubbed out. I'm not sure this behavior is
significantly more "correct" than the existing one, however; it may be
better to leave it as is.
In either case, I'd suggest not putting the fix for this in Emacs
22.2. The first fix can cause subtle problems since c-after-change is
a core part of cc-mode, and the second one is also somewhat delicate.
It can go in the trunk, and be merged into the branch for 22.3 if no
problems are found.