Skip post-minibuffer restore in erc-scrolltobottom-all
* etc/ERC-NEWS: Remove mention of `erc-scrolltobottom-relaxed' in entry for module `scrolltobottom'. * lisp/erc/erc-goodies.el (erc-input-line-position): Fix mention of abandoned option `erc-scrolltobottom-relaxed'. (erc-scrolltobottom-all): Subsume option `erc-scrolltobottom-relaxed' by recognizing a third value state, `relaxed'. A separate option would make more sense if other options also depended on `erc-scrolltobottom-all'. (erc-scrolltobottom-relaxed): Remove redundant option, which was to be new in ERC 5.6. (erc-scrolltobottom-enable, erc-scrolltobottom-mode): Warn if user attempts to enable `erc-scrolltobottom-all' on Emacs 27, which is not supported. (erc--scrolltobottom-relaxed-commands, erc--scrolltobottom-post-force-commands, erc--scrolltobottom-relaxed-skip-commands): Remove unused variables. (erc--scrolltobottom-on-pre-command, erc--scrolltobottom-on-pre-command-relaxed, erc--scrolltobottom-on-post-command-relaxed): Remove unused functions. (erc--scrolltobottom-on-post-command): Remove conditional branch for dealing with a non-nil `erc--scrolltobottom-window-info'. (erc--scrolltobottom-setup): Convert from generic to normal function and remove setup and teardown for unused hooks. Set variable `read-minibuffer-restore-windows' locally when option `erc-scrolltobottom-all' is non-nil. (erc--scrolltobottom-on-pre-insert): Replace reference to subsumed option `erc-scrolltobottom-relaxed' with new value `relaxed' for existing option `erc-scrolltobottom-all'. * test/lisp/erc/erc-scenarios-scrolltobottom-relaxed.el (erc-scenarios-scrolltobottom--relaxed): Replace option `erc-scrolltobottom-relaxed' with new value `relaxed' for `erc-scrolltobottom-all'. (Bug#64855)
This commit is contained in:
parent
bd29713201
commit
328a985651
3 changed files with 60 additions and 159 deletions
15
etc/ERC-NEWS
15
etc/ERC-NEWS
|
|
@ -178,14 +178,13 @@ been restored with a slightly revised role contingent on a few
|
|||
assumptions explained in its doc string. For clarity, it has been
|
||||
renamed 'erc-ensure-target-buffer-on-privmsg'.
|
||||
|
||||
** Module 'scrolltobottom' can attempt to be more aggressive.
|
||||
Enabling the experimental option 'erc-scrolltobottom-all' tells
|
||||
'scrolltobottom' to be more vigilant about staking down the input area
|
||||
and to do so in all ERC windows. The dependent option
|
||||
'erc-scrolltobottom-relaxed', also experimental, makes ERC's prompt
|
||||
stationary wherever it happens to reside instead of forcing it to the
|
||||
bottom of a window. That is, new input appears above the prompt,
|
||||
scrolling existing messages upward to compensate.
|
||||
** Module 'scrolltobottom' now optionally more aggressive.
|
||||
Enabling the experimental option 'erc-scrolltobottom-all' makes ERC
|
||||
more vigilant about staking down the input area in all ERC windows.
|
||||
And the option's 'relaxed' variant makes ERC's prompt stationary
|
||||
wherever it happens to reside instead of forcing it to the bottom of a
|
||||
window, meaning new input appears above the prompt, scrolling existing
|
||||
messages upward to compensate.
|
||||
|
||||
** Subtle changes in two fundamental faces.
|
||||
Users of the default theme may notice that 'erc-action-face' and
|
||||
|
|
|
|||
|
|
@ -44,45 +44,46 @@
|
|||
This should be an integer specifying the line of the buffer on which
|
||||
the input line should stay. A value of \"-1\" would keep the input
|
||||
line positioned on the last line in the buffer. This is passed as an
|
||||
argument to `recenter', unless `erc-scrolltobottom-relaxed' is
|
||||
non-nil, in which case, ERC interprets it as additional lines to
|
||||
scroll down by per message insertion (minus one for the prompt)."
|
||||
argument to `recenter', unless `erc-scrolltobottom-all' is
|
||||
`relaxed', in which case, ERC interprets it as additional lines
|
||||
to scroll down by per message insertion (minus one for the
|
||||
prompt)."
|
||||
:group 'erc-display
|
||||
:type '(choice integer (const nil)))
|
||||
|
||||
(defcustom erc-scrolltobottom-all nil
|
||||
"Whether to scroll all windows or just the selected one.
|
||||
A value of nil preserves pre-5.6 behavior, in which scrolling
|
||||
only affects the selected window. Users should consider its
|
||||
non-nil behavior experimental for the time being. Note also that
|
||||
ERC expects this option to be configured before module
|
||||
initialization."
|
||||
:group 'erc-display
|
||||
:package-version '(ERC . "5.6") ; FIXME sync on release
|
||||
:type 'boolean)
|
||||
initialization. A value of nil preserves pre-5.6 behavior, in
|
||||
which scrolling only affects the selected window. A value of t
|
||||
means ERC attempts to recenter all visible windows whose point
|
||||
resides in the input area.
|
||||
|
||||
(defcustom erc-scrolltobottom-relaxed nil
|
||||
"Whether to forgo forcing prompt to the bottom of the window.
|
||||
When non-nil, and point is at the prompt, ERC scrolls the window
|
||||
up when inserting messages, making the prompt appear stationary.
|
||||
Users who find this effect too \"stagnant\" can adjust the option
|
||||
`erc-input-line-position', which ERC borrows to express a scroll
|
||||
step offset when this option is non-nil. Setting that value to
|
||||
zero lets the prompt drift toward the bottom by one line per
|
||||
message, which is generally slow enough not to distract while
|
||||
composing input. Of course, this doesn't apply when receiving a
|
||||
large influx of messages, such as after typing \"/msg NickServ
|
||||
help\". Note that ERC only considers this option when the
|
||||
experimental companion option `erc-scrolltobottom-all' is enabled
|
||||
and, only then, during module setup."
|
||||
A value of `relaxed' tells ERC to forgo forcing prompt to the
|
||||
bottom of the window. When point is at the prompt, ERC scrolls
|
||||
the window up when inserting messages, making the prompt appear
|
||||
stationary. Users who find this effect too \"stagnant\" can
|
||||
adjust the option `erc-input-line-position', borrowed here to
|
||||
express a scroll step offset. Setting that value to zero lets
|
||||
the prompt drift toward the bottom by one line per message, which
|
||||
is generally slow enough not to distract while composing input.
|
||||
Of course, this doesn't apply when receiving a large influx of
|
||||
messages, such as after typing \"/msg NickServ help\".
|
||||
|
||||
Note that users should consider this option's non-nil behavior to
|
||||
be experimental. It currently only works with Emacs 28+."
|
||||
:group 'erc-display
|
||||
:package-version '(ERC . "5.6") ; FIXME sync on release
|
||||
:type 'boolean)
|
||||
:type '(choice boolean (const relaxed)))
|
||||
|
||||
;;;###autoload(autoload 'erc-scrolltobottom-mode "erc-goodies" nil t)
|
||||
(define-erc-module scrolltobottom nil
|
||||
"This mode causes the prompt to stay at the end of the window."
|
||||
((add-hook 'erc-mode-hook #'erc--scrolltobottom-setup)
|
||||
(when (and erc-scrolltobottom-all (< emacs-major-version 28))
|
||||
(erc-button--display-error-notice-with-keys
|
||||
"Option `erc-scrolltobottom-all' requires Emacs 28+. Disabling.")
|
||||
(setopt erc-scrolltobottom-all nil))
|
||||
(unless erc--updating-modules-p (erc-buffer-do #'erc--scrolltobottom-setup))
|
||||
(if erc-scrolltobottom-all
|
||||
(progn
|
||||
|
|
@ -93,25 +94,17 @@ and, only then, during module setup."
|
|||
(add-hook 'erc-insert-done-hook #'erc-possibly-scroll-to-bottom)))
|
||||
((remove-hook 'erc-mode-hook #'erc--scrolltobottom-setup)
|
||||
(erc-buffer-do #'erc--scrolltobottom-setup)
|
||||
(if erc-scrolltobottom-all
|
||||
(progn
|
||||
(remove-hook 'erc-insert-pre-hook #'erc--scrolltobottom-on-pre-insert)
|
||||
(remove-hook 'erc-send-completed-hook #'erc--scrolltobottom-all)
|
||||
(remove-hook 'erc-insert-done-hook #'erc--scrolltobottom-all)
|
||||
(remove-hook 'erc-pre-send-functions
|
||||
#'erc--scrolltobottom-on-pre-insert))
|
||||
(remove-hook 'erc-insert-done-hook #'erc-possibly-scroll-to-bottom))))
|
||||
(remove-hook 'erc-insert-pre-hook #'erc--scrolltobottom-on-pre-insert)
|
||||
(remove-hook 'erc-send-completed-hook #'erc--scrolltobottom-all)
|
||||
(remove-hook 'erc-insert-done-hook #'erc--scrolltobottom-all)
|
||||
(remove-hook 'erc-pre-send-functions #'erc--scrolltobottom-on-pre-insert)
|
||||
(remove-hook 'erc-insert-done-hook #'erc-possibly-scroll-to-bottom)))
|
||||
|
||||
(defun erc-possibly-scroll-to-bottom ()
|
||||
"Like `erc-add-scroll-to-bottom', but only if window is selected."
|
||||
(when (eq (selected-window) (get-buffer-window))
|
||||
(erc-scroll-to-bottom)))
|
||||
|
||||
(defvar-local erc--scrolltobottom-relaxed-commands '(end-of-buffer)
|
||||
"Commands triggering a forced scroll to prompt.
|
||||
Only applies with `erc-scrolltobottom-relaxed' while away from
|
||||
prompt.")
|
||||
|
||||
(defvar-local erc--scrolltobottom-window-info nil
|
||||
"Alist with windows as keys and lists of window-related info as values.
|
||||
Values are lists containing the last window start position and
|
||||
|
|
@ -119,34 +112,12 @@ the last \"window line\" of point. The \"window line\", which
|
|||
may be nil, is the number of lines between `window-start' and
|
||||
`window-point', inclusive.")
|
||||
|
||||
(defvar erc--scrolltobottom-post-force-commands
|
||||
'(beginning-of-buffer
|
||||
electric-newline-and-maybe-indent
|
||||
newline
|
||||
default-indent-new-line)
|
||||
"Commands that force a scroll after execution at prompt.
|
||||
That is, ERC recalculates the window's start instead of blindly
|
||||
restoring it.")
|
||||
|
||||
;; Unfortunately, this doesn't work when `erc-scrolltobottom-relaxed'
|
||||
;; is enabled (scaling up still moves the prompt).
|
||||
;; FIXME treat `end-of-buffer' specially and always recenter -1.
|
||||
;; FIXME make this work when `erc-scrolltobottom-all' is set to
|
||||
;; `relaxed'.
|
||||
(defvar erc--scrolltobottom-post-ignore-commands '(text-scale-adjust)
|
||||
"Commands to skip instead of force-scroll on `post-command-hook'.")
|
||||
|
||||
(defvar erc--scrolltobottom-relaxed-skip-commands
|
||||
'(recenter-top-bottom scroll-down-command)
|
||||
"Commands exempt from triggering a stash and restore of `window-start'.
|
||||
Only applies with `erc-scrolltobottom-relaxed' while in the input
|
||||
area.")
|
||||
|
||||
(defun erc--scrolltobottom-on-pre-command ()
|
||||
(when (and (eq (selected-window) (get-buffer-window))
|
||||
(>= (point) erc-input-marker))
|
||||
(setq erc--scrolltobottom-window-info
|
||||
(list (list (selected-window)
|
||||
(window-start)
|
||||
(count-screen-lines (window-start) (point-max)))))))
|
||||
|
||||
(defun erc--scrolltobottom-on-post-command ()
|
||||
"Restore window start or scroll to prompt and recenter.
|
||||
When `erc--scrolltobottom-window-info' is non-nil and its first
|
||||
|
|
@ -154,55 +125,8 @@ item is associated with the selected window, restore start of
|
|||
window so long as prompt hasn't moved. Expect buffer to be
|
||||
unnarrowed."
|
||||
(when (eq (selected-window) (get-buffer-window))
|
||||
(if-let (((not (input-pending-p)))
|
||||
(erc--scrolltobottom-window-info)
|
||||
(found (car erc--scrolltobottom-window-info))
|
||||
((eq (car found) (selected-window)))
|
||||
((not (memq this-command
|
||||
erc--scrolltobottom-post-force-commands)))
|
||||
((= (nth 2 found)
|
||||
(count-screen-lines (window-start) (point-max)))))
|
||||
(set-window-start (selected-window) (nth 1 found))
|
||||
(unless (memq this-command erc--scrolltobottom-post-ignore-commands)
|
||||
(erc--scrolltobottom-confirm)))
|
||||
(setq erc--scrolltobottom-window-info nil)))
|
||||
|
||||
(defun erc--scrolltobottom-on-pre-command-relaxed ()
|
||||
"Maybe scroll to bottom when away from prompt.
|
||||
When `erc-scrolltobottom-relaxed' is active, only scroll when
|
||||
prompt is past window's end and the command is `end-of-buffer' or
|
||||
`self-insert-command' (assuming `move-to-prompt' is active).
|
||||
When at prompt and current command does not appear in
|
||||
`erc--scrolltobottom-relaxed-skip-commands', stash
|
||||
`erc--scrolltobottom-window-info' for the selected window.
|
||||
Assume an unnarrowed buffer."
|
||||
(when (eq (selected-window) (get-buffer-window))
|
||||
(when (and (not (input-pending-p))
|
||||
(< (point) erc-input-marker)
|
||||
(memq this-command erc--scrolltobottom-relaxed-commands)
|
||||
(< (window-end nil t) erc-input-marker))
|
||||
(save-excursion
|
||||
(goto-char (point-max))
|
||||
(recenter (or erc-input-line-position -1))))
|
||||
(when (and (>= (point) erc-input-marker)
|
||||
(not (memq this-command
|
||||
erc--scrolltobottom-relaxed-skip-commands)))
|
||||
(setq erc--scrolltobottom-window-info
|
||||
(list (list (selected-window)
|
||||
(window-start)
|
||||
(count-screen-lines (window-start) (point-max))))))))
|
||||
|
||||
(defun erc--scrolltobottom-on-post-command-relaxed ()
|
||||
"Set window start or scroll when data was captured on pre-command."
|
||||
(when-let (((eq (selected-window) (get-buffer-window)))
|
||||
(erc--scrolltobottom-window-info)
|
||||
(found (car erc--scrolltobottom-window-info))
|
||||
((eq (car found) (selected-window))))
|
||||
(if (and (not (memq this-command erc--scrolltobottom-post-force-commands))
|
||||
(= (nth 2 found)
|
||||
(count-screen-lines (window-start) (point-max))))
|
||||
(set-window-start (selected-window) (nth 1 found))
|
||||
(recenter (nth 2 found)))
|
||||
(unless (memq this-command erc--scrolltobottom-post-ignore-commands)
|
||||
(erc--scrolltobottom-confirm))
|
||||
(setq erc--scrolltobottom-window-info nil)))
|
||||
|
||||
;; It may be desirable to also restore the relative line position of
|
||||
|
|
@ -246,54 +170,33 @@ function used `window-scroll-functions', which was replaced by
|
|||
(declare (obsolete erc--scrolltobottom-setup "30.1"))
|
||||
(add-hook 'post-command-hook #'erc-scroll-to-bottom nil t))
|
||||
|
||||
(cl-defgeneric erc--scrolltobottom-setup ()
|
||||
"Arrange for scrolling to bottom on window configuration changes.
|
||||
Undo that arrangement when disabling `erc-scrolltobottom-mode'."
|
||||
(defun erc--scrolltobottom-setup ()
|
||||
"Perform buffer-local setup for module `scrolltobottom'."
|
||||
(if erc-scrolltobottom-mode
|
||||
(add-hook 'post-command-hook #'erc-scroll-to-bottom nil t)
|
||||
(remove-hook 'post-command-hook #'erc-scroll-to-bottom t)))
|
||||
|
||||
(cl-defmethod erc--scrolltobottom-setup (&context
|
||||
(erc-scrolltobottom-all (eql t)))
|
||||
"Add and remove local hooks specific to `erc-scrolltobottom-all'."
|
||||
(if erc-scrolltobottom-mode
|
||||
(if erc-scrolltobottom-relaxed
|
||||
(if erc-scrolltobottom-all
|
||||
(progn
|
||||
(when (or (bound-and-true-p erc-move-to-prompt-mode)
|
||||
(memq 'move-to-prompt erc-modules))
|
||||
(cl-pushnew 'self-insert-command
|
||||
erc--scrolltobottom-relaxed-commands))
|
||||
(add-hook 'post-command-hook
|
||||
#'erc--scrolltobottom-on-post-command-relaxed 60 t)
|
||||
(add-hook 'pre-command-hook ; preempt `move-to-prompt'
|
||||
#'erc--scrolltobottom-on-pre-command-relaxed 60 t))
|
||||
(add-hook 'window-configuration-change-hook
|
||||
#'erc--scrolltobottom-at-prompt-minibuffer-active nil t)
|
||||
(add-hook 'pre-command-hook
|
||||
#'erc--scrolltobottom-on-pre-command 60 t)
|
||||
(add-hook 'post-command-hook
|
||||
#'erc--scrolltobottom-on-post-command 60 t))
|
||||
(setq-local read-minibuffer-restore-windows nil)
|
||||
(unless (eq erc-scrolltobottom-all 'relaxed)
|
||||
(add-hook 'window-configuration-change-hook
|
||||
#'erc--scrolltobottom-at-prompt-minibuffer-active 50 t)
|
||||
(add-hook 'post-command-hook
|
||||
#'erc--scrolltobottom-on-post-command 50 t)))
|
||||
(add-hook 'post-command-hook #'erc-scroll-to-bottom nil t))
|
||||
(remove-hook 'post-command-hook #'erc-scroll-to-bottom t)
|
||||
(remove-hook 'post-command-hook #'erc--scrolltobottom-on-post-command t)
|
||||
(remove-hook 'window-configuration-change-hook
|
||||
#'erc--scrolltobottom-at-prompt-minibuffer-active t)
|
||||
(remove-hook 'pre-command-hook
|
||||
#'erc--scrolltobottom-on-pre-command t)
|
||||
(remove-hook 'post-command-hook
|
||||
#'erc--scrolltobottom-on-post-command t)
|
||||
(remove-hook 'pre-command-hook
|
||||
#'erc--scrolltobottom-on-pre-command-relaxed t)
|
||||
(remove-hook 'post-command-hook
|
||||
#'erc--scrolltobottom-on-post-command-relaxed t)
|
||||
(kill-local-variable 'erc--scrolltobottom-relaxed-commands)
|
||||
(kill-local-variable 'read-minibuffer-restore-windows)
|
||||
(kill-local-variable 'erc--scrolltobottom-window-info)))
|
||||
|
||||
(defun erc--scrolltobottom-on-pre-insert (_)
|
||||
"Remember the `window-start' before inserting a message."
|
||||
"Remember `window-start' before inserting a message."
|
||||
(setq erc--scrolltobottom-window-info
|
||||
(mapcar (lambda (w)
|
||||
(list w
|
||||
(window-start w)
|
||||
(and-let*
|
||||
((erc-scrolltobottom-relaxed)
|
||||
(((eq erc-scrolltobottom-all 'relaxed))
|
||||
(c (count-screen-lines (window-start w)
|
||||
(point-max) nil w)))
|
||||
(if (= ?\n (char-before (point-max))) (1+ c) c))))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;;; erc-scenarios-scrolltobottom-relaxed.el --- erc-scrolltobottom-relaxed -*- lexical-binding: t -*-
|
||||
;;; erc-scenarios-scrolltobottom-relaxed.el --- erc-scrolltobottom-all relaxed -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
|
|
@ -40,8 +40,7 @@
|
|||
(dumb-server (erc-d-run "localhost" t 'help))
|
||||
(port (process-contact dumb-server :service))
|
||||
(erc-modules `(scrolltobottom fill-wrap ,@erc-modules))
|
||||
(erc-scrolltobottom-all t)
|
||||
(erc-scrolltobottom-relaxed t)
|
||||
(erc-scrolltobottom-all 'relaxed)
|
||||
(erc-server-flood-penalty 0.1)
|
||||
(expect (erc-d-t-make-expecter))
|
||||
lower upper)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue