emacs - 在 Emacs 中异步运行命令,但以增量方式显示输出

标签 emacs elisp

我有一个效用函数:

(defun execute-in-buffer (command-with-args buffer)
  "Execute a string COMMAND-WITH-ARGS representing a shell command with arguments,
inserting the results in BUFFER."
  (switch-to-buffer buffer)
  (insert (format ">>> %s\n" command-with-args))
  (let* ((command-args-list (s-split " " command-with-args))
         (command (car command-args-list))
         (args (cdr command-args-list)))
    (apply 'call-process command nil buffer t args)))

这允许我做类似 (execute-in-buffer "ls /" (get-buffer-create "*my-output*") 的事情。但是,它不太适合慢速命令。如果我调用一系列缓慢的命令,直到最后我才得到任何输出:
(let ((buf (get-buffer-create "*my-output")))
  (execute-in-buffer "sleep 10" buf)
  (execute-in-buffer "ls /" buf))

我希望能够同步调用,所以下一个命令只在上一个命令完成后运行。但是,我想在命令运行时查看它们的输出。我该怎么做?

(示例代码仅用于展示,我很高兴放弃它以支持其他东西。)

最佳答案

使用同步进程

如果您想坚持同步进程(例如使用 call-process ),您需要在每次调用 (redisplay) 后调用 execute-in-buffer 以更新显示和可见输出(有关更多详细信息,另请参阅 this question )。但是,每个命令的输出在进程终止之前是不可见的,并且 emacs 将在外部进程运行时挂起。

使用异步进程

使用异步进程有点复杂,但避免了在命令运行时挂起 Emacs,这也解决了重新显示的问题。这里棘手的部分是顺序链接所有命令。这是一个应该可以解决问题的elisp:

(defun execute-commands (buffer &rest commands)
  "Execute a list of shell commands sequentially"
  (with-current-buffer buffer
    (set (make-local-variable 'commands-list) commands)
    (start-next-command)))

(defun start-next-command ()
  "Run the first command in the list"
  (if (null commands-list)
      (insert "\nDone.")
    (let ((command  (car commands-list)))
      (setq commands-list (cdr commands-list))
      (insert (format ">>> %s\n" command))
      (let ((process (start-process-shell-command command (current-buffer) command)))
        (set-process-sentinel process 'sentinel)))))

(defun sentinel (p e)
  "After a process exited, call `start-next-command' again"
  (let ((buffer (process-buffer p)))
    (when (not (null buffer))
      (with-current-buffer buffer
        ;(insert (format "Command `%s' %s" p e) )
        (start-next-command)))))

;; Example use
(with-current-buffer (get-buffer-create "*output*") (erase-buffer))
(execute-commands "*output*"
                  "echo 1"
                  "sleep 1"
                  "echo 2; sleep 1; echo 3"
                  "ls /")

关于emacs - 在 Emacs 中异步运行命令,但以增量方式显示输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16815598/

相关文章:

emacs - emacs中是否可以提供网络摄像头供稿?

c - 为 C 结构定义 gdb 打印函数

emacs - 保存时自动字节编译

emacs - 如何关闭特定主要模式的电子缩进模式?

elisp - Emacs Lisp 嵌套函数 - 无效变量错误

emacs - 如何在 Emacs 中智能地重新缩进 Clojure?

windows - Emacs 在重新加载时不显示 Unicode

vim - 你在 vim 和 emacs 中的想法/写法有什么不同吗?

emacs - Guile和Emacs?

Elisp 中的正则表达式以包含换行符