在emacs中,我是否可以设置*Messages*缓冲区,使其为尾部?

在emacs中,我是否可以设置*Messages*缓冲区,使其为尾部?,emacs,Emacs,基本上,我希望*消息*缓冲区在新消息到达时始终滚动到底部 我可以这样做吗 我找到了自动还原尾部模式,但它适用于访问文件的缓冲区。 当我在消息缓冲区中尝试时,它弹出了一个错误: 自动还原尾部模式:此缓冲区未访问文件此代码似乎有点过分,但简单的(goto char(point max))对我不起作用: (defadvice message (after message-tail activate) "goto point max after a message" (with-current-

基本上,我希望*消息*缓冲区在新消息到达时始终滚动到底部

我可以这样做吗

我找到了
自动还原尾部模式
,但它适用于访问文件的缓冲区。 当我在消息缓冲区中尝试时,它弹出了一个错误:

自动还原尾部模式:此缓冲区未访问文件

此代码似乎有点过分,但简单的
(goto char(point max))
对我不起作用:

(defadvice message (after message-tail activate)
  "goto point max after a message"
  (with-current-buffer "*Messages*"
    (goto-char (point-max))
    (let ((windows (get-buffer-window-list (current-buffer) nil t)))
      (while windows
        (set-window-point (car windows) (point-max))
        (setq windows (cdr windows))))))

对于您可能需要的多个帧:

(defadvice message (after message-tail activate)
  "goto point max after a message"
  (with-current-buffer "*Messages*"
    (goto-char (point-max))
    (walk-windows (lambda (window)
                    (if (string-equal (buffer-name (window-buffer window)) "*Messages*")
                        (set-window-point window (point-max))))
                  nil
                  t)))

我运行了23.3,但仍然有太多的情况下,内置的“解决方案”和消息函数上的原始defadvice没有切断它,所以我将代码包装在一个列表/切换/计时器设置中,它工作得很好-调试时没有更多的挫折感

它是通用的,所以适用于任何缓冲区,尽管我只在..中使用它

(toggle-buffer-tail "*Messages*" "on")
…希望对某人有用

;alist of 'buffer-name / timer' items
(defvar buffer-tail-alist nil)
(defun buffer-tail (name)
  "follow buffer tails"
  (cond ((or (equal (buffer-name (current-buffer)) name)
         (string-match "^ \\*Minibuf.*?\\*$" (buffer-name (current-buffer)))))
        ((get-buffer name)
      (with-current-buffer (get-buffer name)
        (goto-char (point-max))
        (let ((windows (get-buffer-window-list (current-buffer) nil t)))
          (while windows (set-window-point (car windows) (point-max))
         (with-selected-window (car windows) (recenter -3)) (setq windows (cdr windows))))))))

(defun toggle-buffer-tail (name &optional force)
  "toggle tailing of buffer NAME. when called non-interactively, a FORCE arg of 'on' or 'off' can be used to to ensure a given state for buffer NAME"
  (interactive (list (cond ((if name name) (read-from-minibuffer 
      (concat "buffer name to tail" 
        (if buffer-tail-alist (concat " (" (caar buffer-tail-alist) ")") "") ": ")
    (if buffer-tail-alist (caar buffer-tail-alist)) nil nil
           (mapcar '(lambda (x) (car x)) buffer-tail-alist)
        (if buffer-tail-alist (caar buffer-tail-alist)))) nil)))
  (let ((toggle (cond (force force) ((assoc name buffer-tail-alist) "off") (t "on")) ))
    (if (not (or (equal toggle "on") (equal toggle "off"))) 
      (error "invalid 'force' arg. required 'on'/'off'") 
      (progn 
        (while (assoc name buffer-tail-alist) 
           (cancel-timer (cdr (assoc name buffer-tail-alist)))
           (setq buffer-tail-alist (remove* name buffer-tail-alist :key 'car :test 'equal)))
        (if (equal toggle "on")
            (add-to-list 'buffer-tail-alist (cons name (run-at-time t 1 'buffer-tail name))))
        (message "toggled 'tail buffer' for '%s' %s" name toggle)))))

编辑:更改了在窗口底部显示尾部的功能

只需将点放在缓冲区的末尾M->。如果你不手动移动它,它将停留在那里——看,你总是能看到尾巴。

这里有一个关于彼得的解决方案的修正案

(defun modi/messages自动跟踪(&rest)
“使*消息*缓冲区在每条消息后自动滚动到末尾。”
(let*((buf名称“*消息*”)
;创建*消息*缓冲区(如果不存在)
(buf(获取缓冲区创建buf名称)))
;仅当点不在*消息*缓冲区中时才激活此建议
首先,这个条件是必须的,否则你就不能
;能够使用“isearch”和*Messages*缓冲区中的其他内容作为
;该点将继续移动到缓冲区的末尾:P
(当(不是(字符串=buf名称(缓冲区名称)))
;;转到所有*消息*缓冲区窗口中的缓冲区末尾
;;*live*('get buffer window list'返回一个只包含实时窗口的列表)。
(dolist(win(获取缓冲区窗口列表buf name nil:所有帧))
(在选定窗口中)
(转到字符(最大点)))
;转到*Messages*缓冲区的末尾,即使它不在其中一个缓冲区中
活窗。
(带当前缓冲区buf)
(转到字符(最大点(()()())))
(建议添加“消息:在#”之后”modi/messages auto tail)

下面是一个使用新通知样式的实现

(defun message-buffer-goto-end-of-buffer (&rest args)
  (let* ((win (get-buffer-window "*Messages*"))
         (buf (and win (window-buffer win))))
    (and win (not (equal (current-buffer) buf))
         (set-window-point
          win (with-current-buffer buf (point-max))))))

(advice-add 'message :after 'message-buffer-goto-end-of-buffer)

您真是多产,Jackson先生。我觉得上面使用walk windows的表单更优雅。@Nordlöw:至少,这里的
(而windows…
写得更好,就像
walk windows版本:
(mapc(lambda(w)(设置窗口点w(点max)))windows)
。当光标位于缓冲区的末尾时,即使有新消息到达,它也会留在那里。我认为这还不够吗?是的,至少在Emacs 23.2.1中,默认情况下,*消息*尾部,除非您手动从EOF移动点(并且再次将其向后移动将恢复尾部行为)<代码>自动还原尾部模式
似乎没有任何明显的不同。感谢这一点,这正是我想要的:)把它放在github这里(只是为了我自己的方便)非常确定这不是真的。。。当然,它在我身边的任何emacs上都不起作用。@nicferrier是的,它确实起作用。请参阅问题下的其他评论,以了解更多有关其含义的详细信息。确保使用
M->
而不仅仅是其他光标移动来获取
pointmax
处的点。该点确实位于缓冲区的末尾。但这一点并不明显(27.0.50)。我认为保持可见是这个问题中“尾巴”行为的一部分。@ded7:点始终可见-它是光标的缓冲位置,它永远不会超出缓冲区/窗口的可见部分。@Drew我们在这里讨论的是当活动窗口显示的缓冲区不是*Messages*缓冲区,但*Messages*缓冲区在另一个窗口中可见时会发生什么。在这种情况下,*Messages*缓冲区的最大缓冲区位置可能不可见,即使您可能在*Messages*中留下了当时的最大缓冲区位置。很好,但您可能应该使用
get buffer window list
而不是walk windows+过滤器。