如何让 Emacs 更安静一些?

mini buffer 里的一些信息对我来说都有些多余了。比如说:

  1. 行首行尾提示
  2. 顶部底部提示
  3. org-cycle (Fold, Children, Subtree)的提示

主诉

  1. 如何找到相关函数?
  2. 如何对它静音?
  3. 目前尝试的代码如何进一步提升?
  4. 是否有其他相对来说没那么重要的信息?

尝试

目前找到一个方法来完成 1 和 2,3 加进去了好像没啥作用。

Disable these messages by setting command-error-function to a function that ignores unused signals.

(defun filter-command-error-function (data context caller)
  "Ignore the buffer-read-only, beginning-of-line, end-of-line, beginning-of-buffer, end-of-buffer signals; pass the rest to the default handler."
  (when (not (memq (car data) '(buffer-read-only
                                beginning-of-line
                                end-of-line
                                beginning-of-buffer
                                end-of-buffer)))
    (command-error-default-function data context caller)))

(setq command-error-function #'filter-command-error-function)

另外我也看到了下面的方法,成功地应用了 org-cycle,静音了 Fold, Children, Subtree 的信息。

但这个无法静音 beginning-of-line 这种信息,因为是 C 的。

  1. Messages produced by C code will not be supressed but that is probably all for the best.
(defun suppress-messages (old-fun &rest args)
  (cl-flet ((silence (&rest args1) (ignore)))
    (advice-add 'message :around #'silence)
    (unwind-protect
         (apply old-fun args)
      (advice-remove 'message #'silence))))

(advice-add 'org-cycle :around #'suppress-messages)

作者也提供了 backtrace 的方式,但是 mini buffer 里信息太多,我有些难以找到重点所在。

(defun who-called-me? (old-fun format &rest args)
  (let ((trace nil) (n 1) (frame nil))
      (while (setf frame (backtrace-frame n))
        (setf n     (1+ n) 
              trace (cons (cadr frame) trace)) )
      (apply old-fun (concat "<<%S>>\n" format) (cons trace args))))

(advice-remove 'message #'who-called-me?)

针对这个尝试,请问有没有更好的方法对 filter-command-error-functionsuppress-messages 进行结合?

2 个赞
(setq ring-bell-function 'ignore)       ; close noisy ring
1 个赞

我这执行 beginning-of-line 没出现啥提示啊

我是在 evil 中用 h j k l

直接把message换成ignore? :joy: :joy: :joy:

试着体验两天 :rofl:

(setq server-client-instructions nil)  ;;不要显示client消息

;;禁止显示set-shell消息
(advice-add 'sh-set-shell :around
            (lambda (orig-fun &rest args)
              (let ((inhibit-message t))
                (apply orig-fun args))))

;;禁止显示beginning-buffer end-buffer消息
(defun my-command-error-function (data context caller)
  (when (not (memq (car data) '(;; buffer-read-only
                                beginning-of-buffer
                                end-of-buffer)))
    (command-error-default-function data context caller)))
(setq command-error-function #'my-command-error-function)


1 个赞

感觉emacs 够安静的了,用Emacs都有点像与世隔绝了 :sweat_smile:

2 个赞

用 Emacs 不就追求个可定制性嘛~ :stuck_out_tongue_winking_eye:

用控制台(SHELL)版本的 Emacs

谢谢推荐,我尝试一下。 :smile:

现在使用 Emacs 的功力比以往又提升了一点点,自答一下。

  1. 如何找到相关函数?
  • 如果知道是哪个函数直接 C-h f 看 elisp 源码找相关 message 的代码
  • 如果不知道或者是 C 的话 git clone --depth=1 -b work https://bitbucket.org/mituharu/emacs-mac.git,使用 ripgrep 搜索提示信息或函数名称,找 .el 或者 .c 结尾的文件里所包含的相关代码。
  • 否则的话在第三方包里面搜索。
  1. 如何对它静音?
  2. 目前尝试的代码如何进一步提升?
  3. 是否有其他相对来说没那么重要的信息?

最近给 fork 了一下 brew 的 emacs-mac 自己打了个 patch,把 emacs 源码中目前觉得 “吵闹”的 messages 删掉了。

对于第三方包带来的 message

比如说 evil 源码里的

(put 'beginning-of-line 'error-conditions '(beginning-of-line error))
(put 'beginning-of-line 'error-message "Beginning of line")
(put 'end-of-line 'error-conditions '(end-of-line error))
(put 'end-of-line 'error-message "End of line")

这个不知道怎么通过配置来取消,涉及到 C 写的函数和 error message,目前用的是:

(defun filter-command-error-function (data context caller)
  "Ignore the buffer-read-only, beginning-of-line, end-of-line, beginning-of-buffer, end-of-buffer signals; pass the rest to the default handler."
  (when (not (memq (car data) '(buffer-read-only
                                beginning-of-line
                                end-of-line
                                beginning-of-buffer
                                end-of-buffer)))
    (command-error-default-function data context caller)))

(setq command-error-function #'filter-command-error-function)

对于 elisp 的包比如说 xenops

(defun suppress-messages (func &rest args)
  (cl-letf (((symbol-function 'message)
              (lambda (&rest args) nil)))
     (apply func args)))

(advice-add 'xenops-mode :around #'suppress-messages)

目前基本上可以解决所有遇到的相关问题了。

现在的启动界面看得非常舒服 :smiley:

2 个赞

非常 nice. 有时间我也希望按照楼主的思路研究一下如何在 emacs-mac 的 work 分支实现与 emacs-mac master 分支一样的 --with-natural-title-bar 功能 (这个目前在 work 分支用不了). 目前也发现 emacs-mac 是不支持 ns-transparent-titlebar 的.

另外请问楼主展示图中的 Emacs 下方的那条横线一样的 mode-line 是如何实现的? 感觉很好看. (已解决)

刚刚阅读了楼主的 Emacs 配置, 成功找到这串代码了. 借鉴了不少, 十分感谢.

;; Use a single line as modeline
(use-package emacs
  :custom-face
  (header-line ((t (:background "grey90" :foreground "grey20" :box nil))))
  (mode-line ((t (:foreground "dim gray" :height 0.1))))
  (mode-line-inactive ((t (:inherit mode-line))))
  :config
  (setq-default mode-line-format '("")))
1 个赞

我还用了 modus theme,对 modeline 的样式也有影响的。

能实现的话就太好了!

我最近在写让 emacs-mac 拥有原生 mac 快捷键的 patch,不然每次改配置重启报错需要再修改的时候,熟悉的快捷键不能用让自己感觉被拧筋了一样。虽然现在把大部分 mac 编辑文字的快捷键放在 early-init.el 里,可以避免 init.el 出 bug 时的快捷键失效问题,不过 early-init.el 出 bug 的时候就难受了。

1 个赞

目前看起来 railwaycat 已经关注到了这个 issue, 见回复 #281. 作者大概表示 emacs-mac 的 work 分支关于 src/macappkit.m 已经修改了很多 (并且我也关注了这个文件, 里面有上万行的代码, 处理起来确实很棘手).

因此这个 patch 若需要再次实现则工程量很大. 不过看起来作者也是希望着手于完善这个功能的, 总之希望轨道猫的 homebrew-emacsmacport 越来越好 :smiling_face_with_three_hearts:

之前我也尝试了一下变动确实太大了,需要对 Objective-C 和 macOS 的 API 很熟悉才行。

1 个赞

根据最新的 commit, natural-title-bar 已经可以在 emacs-mac 28.1 (HEAD) 正常使用.

brew install emacs-mac --with-mac-metal --with-rsvg --with-starter --with-native-comp --HEAD --with-natural-title-bar
# ==> Applying emacs-mac-title-bar-9.0.patch
# defaults write org.gnu.Emacs TransparentTitleBar DARK
# defaults write org.gnu.Emacs HideDocumentIcon YES (隐藏图标)

1 个赞

太棒了! :star_struck: