From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Chong Yidong Newsgroups: gmane.emacs.devel Subject: Re: [n_schumacher@web.de: modification hooks called only once in c-mode] Date: Fri, 10 Aug 2007 20:46:37 -0400 Message-ID: <874pj6j3te.fsf@stupidchicken.com> References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1186793390 23342 80.91.229.12 (11 Aug 2007 00:49:50 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Sat, 11 Aug 2007 00:49:50 +0000 (UTC) Cc: emacs-devel@gnu.org To: rms@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Aug 11 02:49:46 2007 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1IJfAn-0005qu-Rn for ged-emacs-devel@m.gmane.org; Sat, 11 Aug 2007 02:49:46 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IJfAn-0004ps-3u for ged-emacs-devel@m.gmane.org; Fri, 10 Aug 2007 20:49:45 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1IJfAj-0004pf-Au for emacs-devel@gnu.org; Fri, 10 Aug 2007 20:49:41 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1IJfAg-0004pT-TD for emacs-devel@gnu.org; Fri, 10 Aug 2007 20:49:40 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IJfAg-0004pQ-Ny for emacs-devel@gnu.org; Fri, 10 Aug 2007 20:49:38 -0400 Original-Received: from cyd.mit.edu ([18.115.2.24]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1IJfAd-0005Fq-Rm; Fri, 10 Aug 2007 20:49:35 -0400 Original-Received: by cyd.mit.edu (Postfix, from userid 1000) id E2A6E4E37A; Fri, 10 Aug 2007 20:46:37 -0400 (EDT) In-Reply-To: (Richard Stallman's message of "Wed\, 08 Aug 2007 00\:55\:29 -0400") User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1.50 (gnu/linux) X-Detected-Kernel: Linux 2.6 (newer, 1) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:76337 Archived-At: Richard Stallman 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.