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#63595: 30.0.50; ERC 5.6: Add buffer-list and nick-list modules Date: Tue, 25 Jul 2023 06:32:36 -0700 Message-ID: <87o7k0yv4b.fsf__7628.34761278413$1690292010$gmane$org@neverwas.me> References: <87lehkt97a.fsf@neverwas.me> 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="20635"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: emacs-erc@gnu.org To: 63595@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Tue Jul 25 15:33:24 2023 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 1qOIAF-00057d-6z for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 25 Jul 2023 15:33:23 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qOI9v-00084f-Cf; Tue, 25 Jul 2023 09:33:03 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qOI9u-000840-6u for bug-gnu-emacs@gnu.org; Tue, 25 Jul 2023 09:33:02 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qOI9t-0006wG-Uh for bug-gnu-emacs@gnu.org; Tue, 25 Jul 2023 09:33:01 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qOI9t-0005qf-QG for bug-gnu-emacs@gnu.org; Tue, 25 Jul 2023 09:33:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: "J.P." Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 25 Jul 2023 13:33:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63595 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 63595-submit@debbugs.gnu.org id=B63595.169029196622427 (code B ref 63595); Tue, 25 Jul 2023 13:33:01 +0000 Original-Received: (at 63595) by debbugs.gnu.org; 25 Jul 2023 13:32:46 +0000 Original-Received: from localhost ([127.0.0.1]:44907 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qOI9d-0005pd-NK for submit@debbugs.gnu.org; Tue, 25 Jul 2023 09:32:46 -0400 Original-Received: from mail-108-mta102.mxroute.com ([136.175.108.102]:46747) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qOI9a-0005pQ-UB for 63595@debbugs.gnu.org; Tue, 25 Jul 2023 09:32:44 -0400 Original-Received: from mail-111-mta2.mxroute.com ([136.175.111.2] filter006.mxroute.com) (Authenticated sender: mN4UYu2MZsgR) by mail-108-mta102.mxroute.com (ZoneMTA) with ESMTPSA id 1898d4079020004cef.001 for <63595@debbugs.gnu.org> (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Tue, 25 Jul 2023 13:32:40 +0000 X-Zone-Loop: caf529c14763c309c8bf617e81cecd6efb66f9f1130a X-Originating-IP: [136.175.111.2] 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:Date:References:In-Reply-To: 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=QIXpA43qmWN8el5ptuYtzd7lqkrIYK43+gtLx3RL68U=; b=gIQfNu/xl4FCFxMcAz5qF/VjjI ZYxQQ/UkvSYwwNIPsObnCKijDJU9a9fe/J2KAKd4tA1kvY1KCt2UbUQZVNgPs4CPobqwPVyTN9p5R //odzQtL7862jlol0GrSo6XsoiFrqEMuW6qyzUfkxkyYDiOjmNWiuexvtjIqIlFWVWmYGq5RNsYQ0 duAG6JT/VYsuLDr+tZ9BlSqmdN6H7EtBGSnVaOeUuke7ZuEorSiNpDmYPrJRC77TuF10UYzRz77ob XYs5v8BwUXY7H9QaULtjLOPA4GwcJIMebFSn6IztSdxwzs5t3U6CN2VhNF+vE02uUnCm4SZj2SiST PPyv3iPA==; In-Reply-To: <87lehkt97a.fsf@neverwas.me> (J. P.'s message of "Fri, 19 May 2023 12:25:29 -0700") X-Authenticated-Id: 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-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:266060 Archived-At: --=-=-= Content-Type: text/plain This may come as a shock, but problems exist in the `bufbar' changes recently introduced (by me) to erc-status-sidebar.el. The first involves the new boolean option `erc-status-sidebar-singular'. No matter what its doc string says, the purpose of this option remains difficult to describe and its behavior hard to predict. This makes it only really practical as an internal flag, which is what it should have been from the get-go and how it's been repurposed in the attached patch. Initially, this option was intended to alter the behavior of the minor-mode toggle `erc-bufbar-mode' so that when the option is nil, toggling the mode in a frame where the sidebar is hidden would summon it, regardless of the value of the mode's variable. This kind of extreme DWIM'ness may suit normal, standalone minor modes, but users likely expect mode toggles for global ERC modules to work more or less traditionally. A somewhat related problem stems from my altering the original behavior of existing status-sidebar commands, like `erc-status-sidebar-open', to accommodate and promote `erc-bufbar-mode' as a unified entry point. In retrospect, that probably threatens to anger the rare person who's become accustomed to those commands over the past couple years and who may not be interested in the new module at all (for whatever reason). I've attempted to rectify this in the attached patch so that the newer behavior only takes effect when `erc-bufbar-mode' is active. This means users of the module must now issue an M-x erc-status-sidebar-open RET to see the sidebar in (additional) frames that don't yet have one, but non-module users will still only ever encounter a single sidebar instance in an Emacs session. The last issue involves the sidebar intermittently clobbering the window's scroll position. I've tried to eradicate this while also improving the overall responsiveness by having it refresh when users select another window. Basically, updates were initially tethered to mode-line changes, which often left users with the wrong buffer highlighted whenever updates were few and far between. Although this is now much improved, the change likely adds some overhead, so I've included an escape hatch while we investigate further. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-5.6-Simplify-multi-frame-behavior-of-erc-bufbar-mode.patch >From 7b47f05fbc7093db798f2ee421a3082c9febc363 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Sun, 23 Jul 2023 23:09:42 -0700 Subject: [PATCH 1/2] [5.6] Simplify multi-frame behavior of erc-bufbar-mode * lisp/erc/erc-status-sidebar.el (erc-status-sidebar-singular, erc-status-sidebar--singular-p): Replace public option, new in ERC 5.6, with the latter, an internal state flag. (erc-status-sidebar-get-window): Use new name for option turned ordinary variable `erc-status-sidebar--singular-p'. (erc-status-sidebar-close): Add comment. (erc-status-sidebar--open): New function containing the old body of `erc-status-sidebar-open'. (erc-bufbar-mode, erc-bufbar-enable, erc-bufbar-disable): Update variable names. When disabling, always close window on all frames. Don't set mode variable to nil when enabling outside of an `erc-mode' buffer. This may have made some practical sense but was illogical since the `erc--setup-buffer-hook' was left as is, meaning the activation state was still partially enabled. (erc-status-sidebar-open): Move definition to lower down in file, after `erc-bufbar-mode'. When `erc-bufbar-mode' is active, always create a sidebar if needed, even when another frame is already displaying one. (erc-status-toggle-sidebar): When `erc-bufbar-mode' is disabled, revert to pre-5.6 behavior, ignoring bug fixes. When the module is enabled, adopt new behavior of always ensuring the current frame shows a sidebar, even if another frame already has one. (erc-status-sidebar-refresh): Save and restore window start in all windows showing status sidebar buffer after refreshing. Update option and variable names. (erc-status-sidebar--refresh-unless-input): New function to run `erc-status-sidebar-refresh' unless input is pending or the selected window's buffer is a minibuffer. (erc-status-sidebar--post-refresh): Call `erc-status-sidebar-refresh' wrapper `erc-status-sidebar--refresh-unless-input' instead. (erc-status-sidebar-refresh-triggers): Add doc string, noting that the variable is set locally when the option `erc-status-sidebar-highlight-active-buffer' is non-nil. (erc-status-sidebar--highlight-refresh-triggers): New variable containing additional triggers enabled when the option `erc-status-highlight-active-buffer' is non-nil. (erc-status-sidebar-set-window-preserve-size): Update var name to `erc-status-sidebar--singular-p'. (erc-status-sidebar-mode): Run `erc-status-sidebar--post-refresh' on `window-selection-change-functions' globally when highlighting active buffers. (bug#63595) --- lisp/erc/erc-status-sidebar.el | 107 +++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 37 deletions(-) diff --git a/lisp/erc/erc-status-sidebar.el b/lisp/erc/erc-status-sidebar.el index b8bd7b0065e..a82c846ff1a 100644 --- a/lisp/erc/erc-status-sidebar.el +++ b/lisp/erc/erc-status-sidebar.el @@ -45,8 +45,8 @@ ;; Use M-x erc-status-sidebar-kill RET to kill the sidebar buffer and ;; close the sidebar on all frames. -;; In addition to the commands above, you can also try the all-in-one, -;; "DWIM" command, `erc-bufbar-mode'. See its doc string for usage. +;; In addition to the commands above, you can also try the all-in-one +;; entry point `erc-bufbar-mode'. See its doc string for usage. ;; If you want the status sidebar enabled whenever you use ERC, add ;; `bufbar' to `erc-modules'. Note that this library also has a major @@ -130,8 +130,11 @@ erc-status-sidebar-style `erc-status-sidebar-pad-hierarchy' for the above-mentioned purposes. ERC also accepts a list of -functions to preform these roles a la carte. See doc strings for -a description of their expected arguments and return values." +functions to preform these roles a la carte. Since the members +of the above sets aren't really interoperable, we don't offer +them here as customization choices, but you can still specify +them manually. See doc strings for a description of their +expected arguments and return values." :package-version '(ERC . "5.6") ; FIXME sync on release :type '(choice (const channels-only) (const all-mixed) @@ -158,10 +161,12 @@ erc-status-sidebar-click-display-action :key-type symbol :value-type (sexp :tag "Value"))))) -(defcustom erc-status-sidebar-singular t - "Whether to show the sidebar on all frames or just one (default)." - :package-version '(ERC . "5.6") ; FIXME sync on release - :type 'boolean) +(defvar erc-status-sidebar--singular-p t + "Whether to restrict the sidebar to a single frame. +This variable only affects `erc-bufbar-mode'. Disabling it does +not arrange for automatically showing the sidebar in all frames. +Rather, disabling it allows for displaying the sidebar in the +selected frame even if it's already showing in some other frame.") (defvar hl-line-mode) (declare-function hl-line-highlight "hl-line" nil) @@ -178,7 +183,7 @@ erc-status-sidebar-get-window If NO-CREATION is non-nil, the window is not created." (let ((sidebar-window (get-buffer-window erc-status-sidebar-buffer-name - erc-status-sidebar-singular))) + erc-status-sidebar--singular-p))) (unless (or sidebar-window no-creation) (with-current-buffer (erc-status-sidebar-get-buffer) (setq-local vertical-scroll-bar nil)) @@ -214,7 +219,7 @@ erc-status-sidebar-close containing it on the current frame is closed. See `erc-status-sidebar-kill'." (interactive "P") - (mapcar #'delete-window + (mapcar #'delete-window ; FIXME use `mapc'. (get-buffer-window-list (erc-status-sidebar-get-buffer) nil (if all-frames t)))) @@ -223,10 +228,8 @@ erc-status-sidebar-writable `(let ((buffer-read-only nil)) ,@body)) -;;;###autoload -(defun erc-status-sidebar-open () - "Open or create a sidebar." - (interactive) +(defun erc-status-sidebar--open () + "Maybe open the sidebar, respecting `erc-status-sidebar--singular-p'." (save-excursion (if (erc-status-sidebar-buffer-exists-p) (erc-status-sidebar-get-window) @@ -237,11 +240,15 @@ erc-status-sidebar-open ;;;###autoload(autoload 'erc-bufbar-mode "erc-status-sidebar" nil t) (define-erc-module bufbar nil "Show `erc-track'-like activity in a side window. -When enabling, show the sidebar immediately if called from a -connected ERC buffer. Otherwise, arrange for doing so on connect -or whenever next displaying a new ERC buffer. When disabling, -hide the status window if it's showing. With a negative prefix -arg, also shutdown the session." +When enabling, show the sidebar immediately in the current frame +if called from a connected ERC buffer. Otherwise, arrange for +doing so on connect or whenever next displaying a new ERC buffer. +When disabling, hide the status window in all frames. With a +negative prefix arg, also shutdown the session. Normally, this +module only allows one sidebar window in an Emacs session. To +override this, use `erc-status-sidebar-open' to force creation +and `erc-status-sidebar-close' to hide a single instance on the +current frame only." ((unless erc-track-mode (unless (memq 'track erc-modules) (erc--warn-once-before-connect 'erc-bufbar-mode @@ -249,30 +256,38 @@ bufbar " This will affect \C-]all\C-] ERC sessions." " Add `track' to `erc-modules' to silence this message.")) (erc-track-mode +1)) - (add-hook 'erc--setup-buffer-hook #'erc-status-sidebar-open) + (add-hook 'erc--setup-buffer-hook #'erc-status-sidebar--open) (unless erc--updating-modules-p (if (erc-with-server-buffer erc-server-connected) - (erc-status-sidebar-open) - (setq erc-bufbar-mode nil) + (erc-status-sidebar--open) (when (derived-mode-p 'erc-mode) (erc-error "Not initializing `erc-bufbar-mode' in %s" (current-buffer)))))) - ((remove-hook 'erc--setup-buffer-hook #'erc-status-sidebar-open) - (erc-status-sidebar-close erc-status-sidebar-singular) + ((remove-hook 'erc--setup-buffer-hook #'erc-status-sidebar--open) + (erc-status-sidebar-close 'all-frames) (when-let ((arg erc--module-toggle-prefix-arg) ((numberp arg)) ((< arg 0))) (erc-status-sidebar-kill)))) +;;;###autoload +(defun erc-status-sidebar-open () + "Open or create a sidebar window in the current frame. +When `erc-bufbar-mode' is active, do this even if one already +exists in another frame." + (interactive) + (let ((erc-status-sidebar--singular-p (not erc-bufbar-mode))) + (erc-status-sidebar--open))) + ;;;###autoload (defun erc-status-sidebar-toggle () "Toggle the sidebar open/closed on the current frame. -Do this regardless of `erc-status-sidebar-singular'." +When opening and `erc-bufbar-mode' is active, create a sidebar +even if one already exists in another frame." (interactive) (if (get-buffer-window erc-status-sidebar-buffer-name nil) (erc-status-sidebar-close) - (let (erc-status-sidebar-singular) - (erc-status-sidebar-open)))) + (erc-status-sidebar-open))) (defun erc-status-sidebar-get-channame (buffer) "Return name of BUFFER with all leading \"#\" characters removed." @@ -413,11 +428,10 @@ erc-status-sidebar-refresh erc-status-sidebar-pad-hierarchy)) (v v))) (chanlist (apply sort-fn (funcall list-fn nil) nil)) - (window nil) - (winstart nil)) + (windows nil)) (with-current-buffer (erc-status-sidebar-get-buffer) - (setq window (get-buffer-window nil erc-status-sidebar-singular) - winstart (and window (window-start window))) + (dolist (window (get-buffer-window-list nil nil t)) + (push (cons window (window-start window)) windows)) (erc-status-sidebar-writable (delete-region (point-min) (point-max)) (goto-char (point-min)) @@ -443,9 +457,10 @@ erc-status-sidebar-refresh 0 cnlen 'help-echo "mouse-1: switch to buffer in other window" channame) (funcall insert-fn channame chanbuf chanlist))) - (when winstart - (set-window-point window winstart) - (with-selected-window window (recenter 0))) + (when windows + (pcase-dolist (`(,window . ,winstart) windows) + (set-window-point window winstart) + (with-selected-window window (recenter 0)))) (when (and erc-status-sidebar-highlight-active-buffer (marker-buffer erc-status-sidebar--active-marker)) (goto-char erc-status-sidebar--active-marker) @@ -519,14 +534,28 @@ erc-status-sidebar-refresh-triggers erc-kill-server-hook erc-kick-hook erc-disconnected-hook - erc-quit-hook)) + erc-quit-hook) + "Hooks to refresh the sidebar on. +This may be set locally in the status-sidebar buffer under +various conditions, like when the option +`erc-status-sidebar-highlight-active-buffer' is non-nil.") + +(defvar erc-status-sidebar--highlight-refresh-triggers + '(window-selection-change-functions) + "Triggers enabled with `erc-status-sidebar-highlight-active-buffer'.") + +(defun erc-status-sidebar--refresh-unless-input () + "Run `erc-status-sidebar-refresh' unless there are unread commands. +Also abstain when the user is interacting with the minibuffer." + (unless (or (input-pending-p) (minibuffer-window-active-p (selected-window))) + (erc-status-sidebar-refresh))) (defun erc-status-sidebar--post-refresh (&rest _ignore) "Schedule sidebar refresh for execution after command stack is cleared. Ignore arguments in IGNORE, allowing this function to be added to hooks that invoke it with arguments." - (run-at-time 0 nil #'erc-status-sidebar-refresh)) + (run-at-time 0 nil #'erc-status-sidebar--refresh-unless-input)) (defun erc-status-sidebar-mode--unhook () "Remove hooks installed by `erc-status-sidebar-mode'." @@ -541,7 +570,7 @@ erc-status-sidebar-set-window-preserve-size Note that preserve status needs to be reset when the window is manually resized, so `erc-status-sidebar-mode' adds this function to the `window-configuration-change-hook'." - (when (and (eq (selected-window) (let (erc-status-sidebar-singular) + (when (and (eq (selected-window) (let (erc-status-sidebar--singular-p) (erc-status-sidebar-get-window))) (fboundp 'window-preserve-size)) (unless (eq (window-total-width) (window-min-size nil t)) @@ -563,6 +592,10 @@ erc-status-sidebar-mode (add-hook 'window-configuration-change-hook #'erc-status-sidebar-set-window-preserve-size nil t) + (when erc-status-sidebar-highlight-active-buffer + (setq-local erc-status-sidebar-refresh-triggers + `(,@erc-status-sidebar--highlight-refresh-triggers + ,@erc-status-sidebar-refresh-triggers))) (dolist (hk erc-status-sidebar-refresh-triggers) (add-hook hk #'erc-status-sidebar--post-refresh)) -- 2.41.0 --=-=-=--