I want to focus the *Warnings* buffer whenever there is new warning. I tried this:

(add-hook 'special-mode-hook
          (lambda ()
            (when (string= (buffer-name (current-buffer))
              (pop-to-buffer (current-buffer)))))

However, the cursor only moves to the *Warnings* buffer on the first warning. Subsequent warnings do not move to the cursor to the *Warnings* buffer. What do I need to do to move the cursor to the *Warnings* buffer whenever there is a new warning?

Emacs version: GNU Emacs 26.3.


I am a strong believer in not polluting hooks, especially something so fundamental like special-mode that is used by countless other major-modes. As such, I would recommend not using the special-mode-hook. The following example adds an entry to the display-buffer-alist that will trigger a custom display-buffer-... function when a matching regexp exists.

[The internal function window--display-buffer has five (5) arguments in Emacs 25 and Emacs 26, but only four (4) arguments in Emacs 27. This example should work on all of the aforementioned versions of Emacs.]

(defun display-buffer-fn (buffer-or-name alist direction &optional size pixelwise)
  "BUFFER:  The buffer that will be displayed.
  ALIST:  See the doc-string of `display-buffer' for more information.
  DIRECTION:  Must use one of these symbols:  'left 'right 'below 'above
  SIZE:  See the doc-string for `split-window'.
  PIXELWISE:  See the doc-string for `split-window'.
  There are three possibilities:
  -  (1) If a window on the frame already displays the target buffer,
  then just reuse the same window.
  -  (2) If there is already a window in the specified direction in relation
  to the selected window, then display the target buffer in said window.
  -  (3) If there is no window in the specified direction, then create one
  in that direction and display the target buffer in said window."
    (let* ((buffer
             (if (bufferp buffer-or-name)
               (get-buffer buffer-or-name)))
               ((get-buffer-window buffer (selected-frame)))
               ((window-in-direction direction))
                 (split-window (selected-window) size direction pixelwise)))))
      (window--display-buffer buffer window 'window alist)

(defun display-buffer-right--select-window (buffer alist)
  (select-window (display-buffer-fn buffer nil 'right)))

(add-to-list 'display-buffer-alist '("^[*]warnings[*]$" . (display-buffer-right--select-window)))


TEST:  After evaluating the above code, test it by evaluating the following snippet:

(display-warning :warning "hello-world")

Try this

(add-hook 'special-mode-hook
          (lambda ()
            (let ((buffer-name-list (mapcar 'buffer-name (buffer-list))))
              (when (member "*Warnings*" buffer-name-list)
                (pop-to-buffer "*Warnings*")))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.