Previous: , Up: Integrations   [Contents][Index]

5.4.4 display-buffer

ERC supports the “action” interface used by display-buffer and friends from window.el. See Displaying Buffers in Emacs Lisp, for specifics. When ERC displays a new or “reassociated” buffer, it consults its various buffer-display options, such as erc-buffer-display, to decide whether and how the buffer ought to appear in a window. Exactly which one it consults depends on the context in which the buffer is being manifested.

For some buffer-display options, the context is pretty cut and dry. For instance, in the case of erc-receive-query-display, you’re receiving a query from someone you haven’t yet chatted with in the current session. For other options, like erc-interactive-display, the precise context varies. For example, you might be opening a query buffer with the command /QUERY bob RET or joining a new channel with /JOIN #chan RET. Power users wishing to distinguish between such nuanced contexts or just exercise more control over buffer-display behavior generally can elect to override these options by setting one or more to a “display-buffer-like” function that accepts a buffer and an action argument.

Examples

In this first example, a user-provided buffer-display function displays new server buffers in the current window when issuing an M-x erc-tls RET and in a split window for all other interactve contexts covered by the option erc-interactive-display, like clicking an ‘irc://’-style URL (see URL).

(defun my-erc-interactive-display-buffer (buffer action)
  "Pop to BUFFER when running \\[erc-tls], clicking a link, etc."
  (when-let ((alist (cdr action))
             (found (alist-get 'erc-interactive-display alist)))
    (if (eq found 'erc-tls)
        (pop-to-buffer-same-window buffer action)
      (pop-to-buffer buffer action))))

(setopt erc-interactive-display #'my-erc-interactive-display-buffer)

Observe that ERC supplies the names of buffer-display options as action alist keys and pairs them with contextual constants, like the symbols ‘erc-tls’ or ‘url’, the full lineup of which are listed below.

In this second example, for Emacs 29 and above, the user writes three predicates that somewhat resemble the “display-buffer-like” function above. These too look for action alist keys sharing the names of ERC’s buffer-display options (and, in one case, a module’s minor mode).

(defun my-erc-disp-entry-p (_ action)
  (memq (cdr (or (assq 'erc-buffer-display action)
                 (assq 'erc-interactive-display action)))
        '(erc-tls url)))

(defun my-erc-disp-query-p (_ action)
  (or (eq (cdr (assq 'erc-interactive-display action)) '/QUERY)
      (and (eq (cdr (assq 'erc-receive-query-display action)) 'PRIVMSG)
           (member (erc-default-target) '("bob" "alice")))))

(defun my-erc-disp-chan-p (_ action)
  (or (assq 'erc-autojoin-mode action)
      (and (eq (cdr (assq 'erc-buffer-display action)) 'JOIN)
           (member (erc-default-target) '("#emacs" "#fsf")))))

You’ll notice we ignore the buffer parameter of these predicates because ERC ensures that buffer is already current (which is why we can freely call erc-default-target). Note also that we cheat a little by treating the action parameter like an alist when it’s really a cons of one or more functions and an alist.

To complement our predicates, we set all three buffer-display options referenced in their action-alist lookups to display-buffer. This tells ERC to defer to that function in the display contexts covered by these options.

(setopt erc-buffer-display #'display-buffer
        erc-interactive-display #'display-buffer
        erc-receive-query-display #'display-buffer
        ;;
        erc-auto-reconnect-display 'bury)

The last option above just tells ERC to avoid any buffer-display machinery when auto-reconnecting. (For historical reasons, ERC’s buffer-display options use the term “bury” to mean “ignore” rather than bury-buffer.)

Finally, we compose our predicates into buffer-match-p conditions and pair them with various well known display-buffer action functions and action-alist members.

(setopt display-buffer-alist

        ;; Create new frame with M-x erc-tls RET or (erc-tls ...)
        '(((and (major-mode . erc-mode) my-erc-disp-entry-p)
           display-buffer-pop-up-frame
           (reusable-frames . visible))

          ;; Show important chans and queries in a split.
          ((and (major-mode . erc-mode)
                (or my-erc-disp-chan-p my-erc-disp-query-p))
           display-buffer-pop-up-window)

          ;; Ignore everything else.
          ((major-mode . erc-mode)
           display-buffer-no-window
           (allow-no-window . t))))

Of course, we could just as well set our buffer-display options to one or more homespun functions instead of bothering with display-buffer-alist at all (in what would make for a more complicated version of our first example). But perhaps we already have a growing menagerie of similar predicates and like to keep everything in one place in our init.el.

Action alist items

Option-based keys:

All keys are symbols, as are values, unless otherwise noted.

  • erc-buffer-display
    • - ‘JOIN
    • - ‘NOTICE
    • - ‘PRIVMSG
    • - ‘erc’ (entry point called non-interactively)
    • - ‘erc-tls
  • erc-interactive-display
    • - ‘/QUERY
    • - ‘/JOIN
    • - ‘/RECONNECT
    • - ‘url’ (hyperlink clicked)
    • - ‘erc’ (entry point called interactively)
    • - ‘erc-tls
  • erc-receive-query-display
    • - ‘NOTICE
    • - ‘PRIVMSG
  • erc-auto-reconnect-display
    • - something non-nil
Module-based (minor-mode) keys:
  • erc-autojoin-mode
    • - channel name as a string, e.g., "#chan"

Previous: auth-source, Up: Integrations   [Contents][Index]