正如评论中已经回答的那样,Emacs重新显示长行变得非常缓慢,这是一个众所周知的问题。修复它会非常好,但是需要大量考虑才能正确实现。我有一个如何根据本文档 6.3节实现的想法
(基本上,将视线信息存储在当前缓冲区中,并在插入空白,显示属性,窗口更改等方面对其进行更新,然后在重新显示代码,以避免一直扫描),但对C内部结构并不熟悉,无法将其提取出来。
虽然有解决方法。最明显的是调整与显示相关的参数(例如,在图形Emacs实例中启用视线截断,使用非图形Emacs自动执行该操作,禁用Bidi功能等)并预处理文件内容。重新读入。不太明显的一种是自动对文件进行后处理,方法是通过实际截断它们的行或添加文本属性来使这些行看起来比实际的短。为了将其转化为更有趣的答案,我将介绍一个仅适用于comint
-derived模式的前一个选项的丑陋技巧:
(defun my-comint-shorten-long-lines (text)
(let* ((regexp "^\\(.\\{80\\}\\).*?$")
(shortened-text (replace-regexp-in-string regexp "\\1" text)))
(if (string= shortened-text text)
text
(propertize shortened-text 'help-echo text))))
(add-hook 'comint-preoutput-filter-functions 'my-comint-shorten-long-lines)
这定义my-comint-shorten-long-lines
了一个函数,该函数采用可能由多行组成的字符串,并使用正则表达式的功能将长度在80个字符或更多字符中的任何行替换为缩短的版本,该版本在将鼠标悬停在其上时会显示原始文本。当用作钩子时,
comint-preoutput-filter-functions
它将comint
在显示所有输出之前对其进行过滤。
但是,这种破解方法存在相当严重的缺陷。在具有基本字体化功能的模式下(如M-x ielm
),它将很高兴地切断字符串的一部分行,并将所有内容字体化,直到下一个引号是字符串!那不是我们想要的,可以通过更多的正则表达式来解决(但可能会破坏像Python这样的语言的REPL内部)。当我们讨论它时,我们也要突出显示缩短的输出:
(defun my-comint-shorten-long-lines (text)
(let* ((regexp "^\\(.\\{80\\}\\).*?\\(\"?\\)$")
(shortened-text (replace-regexp-in-string regexp "\\1\\2" text)))
(if (string= shortened-text text)
text
(propertize shortened-text 'font-lock-face 'shadow 'help-echo text))))
(add-hook 'comint-preoutput-filter-functions 'my-comint-shorten-long-lines)
更好一点,但仍然很丑。悬停在诸如find /
in 之类的输出上M-x shell
并不吸引人(理想情况下,我们只希望显示未缩短的行,而不是全部输出),字符串检测充其量是基本的,并且可以用省略号而不是将所有内容都字体化来更好地表示截断。最重要的是,它甚至不能保证输入的文本不会变成批处理。所有这些都要求在临时缓冲区中执行处理步骤,但是将留给读者作为练习(或者由作者作为潜在的博客文章)。