From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.bugs Subject: bug#20266: Emacs doesn't respond when editing the attached c header file. Date: Tue, 21 Apr 2015 16:14:42 +0000 Message-ID: <20150421161442.GA17271@acm.fritz.box> References: <20150407151616.87042.qmail@mail.muc.de> <40D04DD6-2D4F-47AD-BEFA-19AEA5AC0938@icloud.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Trace: ger.gmane.org 1429632933 4848 80.91.229.3 (21 Apr 2015 16:15:33 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 21 Apr 2015 16:15:33 +0000 (UTC) Cc: 20266@debbugs.gnu.org To: =?UTF-8?Q?=E5=BC=A0=E6=B5=B7=E5=90=9B?= Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Apr 21 18:15:23 2015 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1YkapV-0008DK-4k for geb-bug-gnu-emacs@m.gmane.org; Tue, 21 Apr 2015 18:15:21 +0200 Original-Received: from localhost ([::1]:59541 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YkapP-0004qv-Ho for geb-bug-gnu-emacs@m.gmane.org; Tue, 21 Apr 2015 12:15:15 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:38616) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YkapK-0004qR-Vo for bug-gnu-emacs@gnu.org; Tue, 21 Apr 2015 12:15:12 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YkapI-0000o5-Vw for bug-gnu-emacs@gnu.org; Tue, 21 Apr 2015 12:15:10 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:45655) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YkapC-0000cw-Si; Tue, 21 Apr 2015 12:15:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1YkapC-0001sC-3M; Tue, 21 Apr 2015 12:15:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Alan Mackenzie Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org, bug-cc-mode@gnu.org Resent-Date: Tue, 21 Apr 2015 16:15:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20266 X-GNU-PR-Package: emacs,cc-mode X-GNU-PR-Keywords: Original-Received: via spool by 20266-submit@debbugs.gnu.org id=B20266.14296328857153 (code B ref 20266); Tue, 21 Apr 2015 16:15:01 +0000 Original-Received: (at 20266) by debbugs.gnu.org; 21 Apr 2015 16:14:45 +0000 Original-Received: from localhost ([127.0.0.1]:35431 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Ykaot-0001rF-RI for submit@debbugs.gnu.org; Tue, 21 Apr 2015 12:14:45 -0400 Original-Received: from colin.muc.de ([193.149.48.1]:56509 helo=mail.muc.de) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Ykaor-0001r1-31 for 20266@debbugs.gnu.org; Tue, 21 Apr 2015 12:14:42 -0400 Original-Received: (qmail 85260 invoked by uid 3782); 21 Apr 2015 16:14:39 -0000 Original-Received: from acm.muc.de (p548A5EDB.dip0.t-ipconnect.de [84.138.94.219]) by colin.muc.de (tmda-ofmipd) with ESMTP; Tue, 21 Apr 2015 18:14:38 +0200 Original-Received: (qmail 18091 invoked by uid 1000); 21 Apr 2015 16:14:42 -0000 Content-Disposition: inline In-Reply-To: <40D04DD6-2D4F-47AD-BEFA-19AEA5AC0938@icloud.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:101825 Archived-At: Hello, Netjune. On Sun, Apr 12, 2015 at 10:15:15AM +0800, 张海君 wrote: > > 在 2015年4月7日,23:16,Alan Mackenzie 写道: > > In article 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).