Re: bug#64855: 30.0.50; ERC 5.6: Make scrolltobottom less erratic

"J.P." <[email protected]>
Newsgroups gmane.emacs.erc.general
Message-ID <[email protected]>
v4. Fix bug involving new option `erc-scrolltobottom-relaxed'. Specify
explicit hook depths for `erc--scrolltobottom-on-pre-command{,-relaxed}'
and `erc-move-to-prompt' in `pre-command-hook'. Remove assertions.

This still needs tests and a news entry.
0000-v3-v4.diff (text/x-patch, 7.2 KB)
From 78e5fa32620b386b283f16383f16c713e628a0ff Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <[email protected]>
Date: Fri, 18 Aug 2023 06:36:44 -0700
Subject: [PATCH 0/1] *** NOT A PATCH ***

*** BLURB HERE ***

F. Jason Park (1):
  [5.6] Consider all windows in erc-scrolltobottom-mode

 lisp/erc/erc-goodies.el | 222 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 208 insertions(+), 14 deletions(-)

Interdiff:
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 129e17fb5ec..891641f77f7 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -100,15 +100,15 @@ erc--scrolltobottom-window-info
 `window-point', inclusive.")
 
 (defvar erc--scrolltobottom-post-force-commands
-  '(electric-newline-and-maybe-indent)
+  '(electric-newline-and-maybe-indent default-indent-new-line)
   "Commands that force a scroll after execution at prompt.")
 
-(defvar erc--scrolltobottom-relaxed-skip-commands '(recenter-top-bottom))
+(defvar erc--scrolltobottom-relaxed-skip-commands
+  '(recenter-top-bottom scroll-down-command))
 
 (defun erc--scrolltobottom-on-pre-command ()
-  (cl-assert (not erc-scrolltobottom-relaxed)) ; delete me
-  (cl-assert (eq (selected-window) (get-buffer-window))) ; delete me
-  (when (> (point) erc-input-marker)
+  (when (and (eq (selected-window) (get-buffer-window))
+             (>= (point) erc-input-marker))
     (setq erc--scrolltobottom-window-info
           (list (list (selected-window)
                       (window-start)
@@ -120,17 +120,17 @@ erc--scrolltobottom-on-post-command
 item is associated with the selected window, restore start of
 window so long as prompt hasn't moved.  Expect buffer to be
 unnarrowed."
-  (cl-assert (not erc-scrolltobottom-relaxed)) ; delete me
-  (cl-assert (eq (selected-window) (get-buffer-window))) ; delete me
-  (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)))))
-      (set-window-start (selected-window) (nth 1 found))
-    (erc--scrolltobottom-confirm))
-  (setq erc--scrolltobottom-window-info nil))
+  (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)))))
+        (set-window-start (selected-window) (nth 1 found))
+      (erc--scrolltobottom-confirm))
+    (setq erc--scrolltobottom-window-info nil)))
 
 (defun erc--scrolltobottom-on-pre-command-relaxed ()
   "Maybe scroll to bottom when away from prompt in an unnarrowed buffer.
@@ -139,28 +139,26 @@ erc--scrolltobottom-on-pre-command-relaxed
 `self-insert-command' (assuming `move-to-prompt' is active).
 When at prompt and current command is not `recenter-top-bottom',
 stash `erc--scrolltobottom-window-info' for the selected window."
