aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorF. Jason Park2023-07-23 23:09:42 -0700
committerF. Jason Park2023-07-28 16:39:04 -0700
commitdeb74de4f2e6a16b81663cbd95f97bfc9e24e467 (patch)
tree23ed8051e2b98c1cee6bbe2c61f0531a42633c14
parentfb57b6ccb9f033106b0c00539590f22614604f22 (diff)
downloademacs-deb74de4f2e6a16b81663cbd95f97bfc9e24e467.tar.gz
emacs-deb74de4f2e6a16b81663cbd95f97bfc9e24e467.zip
Simplify multi-frame behavior in erc-bufbar-mode
* lisp/erc/erc-status-sidebar.el (erc-status-sidebar-singular, erc-status-sidebar--singular-p): Replace option new in ERC 5.6 with the latter, an internal 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. Close sidebar window on all frames when disabling, and don't set mode variable to nil when enabling. These may have made some practical sense but were illogical. For example, it's confusing to leave `erc-status-sidebar--open' in `erc--setup-buffer-hook' while reporting the mode as being disabled. (erc-status-sidebar-open): Move to slightly later in same file, after defining `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. When the module is enabled, adopt new behavior of 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 a sidebar buffer after refreshing. Update option and variable names. (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--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-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)
-rw-r--r--lisp/erc/erc-status-sidebar.el105
1 files changed, 68 insertions, 37 deletions
diff --git a/lisp/erc/erc-status-sidebar.el b/lisp/erc/erc-status-sidebar.el
index b8bd7b0065e..cf3d20aeffa 100644
--- a/lisp/erc/erc-status-sidebar.el
+++ b/lisp/erc/erc-status-sidebar.el
@@ -45,8 +45,8 @@
45;; Use M-x erc-status-sidebar-kill RET to kill the sidebar buffer and 45;; Use M-x erc-status-sidebar-kill RET to kill the sidebar buffer and
46;; close the sidebar on all frames. 46;; close the sidebar on all frames.
47 47
48;; In addition to the commands above, you can also try the all-in-one, 48;; In addition to the commands above, you can also try the all-in-one
49;; "DWIM" command, `erc-bufbar-mode'. See its doc string for usage. 49;; entry point `erc-bufbar-mode'. See its doc string for usage.
50 50
51;; If you want the status sidebar enabled whenever you use ERC, add 51;; If you want the status sidebar enabled whenever you use ERC, add
52;; `bufbar' to `erc-modules'. Note that this library also has a major 52;; `bufbar' to `erc-modules'. Note that this library also has a major
@@ -130,8 +130,11 @@ buffers, using the functions
130 `erc-status-sidebar-pad-hierarchy' 130 `erc-status-sidebar-pad-hierarchy'
131 131
132for the above-mentioned purposes. ERC also accepts a list of 132for the above-mentioned purposes. ERC also accepts a list of
133functions to preform these roles a la carte. See doc strings for 133functions to preform these roles a la carte. Since the members
134a description of their expected arguments and return values." 134of the above sets aren't really interoperable, we don't offer
135them here as customization choices, but you can still specify
136them manually. See doc strings for a description of their
137expected arguments and return values."
135 :package-version '(ERC . "5.6") ; FIXME sync on release 138 :package-version '(ERC . "5.6") ; FIXME sync on release
136 :type '(choice (const channels-only) 139 :type '(choice (const channels-only)
137 (const all-mixed) 140 (const all-mixed)
@@ -158,10 +161,12 @@ ACTION parameter."
158 :key-type symbol 161 :key-type symbol
159 :value-type (sexp :tag "Value"))))) 162 :value-type (sexp :tag "Value")))))
160 163
161(defcustom erc-status-sidebar-singular t 164(defvar erc-status-sidebar--singular-p t
162 "Whether to show the sidebar on all frames or just one (default)." 165 "Whether to restrict the sidebar to a single frame.
163 :package-version '(ERC . "5.6") ; FIXME sync on release 166This variable only affects `erc-bufbar-mode'. Disabling it does
164 :type 'boolean) 167not arrange for automatically showing the sidebar in all frames.
168Rather, disabling it allows for displaying the sidebar in the
169selected frame even if it's already showing in some other frame.")
165 170
166(defvar hl-line-mode) 171(defvar hl-line-mode)
167(declare-function hl-line-highlight "hl-line" nil) 172(declare-function hl-line-highlight "hl-line" nil)
@@ -178,7 +183,7 @@ ACTION parameter."
178 183
179If NO-CREATION is non-nil, the window is not created." 184If NO-CREATION is non-nil, the window is not created."
180 (let ((sidebar-window (get-buffer-window erc-status-sidebar-buffer-name 185 (let ((sidebar-window (get-buffer-window erc-status-sidebar-buffer-name
181 erc-status-sidebar-singular))) 186 erc-status-sidebar--singular-p)))
182 (unless (or sidebar-window no-creation) 187 (unless (or sidebar-window no-creation)
183 (with-current-buffer (erc-status-sidebar-get-buffer) 188 (with-current-buffer (erc-status-sidebar-get-buffer)
184 (setq-local vertical-scroll-bar nil)) 189 (setq-local vertical-scroll-bar nil))
@@ -214,7 +219,7 @@ The erc-status-sidebar buffer is left alone, but the window
214containing it on the current frame is closed. See 219containing it on the current frame is closed. See
215`erc-status-sidebar-kill'." 220`erc-status-sidebar-kill'."
216 (interactive "P") 221 (interactive "P")
217 (mapcar #'delete-window 222 (mapcar #'delete-window ; FIXME use `mapc'.
218 (get-buffer-window-list (erc-status-sidebar-get-buffer) 223 (get-buffer-window-list (erc-status-sidebar-get-buffer)
219 nil (if all-frames t)))) 224 nil (if all-frames t))))
220 225
@@ -223,10 +228,8 @@ containing it on the current frame is closed. See
223 `(let ((buffer-read-only nil)) 228 `(let ((buffer-read-only nil))
224 ,@body)) 229 ,@body))
225 230
226;;;###autoload 231(defun erc-status-sidebar--open ()
227(defun erc-status-sidebar-open () 232 "Maybe open the sidebar, respecting `erc-status-sidebar--singular-p'."
228 "Open or create a sidebar."
229 (interactive)
230 (save-excursion 233 (save-excursion
231 (if (erc-status-sidebar-buffer-exists-p) 234 (if (erc-status-sidebar-buffer-exists-p)
232 (erc-status-sidebar-get-window) 235 (erc-status-sidebar-get-window)
@@ -237,11 +240,15 @@ containing it on the current frame is closed. See
237;;;###autoload(autoload 'erc-bufbar-mode "erc-status-sidebar" nil t) 240;;;###autoload(autoload 'erc-bufbar-mode "erc-status-sidebar" nil t)
238(define-erc-module bufbar nil 241(define-erc-module bufbar nil
239 "Show `erc-track'-like activity in a side window. 242 "Show `erc-track'-like activity in a side window.
240When enabling, show the sidebar immediately if called from a 243When enabling, show the sidebar immediately in the current frame
241connected ERC buffer. Otherwise, arrange for doing so on connect 244if called from a connected ERC buffer. Otherwise, arrange for
242or whenever next displaying a new ERC buffer. When disabling, 245doing so on connect or whenever next displaying a new ERC buffer.
243hide the status window if it's showing. With a negative prefix 246When disabling, hide the status window in all frames. With a
244arg, also shutdown the session." 247negative prefix arg, also shutdown the session. Normally, this
248module only allows one sidebar window in an Emacs session. To
249override this, use `erc-status-sidebar-open' to force creation
250and `erc-status-sidebar-close' to hide a single instance on the
251current frame only."
245 ((unless erc-track-mode 252 ((unless erc-track-mode
246 (unless (memq 'track erc-modules) 253 (unless (memq 'track erc-modules)
247 (erc--warn-once-before-connect 'erc-bufbar-mode 254 (erc--warn-once-before-connect 'erc-bufbar-mode
@@ -249,30 +256,38 @@ arg, also shutdown the session."
249 " This will affect \C-]all\C-] ERC sessions." 256 " This will affect \C-]all\C-] ERC sessions."
250 " Add `track' to `erc-modules' to silence this message.")) 257 " Add `track' to `erc-modules' to silence this message."))
251 (erc-track-mode +1)) 258 (erc-track-mode +1))
252 (add-hook 'erc--setup-buffer-hook #'erc-status-sidebar-open) 259 (add-hook 'erc--setup-buffer-hook #'erc-status-sidebar--open)
253 (unless erc--updating-modules-p 260 (unless erc--updating-modules-p
254 (if (erc-with-server-buffer erc-server-connected) 261 (if (erc-with-server-buffer erc-server-connected)
255 (erc-status-sidebar-open) 262 (erc-status-sidebar--open)
256 (setq erc-bufbar-mode nil)
257 (when (derived-mode-p 'erc-mode) 263 (when (derived-mode-p 'erc-mode)
258 (erc-error "Not initializing `erc-bufbar-mode' in %s" 264 (erc-error "Not initializing `erc-bufbar-mode' in %s"
259 (current-buffer)))))) 265 (current-buffer))))))
260 ((remove-hook 'erc--setup-buffer-hook #'erc-status-sidebar-open) 266 ((remove-hook 'erc--setup-buffer-hook #'erc-status-sidebar--open)
261 (erc-status-sidebar-close erc-status-sidebar-singular) 267 (erc-status-sidebar-close 'all-frames)
262 (when-let ((arg erc--module-toggle-prefix-arg) 268 (when-let ((arg erc--module-toggle-prefix-arg)
263 ((numberp arg)) 269 ((numberp arg))
264 ((< arg 0))) 270 ((< arg 0)))
265 (erc-status-sidebar-kill)))) 271 (erc-status-sidebar-kill))))
266 272
267;;;###autoload 273;;;###autoload
274(defun erc-status-sidebar-open ()
275 "Open or create a sidebar window in the current frame.
276When `erc-bufbar-mode' is active, do this even if one already
277exists in another frame."
278 (interactive)
279 (let ((erc-status-sidebar--singular-p (not erc-bufbar-mode)))
280 (erc-status-sidebar--open)))
281
282;;;###autoload
268(defun erc-status-sidebar-toggle () 283(defun erc-status-sidebar-toggle ()
269 "Toggle the sidebar open/closed on the current frame. 284 "Toggle the sidebar open/closed on the current frame.
270Do this regardless of `erc-status-sidebar-singular'." 285When opening, and `erc-bufbar-mode' is active, create a sidebar
286even if one already exists in another frame."
271 (interactive) 287 (interactive)
272 (if (get-buffer-window erc-status-sidebar-buffer-name nil) 288 (if (get-buffer-window erc-status-sidebar-buffer-name nil)
273 (erc-status-sidebar-close) 289 (erc-status-sidebar-close)
274 (let (erc-status-sidebar-singular) 290 (erc-status-sidebar-open)))
275 (erc-status-sidebar-open))))
276 291
277(defun erc-status-sidebar-get-channame (buffer) 292(defun erc-status-sidebar-get-channame (buffer)
278 "Return name of BUFFER with all leading \"#\" characters removed." 293 "Return name of BUFFER with all leading \"#\" characters removed."
@@ -413,11 +428,10 @@ name stand out."
413 erc-status-sidebar-pad-hierarchy)) 428 erc-status-sidebar-pad-hierarchy))
414 (v v))) 429 (v v)))
415 (chanlist (apply sort-fn (funcall list-fn nil) nil)) 430 (chanlist (apply sort-fn (funcall list-fn nil) nil))
416 (window nil) 431 (windows nil))
417 (winstart nil))
418 (with-current-buffer (erc-status-sidebar-get-buffer) 432 (with-current-buffer (erc-status-sidebar-get-buffer)
419 (setq window (get-buffer-window nil erc-status-sidebar-singular) 433 (dolist (window (get-buffer-window-list nil nil t))
420 winstart (and window (window-start window))) 434 (push (cons window (window-start window)) windows))
421 (erc-status-sidebar-writable 435 (erc-status-sidebar-writable
422 (delete-region (point-min) (point-max)) 436 (delete-region (point-min) (point-max))
423 (goto-char (point-min)) 437 (goto-char (point-min))
@@ -443,9 +457,8 @@ name stand out."
443 0 cnlen 'help-echo 457 0 cnlen 'help-echo
444 "mouse-1: switch to buffer in other window" channame) 458 "mouse-1: switch to buffer in other window" channame)
445 (funcall insert-fn channame chanbuf chanlist))) 459 (funcall insert-fn channame chanbuf chanlist)))
446 (when winstart 460 (when windows
447 (set-window-point window winstart) 461 (map-apply #'set-window-start windows))
448 (with-selected-window window (recenter 0)))
449 (when (and erc-status-sidebar-highlight-active-buffer 462 (when (and erc-status-sidebar-highlight-active-buffer
450 (marker-buffer erc-status-sidebar--active-marker)) 463 (marker-buffer erc-status-sidebar--active-marker))
451 (goto-char erc-status-sidebar--active-marker) 464 (goto-char erc-status-sidebar--active-marker)
@@ -519,14 +532,28 @@ highlighted."
519 erc-kill-server-hook 532 erc-kill-server-hook
520 erc-kick-hook 533 erc-kick-hook
521 erc-disconnected-hook 534 erc-disconnected-hook
522 erc-quit-hook)) 535 erc-quit-hook)
536 "Hooks to refresh the sidebar on.
537This may be set locally in the status-sidebar buffer under
538various conditions, like when the option
539`erc-status-sidebar-highlight-active-buffer' is non-nil.")
540
541(defvar erc-status-sidebar--highlight-refresh-triggers
542 '(window-selection-change-functions)
543 "Triggers enabled with `erc-status-sidebar-highlight-active-buffer'.")
544
545(defun erc-status-sidebar--refresh-unless-input ()
546 "Run `erc-status-sidebar-refresh' unless there are unread commands.
547Also abstain when the user is interacting with the minibuffer."
548 (unless (or (input-pending-p) (minibuffer-window-active-p (selected-window)))
549 (erc-status-sidebar-refresh)))
523 550
524(defun erc-status-sidebar--post-refresh (&rest _ignore) 551(defun erc-status-sidebar--post-refresh (&rest _ignore)
525 "Schedule sidebar refresh for execution after command stack is cleared. 552 "Schedule sidebar refresh for execution after command stack is cleared.
526 553
527Ignore arguments in IGNORE, allowing this function to be added to 554Ignore arguments in IGNORE, allowing this function to be added to
528hooks that invoke it with arguments." 555hooks that invoke it with arguments."
529 (run-at-time 0 nil #'erc-status-sidebar-refresh)) 556 (run-at-time 0 nil #'erc-status-sidebar--refresh-unless-input))
530 557
531(defun erc-status-sidebar-mode--unhook () 558(defun erc-status-sidebar-mode--unhook ()
532 "Remove hooks installed by `erc-status-sidebar-mode'." 559 "Remove hooks installed by `erc-status-sidebar-mode'."
@@ -541,7 +568,7 @@ hooks that invoke it with arguments."
541Note that preserve status needs to be reset when the window is 568Note that preserve status needs to be reset when the window is
542manually resized, so `erc-status-sidebar-mode' adds this function 569manually resized, so `erc-status-sidebar-mode' adds this function
543to the `window-configuration-change-hook'." 570to the `window-configuration-change-hook'."
544 (when (and (eq (selected-window) (let (erc-status-sidebar-singular) 571 (when (and (eq (selected-window) (let (erc-status-sidebar--singular-p)
545 (erc-status-sidebar-get-window))) 572 (erc-status-sidebar-get-window)))
546 (fboundp 'window-preserve-size)) 573 (fboundp 'window-preserve-size))
547 (unless (eq (window-total-width) (window-min-size nil t)) 574 (unless (eq (window-total-width) (window-min-size nil t))
@@ -563,6 +590,10 @@ to the `window-configuration-change-hook'."
563 590
564 (add-hook 'window-configuration-change-hook 591 (add-hook 'window-configuration-change-hook
565 #'erc-status-sidebar-set-window-preserve-size nil t) 592 #'erc-status-sidebar-set-window-preserve-size nil t)
593 (when erc-status-sidebar-highlight-active-buffer
594 (setq-local erc-status-sidebar-refresh-triggers
595 `(,@erc-status-sidebar--highlight-refresh-triggers
596 ,@erc-status-sidebar-refresh-triggers)))
566 (dolist (hk erc-status-sidebar-refresh-triggers) 597 (dolist (hk erc-status-sidebar-refresh-triggers)
567 (add-hook hk #'erc-status-sidebar--post-refresh)) 598 (add-hook hk #'erc-status-sidebar--post-refresh))
568 599