【问题标题】:How can I make an Emacs shell command output buffer always follow the bottom?如何使 Emacs shell 命令输出缓冲区始终跟随底部?
【发布时间】:2013-05-19 19:33:12
【问题描述】:

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

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

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

【问题讨论】:

    标签: emacs elisp


    【解决方案1】:

    您可以使用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

    进程哨兵是一个函数,每当 相关进程因任何原因更改状态,包括信号 (无论是由 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)
    

    【讨论】:

    • 我有这个问题的一个变种。我在我的 .emacs 中使用 global-set-key 来使某个组合键运行 shell 命令(通过 shell-command 函数)。我和OP有同样的问题;我只看到 Shell 命令输出 的顶部,而不是底部。我盲目地将上述流程过滤器的内容输入到我的 .emacs 文件中,然后我收到来自 set-process-filter 命令的警告“作为变量的符号值是无效的:proc”。我假设 proc 应该是与 shell 缓冲区关联的进程的名称,但我有 0 lisp 知识。我应该通过 M-x 运行 cmd 吗?
    • @KevinBuzzard 您的问题太复杂,无法在评论中回答,请考虑提出适当的问题以便获得更详尽的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 2011-03-28
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多