unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Alan Mackenzie <acm@muc.de>
To: Eli Zaretskii <eliz@gnu.org>
Cc: ofv@wanadoo.es, rcopley@gmail.com, rms@gnu.org, emacs-devel@gnu.org
Subject: Re: Unbalanced change hooks (part 2)
Date: Mon, 8 Aug 2016 18:42:23 +0000	[thread overview]
Message-ID: <20160808184223.GC7208@acm.fritz.box> (raw)
In-Reply-To: <83d1lji3ih.fsf@gnu.org>

Hello, Eli.

On Mon, Aug 08, 2016 at 08:17:42PM +0300, Eli Zaretskii wrote:
> > Date: Mon, 8 Aug 2016 16:54:49 +0000
> > Cc: ofv@wanadoo.es, rcopley@gmail.com, rms@gnu.org, emacs-devel@gnu.org
> > From: Alan Mackenzie <acm@muc.de>

> > > What triggers that code?

> > before/after-change-functions.  For example, in C++ Mode, if a "<"
> > template delimiter is about is in a region about to be deleted, and the
> > matching ">" is after that region, the pertinent function called from
> > c-before-change (c-before-change-check-<>-operators) removes the
> > syntax-table properties from each of them.

> > > E.g., when a file is visited, what invokes that code, and how much of
> > > the buffer it processes when invoked?

> > On a newly visited file, the entire buffer is scanned by (the components
> > of) c-before-change and c-after-change, setting the text properties.

> So, if worse comes to worst, you could trigger such a complete scan
> after revert-buffer, e.g. in a specialized revert-buffer-function.

Why would that be bad?  We detect the bad condition by two consecutive
after-c-f calls, check that revert-buffer is on the call stack, and
twiddle `beg' `end' `old-len' (the parameters to after-change functions)
to indicate the entire buffer.  Then let c-after-change carry on.  This
feels too easy.  :-)  What am I missing?

> Do you have a way of completely forgetting everything about a certain
> region of buffer text, and rescanning that region anew?

This is tricky, because, for example, template delimiters outside that
region are associated with deleted (or unmarked) delimiters inside the
region.

> If so, would it work to do this in c-after-change, since its arguments
> tell you both the old and the new buffer positions where the changes
> were made?  If this works, it might be less expensive then rescanning
> the entire buffer.

I don't think this would work.  beg, end, and old-len only say where
things were changed, not what syntax-table'd characters have been
deleted.  Anyway, what's so bad about scanning the entire buffer after
having reverted it?

> > What I'm looking at at the moment is calling revert-buffer a second time
> > if CC Mode signals a missing before-change-functions the first time.
> > After the test scenario, M-x revert-buffer works, so it might work if
> > called from the code instead.

> I don't understand how this could work reliably: it has the same
> problems as the original recipe.  Am I missing something?

There is nothing like buffer-undo-list which can be corrupted by other
programs.  Anyhow, I've implemented it, and it works well on the test
case from bug #24094.  Here is the embryonic patch (I haven't reindented
code, so as to keep the patch short, and there's message output).  It
works, for the moment, by putting "around" advice around revert-buffer,
and invoking ad-do-it a second time if the first time didn't work:




diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 04d2ed6..4db71b6 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -492,10 +492,13 @@ c-maybe-stale-found-type
 (defvar c-just-done-before-change nil)
 (make-variable-buffer-local 'c-just-done-before-change)
 ;; This variable is set to t by `c-before-change' and to nil by
-;; `c-after-change'.  It is used to detect a spurious invocation of
-;; `before-change-functions' directly following on from a correct one.  This
-;; happens in some Emacsen, for example when `basic-save-buffer' does (insert
-;; ?\n) when `require-final-newline' is non-nil.
+;; `c-after-change'.  It is used for two purposes: (i) to detect a spurious
+;; invocation of `before-change-functions' directly following on from a
+;; correct one.  This happens in some Emacsen, for example when
+;; `basic-save-buffer' does (insert ?\n) when `require-final-newline' is
+;; non-nil; (ii) to detect when Emacs fails to invoke
+;; `before-change-functions'.  This can happend when reverting a buffer - see
+;; bug #24094.
 
 (defun c-basic-common-init (mode default-style)
   "Do the necessary initialization for the syntax handling routines
@@ -643,8 +646,9 @@ c-basic-common-init
   (add-hook 'after-change-functions 'c-after-change nil t)
   (when (boundp 'font-lock-extend-after-change-region-function)
     (set (make-local-variable 'font-lock-extend-after-change-region-function)
-         'c-extend-after-change-region))) ; Currently (2009-05) used by all
+         'c-extend-after-change-region)) ; Currently (2009-05) used by all
                           ; languages with #define (C, C++,; ObjC), and by AWK.
+  (add-hook 'pre-command-hook 'c-pre-command-hook t))
 
 (defun c-setup-doc-comment-style ()
   "Initialize the variables that depend on the value of `c-doc-comment-style'."
@@ -1225,6 +1229,22 @@ c-before-change
     ;; newly inserted parens would foul up the invalidation algorithm.
     (c-invalidate-state-cache beg)))
 
