diff options
| author | F. Jason Park | 2023-07-23 23:09:42 -0700 |
|---|---|---|
| committer | F. Jason Park | 2023-07-28 16:39:04 -0700 |
| commit | deb74de4f2e6a16b81663cbd95f97bfc9e24e467 (patch) | |
| tree | 23ed8051e2b98c1cee6bbe2c61f0531a42633c14 | |
| parent | fb57b6ccb9f033106b0c00539590f22614604f22 (diff) | |
| download | emacs-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.el | 105 |
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 | ||
| 132 | for the above-mentioned purposes. ERC also accepts a list of | 132 | for the above-mentioned purposes. ERC also accepts a list of |
| 133 | functions to preform these roles a la carte. See doc strings for | 133 | functions to preform these roles a la carte. Since the members |
| 134 | a description of their expected arguments and return values." | 134 | of the above sets aren't really interoperable, we don't offer |
| 135 | them here as customization choices, but you can still specify | ||
| 136 | them manually. See doc strings for a description of their | ||
| 137 | expected 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 | 166 | This variable only affects `erc-bufbar-mode'. Disabling it does |
| 164 | :type 'boolean) | 167 | not arrange for automatically showing the sidebar in all frames. |
| 168 | Rather, disabling it allows for displaying the sidebar in the | ||
| 169 | selected 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 | ||
| 179 | If NO-CREATION is non-nil, the window is not created." | 184 | If 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 | |||
| 214 | containing it on the current frame is closed. See | 219 | containing 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. |
| 240 | When enabling, show the sidebar immediately if called from a | 243 | When enabling, show the sidebar immediately in the current frame |
| 241 | connected ERC buffer. Otherwise, arrange for doing so on connect | 244 | if called from a connected ERC buffer. Otherwise, arrange for |
| 242 | or whenever next displaying a new ERC buffer. When disabling, | 245 | doing so on connect or whenever next displaying a new ERC buffer. |
| 243 | hide the status window if it's showing. With a negative prefix | 246 | When disabling, hide the status window in all frames. With a |
| 244 | arg, also shutdown the session." | 247 | negative prefix arg, also shutdown the session. Normally, this |
| 248 | module only allows one sidebar window in an Emacs session. To | ||
| 249 | override this, use `erc-status-sidebar-open' to force creation | ||
| 250 | and `erc-status-sidebar-close' to hide a single instance on the | ||
| 251 | current 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. | ||
| 276 | When `erc-bufbar-mode' is active, do this even if one already | ||
| 277 | exists 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. |
| 270 | Do this regardless of `erc-status-sidebar-singular'." | 285 | When opening, and `erc-bufbar-mode' is active, create a sidebar |
| 286 | even 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. | ||
| 537 | This may be set locally in the status-sidebar buffer under | ||
| 538 | various 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. | ||
| 547 | Also 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 | ||
| 527 | Ignore arguments in IGNORE, allowing this function to be added to | 554 | Ignore arguments in IGNORE, allowing this function to be added to |
| 528 | hooks that invoke it with arguments." | 555 | hooks 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." | |||
| 541 | Note that preserve status needs to be reset when the window is | 568 | Note that preserve status needs to be reset when the window is |
| 542 | manually resized, so `erc-status-sidebar-mode' adds this function | 569 | manually resized, so `erc-status-sidebar-mode' adds this function |
| 543 | to the `window-configuration-change-hook'." | 570 | to 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 | ||