如何使Emacs shell命令输出缓冲区始终跟在底部?

时间:2013-05-19 19:33:12

标签: emacs elisp

我正在编写一个Emacs次要模式,它有一些调用shell命令的Emacs命令。我正在使用以下代码:

    (let ((output (get-buffer-create "*Foo Output*")))
      (start-process "Foo Process" output argv0)
      (display-buffer output))

我希望包含这些shell命令的缓冲区在插入输出时自动滚动到底部,或者至少在命令执行完毕时自动滚动到底部。我怎么能这样做?

1 个答案:

答案 0 :(得分:8)

您可以使用process filter function

来完成此操作
  

过程过滤功能是接收标准的功能   相关进程的输出。如果进程有过滤器,那么   该进程的所有输出都将传递给过滤器。这个过程   只有当存在时,缓冲区才直接用于进程的输出   没有过滤器。

     

[...]

     

许多过滤功能有时(或总是)插入输出   进程的缓冲区,在没有时模仿Emacs的动作   过滤

start-process返回一个代表Lisp中新子进程的进程对象,您可以将其存储在变量中,例如proc。您可以编写一个简单的过滤器函数,只将过程的输出插入到关联的输出缓冲区中,从而将point移动到缓冲区的末尾。

(defun my-insertion-filter (proc string)
  (when (buffer-live-p (process-buffer proc))
    (with-current-buffer (process-buffer proc)
      ;; Insert the text, advancing the process marker.
      (goto-char (process-mark proc))
      (insert string)
      (set-marker (process-mark proc) (point)))))

使用set-process-filter将过滤功能分配给您的流程。

(set-process-filter proc 'my-insertion-filter)

或者,如果只有在进程终止后才跳转到缓冲区的末尾就足够了,您可能希望使用sentinel

  

进程sentinel是一个在每次调用时被调用的函数   相关过程因任何原因(包括信号)而改变状态   (无论是由Emacs发送还是由进程自己的行为引起)   终止,停止或继续该过程。进程哨兵也是   如果进程退出则调用。

(defun my-sentinel (proc event)
  (when (buffer-live-p (process-buffer proc))
    (with-current-buffer (process-buffer proc)
      (end-of-buffer))))

(请注意,每次调用此函数时,此函数都会滚动到进程缓冲区的末尾,这可能不仅发生在进程结束时。如果确实只希望它在执行时流程已终止,请检查event是否为字符串"finished\n"。)

使用set-process-sentinel将该哨兵分配给您的流程。

(set-process-sentinel proc 'my-sentinel)