简体   繁体   English

在进程退出并出现错误或警告之前,不要在 Emacs 中显示 *compilation* 缓冲区

[英]Don't display *compilation* buffer in Emacs until the process exits with error or warning

I am looking for a way to have the Emacs compilation buffer triggered by Mx compile, Mx recompile or some compile on save script only appear when the compilation exits either with an error or a warning.我正在寻找一种方法,让 Emacs编译缓冲区由 Mx 编译、Mx 重新编译或一些编译保存脚本触发,仅在编译退出时​​出现错误或警告。

Note that I am not looking for a way to close the compile buffer if there are no errors or warnings as described in [1].请注意,如果没有 [1] 中所述的错误或警告,我不是在寻找关闭编译缓冲区的方法。 No I want the buffer to never appear until the compilation is fully finished and only appear if there is an error or warning to display.不,我希望缓冲区在编译完全完成之前永远不会出现,并且仅在有错误或警告显示时才出现。

The reasons are simple: The flickering compile buffer is disturbing and rearranges the position of the code on the screen.原因很简单:闪烁的编译缓冲区会干扰并重新排列代码在屏幕上的位置。 This becomes more annoying if you have compile on save turned on.如果您打开了保存时编译,这会变得更加烦人。

The compile buffer contains many different types of compile processes from make to pdflatex so it would be great if the function which determines whether the buffer should be displayed works across the board.编译缓冲区包含从 make 到 pdflatex 的许多不同类型的编译过程,因此如果确定是否应显示缓冲区的功能全面工作,那就太好了。

[1] emacs compile buffer auto close? [1] emacs 编译缓冲区自动关闭?

Looks like you can achieve what you want through temporarily disabling display-buffer across compilation-start .看起来您可以通过在compilation-start临时禁用display-buffer来实现您想要的。

This is a combination of what sds said and something posted on the comments @ here这是 sds 所说的内容和@ 此处评论中发布的内容的组合

The comment there had a nasty problem with point jumping in the original source buffer that I appear to have worked out by also blocking set-window-point and goto-char .那里的评论在原始源缓冲区中点跳转有一个令人讨厌的问题,我似乎已经通过阻止set-window-pointgoto-char It feels like a dirty hack, but is working so far.这感觉就像一个肮脏的黑客,但到目前为止工作。 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)

Now you should see that all compile buffers will only be shown if outstr doesn't return a successful finish status OR the invoked command started with "find" or "grep."现在您应该看到,只有当outstr没有返回成功完成状态或调用的命令以“find”或“grep” outstr ,才会显示所有编译缓冲区。

I edited @assem's answer to use cl-letf instead of flet .我编辑了@assem 的答案以使用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)

The function compilation-start calls display-buffer on the compilation buffer.函数compilation-start调用编译缓冲区上的display-buffer buffer。 This should give you all the control you need.这应该给你你需要的所有控制。

Ie, you need to customize one of the action variables ( display-buffer-overriding-action et al) so that it will handle compilation buffers specially buy displaying it in a separate frame and not displaying the frame itself.即,您需要自定义动作变量之一( display-buffer-overriding-action等),以便它处理编译缓冲区,专门购买在单独的帧中显示它而不是显示帧本身。

Then you need to customize your compilation-filter-hook so that, whenever a warning or an error is inserted into the compilation buffer, the compilation buffer is displayed visibly (eg, by popping up the aforementioned separate frame).然后你需要自定义你的compilation-filter-hook这样,每当警告或错误插入编译缓冲区时,编译缓冲区就会显示出来(例如,通过弹出上述单独的框架)。 Don't forget to bind your action variable to nil there!不要忘记将您的操作变量绑定到nil那里!

assems answer has been overtaken by events, somewhat.大会的答案在某种程度上已被事件所取代。

Emacs core, in their wisdom have decided to deprecate flet . Emacs 核心,以他们的智慧决定弃用flet The suggested alternative is cl-flet .建议的替代方案是cl-flet However, as discussed in this post, this seems to be lexically scoped rather than dynamically scoped.然而,正如本文所讨论的,这似乎是词法范围的,而不是动态范围的。 We explicitly want dynamic scoping.我们明确地想要动态范围。

Should `flet` be replaced with `cl-flet` or `cl-letf` ? 应该将 `flet` 替换为 `cl-flet` 或 `cl-letf` 吗?

This page suggests replace flet to noflet , a third-party library.此页面建议将flet替换为第三方库noflet

This appears to only support the definition of functions and their bodies.这似乎只支持函数及其主体的定义。 So the flet in assem's answer becomes所以flet在ASSEM的答案就

(noflet ((display-buffer ()) ....

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM