From 7155fbd9f4afe9c9fd9dd2c89e28830a9d6612d7 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Mon, 23 May 2022 00:15:18 -0700 Subject: [PATCH 0/1] *** NOT A PATCH *** *** BLURB HERE *** F. Jason Park (1): Allow erc-reuse-frames to favor connections lisp/erc/erc.el | 52 +++++++++++++--- test/lisp/erc/erc-tests.el | 119 +++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 8 deletions(-) Interdiff: diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index f82fb07a66..13ac0ec979 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -1538,11 +1538,12 @@ erc-frame-dedicated-flag (defcustom erc-reuse-frames t "Non-nil means only create a frame for undisplayed buffers. For new target buffers, a value of 'displayed' extends this to mean use -the frame of any buffer from the same server connection, visible or not. -When this option is nil, a new frame is always created. Regardless of -its value, this option is ignored unless `erc-join-buffer' is set to -`frame'. Note that like most options in the `erc-buffer' customize -group, this has no effect on server buffers while reconnecting." +the frame of any buffer from the same server connection, visible or not, +or, as a last resort, a frame showing any ERC buffer. When this option +is nil, a new frame is always created. Regardless of its value, this +option is ignored unless `erc-join-buffer' is set to `frame'. Note that +like most options in the `erc-buffer' customize group, this has no +effect on server buffers while reconnecting." :package-version '(ERC . "5.4.1") ; FIXME update when publishing to ELPA :group 'erc-buffers :type '(choice boolean @@ -1948,18 +1949,30 @@ erc-update-modules (funcall sym 1) (error "`%s' is not a known ERC module" mod)))))) -(defun erc--setup-buffer-frame-displayed (buffer) +(defun erc--setup-buffer-first-win (frame a b) + (catch 'found + (walk-window-tree + (lambda (w) + (when (eq (buffer-local-value a (window-buffer w)) b) + (throw 'found t))) + frame nil 0))) + +(defun erc--display-buffer-use-some-frame (buffer alist) "Maybe display BUFFER in an existing frame for the same connection. -If performed, return window used; otherwise, return nil." +If performed, return window used; otherwise, return nil. Forward ALIST +to display-buffer machinery." (when-let* - ((bs (erc-buffer-list nil erc-server-process)) - (visit (lambda (w) (when (memq (window-buffer w) bs) (throw 'found t)))) - (test (lambda (fr) (catch 'found (walk-windows visit 0 fr)))) - ((or (cdr (frame-list)) (funcall test (selected-frame))))) - (display-buffer buffer `((display-buffer-use-some-frame) - (inhibit-switch-frame . t) - (inhibit-same-window . t) - (frame-predicate . ,test))))) + ((same-proc-p (lambda (fr) + (erc--setup-buffer-first-win fr 'erc-server-process + erc-server-process))) + (same-mode-p (lambda (fr) + (erc--setup-buffer-first-win fr 'major-mode 'erc-mode))) + ((or (cdr (frame-list)) (funcall same-mode-p (selected-frame)))) + (frame (car (or (filtered-frame-list same-proc-p) + (filtered-frame-list same-mode-p)))) + (window (get-lru-window frame nil t))) + ;; FIXME don't rely on internal window.el function (tab-bar also does it) + (window--display-buffer buffer window 'reuse alist))) (defun erc-setup-buffer (buffer) "Consults `erc-join-buffer' to find out how to display `BUFFER'." @@ -1975,9 +1988,9 @@ erc-setup-buffer ('frame (cond ((and (eq erc-reuse-frames 'displayed) - erc-default-recipients ; change this to `erc--target' after bug#48598 - (not (get-buffer-window buffer t)) - (erc--setup-buffer-frame-displayed buffer))) + (not (get-buffer-window buffer t))) + (display-buffer buffer `((erc--display-buffer-use-some-frame) + (inhibit-same-window . t)))) ((or (not erc-reuse-frames) (not (get-buffer-window buffer t))) (let ((frame (make-frame (or erc-frame-alist diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 1eac6b22c9..686db3bb2e 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -173,6 +173,10 @@ erc--switch-to-buffer (ert-deftest erc-reuse-frames () ;; TODO run this in a pseudo terminal subprocess for EMBA + ;; + ;; TODO case that simulates automatic reconnecting, with an + ;; existing, unselected frame containing two windows, one with a + ;; dead ERC buffer and the other a non-ERC buffer (skip-unless (not noninteractive)) (should-not erc-frame-dedicated-flag) (let ((erc-join-buffer 'frame) -- 2.36.1