我正在编写一个Emacs次要模式,它有一些调用shell命令的Emacs命令。我正在使用以下代码:
(let ((output (get-buffer-create "*Foo Output*")))
(start-process "Foo Process" output argv0)
(display-buffer output))
我希望包含这些shell命令的缓冲区在插入输出时自动滚动到底部,或者至少在命令执行完毕时自动滚动到底部。我怎么能这样做?
答案 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)