分享两个 emacs shell 的保命技巧:多行输入确认、长行输出自动关闭语法高亮

问题1: Emacs Shell 输出长行很可能导致 Emacs 卡死

如:cat 一个压缩成一行的 css 或 json 文件;编译时输出了大量过长的编译命令

解决办法就是检测到有输出长行时,自动关闭语法高亮

问题2: 一个回车把 Shell Buffer 中的内容当 Shell 命令执行了

如:误将 Shell Buffer 内容编辑过后、或者在 Shell Buffer 中粘贴了一些乱七八糟的内容后下意识按了一个回车(多次线上操作差点吓出心脏病)

解决办法就是输入多行内容并提交时将内容显示在一个临时 Buffer 中要求确认输入

配置如下:

(defun my/comint-font-lock-off-if-long-line (string)
  (when (bound-and-true-p font-lock-mode)
    (let ((long-line-found nil))
      (mapc #'(lambda (line)
                (if (> (length line) so-long-threshold)
                    (setq long-line-found t)))
            (split-string string "\n"))
      (when long-line-found
        (font-lock-mode -1)
        (message "disable `font-lock-mode' because of long line found in buffer '%s'" (buffer-name))))))

(defun my/shell--ask-if-multiline-input (input)
  "Avoid accidentally INPUT too many commands to shell."
  (let ((p1 (search "\n" input))
        (p2 (search "\n" input :from-end t))
        (buffer nil))
    (when (and (not (eq nil p1)) (not (eq nil p2)) (not (eq p1 p2)))
      (setq buffer (get-buffer-create "*Multiple Line Shell Input*"))
      (with-current-buffer buffer
        (read-only-mode -1)
        (erase-buffer)
        (insert input)
        (read-only-mode t)
        (let ((o (make-overlay (point-min) (point-max) buffer nil t)))
          (overlay-put o 'face `(:background "#000" :foreground "#FFF")))
        (display-buffer buffer))
      (unless (yes-or-no-p "Input multiple line to shell:")
        (kill-buffer buffer)
        (error "Input multiple line to shell aborted"))
      (kill-buffer buffer))))

(add-to-list 'comint-output-filter-functions 'my/comint-font-lock-off-if-long-line)
(add-to-list 'comint-input-filter-functions 'my/shell--ask-if-multiline-input)
5 个赞

关闭语法高亮后输出长行就不会卡了吗

用vterm也不行吗?

是的,卡主要是语法高亮导致

vterm 跟 emacs 没有关系,相当于是 emacs 中内嵌了一个终端软件,上面的这些设置没有效果,语法高亮导致的卡顿问题也不存在。

第二个问题也可以用 Ctrl-x Ctrl-e 解决。

对,这也是个人推荐Emacs中使用终端的最佳方式,用别的都会慢

为了安全操作,我是不敢用emacs eshell、vterm之类的连生产系统,只用secure crt,有时候用kitty之类的终端。

问题不大,vterm挺稳定,加上tmux

目前终端软件secure crt比较适合我的用途。

  1. 记住密码。这是刚需。机器太多,必须记住密码。secure crt可以记住密码。
  2. 多行粘贴时要确认。不能一次性就执行了。
  3. 命令快捷键。有些命令想点一下按钮就执行。如输入密码。查询数据库主备状态。
  4. 稳定性。无论win还是macOS,secure crt非常稳定。
1 个赞

歪楼了,是解决楼主使用Emacs Shell的问题,而不是满足自己的需求。你可以另做推荐。

1 个赞

借楼求问一下,想在eshell中执行带有'号的lisp语句,却总是提醒我引号未补全,怎么回事?

不,vterm依然会卡,因为实质的问题就是emacs本身的长行显示性能问题。只要用到diaplay-buffer的任何接口,如果对应buffer有超长行,就会卡 无解,除非对输出进行截断和省略。

vterm 默认会折行的

安全起见,禁用密码登录比较好 :see_no_evil:

1 个赞