+(defvar c-missed-before-change nil)
+
+(defun c-pre-command-hook ()
+  (setq c-missed-before-change nil))
+
+(defadvice revert-buffer (around c-advise-revert-buffer activate)
+  ad-do-it
+  (when (and c-buffer-is-cc-mode
+	     c-missed-before-change)
+    (message "Repeating revert-buffer.")
+    (setq c-missed-before-change nil)
+    ad-do-it
+    (message "Repeated revert-buffer %s"
+	     (if c-missed-before-change "failed" "succeeded"))
+    ))
+
 (defvar c-in-after-change-fontification nil)
 (make-variable-buffer-local 'c-in-after-change-fontification)
 ;; A flag to prevent region expanding stuff being done twice for after-change
@@ -1244,6 +1264,10 @@ c-after-change
   ;; This calls the language variable c-before-font-lock-functions, if non nil.
   ;; This typically sets `syntax-table' properties.
 
+  ;; Rarely, Emacs will fail to call `before-change-functions'.  See bug
+  ;; #24094.  In such cases, do it "by hand".
+  (if (not c-just-done-before-change)
+      (setq c-missed-before-change t)
   ;; (c-new-BEG c-new-END) will be the region to fontify.  It may become
   ;; larger than (beg end).
   (setq c-new-END (- (+ c-new-END (- end beg)) old-len))
@@ -1291,7 +1315,7 @@ c-after-change
 	  (save-excursion
 	    (mapc (lambda (fn)
 		    (funcall fn beg end old-len))
-		  c-before-font-lock-functions)))))))
+		  c-before-font-lock-functions))))))))
 
 (defun c-fl-decl-start (pos)
   ;; If the beginning of the line containing POS is in the middle of a "local"
@@ -1483,6 +1507,8 @@ c-extend-after-change-region
   ;; Of the seven CC Mode languages, currently (2009-05) only C, C++, Objc
   ;; (the languages with #define) and AWK Mode make non-null use of this
   ;; function.
+  (if c-missed-before-change
+      (cons beg end)
   (when (eq font-lock-support-mode 'jit-lock-mode)
     (save-restriction
       (widen)
@@ -1491,7 +1517,7 @@ c-extend-after-change-region
 	    (put-text-property c-new-BEG beg 'fontified nil))
 	(if (> c-new-END end)
 	    (put-text-property end c-new-END 'fontified nil)))))
-  (cons c-new-BEG c-new-END))
+  (cons c-new-BEG c-new-END)))
 
 ;; Emacs < 22 and XEmacs
 (defmacro c-advise-fl-for-region (function)


-- 
Alan Mackenzie (Nuremberg, Germany).



  reply	other threads:[~2016-08-08 18:42 UTC|newest]

Thread overview: 189+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-31 12:16 Unbalanced change hooks (part 2) Alan Mackenzie
2016-07-31 13:58 ` Noam Postavsky
2016-07-31 15:21   ` Alan Mackenzie
2016-07-31 15:03 ` Eli Zaretskii
2016-07-31 17:28   ` Alan Mackenzie
2016-07-31 18:11     ` Eli Zaretskii
2016-07-31 18:52       ` Eli Zaretskii
2016-07-31 19:08         ` Eli Zaretskii
2016-07-31 19:20       ` Noam Postavsky
2016-07-31 21:26       ` Alan Mackenzie
2016-08-01 13:01         ` Stefan Monnier
2016-08-01 13:07         ` Eli Zaretskii
2016-08-01 16:53           ` Alan Mackenzie
2016-08-01 17:15             ` Alan Mackenzie
2016-08-01 19:39               ` Eli Zaretskii
2016-08-01 20:52                 ` Alan Mackenzie
2016-08-02 14:44                   ` Eli Zaretskii
2016-08-02 16:09                     ` Alan Mackenzie
2016-08-02 16:42                       ` Eli Zaretskii
2016-08-02 17:24                       ` Stefan Monnier
2016-08-07 14:49                         ` Alan Mackenzie
2016-08-07 15:09                           ` Stefan Monnier
2016-08-07 21:48                             ` Alan Mackenzie
2016-08-08  0:55                               ` Stefan Monnier
2016-08-02 14:46                   ` Stefan Monnier
2016-08-01 19:37             ` Eli Zaretskii
2016-08-02 14:39             ` Stefan Monnier
2016-07-31 18:55     ` Stefan Monnier
2016-07-31 19:26       ` Eli Zaretskii
2016-07-31 21:59         ` Stefan Monnier
2016-08-01 13:09           ` Eli Zaretskii
2016-08-01 14:36             ` Stefan Monnier
2016-08-01 14:48               ` Eli Zaretskii
2016-08-01 15:28                 ` Stefan Monnier
2016-07-31 19:33       ` Alan Mackenzie
2016-07-31 19:21     ` Eli Zaretskii
2016-08-09 15:01   ` Alan Mackenzie
2016-08-09 15:14     ` Eli Zaretskii
2016-08-19 14:51   ` Phillip Lord
2016-08-30  1:15     ` Stefan Monnier
2016-08-30 14:34       ` Phillip Lord
2016-08-30 15:11         ` Stefan Monnier
2016-08-31 11:00           ` Phillip Lord
2016-08-31 12:24             ` Stefan Monnier
2016-09-01  6:49               ` Phillip Lord
2016-09-01 13:36                 ` Stefan Monnier
2016-09-01  6:40           ` Phillip Lord
2016-09-01 13:33             ` Stefan Monnier
2016-09-02 11:34               ` Phillip Lord
2016-08-30 16:08         ` Eli Zaretskii
2016-08-01 16:38 ` Richard Stallman
2016-08-02 10:15   ` Alan Mackenzie
2016-08-02 10:37     ` Richard Copley
2016-08-02 16:11       ` Alan Mackenzie
2016-08-02 14:57     ` Eli Zaretskii
2016-08-02 16:55       ` Alan Mackenzie
2016-08-02 17:17         ` Eli Zaretskii
2016-08-02 18:30           ` Eli Zaretskii
2016-08-02 19:38             ` Alan Mackenzie
2016-08-03  2:36               ` Eli Zaretskii
2016-08-08 14:36             ` Alan Mackenzie
2016-08-08 15:42               ` Eli Zaretskii
2016-08-08 16:54                 ` Alan Mackenzie
2016-08-08 17:17                   ` Eli Zaretskii
2016-08-08 18:42                     ` Alan Mackenzie [this message]
2016-08-08 19:04                       ` Eli Zaretskii
2016-08-08 19:54                         ` Unbalanced change hooks (part 2) [PATCH] Alan Mackenzie
2016-08-09 15:08                           ` Eli Zaretskii
2016-08-09 16:38                             ` Unbalanced change hooks (part 2) [Documentation fix still remaining] Alan Mackenzie
2016-08-09 16:42                               ` Eli Zaretskii
2016-08-09 18:13                                 ` Eli Zaretskii
2016-08-09 18:35                                   ` Alan Mackenzie
2016-08-09 17:14                               ` Stefan Monnier
2016-08-09 18:19                                 ` Eli Zaretskii
2016-08-09 19:09                                   ` Stefan Monnier
2016-08-10 14:21                                     ` Eli Zaretskii
2016-08-10 14:56                                       ` Stefan Monnier
2016-08-10 15:16                                         ` Alan Mackenzie
2016-08-10 15:44                                           ` Stefan Monnier
2016-08-10 16:03                                         ` Eli Zaretskii
2016-08-10 16:11                                           ` Stefan Monnier
2016-08-18 14:26                                             ` Eli Zaretskii
2016-08-18 16:56                                               ` Stefan Monnier
2016-08-19  8:45                                               ` Alan Mackenzie
2016-08-19  9:12                                                 ` Eli Zaretskii
2016-08-19  9:21                                                   ` Stefan Monnier
2016-08-19  9:39                                                     ` Eli Zaretskii
2016-08-19  9:19                                                 ` Stefan Monnier
2016-08-10 16:18                                           ` Alan Mackenzie
2016-08-10 16:54                                             ` Eli Zaretskii
2016-08-10 17:49                                               ` Alan Mackenzie
2016-08-10 18:10                                                 ` Eli Zaretskii
2016-08-10 18:57                                               ` Alan Mackenzie
2016-08-10 19:08                                                 ` Eli Zaretskii
2016-08-10 19:50                                                 ` Stefan Monnier
2016-08-11 11:29                                                   ` Alan Mackenzie
2016-08-11 16:43                                                     ` Stefan Monnier
2016-08-28 11:23                                                       ` Daniel Colascione
2016-08-28 15:01                                                         ` Stefan Monnier
2016-08-28 22:16                                                           ` Daniel Colascione
2016-08-28 22:44                                                             ` Stefan Monnier
2016-08-28 23:11                                                               ` Daniel Colascione
2016-08-29  0:09                                                                 ` Stefan Monnier
2016-08-29  3:18                                                                   ` Daniel Colascione
2016-08-29 13:00                                                                     ` Stefan Monnier
2016-08-29 14:51                                                                       ` Eli Zaretskii
2016-08-29 15:50                                                                         ` Stefan Monnier
2016-08-29 16:22                                                                           ` Eli Zaretskii
2016-08-29 15:14                                                                       ` Daniel Colascione
2016-08-29 15:44                                                                         ` Stefan Monnier
2016-08-30 14:07                                                                           ` Phillip Lord
2016-08-30 15:51                                                                             ` Eli Zaretskii
2016-08-30 16:22                                                                               ` Daniel Colascione
2016-08-30 16:46                                                                                 ` Eli Zaretskii
2016-08-29 14:50                                                                     ` Eli Zaretskii
2016-08-29 15:30                                                                       ` Daniel Colascione
2016-08-29 16:20                                                                         ` Eli Zaretskii
2016-08-29 16:26                                                                           ` Daniel Colascione
2016-08-29 17:01                                                                             ` Eli Zaretskii
2016-08-29 17:48                                                                               ` Daniel Colascione
2016-08-29 18:04                                                                                 ` Eli Zaretskii
2016-08-29 18:16                                                                                   ` Eli Zaretskii
2016-08-30  2:27                                                                                     ` Daniel Colascione
2016-08-30  2:44                                                                                       ` Eli Zaretskii
2016-08-30  0:25                                                                                   ` Stefan Monnier
2016-08-30  2:26                                                                                     ` Daniel Colascione
2016-08-30  2:38                                                                                     ` Eli Zaretskii
2016-08-30  2:54                                                                                       ` Daniel Colascione
2016-08-30 14:20                                                                                         ` Phillip Lord
2016-08-30 15:08                                                                                         ` Eli Zaretskii
2016-08-30 12:56                                                                                       ` Stefan Monnier
2016-08-30 14:12                                                                       ` Phillip Lord
2016-08-30 16:06                                                                         ` Eli Zaretskii
2016-08-31 11:20                                                                           ` Phillip Lord
2016-08-31 14:57                                                                             ` Eli Zaretskii
2016-08-30 17:12                                                                       ` Alan Mackenzie
2016-08-30 17:27                                                                         ` Daniel Colascione
2016-08-30 17:42                                                                           ` Eli Zaretskii
2016-08-30 17:46                                                                             ` Daniel Colascione
2016-08-30 18:00                                                                               ` Eli Zaretskii
2016-08-30 18:04                                                                                 ` Daniel Colascione
2016-08-30 18:46                                                                                   ` Eli Zaretskii
2016-08-30 18:58                                                                                     ` Daniel Colascione
2016-08-30 19:17                                                                                       ` Eli Zaretskii
2016-08-30 21:46                                                                                     ` Stefan Monnier
2016-08-31  2:38                                                                                       ` Eli Zaretskii
2016-08-30 18:27                                                                                 ` Stefan Monnier
2016-09-01 13:46                                                                                   ` Eli Zaretskii
2016-08-30 18:01                                                                               ` Alan Mackenzie
2016-08-30 18:06                                                                                 ` Daniel Colascione
2016-08-30 18:17                                                                                   ` Daniel Colascione
2016-08-30 18:30                                                                                     ` Alan Mackenzie
2016-08-30 18:32                                                                                       ` Daniel Colascione
2016-08-30 18:47                                                                                         ` Alan Mackenzie
2016-08-30 18:55                                                                                           ` Daniel Colascione
2016-08-30 19:14                                                                                             ` Alan Mackenzie
2016-08-30 20:34                                                                                               ` Stefan Monnier
2016-08-30 20:53                                                                                                 ` Alan Mackenzie
2016-08-30 21:37                                                                                                   ` Stefan Monnier
2016-08-30 18:36                                                                                       ` Stefan Monnier
2016-08-30 18:22                                                                             ` Stefan Monnier
2016-08-30 18:00                                                                           ` Stefan Monnier
2016-08-30 17:27                                                                         ` Eli Zaretskii
2016-08-30 17:42                                                                           ` Alan Mackenzie
2016-08-30 17:53                                                                             ` Eli Zaretskii
2016-08-30 18:16                                                                               ` Alan Mackenzie
2016-08-30 18:51                                                                                 ` Eli Zaretskii
2016-08-30 19:00                                                                                   ` Alan Mackenzie
2016-08-30 18:14                                                                             ` Stefan Monnier
2016-09-01 21:25                                                                       ` Davis Herring
2016-09-02  7:26                                                                         ` Eli Zaretskii
2016-08-28 22:36                                                         ` Stefan Monnier
2016-08-30 13:30                                                         ` Phillip Lord
2016-08-30 13:39                                                           ` Stefan Monnier
2016-08-31 11:04                                                             ` Phillip Lord
2016-08-30 15:47                                                           ` Eli Zaretskii
2016-08-30 16:01                                                             ` Stefan Monnier
2016-08-30 16:58                                                               ` Eli Zaretskii
2016-08-30 17:57                                                                 ` Stefan Monnier
2016-08-31 11:17                                                                   ` Phillip Lord
2016-08-31 11:12                                                                 ` Phillip Lord
2016-08-30 16:23                                                             ` Daniel Colascione
2016-08-30 16:53                                                               ` Eli Zaretskii
2016-08-02 19:00           ` Unbalanced change hooks (part 2) Alan Mackenzie
2016-08-02 19:25             ` Eli Zaretskii
2016-08-07 21:16               ` Alan Mackenzie
2016-08-08 15:38                 ` Eli Zaretskii
2016-08-08 19:56                 ` Stefan Monnier
2016-08-08 20:16                   ` Alan Mackenzie

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=20160808184223.GC7208@acm.fritz.box \
    --to=acm@muc.de \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=ofv@wanadoo.es \
    --cc=rcopley@gmail.com \
    --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).