Lisp执行顺序和异步调用进程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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秒,是否有一种方式让调用进程异步运行?

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

答案

Switch to buffer

使用现有的宏。例如,以下内容切换到缓冲区(并在必要时创建它)并在其中写入内容。 (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))

Spawning a process and using a buffer to see its output

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

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

Your code

(defvar buffer-name)

defvar仅用于全局变量声明,如forplevel语句。你很少(从不)需要在函数中放置一个defvar

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

你想要做的是一个局部绑定(“buffer-name”符号用作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

以上是关于Lisp执行顺序和异步调用进程的主要内容,如果未能解决你的问题,请参考以下文章

异步编程async/await

获取 异步执行调用的结果

线程和异步的分别与联系

关于同步与异步的那些事儿

多线程,异步

js执行顺序