将进程输出发送到* Messages *缓冲区,但绕过回显区域


9

是否可以将输出从过程过滤器发送到*Messages*缓冲区并抑制该消息输出出现在回显区域中,从而使我能够同时使用交互式命令,而不会minibuffer-prompt被正在进行的subpress过滤器输出所抹除?

(defun rsync-process-filter (proc string)
  (when (not (or
      (string-match "files...\r" string)
      (string-match "files to consider\n" string)))
    (message "%s" string)))

编辑(2015年1月3日):以下是类似问题的链接,但是,我尚未能够使它与确切的字符串未知的进程字符串一起使用-线程的标题为:Emacs -禁用一些Minibuffer消息

/superuser/669701/emacs-disable-some-minibuffer-messages


我不认为你可以。为什么不只是登录到其他缓冲区?那就是大多数处理流程的方式所要做的……
lunaryorn 2015年

@lunaryorn-谢谢您的建议-专用缓冲区是解决此问题的有效选项。我个人比较喜欢将一些过程输出发送到*Messages*缓冲区-与同步相关的项目就是其中之一。还有很多事情我还没有尝试过(因为我认为可能有一个内置的解决方案),例如使*Messages*缓冲区临时可写inhibit-read-onlyinsert在以下位置使用point-max-我不知道它是否会出现在回波区域也是如此。今天晚上我再做一遍。。。
法律名单

一个令人感兴趣的注意事项是,用于消息传递的C函数在很大程度上由“回声”和“记录”问题分开,但是这种区别并没有暴露于elisp。也许您可以M-x report-emacs-bug并要求将此功能作为功能?
phils 2015年

@phils | @lunaryorn:通过使用(let ((inhibit-read-only t)) (with-current-buffer (get-buffer-create "*Messages*") (goto-char (point-max)) (insert string))),我能够达到预期的效果,并且我发布了一个答案草稿,该答案草稿将在用户自己的问题的强制等待期过后才有资格接受。我向以下用户提出了功能请求report-emacs-bugdebbugs.gnu.org/cgi/bugreport.cgi?bug=19495
法律列表

律师名单:我不会建议这种方法,因为您可能会违反处理重复消息等的逻辑。(但也可能很好;我实际上并不知道。)您可能应该使用它(messages-buffer)来获取缓冲区,如果您坚持使用此方法,请注意,它(point-max)不一定总是换行的开头(例如use C-g)。
phils 2015年

Answers:


3

您可以通过将其设置minibuffer-message-timeout为0 来抑制显示在迷你缓冲区中。

例如,在一些我想在minibuffer提示符下切换次要模式的地方(例如ido find-file),我在一些地方使用了类似的方法,而不会被“启用模式”消息打断:

(let ((minibuffer-message-timeout 0))
    (toggle-some-mode))

感谢您的建议; 但是,这并没有达到预期的效果。(let ((minibuffer-message-timeout 0)) (message "%s" string))当键入交互式功能(例如execute-extended-commandswitch-to-buffer-other-window-)时,正在进行的过程输出打印仍将显示在回显区域/微型缓冲区中,即,过程输出消息会删除提示和建议的完成内容。
法律列表

3

初稿初稿(2015年1月3日):根据@phils关于使用该函数messages-buffer查找或创建适当缓冲区(并将其放入messages-buffer-mode)的有用评论,对初稿进行了修订;并且添加了对是否point-max在行首的检查(如果不是,则在插入消息字符串之前插入新行)。

编辑(2015年1月4日):在某些情况下,插入的字符串可能不一定以新行结尾,并且该函数message没有检查以确保它位于新行的开头,因此我们要注意这一点。在此功能。因此,在message插入新行的任何时候,该行将从缓冲区的左对齐位置开始。

(defun rsync-process-filter (proc string)
  (let ((inhibit-read-only t))
    (when (not (or
        (string-match "files...\r" string)
        (string-match "files to consider\n" string)))
      (with-current-buffer (messages-buffer)
        (goto-char (point-max))
        (when (not (bolp))
          (insert "\n"))
        (insert string)
        (when (not (bolp))
          (insert "\n"))))))

2

遍历message它的文档字符串,应该可以通过nil在调用message所需内容后立即调用带参数的message来实现所需的功能。从的文档字符串message

如果第一个参数为nil或空字符串,则该函数清除所有现有消息;这样可以显示迷你缓冲区的内容。

因此,将您的功能修改为如下所示即可

(defun rsync-process-filter (proc string)
  (when (not (or
      (string-match "files...\r" string)
      (string-match "files to consider\n" string)))
    (message "%s" string)
    (message nil)))

我通过执行以下操作对其进行了测试

(defun test ()
  (message "%s" "Test")
  (message nil))

(run-at-time 5 5 #'test)

它似乎有效


感谢您的建议。在将正在运行的进程输出到*Messages*缓冲区然后调用交互式命令进行测试时,此想法execute-extended-command显示以下内容:交互式提示(即,M-x以及部分完成)进程的输出-即两个切换回去,以光速向前移动,但是可以看出两者之间的闪烁。出现这种情况是因为所讨论的特定过程不断吐出新消息,并且该新消息在回声区域中显示的时间仅为几分之一秒。
法律名单
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.