emacs用回车覆盖

时间:2013-10-16 15:18:12

标签: emacs

我喜欢使用start-process-shell-command从emacs中启动子进程,例如编译,渲染或单元测试。我知道我可以通过给出缓冲区名称将输出重定向到缓冲区。

(start-process-shell-command "proc-name" "output-buffer-name" command)

许多进程将使用回车进行实时进度条,以便在终端中进度条在最终输出中只占用一行。但是,当此进度条重定向到emacs缓冲区时,将保留回车符,因此缓冲区显示所有状态更新,这使得读取输出变得很麻烦。

有没有办法让emacs以与终端处理回车相同的方式处理输出缓冲区中的回车?也就是说,将指针返回到行的开头并覆盖现有文本。

2 个答案:

答案 0 :(得分:4)

您可以使用a filter function执行此操作。

这有点工作,但你只需要在输出中找到由\ r \ n终止的行,然后找到缓冲区中的旧行,删除行,并用新行替换它。这是一个玩具版本:

// foo.c
#include <stdio.h>
main() {
  int i;
  for (i = 0; i < 10; i++) {
    printf("  count: %d\r", i);
    fflush(stdout);
    sleep(1);
  }
  printf("\n");
}

然后你可以让每个计数行覆盖前一行(在这种情况下,擦除整个缓冲区。)

(defun filt (proc string)
  (with-current-buffer "foo"
    (delete-region (point-min) (point-max))
    (insert string)))

(progn 
  (setq proc
        (start-process "foo" "foo" "path/to/foo"))
  (set-process-filter proc 'filt))

答案 1 :(得分:0)

从seanmcl的过滤器函数开始,我添加了更多细节,以便有一个过滤器,可以像bash shell一样处理回车和换行。

;Fill the buffer in the same way as it would be shown in bash
(defun shelllike-filter (proc string)
  (let* ((buffer (process-buffer proc))
         (window (get-buffer-window buffer)))
    (with-current-buffer buffer
      (if (not (mark)) (push-mark))
      (exchange-point-and-mark) ;Use the mark to represent the cursor location
      (dolist (char (append string nil))
    (cond ((char-equal char ?\r)
           (move-beginning-of-line 1))
          ((char-equal char ?\n)
           (move-end-of-line 1) (newline))
          (t
           (if (/= (point) (point-max)) ;Overwrite character
           (delete-char 1))
           (insert char))))
      (exchange-point-and-mark))
    (if window
      (with-selected-window window
        (goto-char (point-max))))))