在执行另一个elisp命令之前等待shell命令完成

时间:2014-04-11 20:19:34

标签: emacs elisp

我正在尝试执行以下操作:

  1. 在emacs中打开一个shell并将cd打开到项目文件夹
  2. 从存储库执行mercurial pull。
  3. “等待”直到拉结束
  4. 将完成提取的消息传达给elisp命令,该命令启动了shell命令,因此它可以继续使用编译命令来构建树。
  5. 是否有一种方法/代码可以让我知道shell命令何时完成,然后从.emacs文件中启动一个新的elisp命令?

3 个答案:

答案 0 :(得分:2)

我认为你不必开始使用物理外壳。在您的elisp中,您可以使用例如call-process-shell-command,它会等到您输入的命令,比如说"cd directory ; hg pull"完成。

要进行测试,您可以在*scratch*窗口中尝试(C-x C-e):

(call-process-shell-command "cd directory ; ls" nil t)

它将显示光标之前该目录的文件列表,它将等待执行下一个命令,直到命令完成。

答案 1 :(得分:2)

@Francesco之前在以下链接中回答了类似的问题:https://stackoverflow.com/a/18707182/2112489

我发现使用start-process作为一个自由绑定变量会导致它立即运行,而不是等到函数中进一步关闭时更合适的时刻。我还发现set-process-sentinel阻止使用先前定义的let-bound变量。不是使用let-bound变量或全局变量,另一种选择是使用缓冲区局部变量 - 例如(defvar my-local-variable nil "This is my local variable.") (make-variable-buffer-local 'my-local-variable) - 并将其设置在函数内 - 例如(setq my-local-variable "hello-world")。虽然我看到的大多数例子都是哨兵,但我喜欢将所有内容都包含在一个函数中 - 例如,如下面的代码片段所示:

  
(set-process-sentinel 
  (start-process
    "my-process-name-one"
     "*OUTPUT-BUFFER*"
    "/path/to/executable"
    "argument-one"
    "argument-two"
    "argument-three")
  (lambda (p e) (when (= 0 (process-exit-status p))
    (set-process-sentinel 
      (start-process
        "my-process-name-two"
        nil ;; example of not using an output buffer
        "/path/to/executable"
        "argument-one"
        "argument-two"
        "argument-three")
      (lambda (p e) (when (= 0 (process-exit-status p))
        (set-process-sentinel 
          (start-process . . . ))))))))

答案 2 :(得分:0)

(defun async-proc-with-context ()
  "experiment! set process completion context using the plist"
  (let* ((cmd "ls -la")
         (ctx "it finished")
         (output-buffer (generate-new-buffer (format "*bufname*")))
         (proc (progn
                 (async-shell-command cmd output-buffer)
                 (get-buffer-process output-buffer))))
    (if (process-live-p proc)
        (progn
          (process-put proc 'jw-ctx ctx) ;; set the context
          (set-process-sentinel proc '(lambda (process signal)
                                        (when (memq (process-status process) '(exit signal))
                                          (message (process-get process 'jw-ctx)) ;; get the context
                                          (shell-command-sentinel process signal))))))))