将异步进程的输出插入缓冲区而不滚动到最后

时间:2014-04-15 08:44:46

标签: elisp

我正在编写一个使用async-shell-command运行shell命令的简单函数,并在单独的缓冲区中显示该命令的输出。但是,它主要是输出的第一行很有趣,所以我希望在插入结果时停止向下滚动缓冲区。由于这个过程是异步的,所以我不能在命令完成时向上滚动。

2 个答案:

答案 0 :(得分:0)

最后,我使用了JohanLindström的async-shell-command-to-string,我在emacs邮件列表中找到了它:

(require 'cl)

(defun async-shell-command-to-string (command callback)
  "Execute shell command COMMAND asynchronously in the
  background.

Return the temporary output buffer which command is writing to
during execution.

When the command is finished, call CALLBACK with the resulting
output as a string."
  (lexical-let
      ((output-buffer (generate-new-buffer " *temp*"))
       (callback-fun callback))
    (set-process-sentinel
(start-process "Shell" output-buffer shell-file-name shell-command-switch command)
     (lambda (process signal)
       (when (memq (process-status process) '(exit signal))
         (with-current-buffer output-buffer
           (let ((output-string
                  (buffer-substring-no-properties
                   (point-min)
                   (point-max))))
             (funcall callback-fun output-string)))
         (kill-buffer output-buffer))))
    output-buffer))

(provide 'async-shell-command-to-string)
然后我的代码变成了:

(defun fr-wordreference-word-at-point ()
  "Looks up word in point using Wordreference."
  (interactive)
  (let* ((word (asciify-string (downcase (current-word t)))))
    (async-shell-command-to-string
     (concat "wr.sh " word)
     (lambda (s)
       (save-excursion
         (set-buffer (get-buffer-create "*wr*"))
         (erase-buffer)
         (insert s)
         (display-buffer "*wr*" t))))))

似乎工作正常。

答案 1 :(得分:0)

我发现这个问题的时间比较晚,但是对于其他尝试完成同样事情的人来说,可以使用进程过滤器来避免添加依赖项。以下过滤器将过程输出打印到缓冲区而不向下滚动窗口:

(defun no-scroll-filter (proc string)
  "Process filter that outputs to buffer without moving point."
  (when (buffer-live-p (process-buffer proc))
    (with-current-buffer (process-buffer proc)
      (save-excursion
        (let ((moving (= (point) (process-mark proc))))
          (goto-char (process-mark proc))
          (insert string)
          (set-marker (process-mark proc) (point))
          (if moving (goto-char (process-mark proc))))))))

然后可以使用set-process-filter激活它。

更多信息可以在"过滤功能"下的Elisp信息页面中找到。