最近在用 Haskell-mode 的时候发现输入[1..10]
这样的列表时,会造成 Emacs 卡死。
经过debug 发是 symbol-overlay-mode
造成的。但是又很难说是哪个包的问题,不知道该向哪个包提交issue。
请教下大家有没有遇到类似的问题的?
以下最小配置可以重现问题:
(require 'package)
(add-to-list 'package-archives '( "melpa" . "https://melpa.org/packages/") t)
(package-initialize)
(require 'symbol-overlay)
(global-set-key (kbd "M-i") 'symbol-overlay-put)
(global-set-key (kbd "M-n") 'symbol-overlay-switch-forward)
(global-set-key (kbd "M-p") 'symbol-overlay-switch-backward)
(global-set-key (kbd "<f7>") 'symbol-overlay-mode)
(global-set-key (kbd "<f8>") 'symbol-overlay-remove-all)
(require 'haskell-mode)
(add-hook 'haskell-mode-hook 'interactive-haskell-mode)
比如输入以下haskell 代码, 在输入1
以后再输入空格或者 .
都会卡死,C-g
可以取消:
triples = [(a,b,c) | c <- [1..10], a <- [1..c], b <- [1..a]]
OS: Window 10 和 Mac big sur
Emacs 28 和 27.2
我试了一下,没有你说的卡死问题,你可以用emacs-sandbox 试一下你自己的配置,看是不是别的问题. 我是Arch,Emacs 27.2
我在不同机器上用上面的最小配置都能重现问题。用上面的配置需要 按 f7
启动symbol-overlay-mode
你如何加载最小配置,是用 emacs -Q
吗,如果不是的话则测试可能已经受到干扰。
而且操作步骤描述也不够具体,如:
aqua0210:
比如输入以下haskell 代码, 在输入 1
以后再输入空格或者 .
都会卡死, C-g
可以取消:
triples = [(a,b,c) | c <- [1..10], a <- [1..c], b <- [1..a]]
这个描述看不太懂,输入 1
的时候光标在哪里?光标后面的内容已经存在了吗?
假如没有开启 electric-pair-mode
,则依次输入的时候括号不会自动闭合(█ 表示光标):
triples = [(a,b,c) | c <- [1..█
开启了 electric-pair-mode
则是括号会自动闭合:
triples = [(a,b,c) | c <- [1..█]]
然而不管怎样,我这里(配置稍作修改,使之自动就绪,处于等待输入的状态)都无法重现你所说的问题:
$ emacsq.sh -p ~/.local/bin/emacs -P haskell-mode,symbol-overlay --eval "
(progn
(add-hook 'haskell-mode-hook 'interactive-haskell-mode)
(add-hook 'haskell-mode-hook 'symbol-overlay-mode)
(switch-to-buffer \"*.hs\")
(haskell-mode)
(insert \"triples = [(a,b,c) | c <- [1\")
(goto-char (point-max)))" -nw
$ emacsq.sh -p ~/.local/bin/emacs -P haskell-mode,symbol-overlay --eval "
(progn
(add-hook 'haskell-mode-hook 'interactive-haskell-mode)
(add-hook 'haskell-mode-hook 'symbol-overlay-mode)
(switch-to-buffer \"*.hs\")
(haskell-mode)
(insert \"triples = [(a,b,c) | c <- [1]]\")
(goto-char (- (point-max) 2)))" -nw
macOS 10.12.6
Emacs 27.1 & 28.0.50 (6f776fbc3532a96dc86eb4e6091ed94f4c52aae7)
emacsq.sh 是一个辅助测试的脚本
不好意思,是我描述的不够清楚。
我没用 emacs -Q
来测试,我是去掉了自己的配置,直接重新安装新的包,保证完全没干扰。我的操作步骤如下:
备份自己当前配置的 .emacs.d 文件为其他名称
在当前用户的 HOME
目录(比如:我的HOME 是 C:\Users\Aqua
目录)下创建 .emacs
文件,并将下面的代码复制到 .emacs
文件中。
(require 'package)
(add-to-list 'package-archives '( "melpa" . "https://melpa.org/packages/") t)
(package-initialize)
(require 'symbol-overlay)
(global-set-key (kbd "M-i") 'symbol-overlay-put)
(global-set-key (kbd "M-n") 'symbol-overlay-switch-forward)
(global-set-key (kbd "M-p") 'symbol-overlay-switch-backward)
(global-set-key (kbd "<f7>") 'symbol-overlay-mode)
(global-set-key (kbd "<f8>") 'symbol-overlay-remove-all)
(require 'haskell-mode)
(add-hook 'haskell-mode-hook 'interactive-haskell-mode)
启动Emacs,这时会报错,因为还没安装需要的包。
手动刷新 Package 列表 并安装 haskell-mode
和 symbol-overlay
M-x package-refresh-contents
M-x package-install RET haskell-mode
M-x package-install RET symbol-overlay
重启 Emacs,这时可以正常启动了。
C-x,C-f
在任意目录下创建一个 test.hs 文件,按 开启 symbol-overlay-mode
。
在空的 test.hs 文件中从头输入下面的内容
triples = [(a,b,c) | c <- [1..10], a <- [1..c], b <- [1..a]]
当输入到第三个 1 的后面时, 再输入空格 或者 . 就会卡住(如下图,光标在箭头所指示的位置)。
其他: 我只用了上面的配置,其他都是 Emacs 默认,electric-pair-mode
我是没开的。
1 个赞
的确在第三个 1
的时候无响应,我打开 profiler 看了一下,问题似乎出在 symbol-overlay-refresh
函数:
*CPU-Profiler-Report 2021-08-05 14:22:44*
Function CPU samples %
+ ... 847 54%
- command-execute 717 45%
- call-interactively 717 45%
- funcall-interactively 703 44%
- self-insert-command 639 40%
- symbol-overlay-refresh 639 40%
- looking-at 639 40%
- internal--syntax-propertize 639 40%
- syntax-propertize 639 40%
- haskell-syntax-propertize 616 39%
- haskell-lexeme-looking-at-token 510 32%
haskell-lexeme-looking-at-qidsym 110 7%
haskell-lexeme-looking-at-char-literal 38 2%
haskell-lexeme-looking-at-string-lit... 28 1%
match-string-no-properties 10 0%
For information about GNU Emacs and the GNU system, type C-h C-a.
Package cl is deprecated
CPU profiler started
You can run the command ‘profiler-start’ with M-x p-sta RET
CPU profiler started
Symbol-Overlay mode enabled in current buffer
Error during redisplay: (internal--syntax-propertize 57) signaled (quit)
2 个赞
估计是 Symbol-Overlay 的问题更多一些,先给这个包报个 issue吧。
opened 07:39AM - 05 Aug 21 UTC
Symbol-overlay-mode will cause Emacs to freeze with haskell-mode enabled,I am no… t sure it is cause by `haskell-mode` or `symbol-overlay`.
Steps to reproduce the issue:
1. Back up your current configuration `.emacs.d` file with another name
2. Create an `.emacs` file in the current user's `HOME` directory (for example, my `HOME` is the `C:\Users\Aqua` directory), and copy the following code to the `.emacs` file.
```emacs-lisp
(require 'package)
(add-to-list 'package-archives '( "melpa" . "https://melpa.org/packages/") t)
(package-initialize)
(require 'symbol-overlay)
(global-set-key (kbd "M-i") 'symbol-overlay-put)
(global-set-key (kbd "M-n") 'symbol-overlay-switch-forward)
(global-set-key (kbd "M-p") 'symbol-overlay-switch-backward)
(global-set-key (kbd "<f7>") 'symbol-overlay-mode)
(global-set-key (kbd "<f8>") 'symbol-overlay-remove-all)
(require 'haskell-mode)
(add-hook 'haskell-mode-hook 'interactive-haskell-mode)
```
3. Start Emacs, an error will be raised now, because the required packages have not been installed.
4. Manually refresh the package contents and install `haskell-mode` and `symbol-overlay`
```
M-x package-refresh-contents
M-x package-install RET haskell-mode
M-x package-install RET symbol-overlay
```
5. Restart Emacs, now it can start normally.
6. `C-x, C-f` Create a `test.hs` file in any directory, press <f7> to turn on symbol-overlay-mode. Enter the following content from the beginning in the empty `test.hs` file.
```haskell
triples = [(a,b,c) | c <- [1..10], a <- [1..c], b <- [1..a]]
```
7. When I input the third `1`, and then input a `space` or `.` It will be stuck (as shown in the figure below, the cursor now is at the position indicated by the red arrow).
![image](https://user-images.githubusercontent.com/47546452/128308554-426776a4-a3a8-4a59-94ef-50a1a8cc364a.png)
8. press `C-g` can go back to normal , and get error from *Messages* :
```
Symbol-Overlay mode enabled in current buffer
Error during redisplay: (internal--syntax-propertize 44) signaled (quit)
Error during redisplay: (internal--syntax-propertize 57) signaled (quit)
```
9. if at step 7 can't reproduce issue, you can move cursor back to the the position after the second `1` , and delete `..c` , and input `..c` again.
Tested on:
Emacs 28.0.50 native compile and Emacs 27.2
OS: macOS Big Sur 11.5 and Windows 10
这个问题,上游一直没有解决。
干脆直接弃用 symbol-overlay
了。这个包平时用的最多的功能就是通过 M-n ,M-p 在相同的 symbol
上跳转,非常方便。
其实上面提到的这个 feature 在 embark 已经集成了
(use-package embark
:bind
("C-." . embark-act)
("M-." . embark-dwim)
("M-n" . embark-next-symbol)
("M-p" . embark-previous-symbol)
)
而且去掉 symbol-overlay 后,输入流畅度有明显提升,可能因为 embark 默认没高亮 symbol 的原因。
1 个赞