-  (cl-assert erc-scrolltobottom-relaxed) ; delete me
-  (cl-assert (eq (selected-window) (get-buffer-window))) ; delete me
-  (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)))))))
+  (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."
-  (cl-assert erc-scrolltobottom-relaxed) ; delete me
-  (cl-assert (eq (selected-window) (get-buffer-window))) ; delete me
-  (when-let ((erc--scrolltobottom-window-info)
+  (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))
@@ -217,13 +215,13 @@ erc-add-scroll-to-bottom
                 (cl-pushnew 'self-insert-command
                             erc--scrolltobottom-relaxed-commands))
               (add-hook 'post-command-hook
-                        #'erc--scrolltobottom-on-post-command-relaxed -90 t)
+                        #'erc--scrolltobottom-on-post-command-relaxed 60 t)
               (add-hook 'pre-command-hook ; preempt `move-to-prompt'
-                        #'erc--scrolltobottom-on-pre-command-relaxed -90 t))
+                        #'erc--scrolltobottom-on-pre-command-relaxed 60 t))
           (add-hook 'pre-command-hook
-                    #'erc--scrolltobottom-on-pre-command nil t)
+                    #'erc--scrolltobottom-on-pre-command 60 t)
           (add-hook 'post-command-hook
-                    #'erc--scrolltobottom-on-post-command nil t)))
+                    #'erc--scrolltobottom-on-post-command 60 t)))
     (remove-hook 'window-configuration-change-hook
                  #'erc--scrolltobottom-away-from-prompt t)
     (remove-hook 'pre-command-hook
@@ -246,7 +244,7 @@ erc--scrolltobottom-on-pre-insert
                         (and-let*
                             ((erc-scrolltobottom-relaxed)
                              (c (count-screen-lines (window-start w)
-                                                    (window-point w) nil w)))
+                                                    (point-max) nil w)))
                           (if (= ?\n (char-before (point-max))) (1+ c) c))))
                 (get-buffer-window-list nil nil 'visible))))
 
@@ -328,7 +326,7 @@ erc-move-to-prompt
 
 (defun erc-move-to-prompt-setup ()
   "Initialize the move-to-prompt module."
-  (add-hook 'pre-command-hook #'erc-move-to-prompt nil t))
+  (add-hook 'pre-command-hook #'erc-move-to-prompt 70 t))
 
 ;;; Keep place in unvisited channels
 ;;;###autoload(autoload 'erc-keep-place-mode "erc-goodies" nil t)
-- 
2.41.0
0001-5.6-Consider-all-windows-in-erc-scrolltobottom-mode.patch (text/x-patch, 15.9 KB)
From 78e5fa32620b386b283f16383f16c713e628a0ff Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <[email protected]>
Date: Sat, 22 Jul 2023 00:46:44 -0700
Subject: [PATCH 1/1] [5.6] Consider all windows in erc-scrolltobottom-mode

* lisp/erc/erc-goodies.el (erc-input-line-position): Mention secondary
role when new option `erc-scroll-to-bottom-relaxed' is non-nil.
(erc-scrolltobottom-relaxed): New option to leave the prompt
stationary instead of forcing it to the bottom of the window.
(erc-scrolltobottom-mode, erc-scrolltobottom-enable,
erc-scrolltobottom-disable): Use `erc--scrolltobottom-all' instead
of `erc-possibly-scroll-to-bottom' for `erc-insert-done-hook' and now
also `erc-send-completed-hook'.  Add
`erc--scrolltobottom-on-pre-insert' to `erc-insert-pre-hook' and
`erc-pre-send-functions'.  Call `erc-add-scroll-to-bottom' for
teardown as well.
(erc--scrolltobottom-relaxed-commands,
erc--scrolltobottom-window-info,
erc--scrolltobottom-post-force-commands,
erc--scrolltobottom-relaxed-skip-commands): New internal variables.
(erc--scrolltobottom-on-pre-command
erc--scrolltobottom-on-post-command): New functions resembling
`erc-possibly-scroll-to-bottom' that try to avoid scrolling repeatedly
for no reason.
(erc--scrolltobottom-on-pre-command-relaxed,
erc--scrolltobottom-on-post-command-relaxed): New commands to help
implement `erc-scroll-to-bottom-relaxed'.
(erc--scrolltobottom-away-from-prompt): New function to scroll to
bottom on window configuration changes.
(erc--scrolltobottom-all): New function to scroll all windows
displaying the current buffer.
(erc-add-scroll-to-bottom): Perform teardown as well when mode is
disabled.  Also scroll on `window-configuration-changed-hook'.
(erc--scrolltobottom-on-pre-insert): New generic function that
remembers the last `window-start' and maybe the current line before
inserting a message in order to restore it afterward.
(erc--scrolltobottom-confirm): New function, a replacement for
`erc-scroll-to-bottom', that returns non-nil when it's actually
recentered the window.
(erc-move-to-prompt-setup): Add `erc-move-to-prompt' to
`pre-command-hook' at a depth of 70.
(erc--keep-place-indicator-setup): Add overlay arrow `after-string' in
non-graphical settings in case users have time stamps or other content
occupying the left margin.  (Bug#64855)
---
 lisp/erc/erc-goodies.el | 222 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 208 insertions(+), 14 deletions(-)

diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index d9ededa8e68..891641f77f7 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -44,42 +44,233 @@ erc-input-line-position
 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'."
+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)."
   :group 'erc-display
   :type '(choice integer (const nil)))
 
+(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
+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 initializing the
+`scrolltobottom' module and enabling `erc-scrolltobottom-mode'."
+  :group 'erc-display
+  :package-version '(ERC . "5.6") ; FIXME sync on release
+  :type 'boolean)
+
 ;;;###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-add-scroll-to-bottom)
-   (add-hook 'erc-insert-done-hook #'erc-possibly-scroll-to-bottom)
+   (add-hook 'erc-insert-pre-hook #'erc--scrolltobottom-on-pre-insert)
+   (add-hook 'erc-pre-send-functions #'erc--scrolltobottom-on-pre-insert)
+   (add-hook 'erc-insert-done-hook #'erc--scrolltobottom-all)
+   (add-hook 'erc-send-completed-hook #'erc--scrolltobottom-all)
    (unless erc--updating-modules-p (erc-buffer-do #'erc-add-scroll-to-bottom)))
   ((remove-hook 'erc-mode-hook #'erc-add-scroll-to-bottom)
-   (remove-hook 'erc-insert-done-hook #'erc-possibly-scroll-to-bottom)
-   (dolist (buffer (erc-buffer-list))
-     (with-current-buffer buffer
-       (remove-hook 'post-command-hook #'erc-scroll-to-bottom t)))))
+   (remove-hook 'erc-insert-pre-hook #'erc--scrolltobottom-on-pre-insert)
+   (remove-hook 'erc-pre-send-functions #'erc--scrolltobottom-on-pre-insert)
+   (remove-hook 'erc-insert-done-hook #'erc--scrolltobottom-all)
+   (remove-hook 'erc-send-completed-hook #'erc--scrolltobottom-all)
+   (erc-buffer-do #'erc-add-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 force scroll to prompt.
+Only applies with `erc-scrolltobottom-relaxed' when 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
+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
+  '(electric-newline-and-maybe-indent default-indent-new-line)
+  "Commands that force a scroll after execution at prompt.")
+
+(defvar erc--scrolltobottom-relaxed-skip-commands
+  '(recenter-top-bottom scroll-down-command))
+
+(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)))))))
+
+(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
+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)))))
+        (set-window-start (selected-window) (nth 1 found))
+      (erc--scrolltobottom-confirm))
+    (setq erc--scrolltobottom-window-info nil)))
+
+(defun erc--scrolltobottom-on-pre-command-relaxed ()
+  "Maybe scroll to bottom when away from prompt in an unnarrowed buffer.
+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 is not `recenter-top-bottom',
+stash `erc--scrolltobottom-window-info' for the selected window."
+  (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)))
+    (setq erc--scrolltobottom-window-info nil)))
+
+;; FIXME this is currently of little value because it doesn't restore
+;; the relative position of window point after changing dimensions.
+;; It would be preferable to instead stash the previous ratio of
+;; window line to body height and later recenter proportionally.  But
+;; that may not be worth the added bookkeeping.
+(defun erc--scrolltobottom-away-from-prompt ()
+  "Scroll to bottom unless at prompt."
+  (unless (input-pending-p)
+    (erc--scrolltobottom-confirm)))
+
+(defun erc--scrolltobottom-all (&rest _)
+  "Maybe put prompt on last line in all windows displaying current buffer.
+Expect to run when narrowing is in effect, such as on insertion
+or send-related hooks.  When recentering has not been performed,
+attempt to restore last `window-start', if known."
+  (dolist (window (get-buffer-window-list nil nil 'visible))
+    (with-selected-window window
+      (when-let
+          ((erc--scrolltobottom-window-info)
+           (found (assq window erc--scrolltobottom-window-info))
+           ((not (erc--scrolltobottom-confirm (nth 2 found)))))
+        (setf (window-start window) (cadr found)))))
+  ;; Necessary unless we're sure `erc--scrolltobottom-on-pre-insert'
+  ;; always runs between calls to this function.
+  (setq erc--scrolltobottom-window-info nil))
+
 (defun erc-add-scroll-to-bottom ()
-  "A hook function for `erc-mode-hook' to recenter output at bottom of window.
+  "Arrange for scrolling to bottom on window configuration changes.
+Undo that arrangement when disabling `erc-scrolltobottom-mode'.
 
 If you find that ERC hangs when using this function, try customizing
 the value of `erc-input-line-position'.
 
-This works whenever scrolling happens, so it's added to
-`window-scroll-functions' rather than `erc-insert-post-hook'."
-  (add-hook 'post-command-hook #'erc-scroll-to-bottom nil t))
+Note that the prior suggestion comes from a time when this
+function used `window-scroll-functions', which was replaced by
+`post-command-hook' in ERC 5.3."
+  (if erc-scrolltobottom-mode
+      (progn
+        (add-hook 'window-configuration-change-hook
+                  #'erc--scrolltobottom-away-from-prompt nil t)
+        (if erc-scrolltobottom-relaxed
+            (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 'pre-command-hook
+                    #'erc--scrolltobottom-on-pre-command 60 t)
+          (add-hook 'post-command-hook
+                    #'erc--scrolltobottom-on-post-command 60 t)))
+    (remove-hook 'window-configuration-change-hook
+                 #'erc--scrolltobottom-away-from-prompt 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 'erc--scrolltobottom-window-info)))
+
+(cl-defmethod erc--scrolltobottom-on-pre-insert (_input-or-string)
+  "Remember the `window-start' before inserting a message."
+  (setq erc--scrolltobottom-window-info
+        (mapcar (lambda (w)
+                  (list w
+                        (window-start w)
+                        (and-let*
+                            ((erc-scrolltobottom-relaxed)
+                             (c (count-screen-lines (window-start w)
+                                                    (point-max) nil w)))
+                          (if (= ?\n (char-before (point-max))) (1+ c) c))))
+                (get-buffer-window-list nil nil 'visible))))
+
+(cl-defmethod erc--scrolltobottom-on-pre-insert ((input erc-input))
+  "Remember the `window-start' before inserting a message."
+  (when (erc-input-insertp input)
+    (cl-call-next-method)))
+
+(defun erc--scrolltobottom-confirm (&optional scroll-to)
+  "Like `erc-scroll-to-bottom', but use `window-point'.
+Expect to run in some window, not necessarily the user-selected
+one.  Scroll to SCROLL-TO (or 0) lines from the window's top.
+Return non-nil when recentering has occurred."
+  (when erc-insert-marker
+    (let ((resize-mini-windows nil))
+      (save-restriction
+        (widen)
+        (when (>= (window-point) erc-input-marker)
+          (save-excursion
+            (goto-char (point-max))
+            (recenter (+ (or scroll-to 0) (or erc-input-line-position -1)))
+            t))))))
 
 (defun erc-scroll-to-bottom ()
   "Recenter WINDOW so that `point' is on the last line.
 
-This is added to `window-scroll-functions' by `erc-add-scroll-to-bottom'.
-
 You can control which line is recentered to by customizing the
 variable `erc-input-line-position'."
       ;; Temporarily bind resize-mini-windows to nil so that users who have it
@@ -135,7 +326,7 @@ erc-move-to-prompt
 
 (defun erc-move-to-prompt-setup ()
   "Initialize the move-to-prompt module."
-  (add-hook 'pre-command-hook #'erc-move-to-prompt nil t))
+  (add-hook 'pre-command-hook #'erc-move-to-prompt 70 t))
 
 ;;; Keep place in unvisited channels
 ;;;###autoload(autoload 'erc-keep-place-mode "erc-goodies" nil t)
@@ -213,12 +404,15 @@ erc--keep-place-indicator-setup
   (add-hook 'window-configuration-change-hook
             #'erc--keep-place-indicator-on-window-configuration-change nil t)
   (when-let* (((memq erc-keep-place-indicator-style '(t arrow)))
+              (ov-property (if (zerop (fringe-columns 'left))
+                               'after-string
+                             'before-string))
               (display (if (zerop (fringe-columns 'left))
                            `((margin left-margin) ,overlay-arrow-string)
                          '(left-fringe right-triangle
                                        erc-keep-place-indicator-arrow)))
               (bef (propertize " " 'display display)))
-    (overlay-put erc--keep-place-indicator-overlay 'before-string bef))
+    (overlay-put erc--keep-place-indicator-overlay ov-property bef))
   (when (memq erc-keep-place-indicator-style '(t face))
     (overlay-put erc--keep-place-indicator-overlay 'face
                  'erc-keep-place-indicator-line)))
-- 
2.41.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.