From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: "J.P." Newsgroups: gmane.emacs.bugs Subject: bug#51753: ERC switches to channel buffer on reconnect Date: Sun, 22 May 2022 18:56:07 -0700 Message-ID: <87a6b92ers.fsf__10809.7206613579$1653271045$gmane$org@neverwas.me> References: <878rqwjqua.fsf@codeisgreat.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="12290"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) Cc: 51753@debbugs.gnu.org, emacs-erc@gnu.org To: Pankaj Jangid Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon May 23 03:57:19 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nsxJu-00033p-RK for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 23 May 2022 03:57:19 +0200 Original-Received: from localhost ([::1]:35100 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nsxJt-0000DC-FD for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 22 May 2022 21:57:17 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:45808) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nsxJg-0000Ca-Ry for bug-gnu-emacs@gnu.org; Sun, 22 May 2022 21:57:04 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:52859) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nsxJe-0003Mt-Ha for bug-gnu-emacs@gnu.org; Sun, 22 May 2022 21:57:04 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1nsxJe-0005Cl-Ef for bug-gnu-emacs@gnu.org; Sun, 22 May 2022 21:57:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: "J.P." Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 23 May 2022 01:57:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51753 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 51753-submit@debbugs.gnu.org id=B51753.165327097919956 (code B ref 51753); Mon, 23 May 2022 01:57:02 +0000 Original-Received: (at 51753) by debbugs.gnu.org; 23 May 2022 01:56:19 +0000 Original-Received: from localhost ([127.0.0.1]:46756 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nsxIx-0005Bn-2B for submit@debbugs.gnu.org; Sun, 22 May 2022 21:56:19 -0400 Original-Received: from mail-108-mta27.mxroute.com ([136.175.108.27]:38323) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nsxIu-0005BZ-Gh for 51753@debbugs.gnu.org; Sun, 22 May 2022 21:56:17 -0400 Original-Received: from filter006.mxroute.com ([140.82.40.27] 140.82.40.27.vultrusercontent.com) (Authenticated sender: mN4UYu2MZsgR) by mail-108-mta27.mxroute.com (ZoneMTA) with ESMTPSA id 180eea10095000c327.002 for <51753@debbugs.gnu.org> (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256); Mon, 23 May 2022 01:56:10 +0000 X-Zone-Loop: 0a917dc88435fe3fbfd4eeb97bbd1fd5c0d5b4c66c61 X-Originating-IP: [140.82.40.27] DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=neverwas.me ; s=x; h=Content-Type:MIME-Version:Message-ID:In-Reply-To:Date:References: Subject:Cc:To:From:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=XYMb77mCsm4RjmBjtXFfJXuTP6AFRrdIcMnahtbe/YI=; b=ebognFYFTBwzvxJ4zJB1PNCiVV Psq84E/sxhh8I2QHoR9WiVIp18svSAD+POO4+43FdFRw6XRCXvG8Y7X4pfHIs4SsLjspuOzW8l0yo HRG2g68PvNNaOKh/7weSNXazQjVTVoCaIbKNf4MKVpYuNSDXKDEsk+ZHG9Qe3FGJ/nspjUkT5Gkvv HMkTau/ysrgxS8fDHszyPjPAQAFiUSgzc4Jy0tOSBasCyddu3JltRuyO/pRcR795BPZB59TiRdaLj oWvR4j2t4HHrOgk2XwErQ4l/Q20+5wiAfTuj1TNn7gHdSlt+BP7kl/JPREcAAFtmJu6tXWstFeaVZ EGIRVSOw==; In-Reply-To: <878rqwjqua.fsf@codeisgreat.org> (Pankaj Jangid's message of "Fri, 20 May 2022 18:36:37 +0530") X-AuthUser: masked@neverwas.me X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:232923 Archived-At: --=-=-= Content-Type: text/plain Hi Pankaj, Pankaj Jangid writes: > 5. While it is connecting to the server, switch to the other frame to > work on other stuff > > Result: After the ERC connects to the server, it opens the autojoin > channels in the current frame. Ideally, it should open the channels in > the (dedicated) original frame where ERC was launched. Are you saying ERC ought to remember the frame in which an entry-point command, like `erc-tls', was originally invoked? Or might it be enough to make a best effort attempt at finding such a "dedicated" frame? If it's door #2, what if we used the first frame found containing a buffer belonging to the same connection (and if no such frame exists, just leave it up to the display-buffer gods)? This way, we could rely more fully on window.el facilities and avoid having to wrangle yet more state. Or, if really necessary, we could maybe fall back on a strategy that uses `window-prev-buffers' (or whatever) to find the most recently used frame for that connection (overkill, IMO). Either way, any solution would need to address not just autojoined channels but also server-initiated JOINs, PMs, etc. The attached patch claims to do something like I've described. If you're able to try it, please set these options beforehand: (setq erc-join-buffer 'frame erc-auto-query 'frame erc-query-display 'frame erc-reuse-frames 'displayed) If you're unable to try it, please let me know, and I can maybe add it temporarily to one of ERC's installable bug packages. Thanks, J.P. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Allow-erc-reuse-frames-to-favor-connections.patch >From be5ec788ea9fa4375b7d0c96b7d646796daf56d0 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Sat, 21 May 2022 00:04:04 -0700 Subject: [PATCH] Allow erc-reuse-frames to favor connections * lisp/erc/erc.el (erc-reuse-frames): Add alternate value to favor existing frames already displaying other buffers from the same connection. (erc-setup-buffer): Add case for "displayed" variant of `erc-reuse-frames'. --- lisp/erc/erc.el | 39 ++++++++++--- test/lisp/erc/erc-tests.el | 115 +++++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 8 deletions(-) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index ff482d4933..f82fb07a66 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -1536,12 +1536,17 @@ erc-frame-dedicated-flag :type 'boolean) (defcustom erc-reuse-frames t - "Determines whether new frames are always created. -Non-nil means that a new frame is not created to display an ERC -buffer if there is already a window displaying it. This only has -effect when `erc-join-buffer' is set to `frame'." + "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." + :package-version '(ERC . "5.4.1") ; FIXME update when publishing to ELPA :group 'erc-buffers - :type 'boolean) + :type '(choice boolean + (const displayed))) (defun erc-channel-p (channel) "Return non-nil if CHANNEL seems to be an IRC channel name." @@ -1943,6 +1948,19 @@ erc-update-modules (funcall sym 1) (error "`%s' is not a known ERC module" mod)))))) +(defun erc--setup-buffer-frame-displayed (buffer) + "Maybe display BUFFER in an existing frame for the same connection. +If performed, return window used; otherwise, return nil." + (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))))) + (defun erc-setup-buffer (buffer) "Consults `erc-join-buffer' to find out how to display `BUFFER'." (pcase erc-join-buffer @@ -1955,15 +1973,20 @@ erc-setup-buffer ('bury nil) ('frame - (when (or (not erc-reuse-frames) - (not (get-buffer-window buffer t))) + (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))) + ((or (not erc-reuse-frames) + (not (get-buffer-window buffer t))) (let ((frame (make-frame (or erc-frame-alist default-frame-alist)))) (raise-frame frame) (select-frame frame)) (switch-to-buffer buffer) (when erc-frame-dedicated-flag - (set-window-dedicated-p (selected-window) t)))) + (set-window-dedicated-p (selected-window) t))))) (_ (if (active-minibuffer-window) (display-buffer buffer) diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 520f10dd4e..1eac6b22c9 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -171,6 +171,121 @@ erc--switch-to-buffer (dolist (b '("server" "other" "#chan" "#foo" "#fake")) (kill-buffer b)))) +(ert-deftest erc-reuse-frames () + ;; TODO run this in a pseudo terminal subprocess for EMBA + (skip-unless (not noninteractive)) + (should-not erc-frame-dedicated-flag) + (let ((erc-join-buffer 'frame) + (erc-reuse-frames t) + (orig-frame (selected-frame)) + erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook) + + (ert-info ("Value: t") + (with-current-buffer (generate-new-buffer "server") + (erc-mode) + (setq erc-server-process (start-process "server" (current-buffer) + "sleep" "1") + erc-frame-alist (cons '(name . "server") default-frame-alist)) + (set-process-query-on-exit-flag erc-server-process nil) + (should-not (get-buffer-window (current-buffer) t)) + (erc-setup-buffer (current-buffer)) + ;; New frame created and raised + (should (equal "server" (frame-parameter (window-frame) 'name))) + (should (get-buffer-window (current-buffer) t)) + + (with-current-buffer (generate-new-buffer "#chan") + (erc-mode) + (setq erc-server-process erc-server-process + erc-frame-alist (cons '(name . "#chan") default-frame-alist) + erc-default-recipients '("#chan")) + (should-not (get-buffer-window (current-buffer) t)) + (erc-setup-buffer (current-buffer)) + ;; Another frame was created just for #chan + (should (equal "#chan" (frame-parameter (window-frame) 'name))) + (should (get-buffer-window (current-buffer) t)) + (delete-frame)) + + (select-frame-by-name "server") + (pop-to-buffer "#chan") + ;; The server frame contains two vertical windows + (let ((tree (window-tree))) + (should (memq (get-buffer-window "server" t) (car tree))) + (should (memq (get-buffer-window "#chan" t) (car tree)))) + (should (eq (get-buffer "#chan") (window-buffer (selected-window)))) + (should (eq (get-buffer "server") (window-buffer (next-window)))))) + + (ert-info ("Value: displayed, scratch frame selected") + (select-frame orig-frame) + (with-current-buffer "*scratch*" + (with-current-buffer (generate-new-buffer "#spam") + (erc-mode) + (setq erc-server-process (buffer-local-value 'erc-server-process + (get-buffer "server")) + erc-reuse-frames 'displayed + erc-frame-alist (cons '(name . "#spam") default-frame-alist) + erc-default-recipients '("#spam")) + (should-not (get-buffer-window (current-buffer) t)) + (erc-setup-buffer (current-buffer)) + ;; Window shows up in other frame + (should (eq (selected-frame) orig-frame)) + (let ((fr (window-frame (get-buffer-window (current-buffer) t)))) + (should (equal "server" (frame-parameter fr 'name))) + (with-selected-frame fr + (should (memq (get-buffer-window "#spam" t) + (car (window-tree)))))))) + + (with-current-buffer "server" + (ert-info ("Value: displayed, server frame selected") + (select-frame-by-name "server") + (select-window (get-buffer-window "#spam")) + (with-current-buffer (generate-new-buffer "bob") + (erc-mode) + (setq erc-server-process (buffer-local-value 'erc-server-process + (get-buffer "server")) + erc-frame-alist (cons '(name . "bob") default-frame-alist) + erc-default-recipients '("bob")) + (should-not (get-buffer-window (current-buffer) t)) + (erc-setup-buffer (current-buffer)) + ;; Window shows up in this frame + (let ((fr (window-frame (get-buffer-window (current-buffer) t)))) + (should (eq fr (selected-frame))) + (should (equal "server" (frame-parameter fr 'name))) + (with-selected-frame fr + (should (memq (get-buffer-window "bob" t) + (car (window-tree))))) + ;; `inhibit-same-window' respected + (should-not (eq (get-buffer-window "bob") (selected-window)))))) + + (ert-info ("Value: displayed, other frames deleted") + (with-selected-frame orig-frame + (delete-frame)) + (should-not (cdr (frame-list))) + (select-window (get-buffer-window "bob")) + (with-current-buffer (generate-new-buffer "alice") + (erc-mode) + (setq erc-server-process (buffer-local-value 'erc-server-process + (get-buffer "server")) + erc-frame-alist (cons '(name . "alice") default-frame-alist) + erc-default-recipients '("alice")) + (should-not (get-buffer-window (current-buffer) t)) + (erc-setup-buffer (current-buffer)) + (let ((fr (window-frame (get-buffer-window (current-buffer) t)))) + (should (eq fr (selected-frame))) + (should (equal "server" (frame-parameter fr 'name))) + (with-selected-frame fr + (should (memq (get-buffer-window "alice" t) + (car (window-tree))))) + (should-not (eq (get-buffer-window "alice") + (selected-window))))))))) + + (should-not (cdr (frame-list))) + (delete-other-windows) + (kill-buffer "server") + (kill-buffer "bob") + (kill-buffer "alice") + (kill-buffer "#spam") + (kill-buffer "#chan")) + (ert-deftest erc-lurker-maybe-trim () (let (erc-lurker-trim-nicks (erc-lurker-ignore-chars "_`")) -- 2.36.1 --=-=-=--