From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: "Mingde (Matthew) Zeng" Newsgroups: gmane.emacs.devel Subject: [PATCHv2] erc: fix erc-reuse-buffers behavior Date: Fri, 24 Jul 2020 03:20:25 -0400 Message-ID: <87mu3p4bwm.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="33507"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: mu4e 1.4.10; emacs 27.0.91 Cc: bandali@gnu.org To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Jul 24 09:21:17 2020 Return-path: Envelope-to: ged-emacs-devel@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 1jys17-0008av-Gg for ged-emacs-devel@m.gmane-mx.org; Fri, 24 Jul 2020 09:21:17 +0200 Original-Received: from localhost ([::1]:52094 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jys16-000150-J5 for ged-emacs-devel@m.gmane-mx.org; Fri, 24 Jul 2020 03:21:16 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:47766) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jys0N-0000TY-Dm for emacs-devel@gnu.org; Fri, 24 Jul 2020 03:20:31 -0400 Original-Received: from mail-qk1-x736.google.com ([2607:f8b0:4864:20::736]:36128) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jys0L-0005cG-DL; Fri, 24 Jul 2020 03:20:31 -0400 Original-Received: by mail-qk1-x736.google.com with SMTP id g26so7844115qka.3; Fri, 24 Jul 2020 00:20:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=user-agent:from:to:cc:subject:date:message-id:mime-version; bh=qEmY2cvdZgGvo2rCxtP/kN1coTiLrqxfuaFBY6YdwIQ=; b=ECt2bYS9OTVTEXUqXIoFWuRomWJoM+uBgPcbEM2ubI3vE4ZtDtM8ukrp2iJAAOlccg qGLxSf1tytdXIGrsuklOAaQbiKwpWzxG97F6NfL251iC0J94Ttcs0FSaHOF+LAKHkiTB XedcwAMXZXNn2J+vraUqTjtxeO5atCipO5HMatqZCCdkDn/R+fo5n1QnfN6jxZhHmw2t bKCN6r90gvY+GnGpNp9SWr3t50b359quURIQ4Z9PnXUZOFrf03Y/RC7pPxPlQkR2IqdR Jof0e4TdMWXufWStgB9xIRh56BTr0QxcZfSyKbXcMHnlQGLEF7NH2o5l8/DtObvASlXX OsRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:user-agent:from:to:cc:subject:date:message-id :mime-version; bh=qEmY2cvdZgGvo2rCxtP/kN1coTiLrqxfuaFBY6YdwIQ=; b=pW8cvXcdvrgkBZYGxmp4pe9Xl6SK2sz1nyg2p3tOL07ibTQTllYNsKQSQNtmyPhJ11 ICuatiOnfTs2S7X+N1+C/Rrbqi1t5Wasd/y0bvt63oQkxxpC9p+WaHNqRUQotstjjQiw jGvI/ss6mG2AMz4sKRQvQcJjG0zOpxf5gvvz6IzP9GBV2/rhZmGE+vmKI0jq2anKfYpY aY7E7dG1KCvpPiodGsikRoRTPpGjKjZGj1TtQqyyu8jFNeG/HistgfQZGNpScRFeP76X /GXKt0xGwuuquQyhGuhp4D04vNVntA/ABKpWjGMAmmTfXgdvyK5bVgAVJZyUADErlNUr l8aw== X-Gm-Message-State: AOAM533Le4rB30SbGO1e5e2+1I1jTYFBIzT5W2UilFpJt0+yMYazisqt AVZpc8ZgkUzE2YQERIhGuJr32A0c X-Google-Smtp-Source: ABdhPJwYrgOLO80IsC05BinWJQN5jF4fWHZ+t3T/fvCYiLGVS+yZaPi6kyTvxqKfgdYKdkCElJ2aXA== X-Received: by 2002:a37:4e07:: with SMTP id c7mr8784778qkb.462.1595575227089; Fri, 24 Jul 2020 00:20:27 -0700 (PDT) Original-Received: from mt-manjaro (216-58-109-18.cpe.distributel.net. [216.58.109.18]) by smtp.gmail.com with ESMTPSA id f189sm5219141qke.15.2020.07.24.00.20.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Jul 2020 00:20:26 -0700 (PDT) Received-SPF: pass client-ip=2607:f8b0:4864:20::736; envelope-from=matthewzmd@gmail.com; helo=mail-qk1-x736.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:253181 Archived-At: By definition of erc-reuse-buffers, if non-nil it should create a new buffer when joining channels with same names on different servers. The current behavior of erc-reuse-buffers is: 1. when non-nil, it will always reuse the same channel buffer, resulting in server A's channel gets reconnected to the channel with the same name of server B. 2. when nil, the buffer-name of the joined channel is '#channel/server'. However if one tries to '/join #channel' from the server buffer, it creates a new empty buffer with buffer-name '#channel', instead of opening the already-joined channel buffer. * lisp/erc/erc.el (erc-generate-new-buffer-name): since `target' is always non-nil, buffer-name is non-nil, erc-reuse-buffers is t, it will always use the first candidate, resulting in behavior 1. This is now fixed, and both channel buffers with the same name will be formated '#channel/serverA' and '#channel/serverB' for the sake of consistency. * lisp/erc/erc.el (erc-cmd-JOIN): with some refactoring, it ensures the joined channel buffer is selected and thereby fixes behavior 2. * lisp/erc/erc-join.el (erc-autojoin-channels): the logic is simplified ensuring that when autojoining channels specified in erc-autojoin-channels-alist, if there exists an erc buffer with the same channel name but a different server, it will create a new buffer to join the channel. The current logic is very weak that will skip joining same channel on different servers altogether. Signed-off-by: Mingde (Matthew) Zeng --- lisp/erc/erc-join.el | 22 +++++++------ lisp/erc/erc.el | 74 ++++++++++++++++++++++++++------------------ 2 files changed, 56 insertions(+), 40 deletions(-) diff --git a/lisp/erc/erc-join.el b/lisp/erc/erc-join.el index 280d6bfe0f..c59f7118d1 100644 --- a/lisp/erc/erc-join.el +++ b/lisp/erc/erc-join.el @@ -153,18 +153,20 @@ This function is run from `erc-nickserv-identified-hook'." 'erc-autojoin-channels-delayed server nick (current-buffer)))) ;; `erc-autojoin-timing' is `connect': - (dolist (l erc-autojoin-channels-alist) - (when (string-match (car l) server) - (let ((server (or erc-session-server erc-server-announced-name))) + (let ((server (or erc-session-server erc-server-announced-name))) + (dolist (l erc-autojoin-channels-alist) + (when (string-match (car l) server) (dolist (chan (cdr l)) - (let ((buffer (erc-get-buffer chan))) - ;; Only auto-join the channels that we aren't already in - ;; using a different nick. + (let ((buffer + (car (erc-buffer-filter + (lambda () + (let ((current (erc-default-target))) + (and (stringp current) + (string-match (car l) + (or erc-session-server erc-server-announced-name)) + (string-equal (erc-downcase chan) + (erc-downcase current))))))))) (when (or (not buffer) - ;; If the same channel is joined on another - ;; server the best-effort is to just join - (not (string-match (car l) - (process-name erc-server-process))) (not (with-current-buffer buffer (erc-server-process-alive)))) (erc-server-join-channel server chan)))))))) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 3880778794..2b2cc578d9 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -1606,33 +1606,45 @@ symbol, it may have these values: (defun erc-generate-new-buffer-name (server port target) "Create a new buffer name based on the arguments." (when (numberp port) (setq port (number-to-string port))) - (let ((buf-name (or target - (or (let ((name (concat server ":" port))) - (when (> (length name) 1) - name)) - ;; This fallback should in fact never happen - "*erc-server-buffer*"))) - buffer-name) + (let* ((buf-name (or target + (or (let ((name (concat server ":" port))) + (when (> (length name) 1) + name)) + ;; This fallback should in fact never happen + "*erc-server-buffer*"))) + (full-buf-name (concat buf-name "/" server)) + (dup-buf-name (car (mapcar #'(lambda (chanbuf) + (buffer-name chanbuf)) + (erc-channel-list nil)))) + buffer-name) ;; Reuse existing buffers, but not if the buffer is a connected server ;; buffer and not if its associated with a different server than the ;; current ERC buffer. ;; if buf-name is taken by a different connection (or by something !erc) ;; then see if "buf-name/server" meets the same criteria - (dolist (candidate (list buf-name (concat buf-name "/" server))) - (if (and (not buffer-name) - erc-reuse-buffers - (or (not (get-buffer candidate)) - (or target - (with-current-buffer (get-buffer candidate) - (and (erc-server-buffer-p) - (not (erc-server-process-alive))))) - (with-current-buffer (get-buffer candidate) - (and (string= erc-session-server server) - (erc-port-equal erc-session-port port))))) - (setq buffer-name candidate))) + (if (and dup-buf-name (string-match (concat buf-name "/") dup-buf-name)) + (setq buffer-name full-buf-name) ; already exists erc buffer with the full name + (dolist (candidate (list buf-name full-buf-name)) + (if (and (not buffer-name) + erc-reuse-buffers + (or (not (get-buffer candidate)) + (with-current-buffer (get-buffer candidate) + (and (erc-server-buffer-p) + (not (erc-server-process-alive)))) + (with-current-buffer (get-buffer candidate) + (and (string= erc-session-server server) + (erc-port-equal erc-session-port port))))) + (setq buffer-name candidate) + (when (and (not buffer-name) (get-buffer buf-name) erc-reuse-buffers) + ;; a new buffer will be created with the name buf-name/server, rename + ;; the existing name-duplicated buffer with the same format as well + (with-current-buffer (get-buffer buf-name) + (when (derived-mode-p 'erc-mode) ; ensure it's an erc buffer + (rename-buffer + (concat buf-name "/" (or erc-session-server erc-server-announced-name))))))))) ;; if buffer-name is unset, neither candidate worked out for us, ;; fallback to the old uniquification method: - (or buffer-name (generate-new-buffer-name (concat buf-name "/" server))))) + (or buffer-name (generate-new-buffer-name full-buf-name)))) (defun erc-get-buffer-create (server port target) "Create a new buffer based on the arguments." @@ -3097,16 +3109,18 @@ were most recently invited. See also `invitation'." (setq chnl (erc-ensure-channel-name channel))) (when chnl ;; Prevent double joining of same channel on same server. - (let ((joined-channels - (mapcar #'(lambda (chanbuf) - (with-current-buffer chanbuf (erc-default-target))) - (erc-channel-list erc-server-process)))) - (if (erc-member-ignore-case chnl joined-channels) - (switch-to-buffer (car (erc-member-ignore-case chnl - joined-channels))) - (let ((server (with-current-buffer (process-buffer erc-server-process) - (or erc-session-server erc-server-announced-name)))) - (erc-server-join-channel server chnl key)))))) + (let* ((joined-channels + (mapcar #'(lambda (chanbuf) + (with-current-buffer chanbuf (erc-default-target))) + (erc-channel-list erc-server-process))) + (server (with-current-buffer (process-buffer erc-server-process) + (or erc-session-server erc-server-announced-name))) + (chnl-name (car (erc-member-ignore-case chnl joined-channels)))) + (if chnl-name + (switch-to-buffer (if (get-buffer chnl-name) + chnl-name + (concat chnl-name "/" server))) + (erc-server-join-channel server chnl key))))) t) (defalias 'erc-cmd-CHANNEL 'erc-cmd-JOIN) -- 2.27.0