我正在寻找一种方法,让由 M-x 编译、M-x 重新编译或某些保存时编译脚本触发的 Emacs compilation 缓冲区仅在编译因错误或警告退出时出现。
请注意,如果没有[1]中所述的错误或警告,我并不是在寻找关闭编译缓冲区的方法。不,我希望缓冲区在编译完全完成之前永远不会出现,并且仅在有错误或警告要显示时才出现。
原因很简单:闪烁的编译缓冲区令人不安,并重新排列了代码在屏幕上的位置。如果您打开保存时编译,这会变得更烦人。
compile缓冲区包含从make到pdflatex的许多不同类型的编译过程,因此如果确定是否应显示缓冲区的函数能够全面工作,那就太好了。
[1]display-buffer
和
compilation-start
来实现您想要的目的。这是 sds 所说内容和评论@那里的评论有一个令人讨厌的问题,即原始源缓冲区中的点跳转,我似乎已经通过阻止
set-window-point
和
goto-char
解决了这个问题。这感觉像是一个肮脏的黑客,但到目前为止正在发挥作用。 YMMV!
(defun brian-compile-finish (buffer outstr)
(unless (string-match "finished" outstr)
(switch-to-buffer-other-window buffer))
t)
(setq compilation-finish-functions 'brian-compile-finish)
(require 'cl)
(defadvice compilation-start
(around inhibit-display
(command &optional mode name-function highlight-regexp))
(if (not (string-match "^\\(find\\|grep\\)" command))
(flet ((display-buffer)
(set-window-point)
(goto-char))
(fset 'display-buffer 'ignore)
(fset 'goto-char 'ignore)
(fset 'set-window-point 'ignore)
(save-window-excursion
ad-do-it))
ad-do-it))
(ad-activate 'compilation-start)
现在您应该看到,仅当
outstr
未返回成功完成状态或调用的命令以“find”或“grep”开头时,才会显示所有编译缓冲区。
cl-letf
而不是
flet
。
(defun brian-compile-finish (buffer outstr)
(unless (string-match "finished" outstr)
(switch-to-buffer-other-window buffer))
t)
(setq compilation-finish-functions 'brian-compile-finish)
(defadvice compilation-start
(around inhibit-display
(command &optional mode name-function highlight-regexp))
(if (not (string-match "^\\(find\\|grep\\)" command))
(cl-letf ((display-buffer #'ignore)
(set-window-point #'ignoreco)
(goto-char #'ignore))
(save-window-excursion
ad-do-it))
ad-do-it))
(ad-activate 'compilation-start)
(provide 'only-display-compile-on-error)
compilation-start
在编译缓冲区上调用
display-buffer
。这应该为您提供所需的所有控制。即,您需要自定义其中一个
action 变量(display-buffer-overriding-action
等),以便它能够处理编译缓冲区,特别是在单独的框架中显示它,而不是显示框架本身。 然后您需要自定义您的
compilation-filter-hook
,以便每当将警告或错误插入到编译缓冲区时,编译缓冲区就会清晰地显示(例如,通过弹出上述单独的框架)。不要忘记将您的
action变量绑定到那里的
nil
!;; Prevent the compilation buffer from being displayed until the compilation
;; process has finished. After that, ensure that this buffer is visible if and
;; only if the compilation failed.
;; (compile.el displays the buffer with (allow-no-window . t))
(add-to-list 'display-buffer-alist
'("\\*compilation\\*" (display-buffer-no-window)))
;; After the compilation process is finished:
(setq compilation-exit-message-function
(lambda (status code msg)
(let ((compilation-window
(get-buffer-window "*compilation*")))
(cond
;; If compilation failed and compilation buffer is not visible,
((and (eq status 'exit)
(not (zerop code))
(not compilation-window))
;; temporarily allow displaying the buffer,
(let ((display-buffer-overriding-action
'((display-buffer-use-least-recent-window))))
;; and display that buffer.
(display-buffer "*compilation*")))
;; If compilation succeeded and compilation buffer is visible,
((and (eq status 'exit)
(zerop code)
compilation-window)
;; bury that buffer.
(with-selected-window compilation-window
(bury-buffer)))))
(cons msg code))) ;; default return value