首页 > 解决方案 > Lisp 执行顺序和异步调用过程

问题描述

我有以下代码:

((lambda()
   (defvar buffer-name)
   (setq buffer-name "*mongo-dev*")
   (switch-to-buffer-other-window buffer-name)
   (call-process "sleep" nil buffer-name  nil "2")
  ))

有 2 种意外行为

  1. 看起来call-process总是在switch-to-buffer-xxx. 我怎样才能switch-to-buffer先执行?
  2. 执行上述代码时,我的 emacs 挂了 2 秒,有没有办法让 call-process 异步运行?

顺便说一句,在 Emacs 中,是否有 elisp 代码的内置格式?

标签: emacs

解决方案


切换到缓冲区

使用现有的宏。例如,以下切换到缓冲区(并在必要时创建它)并在其中写入一些内容。里面的所有代码(with-current-buffer-window ...)都在所选缓冲区处于活动状态且可见的上下文中执行。

(with-current-buffer-window "*mongo-dev*" nil nil
  (insert "Hello"))

以上是一个宏,它在被评估之前被扩展为代码。调用macroexpand-all代码(注意引号'),您可以看到代码转换的结果是什么:

(macroexpand-all '(with-current-buffer-window "*mongo-dev*" nil nil
                   (insert "Hello")))

(let* ((buffer (temp-buffer-window-setup "*mongo-dev*"))
       (standard-output buffer)
       window
       value)
  (save-current-buffer
    (set-buffer buffer)
    (setq value (progn (insert "Hello")))
    (setq window (temp-buffer-window-show buffer nil)))
  (if (functionp nil)
      (funcall nil window value)
    value))

生成进程并使用缓冲区查看其输出

这是一项常见任务,您可能希望使用以下命令:

(start-process-shell-command "my-process"
                             "*mongo-dev*"
                             "ls -la /usr/bin")

你的代码

(defvar buffer-name)

defvar仅用于全局变量声明,作为顶级语句。您很少(从不)需要将 adefvar放入函数中。

(setq buffer-name "*mongo-dev*")

您想要做的是本地绑定(“缓冲区名称”符号用作 体内的局部变量let)。

(let ((buffer-name "*mongo-dev*"))
  (switch-to-buffer-other-window buffer-name)
  (call-process "sleep" nil buffer-name  nil "2"))

call-process 是同步的,您还有其他选择,但这太宽泛了,无法在此处详述。见手册。

顺便说一句,在 Emacs 中,是否有 elisp 代码的内置格式?

是的,emacs-lisp-mode


推荐阅读