diff options
author | Alan Mackenzie <acm@muc.de> | 2020-05-15 19:24:29 +0000 |
---|---|---|
committer | Alan Mackenzie <acm@muc.de> | 2020-05-15 19:24:29 +0000 |
commit | 66cbe8b946bf83ab19c0d9a7b9fc03e951ffd5b6 (patch) | |
tree | c829c22997d507dec9142eadad25967a8362db3f /lisp/progmodes/cc-engine.el | |
parent | afca37343d0637386e4dfc4fb04d8700f3c6bf0d (diff) | |
download | emacs-66cbe8b946bf83ab19c0d9a7b9fc03e951ffd5b6.tar.gz |
CC Mode: Fix bug #40052, where a very large macro was too slow in scrolling
* lisp/progmodes/cc-engine.el (c-end-of-macro): Fix faulty cache handling,
where the upper bound of c-macro-cache was never being set.
(c-forward-comment-minus-1): New macro which terminates unwanted indefinite
backward searching with lots of escaped newlines in c-backward-single-comment.
(c-backward-single-comment, c-backward-comments): Use the new macro above.
* lisp/progmodes/cc-mode.el (c-before-change-check-unbalanced-strings)
(c-after-change-mark-abnormal-strings, c-after-change-escape-NL-in-string):
Optimize three regexps by using shy groups, thus preventing regexp stack
overflow while handling the large C Macro.
Diffstat (limited to 'lisp/progmodes/cc-engine.el')
-rw-r--r-- | lisp/progmodes/cc-engine.el | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index aa3f7d399e9..8c8296fd6da 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -405,7 +405,7 @@ comment at the start of cc-engine.el for more info." (when (and (car c-macro-cache) (> (point) (car c-macro-cache)) ; in case we have a ; zero-sized region. - (not (eq (char-before (1- (point))) ?\\))) + (not lim)) (setcdr c-macro-cache (point)) (setq c-macro-cache-syntactic nil))))))) @@ -1642,6 +1642,21 @@ comment at the start of cc-engine.el for more info." (forward-char 2) t)))) +(defmacro c-forward-comment-minus-1 () + "Call (forward-comment -1), taking care of escaped newlines. +Return the result of `forward-comment' if it gets called, nil otherwise." + `(if (not comment-end-can-be-escaped) + (forward-comment -1) + (when (and (< (skip-syntax-backward " >") 0) + (eq (char-after) ?\n)) + (forward-char)) + (cond + ((and (eq (char-before) ?\n) + (eq (char-before (1- (point))) ?\\)) + (backward-char) + nil) + (t (forward-comment -1))))) + (defun c-backward-single-comment () "Move backward past whitespace and the closest preceding comment, if any. Return t if a comment was found, nil otherwise. In either case, the @@ -1675,12 +1690,12 @@ This function does not do any hidden buffer changes." ;; same line. (re-search-forward "\\=\\s *[\n\r]" start t) - (if (if (forward-comment -1) + (if (if (c-forward-comment-minus-1) (if (eolp) ;; If forward-comment above succeeded and we're at eol ;; then the newline we moved over above didn't end a ;; line comment, so we give it another go. - (forward-comment -1) + (c-forward-comment-minus-1) t)) ;; Emacs <= 20 and XEmacs move back over the closer of a @@ -1709,7 +1724,7 @@ comment at the start of cc-engine.el for more info." (if (let (moved-comment) (while - (and (not (setq moved-comment (forward-comment -1))) + (and (not (setq moved-comment (c-forward-comment-minus-1))) ;; Cope specifically with ^M^J here - ;; forward-comment sometimes gets stuck after ^Ms, ;; sometimes after ^M^J. |