В emacs можно ли настроить буфер * Messages * так, чтобы он был хвостовым? - PullRequest
14 голосов
/ 13 января 2011

Как правило, я хочу, чтобы буфер * Messages * всегда прокручивался вниз, когда приходит новое сообщение

Могу ли я это сделать?

Я нашел auto-revert-tail-mode, но это работает для буферов, которые посещают файлы.Когда я попробовал это в буфере сообщений, он выдал ошибку:
auto-revert-tail-mode: This buffer is not visiting a file

Ответы [ 6 ]

9 голосов
/ 13 января 2011

Для нескольких кадров вы, вероятно, хотите:

(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)))
3 голосов
/ 20 августа 2011

Просто поставьте точку в конце буфера M -> . Если вы не переместите его вручную, он останется там - IOW, вы всегда увидите хвост.

2 голосов
/ 13 января 2011

Этот код кажется немного излишним, но простой (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))))))
1 голос
/ 21 мая 2016

Вот поправка к Питеру 's / Решения Трея

(defun modi/messages-auto-tail (&rest _)
  "Make *Messages* buffer auto-scroll to the end after each message."
  (let* ((buf-name "*Messages*")
         ;; Create *Messages* buffer if it does not exist
         (buf (get-buffer-create buf-name)))
    ;; Activate this advice only if the point is _not_ in the *Messages* buffer
    ;; to begin with. This condition is required; otherwise you will not be
    ;; able to use `isearch' and other stuff within the *Messages* buffer as
    ;; the point will keep moving to the end of buffer :P
    (when (not (string= buf-name (buffer-name)))
      ;; Go to the end of buffer in all *Messages* buffer windows that are
      ;; *live* (`get-buffer-window-list' returns a list of only live windows).
      (dolist (win (get-buffer-window-list buf-name nil :all-frames))
        (with-selected-window win
          (goto-char (point-max))))
      ;; Go to the end of the *Messages* buffer even if it is not in one of
      ;; the live windows.
      (with-current-buffer buf
        (goto-char (point-max))))))
(advice-add 'message :after #'modi/messages-auto-tail)
0 голосов
/ 23 июня 2019

Вот реализация, которая использует новый стиль совета.

(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)
0 голосов
/ 14 июня 2011

я запускаю 23.3, и было все еще слишком много случаев, когда встроенное «решение» и оригинальное defadvice в функции сообщения просто не вырезали его, поэтому я завернул этот код в набор list / toggle / timerи он работает прекрасно - больше нет разочарований при отладке!

это универсально, поэтому работает на любом буфере, хотя я действительно использую его только для ..

(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)))))

редактировать: изменена функциональность для отображения хвоста в нижней части окна

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...