GNU bug report logs - #20266
Emacs doesn't respond when editing the attached c header file.

Previous Next

Packages: emacs, cc-mode;

Reported by: 张海君 <netjune <at> icloud.com>

Date: Mon, 6 Apr 2015 10:11:02 UTC

Severity: normal

Done: Alan Mackenzie <acm <at> muc.de>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 20266 in the body.
You can then email your comments to 20266 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#20266; Package emacs. (Mon, 06 Apr 2015 10:11:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to 张海君 <netjune <at> icloud.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Mon, 06 Apr 2015 10:11:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: 张海君 <netjune <at> icloud.com>
To: bug-gnu-emacs <at> gnu.org
Subject: Emacs doesn't respond when editing the attached c header file.
Date: Mon, 06 Apr 2015 18:09:40 +0800
[Message part 1 (text/plain, inline)]
Emacs doesn't respond when editing the attached c header file.
Emacs version: 24.4.

------------------------------------
Run emacs with "emacs -Q test.h".
M-x mark-whole-buffer
M-x kill-ring-save
M-x end-of-buffer
M-x yank
Then emacs doesn't respond for about 5 seconds.
M-x scroll-down-command. 
Then emacs doesn't respond for about 5 seconds too.
[test.h (application/octet-stream, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org, bug-cc-mode <at> gnu.org:
bug#20266; Package emacs,cc-mode. (Tue, 07 Apr 2015 15:17:02 GMT) Full text and rfc822 format available.

Message #8 received at 20266 <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: ??? <netjune <at> icloud.com>, 20266 <at> debbugs.gnu.org
Subject: Re: bug#20266: Emacs doesn't respond when editing the attached c
 header	file.
Date: 7 Apr 2015 15:16:16 -0000
Hello, Netjune.

In article <mailman.71.1428315070.904.bug-gnu-emacs <at> gnu.org> you wrote:
> [-- text/plain, encoding 7bit, charset: us-ascii, 13 lines --]

> Emacs doesn't respond when editing the attached c header file.
> Emacs version: 24.4.

> ------------------------------------
> Run emacs with "emacs -Q test.h".
> M-x mark-whole-buffer
> M-x kill-ring-save
> M-x end-of-buffer
> M-x yank
> Then emacs doesn't respond for about 5 seconds.
> M-x scroll-down-command. 
> Then emacs doesn't respond for about 5 seconds too.

Yes.  This isn't good at all.

> M-x scroll-down-command.
> Then emacs doesn't respond for about 5 seconds too.

I can't actually reproduce this delay.

There is special handling on `yank' for some arcane mechanisms in Emacs,
and these simply waste time in CC Mode for no productive purpose.  The
patch below should switch off this processing.



diff -r 5cc874770a5d cc-mode.el
--- a/cc-mode.el        Tue Apr 07 10:25:37 2015 +0000
+++ b/cc-mode.el        Tue Apr 07 14:58:37 2015 +0000
@@ -502,6 +502,7 @@
   (make-local-variable 'adaptive-fill-mode)
   (make-local-variable 'adaptive-fill-regexp)
   (make-local-variable 'fill-paragraph-handle-comment)
+  (make-local-variable 'yank-handled-properties)

   ;; now set their values
   (setq parse-sexp-ignore-comments t
@@ -511,6 +512,12 @@
        comment-multi-line t
        comment-line-break-function 'c-indent-new-comment-line)

+  ;; Prevent time-wasting activity on C-y.
+  (let ((yank-cat-handler (assq 'category yank-handled-properties)))
+    (when yank-cat-handler
+      (setq yank-handled-properties (remq yank-cat-handler
+                                         yank-handled-properties))))
+
   ;; For the benefit of adaptive file, which otherwise mis-fills.
   (setq fill-paragraph-handle-comment nil)
 



Please try applying this patch to .../emacs/lisp/progmodes/cc-mode.el,
then recompiling that file with either:

(on the command line):
    $ emacs -Q -batch -f batch-byte-compile .../path/to/cc-mode.el

, or (from within Emacs):
    M-x byte-compile-file <CR> .../path/to/cc-mode.el.

Either load this file (with M-x load-file) or restart Emacs.  Hopefully
the first problem (with M-x yank) will have gone away.

Could you please get back to me and confirm that the M-x yank delay has
gone, and let me know whether the delay on M-x scroll-down-command is
still a problem.

Thanks for taking the trouble to report this bug.

-- 
Alan Mackenzie (Nuremberg, Germany).





Information forwarded to bug-gnu-emacs <at> gnu.org, bug-cc-mode <at> gnu.org:
bug#20266; Package emacs,cc-mode. (Sun, 12 Apr 2015 02:16:02 GMT) Full text and rfc822 format available.

Message #11 received at 20266 <at> debbugs.gnu.org (full text, mbox):

From: 张海君 <netjune <at> icloud.com>
To: Alan Mackenzie <acm <at> muc.de>
Cc: 20266 <at> debbugs.gnu.org
Subject: Re: bug#20266: Emacs doesn't respond when editing the attached c
 header	file.
Date: Sun, 12 Apr 2015 10:15:15 +0800
> 在 2015年4月7日,23:16,Alan Mackenzie <acm <at> muc.de> 写道:
> 
> Hello, Netjune.
> 
> In article <mailman.71.1428315070.904.bug-gnu-emacs <at> gnu.org> you wrote:
>> [-- text/plain, encoding 7bit, charset: us-ascii, 13 lines --]
> 
>> Emacs doesn't respond when editing the attached c header file.
>> Emacs version: 24.4.
> 
>> ------------------------------------
>> Run emacs with "emacs -Q test.h".
>> M-x mark-whole-buffer
>> M-x kill-ring-save
>> M-x end-of-buffer
>> M-x yank
>> Then emacs doesn't respond for about 5 seconds.
>> M-x scroll-down-command. 
>> Then emacs doesn't respond for about 5 seconds too.
> 
> Yes.  This isn't good at all.
> 
>> M-x scroll-down-command.
>> Then emacs doesn't respond for about 5 seconds too.
> 
> I can't actually reproduce this delay.

Try do it more than 4 times, like: M-> M-v M-v M-v M-v M-v.
The delay often happens at the first M-v, but not always.
The delay is about 5 seconds on mac OSX (cpu: 1.4GHz), and is about 2 seconds on linux (cpu: 2.53Ghz).

Or try to input some text (like newline chars) at the end of buffer.
I input a newline at the end of buffer, and emacs didn't respond about 2 seconds on linux.

After apply the patch, there is no delay after yank.






Information forwarded to bug-gnu-emacs <at> gnu.org, bug-cc-mode <at> gnu.org:
bug#20266; Package emacs,cc-mode. (Tue, 21 Apr 2015 16:15:01 GMT) Full text and rfc822 format available.

Message #14 received at 20266 <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: 张海君 <netjune <at> icloud.com>
Cc: 20266 <at> debbugs.gnu.org
Subject: Re: bug#20266: Emacs doesn't respond when editing the attached c
 header	file.
Date: Tue, 21 Apr 2015 16:14:42 +0000
Hello, Netjune.

On Sun, Apr 12, 2015 at 10:15:15AM +0800, 张海君 wrote:

> > 在 2015年4月7日,23:16,Alan Mackenzie <acm <at> muc.de> 写道:

> > In article <mailman.71.1428315070.904.bug-gnu-emacs <at> gnu.org> you wrote:
> >> [-- text/plain, encoding 7bit, charset: us-ascii, 13 lines --]

> >> Emacs doesn't respond when editing the attached c header file.
> >> Emacs version: 24.4.

> >> ------------------------------------
> >> Run emacs with "emacs -Q test.h".
> >> M-x mark-whole-buffer
> >> M-x kill-ring-save
> >> M-x end-of-buffer
> >> M-x yank
> >> Then emacs doesn't respond for about 5 seconds.
> >> M-x scroll-down-command. 
> >> Then emacs doesn't respond for about 5 seconds too.

> > Yes.  This isn't good at all.

> >> M-x scroll-down-command.
> >> Then emacs doesn't respond for about 5 seconds too.

> > I can't actually reproduce this delay.

> Try do it more than 4 times, like: M-> M-v M-v M-v M-v M-v.
> The delay often happens at the first M-v, but not always.
> The delay is about 5 seconds on mac OSX (cpu: 1.4GHz), and is about 2 seconds on linux (cpu: 2.53Ghz).

After applying the patch below, I measured a single M-v from the end of
the buffer, and it took 0.14s.  This is on GNU/Linux on a 5 year old PC
(2.6 GHz processor).

> Or try to input some text (like newline chars) at the end of buffer.
> I input a newline at the end of buffer, and emacs didn't respond about 2 seconds on linux.

Yes.  That is a different kettle of fish altogether.

> After apply the patch, there is no delay after yank.

Thanks.  With the following patch (instead of the first one) there
shouldn't be much delay with C-x u after having done the yank.

The patch is calculated in Emacs-24.4.  Please try it out.



--- cc-mode.el.orig	2014-03-21 05:34:40.000000000 +0000
+++ cc-mode.el	2015-04-21 14:33:55.571993081 +0000
@@ -509,6 +509,14 @@
   (set (make-local-variable 'comment-line-break-function)
        'c-indent-new-comment-line)
 
+  ;; Prevent time-wasting activity on C-y.
+  (when (boundp 'yank-handled-properties)
+    (make-local-variable 'yank-handled-properties)
+    (let ((yank-cat-handler (assq 'category yank-handled-properties)))
+      (when yank-cat-handler
+	(setq yank-handled-properties (remq yank-cat-handler
+					    yank-handled-properties)))))
+
   ;; For the benefit of adaptive file, which otherwise mis-fills.
   (setq fill-paragraph-handle-comment nil)
 
@@ -831,6 +839,18 @@
 (defvar c-old-EOM 0)
 (make-variable-buffer-local 'c-old-EOM)
 
+(defun c-called-from-text-property-change-p ()
+  ;; Is the primitive which invoked `before-change-functions' or
+  ;; `after-change-functions' one which merely changes text properties?  This
+  ;; function must be called directly from a member of one of the above hooks.
+  ;;
+  ;; In the following call, frame 0 is `backtrace-frame', frame 1 is
+  ;; `c-called-from-text-property-change-p', frame 2 is
+  ;; `c-before/after-change', frame 3 is the primitive invoking the change
+  ;; hook.
+  (memq (cadr (backtrace-frame 3))
+	'(put-text-property remove-list-of-text-properties)))
+
 (defun c-extend-region-for-CPP (beg end)
   ;; Set c-old-BOM or c-old-EOM respectively to BEG, END, each extended to the
   ;; beginning/end of any preprocessor construct they may be in.
@@ -988,64 +1008,65 @@
   ;; it/them from the cache.  Don't worry about being inside a string
   ;; or a comment - "wrongly" removing a symbol from `c-found-types'
   ;; isn't critical.
-  (setq c-maybe-stale-found-type nil)
-  (save-restriction
-    (save-match-data
-      (widen)
-      (save-excursion
-	;; Are we inserting/deleting stuff in the middle of an identifier?
-	(c-unfind-enclosing-token beg)
-	(c-unfind-enclosing-token end)
-	;; Are we coalescing two tokens together, e.g. "fo o" -> "foo"?
-	(when (< beg end)
-	  (c-unfind-coalesced-tokens beg end))
-	;; Are we (potentially) disrupting the syntactic context which
-	;; makes a type a type?  E.g. by inserting stuff after "foo" in
-	;; "foo bar;", or before "foo" in "typedef foo *bar;"?
-	;;
-	;; We search for appropriate c-type properties "near" the change.
-	;; First, find an appropriate boundary for this property search.
-	(let (lim
-	      type type-pos
-	      marked-id term-pos
-	      (end1
-	       (or (and (eq (get-text-property end 'face) 'font-lock-comment-face)
-			(previous-single-property-change end 'face))
-		   end)))
-	  (when (>= end1 beg) ; Don't hassle about changes entirely in comments.
-	    ;; Find a limit for the search for a `c-type' property
-	    (while
-		(and (/= (skip-chars-backward "^;{}") 0)
-		     (> (point) (point-min))
-		     (memq (c-get-char-property (1- (point)) 'face)
-			   '(font-lock-comment-face font-lock-string-face))))
-	    (setq lim (max (point-min) (1- (point))))
-
-	    ;; Look for the latest `c-type' property before end1
-	    (when (and (> end1 (point-min))
-		       (setq type-pos
-			     (if (get-text-property (1- end1) 'c-type)
-				 end1
-			       (previous-single-property-change end1 'c-type nil lim))))
-	      (setq type (get-text-property (max (1- type-pos) lim) 'c-type))
-
-	      (when (memq type '(c-decl-id-start c-decl-type-start))
-		;; Get the identifier, if any, that the property is on.
-		(goto-char (1- type-pos))
-		(setq marked-id
-		      (when (looking-at "\\(\\sw\\|\\s_\\)")
-			(c-beginning-of-current-token)
-			(buffer-substring-no-properties (point) type-pos)))
-
-		(goto-char end1)
-		(skip-chars-forward "^;{}") ; FIXME!!!  loop for comment, maybe
-		(setq lim (point))
-		(setq term-pos
-		      (or (next-single-property-change end 'c-type nil lim) lim))
-		(setq c-maybe-stale-found-type
-		      (list type marked-id
-			    type-pos term-pos
-			    (buffer-substring-no-properties type-pos term-pos)
+  (unless (c-called-from-text-property-change-p)
+    (setq c-maybe-stale-found-type nil)
+    (save-restriction
+      (save-match-data
+	(widen)
+	(save-excursion
+	  ;; Are we inserting/deleting stuff in the middle of an identifier?
+	  (c-unfind-enclosing-token beg)
+	  (c-unfind-enclosing-token end)
+	  ;; Are we coalescing two tokens together, e.g. "fo o" -> "foo"?
+	  (when (< beg end)
+	    (c-unfind-coalesced-tokens beg end))
+	  ;; Are we (potentially) disrupting the syntactic context which
+	  ;; makes a type a type?  E.g. by inserting stuff after "foo" in
+	  ;; "foo bar;", or before "foo" in "typedef foo *bar;"?
+	  ;;
+	  ;; We search for appropriate c-type properties "near" the change.
+	  ;; First, find an appropriate boundary for this property search.
+	  (let (lim
+		type type-pos
+		marked-id term-pos
+		(end1
+		 (or (and (eq (get-text-property end 'face) 'font-lock-comment-face)
+			  (previous-single-property-change end 'face))
+		     end)))
+	    (when (>= end1 beg) ; Don't hassle about changes entirely in comments.
+	      ;; Find a limit for the search for a `c-type' property
+	      (while
+		  (and (/= (skip-chars-backward "^;{}") 0)
+		       (> (point) (point-min))
+		       (memq (c-get-char-property (1- (point)) 'face)
+			     '(font-lock-comment-face font-lock-string-face))))
+	      (setq lim (max (point-min) (1- (point))))
+
+	      ;; Look for the latest `c-type' property before end1
+	      (when (and (> end1 (point-min))
+			 (setq type-pos
+			       (if (get-text-property (1- end1) 'c-type)
+				   end1
+				 (previous-single-property-change end1 'c-type nil lim))))
+		(setq type (get-text-property (max (1- type-pos) lim) 'c-type))
+
+		(when (memq type '(c-decl-id-start c-decl-type-start))
+		  ;; Get the identifier, if any, that the property is on.
+		  (goto-char (1- type-pos))
+		  (setq marked-id
+			(when (looking-at "\\(\\sw\\|\\s_\\)")
+			  (c-beginning-of-current-token)
+			  (buffer-substring-no-properties (point) type-pos)))
+
+		  (goto-char end1)
+		  (skip-chars-forward "^;{}") ; FIXME!!!  loop for comment, maybe
+		  (setq lim (point))
+		  (setq term-pos
+			(or (next-single-property-change end 'c-type nil lim) lim))
+		  (setq c-maybe-stale-found-type
+			(list type marked-id
+			      type-pos term-pos
+			      (buffer-substring-no-properties type-pos term-pos)
 			      (buffer-substring-no-properties beg end)))))))
 
 	  (if c-get-state-before-change-functions
@@ -1056,7 +1077,7 @@
 	  )))
     ;; The following must be done here rather than in `c-after-change' because
     ;; newly inserted parens would foul up the invalidation algorithm.
-  (c-invalidate-state-cache beg))
+    (c-invalidate-state-cache beg)))
 
 (defvar c-in-after-change-fontification nil)
 (make-variable-buffer-local 'c-in-after-change-fontification)
@@ -1077,49 +1098,51 @@
   ;; This calls the language variable c-before-font-lock-functions, if non nil.
   ;; This typically sets `syntax-table' properties.
 
-  (c-save-buffer-state (case-fold-search open-paren-in-column-0-is-defun-start)
-    ;; When `combine-after-change-calls' is used we might get calls
-    ;; with regions outside the current narrowing.  This has been
-    ;; observed in Emacs 20.7.
-    (save-restriction
-      (save-match-data		  ; c-recognize-<>-arglists changes match-data
-	(widen)
-
-	(when (> end (point-max))
-	  ;; Some emacsen might return positions past the end. This has been
-	  ;; observed in Emacs 20.7 when rereading a buffer changed on disk
-	  ;; (haven't been able to minimize it, but Emacs 21.3 appears to
-	  ;; work).
-	  (setq end (point-max))
-	  (when (> beg end)
-	    (setq beg end)))
-
-	;; C-y is capable of spuriously converting category properties
-	;; c-</>-as-paren-syntax and c-cpp-delimiter into hard syntax-table
-	;; properties.  Remove these when it happens.
-	(c-clear-char-property-with-value beg end 'syntax-table
-					  c-<-as-paren-syntax)
-	(c-clear-char-property-with-value beg end 'syntax-table
-					  c->-as-paren-syntax)
-	(c-clear-char-property-with-value beg end 'syntax-table nil)
-
-	(c-trim-found-types beg end old-len) ; maybe we don't need all of these.
-	(c-invalidate-sws-region-after beg end)
-	;; (c-invalidate-state-cache beg) ; moved to `c-before-change'.
-	(c-invalidate-find-decl-cache beg)
-
-	(when c-recognize-<>-arglists
-	  (c-after-change-check-<>-operators beg end))
-
-	;; (c-new-BEG c-new-END) will be the region to fontify.  It may become
-	;; larger than (beg end).
-	(setq c-new-BEG beg
-	      c-new-END end)
-	(setq c-in-after-change-fontification t)
-	(save-excursion
-	  (mapc (lambda (fn)
-		  (funcall fn beg end old-len))
-		c-before-font-lock-functions))))))
+  ;; (c-new-BEG c-new-END) will be the region to fontify.  It may become
+  ;; larger than (beg end).
+  (setq c-new-BEG beg  c-new-END end)
+  
+  (unless (c-called-from-text-property-change-p)
+    (c-save-buffer-state (case-fold-search open-paren-in-column-0-is-defun-start)
+      ;; When `combine-after-change-calls' is used we might get calls
+      ;; with regions outside the current narrowing.  This has been
+      ;; observed in Emacs 20.7.
+      (save-restriction
+	(save-match-data  ; c-recognize-<>-arglists changes match-data
+	  (widen)
+
+	  (when (> end (point-max))
+	    ;; Some emacsen might return positions past the end. This has been
+	    ;; observed in Emacs 20.7 when rereading a buffer changed on disk
+	    ;; (haven't been able to minimize it, but Emacs 21.3 appears to
+	    ;; work).
+	    (setq end (point-max))
+	    (when (> beg end)
+	      (setq beg end)))
+
+	  ;; C-y is capable of spuriously converting category properties
+	  ;; c-</>-as-paren-syntax and c-cpp-delimiter into hard syntax-table
+	  ;; properties.  Remove these when it happens.
+	  (c-save-buffer-state ()
+	    (c-clear-char-property-with-value beg end 'syntax-table
+					      c-<-as-paren-syntax)
+	    (c-clear-char-property-with-value beg end 'syntax-table
+					      c->-as-paren-syntax)
+	    (c-clear-char-property-with-value beg end 'syntax-table nil))
+
+	  (c-trim-found-types beg end old-len) ; maybe we don't need all of these.
+	  (c-invalidate-sws-region-after beg end)
+	  ;; (c-invalidate-state-cache beg) ; moved to `c-before-change'.
+	  (c-invalidate-find-decl-cache beg)
+
+	  (when c-recognize-<>-arglists
+	    (c-after-change-check-<>-operators beg end))
+
+	  (setq c-in-after-change-fontification t)
+	  (save-excursion
+	    (mapc (lambda (fn)
+		    (funcall fn beg end old-len))
+		  c-before-font-lock-functions)))))))
 
 (defun c-set-fl-decl-start (pos)
   ;; If the beginning of the line containing POS is in the middle of a "local"



-- 
Alan Mackenzie (Nuremberg, Germany).




Reply sent to Alan Mackenzie <acm <at> muc.de>:
You have taken responsibility. (Sat, 25 Apr 2015 21:12:02 GMT) Full text and rfc822 format available.

Notification sent to 张海君 <netjune <at> icloud.com>:
bug acknowledged by developer. (Sat, 25 Apr 2015 21:12:02 GMT) Full text and rfc822 format available.

Message #19 received at 20266-done <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: 20266-done <at> debbugs.gnu.org
Cc: � � � <netjune <at> icloud.com>
Subject: Re: bug#20266: Emacs doesn't respond when editing the attached c
 header	file.
Date: Sat, 25 Apr 2015 21:11:54 +0000
Bug fixed.

-- 
Alan Mackenzie (Nuremberg, Germany).




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sun, 24 May 2015 11:24:05 GMT) Full text and rfc822 format available.

This bug report was last modified 10 years and 85 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.