使用emacs打开c++文件时,有些文件会卡顿 移动卡顿;编辑卡顿;甚至弹出的minibuffer都是先在中央跳动一下,再显示在底部 而这种卡顿针对某个文件,其他的文件不会有问题 求教 (环境:archlinux) (嫌疑犯:lsp-mode, eaf等)
二分注释法排除问题,结合emacs -Q一起排查,猜没用
找到了,是highlight-indent-guides-mode,谢谢
问题复现了
emacs -Q启动仍旧卡顿
是emacs本身的问题吗?
程序代码:
#include <iostream>
#include <vector>
#define MAX 10000
void merge(std::vector<int> array, int p, int q, int r) {
int len_1 = q - p + 1;
int len_2 = r - q;
int a = 0;
int b = 0;
std::vector<int> left_array(len_1 + 2, 0);
std::vector<int> right_array(len_2 + 2, 0);
for (int i = 0; i < len_1; ++i) {
left_array[i] = array[p + i - 1];
}
for (int i = 0; i < len_2; ++i) {
right_array[i] = array[q + i];
}
left_array[len_1 + 1] = MAX;
right_array[len_2 + 1] = MAX;
for (int i = p; i < r + 1; ++i) {
if (left_array[a] <= right_array[b]) {
array[i] = left_array[a];
++a;
} else {
array[i] = right_array[b];
++b;
}
}
}
void merge_sort(std::vector<int> array, int p, int r) {
if (p < r) {
int q = (p + r) / 2;
merge_sort(array, p, q);
merge_sort(array, q + 1, r);
merge(array, p, q, r);
}
}
int main() {
std::vector<int> array = {3, 1, 2, 6, 4, 5};
merge_sort(array, 0, array.size() - 1);
for (auto i : array) {
std::cout << i << "\n";
}
return 0;
}
buffer中一旦出现merge代码部分就会卡顿
代码定位出来了
是因为有了 for (int i = p; i < r + 1; ++i) {
这句代码才卡顿的
1 个赞
是r+1
这里的问题,i < r + 1
是触发了emacs的什么机制吗
回下帖:你提一下issus,但我感觉这应该是emacs内部的问题
我这边 Emacs 29 也复现了… CPU 100%
2952 62% - redisplay_internal (C function)
2936 62% - jit-lock-function
2936 62% - jit-lock-fontify-now
2920 62% - jit-lock--run-functions
2920 62% - run-hook-wrapped
2920 62% - #<compiled 0x19b62a583670403d>
2920 62% - font-lock-fontify-region
2920 62% - c-font-lock-fontify-region
2605 55% - font-lock-default-fontify-region
2534 53% - font-lock-fontify-keywords-region
1339 28% - c-font-lock-declarations
1317 27% - c-find-decl-spots
593 12% + #<compiled 0x62f8c10afa44432>
582 12% + c-bs-at-toplevel-p
profile 显示是 cc-mode 的 fontification 有点问题。
如果不介意的话,我就把这个 bug 报到上游去了?
1 个赞
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=51692
对应的 patch。
diff -r 05fd00cb5937 cc-engine.el
--- a/cc-engine.el Sat Oct 30 15:57:26 2021 +0000
+++ b/cc-engine.el Thu Nov 11 18:47:47 2021 +0000
@@ -6838,6 +6838,13 @@
(defvar c-found-types nil)
(make-variable-buffer-local 'c-found-types)
+;; Dynamically bound variable that instructs `c-forward-type' to
+;; record the ranges of types that only are found. Behaves otherwise
+;; like `c-record-type-identifiers'. Also when this variable is non-nil,
+;; `c-fontify-new-found-type' doesn't get called (yet) for the purported
+;; type.
+(defvar c-record-found-types nil)
+
(defsubst c-clear-found-types ()
;; Clears `c-found-types'.
(setq c-found-types
@@ -6851,7 +6858,10 @@
(let ((type (c-syntactic-content from to c-recognize-<>-arglists)))
(unless (gethash type c-found-types)
(puthash type t c-found-types)
- (when (and (eq (string-match c-symbol-key type) 0)
+ (when (and (not c-record-found-types) ; Only call `c-fontify-new-fount-type'
+ ; when we haven't "bound" c-found-types
+ ; to itself in c-forward-<>-arglist.
+ (eq (string-match c-symbol-key type) 0)
(eq (match-end 0) (length type)))
(c-fontify-new-found-type type)))))
@@ -8248,11 +8258,6 @@
(setq c-record-ref-identifiers
(cons range c-record-ref-identifiers))))))
-;; Dynamically bound variable that instructs `c-forward-type' to
-;; record the ranges of types that only are found. Behaves otherwise
-;; like `c-record-type-identifiers'.
-(defvar c-record-found-types nil)
-
(defmacro c-forward-keyword-prefixed-id (type)
;; Used internally in `c-forward-keyword-clause' to move forward
;; over a type (if TYPE is 'type) or a name (otherwise) which
@@ -8480,6 +8485,11 @@
(c-forward-<>-arglist-recur all-types)))
(progn
(when (consp c-record-found-types)
+ (let ((cur c-record-found-types))
+ (while (consp (car-safe cur))
+ (c-fontify-new-found-type
+ (buffer-substring-no-properties (caar cur) (cdar cur)))
+ (setq cur (cdr cur))))
(setq c-record-type-identifiers
;; `nconc' doesn't mind that the tail of
;; `c-record-found-types' is t.
@@ -9203,6 +9213,12 @@
(when (and (eq res t)
(consp c-record-found-types))
+ ;; Cause the confirmed types to get fontified.
+ (let ((cur c-record-found-types))
+ (while (consp (car-safe cur))
+ (c-fontify-new-found-type
+ (buffer-substring-no-properties (caar cur) (cdar cur)))
+ (setq cur (cdr cur))))
;; Merge in the ranges of any types found by the second
;; `c-forward-type'.
(setq c-record-type-identifiers
diff -r 05fd00cb5937 cc-fonts.el
--- a/cc-fonts.el Sat Oct 30 15:57:26 2021 +0000
+++ b/cc-fonts.el Thu Nov 11 18:47:47 2021 +0000
@@ -105,6 +105,7 @@
(cc-bytecomp-defun c-font-lock-objc-method)
(cc-bytecomp-defun c-font-lock-invalid-string)
(cc-bytecomp-defun c-before-context-fl-expand-region)
+(cc-bytecomp-defun c-font-lock-fontify-region)
;; Note that font-lock in XEmacs doesn't expand face names as
@@ -2431,6 +2432,7 @@
(defun c-force-redisplay (start end)
;; Force redisplay immediately. This assumes `font-lock-support-mode' is
;; 'jit-lock-mode. Set the variable `c-re-redisplay-timer' to nil.
+ (save-excursion (c-font-lock-fontify-region start end))
(jit-lock-force-redisplay (copy-marker start) (copy-marker end))
(setq c-re-redisplay-timer nil))
@@ -2458,7 +2460,6 @@
(dolist (win-boundary window-boundaries)
(when (and (< (match-beginning 0) (cdr win-boundary))
(> (match-end 0) (car win-boundary))
- (c-get-char-property (match-beginning 0) 'fontified)
(not c-re-redisplay-timer))
(setq c-re-redisplay-timer
(run-with-timer 0 nil #'c-force-redisplay
我试用了一下,基本没啥问题了。可以等待 Alan 提交对应的 patch
patch 已提交,可以重新 build Emacs 了。
10 个赞
我这边也是这样,