Emacs 启动进程后滚动窗口并弹出到缓冲区

Emacs 启动进程后滚动窗口并弹出到缓冲区,emacs,elisp,Emacs,Elisp,我正在尝试编写一个编译某些代码的函数,如果编译成功,它将生成进程并在新窗口中打开其输出。编译位工作正常,但第二部分出现了一些奇怪的情况。我编写了一些代码,如下所示: (defun test-function () (with-current-buffer (get-buffer-create "*output*") (erase-buffer) (start-process "echo" (current-buffer) "echo" "hi") (pop-to-bu

我正在尝试编写一个编译某些代码的函数,如果编译成功,它将生成进程并在新窗口中打开其输出。编译位工作正常,但第二部分出现了一些奇怪的情况。我编写了一些代码,如下所示:

(defun test-function ()
  (with-current-buffer (get-buffer-create "*output*")
    (erase-buffer)
    (start-process "echo" (current-buffer) "echo" "hi")
    (pop-to-buffer (current-buffer))))
这段代码几乎可以工作,但当它运行时,屏幕的顶部似乎正好位于程序实际输出的正下方。因此,一旦echo退出,屏幕看起来像

Process echo finished 过程已完成 向上滚动一行可以得到(预期的)

废话 过程已完成
有没有办法让它从缓冲区的实际顶部开始?在启动过程之前和之后,我尝试了
向上滚动
转到字符
之类的方法,但它们似乎对任何事情都没有影响。从其他一些来源来看,我似乎可以在进程上附加一个哨兵,并在有输出时让它向上滚动,但如果只是在开始时向上滚动,那就太过分了。

看起来在
进程
之前有一个
\n
内置在
进程.c
中。也许有人可以建议您在Emacs已经构建之后如何修改它——如果没有,定制构建似乎是一个极端的解决方案

当然,您可以使用elisp代码在事件发生后继续删除硬回车

Searching 5342 files for "\nprocess"

/Users/HOME/Desktop/emacs-trunk/src/process.c:
 6405        tem = BVAR (current_buffer, read_only);
 6406        bset_read_only (current_buffer, Qnil);
 6407:       insert_string ("\nProcess ");
 6408        { /* FIXME: temporary kludge.  */
 6409   Lisp_Object tem2 = p->name; Finsert (1, &tem2); }

/Users/HOME/Desktop/emacs-trunk/lisp/man.el:
 1304                      (substring msg 0 eos) msg))))
 1305              (goto-char (point-max))
 1306:             (insert (format "\nprocess %s" msg))))
 1307        ))
 1308          (if delete-buff

/Users/HOME/Desktop/emacs-trunk/lisp/progmodes/sql.el:
 3944    (if (and (eq (current-buffer) sql-buffer)
 3945      (not buffer-read-only))
 3946:       (insert (format "\nProcess %s %s\n" process event))
 3947      (message "Process %s %s" process event)))
 3948  

/Users/HOME/Desktop/emacs-trunk/lisp/shell.el:
  641      (when (buffer-live-p buf)
  642        (with-current-buffer buf
  643:         (insert (format "\nProcess %s %s\n" process event))))))
  644  
  645  ;;;###autoload

4 matches across 4 files

有点像黑客,但对我来说这很有效:

(insert "\n")
(start-process ...

使用进程哨兵修复它:

(defun recenter-temp-buffer (process event)
  (pop-to-buffer (process-buffer process)) (recenter-top-bottom))

(with-output-to-temp-buffer "test-buffer"
  (set-process-sentinel 
    (start-process "test-process" "test-buffer" "echo" "hello") 
                   'recenter-temp-buffer))

请注意,sentinel会在每次状态更改时调用
(recenter top-bottom)
,这可能不是您想要的。

是不是因为换行符导致了问题?即使没有换行符,它也不会显示“blah”,它只会显示“processecho finished”,而没有空行。我猜在
blah
之后有一个
\n
(可能也在
Process.c
中定义),在
Process
之前有另一个
\n
,如上所述。我理解,但我不明白为什么换行符会导致窗口位于那个特定位置。我很难想象这个问题——也许是在你的问题上添加一个截图,我或其他人可能能够进一步帮助您。
向上滚动
转到字符
没有帮助,因为
启动进程
是异步工作的:进程启动,函数调用通常在任何进程有机会将任何内容写入缓冲区之前返回。IMHO在进程完成状态更改时将点移动到开始位置的哨兵不是过激,而是有效的解决方案。
(defun recenter-temp-buffer (process event)
  (pop-to-buffer (process-buffer process)) (recenter-top-bottom))

(with-output-to-temp-buffer "test-buffer"
  (set-process-sentinel 
    (start-process "test-process" "test-buffer" "echo" "hello") 
                   'recenter-temp-buffer))