all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#59943: 30.0.50; ERC 5.5+: Add visual indicator to ERC keep-place
@ 2022-12-10 15:52 J.P.
  0 siblings, 0 replies; 8+ messages in thread
From: J.P. @ 2022-12-10 15:52 UTC (permalink / raw)
  To: 59943; +Cc: emacs-erc

[-- Attachment #1: Type: text/plain, Size: 3711 bytes --]

Tags: patch

Hi people,

There's been some recent talk regarding ERC's lack of a visual element
to demarcate the boundary between seen and unseen messages in a target
buffer. This approach leverages the existing `keep-place' module located
in erc-goodies. (But perhaps there's a smarter way?) Improvements or
replacements welcome, as always.

Thanks,
J.P.


In GNU Emacs 30.0.50 (build 2, x86_64-pc-linux-gnu, GTK+ Version
 3.24.35, cairo version 1.17.6) of 2022-12-10 built on localhost
Repository revision: 9c670695b91deb3424a74cd2b0f6a37356a4efcc
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12014000
System Description: Fedora Linux 36 (Workstation Edition)

Configured using:
 'configure --enable-check-lisp-object-type --enable-checking=yes,glyphs
 'CFLAGS=-O0 -g3'
 PKG_CONFIG_PATH=:/usr/lib64/pkgconfig:/usr/share/pkgconfig'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES NOTIFY
INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: @im=ibus
  locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message mailcap yank-media puny dired
dired-loaddefs rfc822 mml mml-sec epa derived epg rfc6068 epg-config
gnus-util text-property-search mm-decode mm-bodies mm-encode mail-parse
rfc2231 mailabbrev gmm-utils mailheader sendmail rfc2047 rfc2045
ietf-drums mm-util mail-prsvr mail-utils erc iso8601 time-date
auth-source cl-seq eieio eieio-core cl-macs password-cache json subr-x
map thingatpt pp format-spec cl-loaddefs cl-lib erc-backend erc-goodies
erc-networks byte-opt gv bytecomp byte-compile erc-common erc-compat
erc-loaddefs rmc iso-transl tooltip cconv eldoc paren electric uniquify
ediff-hook vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win
term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode lisp-mode prog-mode register
page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads dbusbind inotify lcms2 dynamic-setting system-font-setting
font-render-setting cairo move-toolbar gtk x-toolkit xinput2 x multi-tty
make-network-process emacs)

Memory information:
((conses 16 64369 5963)
 (symbols 48 8607 0)
 (strings 32 23642 2119)
 (string-bytes 1 684025)
 (vectors 16 15217)
 (vector-slots 8 208839 8628)
 (floats 8 24 27)
 (intervals 56 227 0)
 (buffers 984 11))


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-option-to-show-visual-erc-keep-place-indicator.patch --]
[-- Type: text/x-patch, Size: 7360 bytes --]

From 685e151fa4565970683cd76eb111afd308d1b531 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Fri, 9 Dec 2022 22:00:59 -0800
Subject: [PATCH] Add option to show visual erc-keep-place indicator

* etc/ERC-NEWS: Create new section for version 5.6 and mention
keep-place indicator.
* lisp/erc/erc-goodies.el (erc-keep-place-indicator,
erc-keep-place-indicator-follow): New options for anchoring kept place
visually.
(erc-keep-place-indicator-line, erc-keep-place-indicator-arrow): New
faces.
(erc--keep-place-overlay): New internal local state var.
(erc--keep-place-on-window-configuration-change): New function to
subscribe to `window-configuration-change-hook' and maybe update
keep-place indicator.
(erc--keep-place-setup-overlay): New function to initialize buffer for
option `erc-keep-place-indicator'.
(erc-keep-place-enable, erc-keep-place-disable): Add setup and
teardown to support `erc-keep-place-indicator'.
(erc-keep-place-move, erc-keep-place-goto): Add new commands for
manually updating and jumping to keep-place indicator.
(erc-keep-place): Move `erc--keep-place-overlay' when applicable.
---
 etc/ERC-NEWS            |  10 ++++
 lisp/erc/erc-goodies.el | 102 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 110 insertions(+), 2 deletions(-)

diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS
index d0d84d0a98..af1cfcacea 100644
--- a/etc/ERC-NEWS
+++ b/etc/ERC-NEWS
@@ -11,6 +11,16 @@ This file is about changes in ERC, the powerful, modular, and
 extensible IRC (Internet Relay Chat) client distributed with
 GNU Emacs since Emacs version 22.1.
 
+\f
+* Changes in ERC 5.6
+
+** Module 'keep-place' now offers a visual indicator.
+
+Remember your place in a target buffer a bit more easily while also
+having the freedom to roam.  Optionally sync the indicator manually if
+you've made progress but still haven't caught up to the live stream.
+See new option 'erc-keep-place-indicator'.
+
 \f
 * Changes in ERC 5.5
 
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 1af83b58ba..18e9f665bd 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -46,6 +46,7 @@ erc-log-p
 (declare-function erc-error "erc" (&rest args))
 (declare-function erc-extract-command-from-line "erc" (line))
 (declare-function erc-beg-of-input-line "erc" nil)
+(declare-function erc-default-target "erc" nil)
 
 (defun erc-imenu-setup ()
   "Setup Imenu support in an ERC buffer."
@@ -154,11 +155,106 @@ erc-move-to-prompt-setup
   "Initialize the move-to-prompt module."
   (add-hook 'pre-command-hook #'erc-move-to-prompt nil t))
 
+(defcustom erc-keep-place-indicator nil
+  "Show kept place with visual indicator in target buffers.
+For use with the `keep-place' module.  A value of `arrow'
+displays an arrow in the left fringe or margin.  A value of
+`face' applies `erc-keep-place-indicator-line' to the appropriate
+line.  A value of t does both.  A value of nil does neither."
+  :group 'erc
+  :package-version '(ERC . "5.6")
+  :type '(choice (const nil) (const t) (const face) (const arrow)))
+
+(defcustom erc-keep-place-indicator-follow nil
+  "Whether to sync visual kept place to window's top when reading."
+  :group 'erc
+  :package-version '(ERC . "5.6")
+  :type 'boolean)
+
+(defface erc-keep-place-indicator-line
+  '((((class color) (min-colors 88) (background light)
+      (supports :underline (:style wave)))
+     (:underline (:color "PaleGreen3" :style wave)))
+    (((class color) (min-colors 88) (background dark)
+      (supports :underline (:style wave)))
+     (:underline (:color "PaleGreen1" :style wave)))
+    (t :underline t))
+  "Face for option `erc-keep-place-indicator'."
+  :group 'erc-faces)
+
+(defface erc-keep-place-indicator-arrow
+  '((((class color) (min-colors 88) (background light))
+     (:foreground "PaleGreen3"))
+    (((class color) (min-colors 88) (background dark))
+     (:foreground "PaleGreen1"))
+    (t :inherit fringe))
+  "Face for arrow value of option `erc-keep-place-indicator'."
+  :group 'erc-faces)
+
+(defvar-local erc--keep-place-overlay nil
+  "Overlay for option `erc-keep-place-indicator'.")
+
+(defun erc--keep-place-on-window-configuration-change ()
+  "Maybe sync `erc--keep-place-overlay'."
+  (when erc-keep-place-indicator-follow
+    (unless (minibuffer-window-active-p (minibuffer-window))
+      (when (< (overlay-end erc--keep-place-overlay)
+               (window-start)
+               erc-insert-marker)
+        (erc-keep-place-move (window-start))))))
+
+(defun erc--keep-place-setup-overlay ()
+  (when (erc-default-target)
+    (add-hook 'window-configuration-change-hook
+              #'erc--keep-place-on-window-configuration-change nil t)
+    (setq erc--keep-place-overlay (make-overlay 0 0))
+    (when (memq erc-keep-place-indicator '(t arrow))
+      (overlay-put erc--keep-place-overlay 'before-string
+                   (propertize
+                    " "
+                    'display
+                    (if (zerop (fringe-columns 'left))
+                        `((margin left-margin) ,overlay-arrow-string)
+                      '(left-fringe right-triangle
+                                    erc-keep-place-indicator-arrow)))))
+    (when (memq erc-keep-place-indicator '(t face))
+      (overlay-put erc--keep-place-overlay 'face
+                   'erc-keep-place-indicator-line))))
+
 ;;; Keep place in unvisited channels
 (define-erc-module keep-place nil
   "Leave point above un-viewed text in other channels."
-  ((add-hook 'erc-insert-pre-hook  #'erc-keep-place))
-  ((remove-hook 'erc-insert-pre-hook  #'erc-keep-place)))
+  ((add-hook 'erc-insert-pre-hook  #'erc-keep-place)
+   (when erc-keep-place-indicator
+     (if (derived-mode-p 'erc-mode)
+         (erc--keep-place-setup-overlay)
+       (add-hook 'erc-mode-hook #'erc--keep-place-setup-overlay))))
+  ((remove-hook 'erc-insert-pre-hook  #'erc-keep-place)
+   (when erc-keep-place-indicator
+     (remove-hook 'erc-mode-hook #'erc--keep-place-setup-overlay)
+     (erc-with-all-buffers-of-server erc-server-process nil
+       (when erc--keep-place-overlay
+         (delete-overlay erc--keep-place-overlay)
+         (remove-hook 'window-configuration-change-hook
+                      #'erc--keep-place-on-window-configuration-change t)
+         (kill-local-variable 'erc--keep-place-overlay))))))
+
+(defun erc-keep-place-move (&optional pos)
+  "Move keep-place indicator to the current line."
+  (interactive "P")
+  (save-excursion
+    (let ((inhibit-field-text-motion t))
+      (when (numberp pos)
+        (goto-char pos))
+      (move-overlay erc--keep-place-overlay
+                    (line-beginning-position)
+                    (line-end-position)))))
+
+(defun erc-keep-place-goto ()
+  "Jump to keep-place indicator."
+  (interactive)
+  (goto-char (overlay-start erc--keep-place-overlay))
+  (recenter (truncate (* (window-height) 0.25)) t))
 
 (defun erc-keep-place (_ignored)
   "Move point away from the last line in a non-selected ERC buffer."
@@ -168,6 +264,8 @@ erc-keep-place
     (deactivate-mark)
     (goto-char (erc-beg-of-input-line))
     (forward-line -1)
+    (when erc-keep-place-indicator
+      (erc-keep-place-move))
     ;; if `switch-to-buffer-preserve-window-point' is set,
     ;; we cannot rely on point being saved, and must commit
     ;; it to window-prev-buffers.
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* bug#59943: 30.0.50; ERC 5.5+: Add visual indicator to ERC keep-place
       [not found] <87fsdndzo1.fsf@neverwas.me>
@ 2022-12-16 14:26 ` J.P.
       [not found] ` <87bko3jug8.fsf@neverwas.me>
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: J.P. @ 2022-12-16 14:26 UTC (permalink / raw)
  To: 59943; +Cc: emacs-erc

[-- Attachment #1: Type: text/plain, Size: 122 bytes --]

v2. Show indicator in server buffers (kind of annoying IMO). Don't
update indicator when buffer appears in active frame.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0000-v1-v2.diff --]
[-- Type: text/x-patch, Size: 7335 bytes --]

From 0f2350b9dee5b1c9902de7891c88d53b36d01b4d Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Fri, 16 Dec 2022 06:31:41 -0800
Subject: [PATCH 0/1] *** NOT A PATCH ***

*** BLURB HERE ***

F. Jason Park (1):
  Add option to show visual erc-keep-place indicator

 etc/ERC-NEWS            |  10 ++++
 lisp/erc/erc-goodies.el | 117 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 125 insertions(+), 2 deletions(-)

Interdiff:
diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS
index 5b73760741..a994a37d83 100644
--- a/etc/ERC-NEWS
+++ b/etc/ERC-NEWS
@@ -16,10 +16,10 @@ GNU Emacs since Emacs version 22.1.
 
 ** Module 'keep-place' now offers a visual indicator.
 
-Remember your place in a target buffer a bit more easily while also
-having the freedom to roam.  Optionally sync the indicator manually if
-you've made progress but still haven't caught up to the live stream.
-See new option 'erc-keep-place-indicator'.
+Remember your place in ERC buffers a bit more easily while also having
+the freedom to look around.  Optionally sync the indicator to any
+progress made when you haven't yet caught up to the live stream.  See
+new option 'erc-keep-place-indicator' and friends.
 
 \f
 * Changes in ERC 5.5
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 18e9f665bd..4efb88139f 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -47,6 +47,9 @@ erc-log-p
 (declare-function erc-extract-command-from-line "erc" (line))
 (declare-function erc-beg-of-input-line "erc" nil)
 (declare-function erc-default-target "erc" nil)
+(declare-function erc-buffer-filter "erc" (predicate &optional proc))
+(declare-function pulse-available-p "pulse" nil)
+(declare-function pulse-momentary-highlight-overlay "pulse" (o &optional face))
 
 (defun erc-imenu-setup ()
   "Setup Imenu support in an ERC buffer."
@@ -194,57 +197,63 @@ erc-keep-place-indicator-arrow
 (defvar-local erc--keep-place-overlay nil
   "Overlay for option `erc-keep-place-indicator'.")
 
+;; Replace this with whatever mechanism is devised for persisting
+;; a target buffer's variables (if not limited to local modules)
+(put 'erc--keep-place-overlay 'permanent-local t)
+
 (defun erc--keep-place-on-window-configuration-change ()
-  "Maybe sync `erc--keep-place-overlay'."
+  "Maybe sync `erc--keep-place-overlay'.
+Specifically, do so unless switching to or from another window in
+the active frame."
   (when erc-keep-place-indicator-follow
-    (unless (minibuffer-window-active-p (minibuffer-window))
+    (unless (or (minibuffer-window-active-p (minibuffer-window))
+                (eq (window-old-buffer) (current-buffer)))
       (when (< (overlay-end erc--keep-place-overlay)
                (window-start)
                erc-insert-marker)
         (erc-keep-place-move (window-start))))))
 
 (defun erc--keep-place-setup-overlay ()
-  (when (erc-default-target)
+  (when erc-keep-place-indicator
     (add-hook 'window-configuration-change-hook
               #'erc--keep-place-on-window-configuration-change nil t)
-    (setq erc--keep-place-overlay (make-overlay 0 0))
-    (when (memq erc-keep-place-indicator '(t arrow))
-      (overlay-put erc--keep-place-overlay 'before-string
-                   (propertize
-                    " "
-                    'display
-                    (if (zerop (fringe-columns 'left))
-                        `((margin left-margin) ,overlay-arrow-string)
-                      '(left-fringe right-triangle
-                                    erc-keep-place-indicator-arrow)))))
-    (when (memq erc-keep-place-indicator '(t face))
-      (overlay-put erc--keep-place-overlay 'face
-                   'erc-keep-place-indicator-line))))
+    (unless erc--keep-place-overlay
+      (setq erc--keep-place-overlay (make-overlay 0 0))
+      (when (memq erc-keep-place-indicator '(t arrow))
+        (overlay-put erc--keep-place-overlay 'before-string
+                     (propertize
+                      " "
+                      'display
+                      (if (zerop (fringe-columns 'left))
+                          `((margin left-margin) ,overlay-arrow-string)
+                        '(left-fringe right-triangle
+                                      erc-keep-place-indicator-arrow)))))
+      (when (memq erc-keep-place-indicator '(t face))
+        (overlay-put erc--keep-place-overlay 'face
+                     'erc-keep-place-indicator-line)))))
 
 ;;; Keep place in unvisited channels
 (define-erc-module keep-place nil
   "Leave point above un-viewed text in other channels."
   ((add-hook 'erc-insert-pre-hook  #'erc-keep-place)
-   (when erc-keep-place-indicator
-     (if (derived-mode-p 'erc-mode)
-         (erc--keep-place-setup-overlay)
-       (add-hook 'erc-mode-hook #'erc--keep-place-setup-overlay))))
+   (add-hook 'erc-mode-hook #'erc--keep-place-setup-overlay)
+   (erc-with-all-buffers-of-server erc-server-process nil
+     (erc--keep-place-setup-overlay)))
   ((remove-hook 'erc-insert-pre-hook  #'erc-keep-place)
-   (when erc-keep-place-indicator
-     (remove-hook 'erc-mode-hook #'erc--keep-place-setup-overlay)
-     (erc-with-all-buffers-of-server erc-server-process nil
-       (when erc--keep-place-overlay
-         (delete-overlay erc--keep-place-overlay)
-         (remove-hook 'window-configuration-change-hook
-                      #'erc--keep-place-on-window-configuration-change t)
-         (kill-local-variable 'erc--keep-place-overlay))))))
+   (remove-hook 'erc-mode-hook #'erc--keep-place-setup-overlay)
+   (erc-with-all-buffers-of-server erc-server-process nil
+     (when erc--keep-place-overlay
+       (delete-overlay erc--keep-place-overlay)
+       (remove-hook 'window-configuration-change-hook
+                    #'erc--keep-place-on-window-configuration-change t)
+       (kill-local-variable 'erc--keep-place-overlay)))))
 
 (defun erc-keep-place-move (&optional pos)
-  "Move keep-place indicator to the current line."
-  (interactive "P")
+  "Move keep-place indicator to the current line or POS."
+  (interactive)
   (save-excursion
     (let ((inhibit-field-text-motion t))
-      (when (numberp pos)
+      (when pos
         (goto-char pos))
       (move-overlay erc--keep-place-overlay
                     (line-beginning-position)
@@ -254,7 +263,10 @@ erc-keep-place-goto
   "Jump to keep-place indicator."
   (interactive)
   (goto-char (overlay-start erc--keep-place-overlay))
-  (recenter (truncate (* (window-height) 0.25)) t))
+  (recenter (truncate (* (window-height) 0.25)) t)
+  (require 'pulse)
+  (when (pulse-available-p)
+    (pulse-momentary-highlight-overlay erc--keep-place-overlay)))
 
 (defun erc-keep-place (_ignored)
   "Move point away from the last line in a non-selected ERC buffer."
@@ -265,7 +277,10 @@ erc-keep-place
     (goto-char (erc-beg-of-input-line))
     (forward-line -1)
     (when erc-keep-place-indicator
-      (erc-keep-place-move))
+      (unless (or (minibuffer-window-active-p (selected-window))
+                  (and (frame-visible-p (selected-frame))
+                       (get-buffer-window (current-buffer) (selected-frame))))
+        (erc-keep-place-move)))
     ;; if `switch-to-buffer-preserve-window-point' is set,
     ;; we cannot rely on point being saved, and must commit
     ;; it to window-prev-buffers.
-- 
2.38.1


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-Add-option-to-show-visual-erc-keep-place-indicator.patch --]
[-- Type: text/x-patch, Size: 8223 bytes --]

From 0f2350b9dee5b1c9902de7891c88d53b36d01b4d Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Fri, 9 Dec 2022 22:00:59 -0800
Subject: [PATCH 1/1] Add option to show visual erc-keep-place indicator

* etc/ERC-NEWS: Create new section for version 5.6 and mention
keep-place indicator.
* lisp/erc/erc-goodies.el (erc-keep-place-indicator,
erc-keep-place-indicator-follow): New options for anchoring kept place
visually.
(erc-keep-place-indicator-line, erc-keep-place-indicator-arrow): New
faces.
(erc--keep-place-overlay): New internal local state var.
(erc--keep-place-on-window-configuration-change): New function to
subscribe to `window-configuration-change-hook' and maybe update
keep-place indicator.
(erc--keep-place-setup-overlay): New function to initialize buffer for
option `erc-keep-place-indicator'.
(erc-keep-place-enable, erc-keep-place-disable): Add setup and
teardown to support `erc-keep-place-indicator'.
(erc-keep-place-move, erc-keep-place-goto): Add new commands for
manually updating and jumping to keep-place indicator.
(erc-keep-place): Move `erc--keep-place-overlay' when applicable.
---
 etc/ERC-NEWS            |  10 ++++
 lisp/erc/erc-goodies.el | 117 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 125 insertions(+), 2 deletions(-)

diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS
index 76439f1d06..a994a37d83 100644
--- a/etc/ERC-NEWS
+++ b/etc/ERC-NEWS
@@ -11,6 +11,16 @@ This file is about changes in ERC, the powerful, modular, and
 extensible IRC (Internet Relay Chat) client distributed with
 GNU Emacs since Emacs version 22.1.
 
+\f
+* Changes in ERC 5.6
+
+** Module 'keep-place' now offers a visual indicator.
+
+Remember your place in ERC buffers a bit more easily while also having
+the freedom to look around.  Optionally sync the indicator to any
+progress made when you haven't yet caught up to the live stream.  See
+new option 'erc-keep-place-indicator' and friends.
+
 \f
 * Changes in ERC 5.5
 
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 1af83b58ba..4efb88139f 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -46,6 +46,10 @@ erc-log-p
 (declare-function erc-error "erc" (&rest args))
 (declare-function erc-extract-command-from-line "erc" (line))
 (declare-function erc-beg-of-input-line "erc" nil)
+(declare-function erc-default-target "erc" nil)
+(declare-function erc-buffer-filter "erc" (predicate &optional proc))
+(declare-function pulse-available-p "pulse" nil)
+(declare-function pulse-momentary-highlight-overlay "pulse" (o &optional face))
 
 (defun erc-imenu-setup ()
   "Setup Imenu support in an ERC buffer."
@@ -154,11 +158,115 @@ erc-move-to-prompt-setup
   "Initialize the move-to-prompt module."
   (add-hook 'pre-command-hook #'erc-move-to-prompt nil t))
 
+(defcustom erc-keep-place-indicator nil
+  "Show kept place with visual indicator in target buffers.
+For use with the `keep-place' module.  A value of `arrow'
+displays an arrow in the left fringe or margin.  A value of
+`face' applies `erc-keep-place-indicator-line' to the appropriate
+line.  A value of t does both.  A value of nil does neither."
+  :group 'erc
+  :package-version '(ERC . "5.6")
+  :type '(choice (const nil) (const t) (const face) (const arrow)))
+
+(defcustom erc-keep-place-indicator-follow nil
+  "Whether to sync visual kept place to window's top when reading."
+  :group 'erc
+  :package-version '(ERC . "5.6")
+  :type 'boolean)
+
+(defface erc-keep-place-indicator-line
+  '((((class color) (min-colors 88) (background light)
+      (supports :underline (:style wave)))
+     (:underline (:color "PaleGreen3" :style wave)))
+    (((class color) (min-colors 88) (background dark)
+      (supports :underline (:style wave)))
+     (:underline (:color "PaleGreen1" :style wave)))
+    (t :underline t))
+  "Face for option `erc-keep-place-indicator'."
+  :group 'erc-faces)
+
+(defface erc-keep-place-indicator-arrow
+  '((((class color) (min-colors 88) (background light))
+     (:foreground "PaleGreen3"))
+    (((class color) (min-colors 88) (background dark))
+     (:foreground "PaleGreen1"))
+    (t :inherit fringe))
+  "Face for arrow value of option `erc-keep-place-indicator'."
+  :group 'erc-faces)
+
+(defvar-local erc--keep-place-overlay nil
+  "Overlay for option `erc-keep-place-indicator'.")
+
+;; Replace this with whatever mechanism is devised for persisting
+;; a target buffer's variables (if not limited to local modules)
+(put 'erc--keep-place-overlay 'permanent-local t)
+
+(defun erc--keep-place-on-window-configuration-change ()
+  "Maybe sync `erc--keep-place-overlay'.
+Specifically, do so unless switching to or from another window in
+the active frame."
+  (when erc-keep-place-indicator-follow
+    (unless (or (minibuffer-window-active-p (minibuffer-window))
+                (eq (window-old-buffer) (current-buffer)))
+      (when (< (overlay-end erc--keep-place-overlay)
+               (window-start)
+               erc-insert-marker)
+        (erc-keep-place-move (window-start))))))
+
+(defun erc--keep-place-setup-overlay ()
+  (when erc-keep-place-indicator
+    (add-hook 'window-configuration-change-hook
+              #'erc--keep-place-on-window-configuration-change nil t)
+    (unless erc--keep-place-overlay
+      (setq erc--keep-place-overlay (make-overlay 0 0))
+      (when (memq erc-keep-place-indicator '(t arrow))
+        (overlay-put erc--keep-place-overlay 'before-string
+                     (propertize
+                      " "
+                      'display
+                      (if (zerop (fringe-columns 'left))
+                          `((margin left-margin) ,overlay-arrow-string)
+                        '(left-fringe right-triangle
+                                      erc-keep-place-indicator-arrow)))))
+      (when (memq erc-keep-place-indicator '(t face))
+        (overlay-put erc--keep-place-overlay 'face
+                     'erc-keep-place-indicator-line)))))
+
 ;;; Keep place in unvisited channels
 (define-erc-module keep-place nil
   "Leave point above un-viewed text in other channels."
-  ((add-hook 'erc-insert-pre-hook  #'erc-keep-place))
-  ((remove-hook 'erc-insert-pre-hook  #'erc-keep-place)))
+  ((add-hook 'erc-insert-pre-hook  #'erc-keep-place)
+   (add-hook 'erc-mode-hook #'erc--keep-place-setup-overlay)
+   (erc-with-all-buffers-of-server erc-server-process nil
+     (erc--keep-place-setup-overlay)))
+  ((remove-hook 'erc-insert-pre-hook  #'erc-keep-place)
+   (remove-hook 'erc-mode-hook #'erc--keep-place-setup-overlay)
+   (erc-with-all-buffers-of-server erc-server-process nil
+     (when erc--keep-place-overlay
+       (delete-overlay erc--keep-place-overlay)
+       (remove-hook 'window-configuration-change-hook
+                    #'erc--keep-place-on-window-configuration-change t)
+       (kill-local-variable 'erc--keep-place-overlay)))))
+
+(defun erc-keep-place-move (&optional pos)
+  "Move keep-place indicator to the current line or POS."
+  (interactive)
+  (save-excursion
+    (let ((inhibit-field-text-motion t))
+      (when pos
+        (goto-char pos))
+      (move-overlay erc--keep-place-overlay
+                    (line-beginning-position)
+                    (line-end-position)))))
+
+(defun erc-keep-place-goto ()
+  "Jump to keep-place indicator."
+  (interactive)
+  (goto-char (overlay-start erc--keep-place-overlay))
+  (recenter (truncate (* (window-height) 0.25)) t)
+  (require 'pulse)
+  (when (pulse-available-p)
+    (pulse-momentary-highlight-overlay erc--keep-place-overlay)))
 
 (defun erc-keep-place (_ignored)
   "Move point away from the last line in a non-selected ERC buffer."
@@ -168,6 +276,11 @@ erc-keep-place
     (deactivate-mark)
     (goto-char (erc-beg-of-input-line))
     (forward-line -1)
+    (when erc-keep-place-indicator
+      (unless (or (minibuffer-window-active-p (selected-window))
+                  (and (frame-visible-p (selected-frame))
+                       (get-buffer-window (current-buffer) (selected-frame))))
+        (erc-keep-place-move)))
     ;; if `switch-to-buffer-preserve-window-point' is set,
     ;; we cannot rely on point being saved, and must commit
     ;; it to window-prev-buffers.
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* bug#59943: 30.0.50; ERC 5.5+: Add visual indicator to ERC keep-place
       [not found] ` <87bko3jug8.fsf@neverwas.me>
@ 2023-02-01  2:49   ` J.P.
  0 siblings, 0 replies; 8+ messages in thread
From: J.P. @ 2023-02-01  2:49 UTC (permalink / raw)
  To: 59943; +Cc: emacs-erc

"J.P." <jp@neverwas.me> writes:

> v2. Show indicator in server buffers (kind of annoying IMO). Don't
> update indicator when buffer appears in active frame.

Just noticed there's a forward declaration missing for `fringe-column'
atop goodies. The ones for ERC's own libraries can be removed whenever
bug#60954 happens because it'll have us requiring `erc' anyhow (not
present in latest "v3" change set).





^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#59943: 30.0.50; ERC 5.5+: Add visual indicator to ERC keep-place
       [not found] <87fsdndzo1.fsf@neverwas.me>
  2022-12-16 14:26 ` bug#59943: 30.0.50; ERC 5.5+: Add visual indicator to ERC keep-place J.P.
       [not found] ` <87bko3jug8.fsf@neverwas.me>
@ 2023-02-20 15:33 ` J.P.
  2023-03-09 14:41 ` J.P.
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: J.P. @ 2023-02-20 15:33 UTC (permalink / raw)
  To: 59943; +Cc: emacs-erc

[-- Attachment #1: Type: text/plain, Size: 310 bytes --]

v3. Convert to local module. Add option to discriminate on buffer type.

(This is meant to be applied atop bug#60954. The attached version has
been modified to apply cleanly on HEAD but is untested as such. See
https://emacs-erc.gitlab.io/bugs/49860/patches.tar.gz for the combined
set in its natural order.)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0000-v2-v3.diff --]
[-- Type: text/x-patch, Size: 17159 bytes --]

From 6cc6dbbbb1e5add24bea2495cded7c2d5c5429f7 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Mon, 20 Feb 2023 06:39:18 -0800
Subject: [PATCH 0/1] *** NOT A PATCH ***

*** BLURB HERE ***

F. Jason Park (1):
  [5.6] Add option to show visual erc-keep-place indicator

 lisp/erc/erc-goodies.el            | 164 ++++++++++++++++++++++++++++-
 test/lisp/erc/erc-goodies-tests.el | 105 ++++++++++++++++++
 2 files changed, 266 insertions(+), 3 deletions(-)
 create mode 100644 test/lisp/erc/erc-goodies-tests.el

Interdiff:
diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS
index 3f1f8cd157e..d5e256d9d33 100644
--- a/etc/ERC-NEWS
+++ b/etc/ERC-NEWS
@@ -11,16 +11,6 @@ This file is about changes in ERC, the powerful, modular, and
 extensible IRC (Internet Relay Chat) client distributed with
 GNU Emacs since Emacs version 22.1.
 
-\f
-* Changes in ERC 5.6
-
-** Module 'keep-place' now offers a visual indicator.
-
-Remember your place in ERC buffers a bit more easily while also having
-the freedom to look around.  Optionally sync the indicator to any
-progress made when you haven't yet caught up to the live stream.  See
-new option 'erc-keep-place-indicator' and friends.
-
 \f
 * Changes in ERC 5.5
 
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 1c7c8f6a1be..b7f7214eed9 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -34,19 +34,24 @@
 (eval-when-compile (require 'cl-lib))
 (require 'erc-common)
 
+(defvar erc--server-reconnecting)
+(defvar erc--target)
+(defvar erc--target-priors)
 (defvar erc-controls-highlight-regexp)
 (defvar erc-controls-remove-regexp)
 (defvar erc-input-marker)
 (defvar erc-insert-marker)
-(defvar erc-server-process)
-(defvar erc-modules)
 (defvar erc-log-p)
+(defvar erc-modules)
+(defvar erc-server-process)
 
 (declare-function erc-beg-of-input-line "erc" nil)
-(declare-function erc-buffer-filter "erc" (predicate &optional proc))
 (declare-function erc-buffer-list "erc" (&optional predicate proc))
+(declare-function erc-display-error-notice "erc" (parsed string))
 (declare-function erc-error "erc" (&rest args))
 (declare-function erc-extract-command-from-line "erc" (line))
+
+(declare-function fringe-columns "fringe" (side &optional real))
 (declare-function pulse-available-p "pulse" nil)
 (declare-function pulse-momentary-highlight-overlay "pulse" (o &optional face))
 
@@ -157,18 +162,32 @@ erc-move-to-prompt-setup
   "Initialize the move-to-prompt module."
   (add-hook 'pre-command-hook #'erc-move-to-prompt nil t))
 
-(defcustom erc-keep-place-indicator nil
-  "Show kept place with visual indicator in target buffers.
-For use with the `keep-place' module.  A value of `arrow'
-displays an arrow in the left fringe or margin.  A value of
-`face' applies `erc-keep-place-indicator-line' to the appropriate
-line.  A value of t does both.  A value of nil does neither."
+;;; Keep place in unvisited channels
+(define-erc-module keep-place nil
+  "Leave point above un-viewed text in other channels."
+  ((add-hook 'erc-insert-pre-hook  #'erc-keep-place))
+  ((remove-hook 'erc-insert-pre-hook  #'erc-keep-place)))
+
+(defcustom erc-keep-place-indicator-style t
+  "Flavor of visual indicator applied to kept place.
+For use with the `keep-place-indicator' module.  A value of `arrow'
+displays an arrow in the left fringe or margin.  When it's
+`face', ERC adds the face `erc-keep-place-indicator-line' to the
+appropriate line.  A value of t does both."
+  :group 'erc
+  :package-version '(ERC . "5.6")
+  :type '(choice (const t) (const server) (const target)))
+
+(defcustom erc-keep-place-indicator-buffer-type t
+  "ERC buffer type in which to display `keep-place-indicator'.
+A value of t means \"all\" ERC buffers."
   :group 'erc
   :package-version '(ERC . "5.6")
-  :type '(choice (const nil) (const t) (const face) (const arrow)))
+  :type '(choice (const t) (const server) (const target)))
 
 (defcustom erc-keep-place-indicator-follow nil
-  "Whether to sync visual kept place to window's top when reading."
+  "Whether to sync visual kept place to window's top when reading.
+For use with `erc-keep-place-indicator-mode'."
   :group 'erc
   :package-version '(ERC . "5.6")
   :type 'boolean)
@@ -181,7 +200,7 @@ erc-keep-place-indicator-line
       (supports :underline (:style wave)))
      (:underline (:color "PaleGreen1" :style wave)))
     (t :underline t))
-  "Face for option `erc-keep-place-indicator'."
+  "Face for option `erc-keep-place-indicator-style'."
   :group 'erc-faces)
 
 (defface erc-keep-place-indicator-arrow
@@ -190,82 +209,109 @@ erc-keep-place-indicator-arrow
     (((class color) (min-colors 88) (background dark))
      (:foreground "PaleGreen1"))
     (t :inherit fringe))
-  "Face for arrow value of option `erc-keep-place-indicator'."
+  "Face for arrow value of option `erc-keep-place-indicator-style'."
   :group 'erc-faces)
 
-(defvar-local erc--keep-place-overlay nil
-  "Overlay for option `erc-keep-place-indicator'.")
-
-;; Replace this with whatever mechanism is devised for persisting
-;; a target buffer's variables (if not limited to local modules)
-(put 'erc--keep-place-overlay 'permanent-local t)
+(defvar-local erc--keep-place-indicator-overlay nil
+  "Overlay for `erc-keep-place-indicator-mode'.")
 
-(defun erc--keep-place-on-window-configuration-change ()
-  "Maybe sync `erc--keep-place-overlay'.
+(defun erc--keep-place-indicator-on-window-configuration-change ()
+  "Maybe sync `erc--keep-place-indicator-overlay'.
 Specifically, do so unless switching to or from another window in
 the active frame."
   (when erc-keep-place-indicator-follow
     (unless (or (minibuffer-window-active-p (minibuffer-window))
                 (eq (window-old-buffer) (current-buffer)))
-      (when (< (overlay-end erc--keep-place-overlay)
+      (when (< (overlay-end erc--keep-place-indicator-overlay)
                (window-start)
                erc-insert-marker)
         (erc-keep-place-move (window-start))))))
 
-(defun erc--keep-place-setup-overlay ()
-  (when erc-keep-place-indicator
-    (add-hook 'window-configuration-change-hook
-              #'erc--keep-place-on-window-configuration-change nil t)
-    (unless erc--keep-place-overlay
-      (setq erc--keep-place-overlay (make-overlay 0 0))
-      (when (memq erc-keep-place-indicator '(t arrow))
-        (overlay-put erc--keep-place-overlay 'before-string
-                     (propertize
-                      " "
-                      'display
-                      (if (zerop (fringe-columns 'left))
-                          `((margin left-margin) ,overlay-arrow-string)
-                        '(left-fringe right-triangle
-                                      erc-keep-place-indicator-arrow)))))
-      (when (memq erc-keep-place-indicator '(t face))
-        (overlay-put erc--keep-place-overlay 'face
-                     'erc-keep-place-indicator-line)))))
-
-;;; Keep place in unvisited channels
-(define-erc-module keep-place nil
-  "Leave point above un-viewed text in other channels."
-  ((add-hook 'erc-insert-pre-hook  #'erc-keep-place)
-   (add-hook 'erc-mode-hook #'erc--keep-place-setup-overlay)
-   (erc-with-all-buffers-of-server erc-server-process nil
-     (erc--keep-place-setup-overlay)))
-  ((remove-hook 'erc-insert-pre-hook  #'erc-keep-place)
-   (remove-hook 'erc-mode-hook #'erc--keep-place-setup-overlay)
-   (erc-with-all-buffers-of-server erc-server-process nil
-     (when erc--keep-place-overlay
-       (delete-overlay erc--keep-place-overlay)
-       (remove-hook 'window-configuration-change-hook
-                    #'erc--keep-place-on-window-configuration-change t)
-       (kill-local-variable 'erc--keep-place-overlay)))))
-
-(defun erc-keep-place-move (&optional pos)
-  "Move keep-place indicator to the current line or POS."
-  (interactive)
+(defun erc--keep-place-indicator-setup ()
+  "Initialize buffer for maintaining `erc--keep-place-indicator-overlay'."
+  (require 'fringe)
+  (setq erc--keep-place-indicator-overlay
+        (if-let* ((vars (or erc--server-reconnecting erc--target-priors))
+                  ((alist-get 'erc-keep-place-indicator-mode vars)))
+            (alist-get 'erc--keep-place-indicator-overlay vars)
+          (make-overlay 0 0)))
+  (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)))
+              (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))
+  (when (memq erc-keep-place-indicator-style '(t face))
+    (overlay-put erc--keep-place-indicator-overlay 'face
+                 'erc-keep-place-indicator-line)))
+
+;;;###autoload(put 'keep-place-indicator 'erc--feature 'erc-goodies)
+(define-erc-module keep-place-indicator nil
+  "`keep-place' with a fringe arrow and/or highlighted face."
+  ((unless erc-keep-place-mode
+     (unless (memq 'keep-place erc-modules)
+       ;; FIXME use `erc-button--display-error-notice-with-keys'
+       ;; to display this message when bug#60933 is ready.
+       (erc-display-error-notice
+        nil (concat
+             "Local module `keep-place-indicator' needs module `keep-place'."
+             "  Enabling now.  This will affect \C-]all\C-] ERC sessions."
+             "  Add `keep-place' to `erc-modules' to silence this message.")))
+     (erc-keep-place-mode +1))
+   (if (pcase erc-keep-place-indicator-buffer-type
+         ('target erc--target)
+         ('server (not erc--target))
+         ('t t))
+       (erc--keep-place-indicator-setup)
+     (setq erc-keep-place-indicator-mode nil)))
+  ((when erc--keep-place-indicator-overlay
+     (delete-overlay erc--keep-place-indicator-overlay)
+     (remove-hook 'window-configuration-change-hook
+                  #'erc--keep-place-indicator-on-window-configuration-change t)
+     (kill-local-variable 'erc--keep-place-indicator-overlay)))
+  'local)
+
+(defun erc-keep-place-move (pos)
+  "Move keep-place indicator to current line or POS.
+For use with `keep-place-indicator' module.  When called
+interactively, interpret POS as an offset.  Specifically, when
+POS is a raw prefix arg, like (4), move the indicator to the
+window's last line.  When it's the minus sign, put it on the
+window's first line.  Interpret an integer as an offset in lines."
+  (interactive
+   (progn
+     (unless erc-keep-place-indicator-mode
+       (user-error "`erc-keep-place-indicator-mode' not enabled"))
+     (list (pcase current-prefix-arg
+             ((and (pred integerp) v)
+              (save-excursion
+                (let ((inhibit-field-text-motion t))
+                  (forward-line v)
+                  (point))))
+             (`(,_) (1- (min erc-insert-marker (window-end))))
+             ('- (min (1- erc-insert-marker) (window-start)))))))
   (save-excursion
     (let ((inhibit-field-text-motion t))
       (when pos
         (goto-char pos))
-      (move-overlay erc--keep-place-overlay
+      (move-overlay erc--keep-place-indicator-overlay
                     (line-beginning-position)
                     (line-end-position)))))
 
 (defun erc-keep-place-goto ()
-  "Jump to keep-place indicator."
-  (interactive)
-  (goto-char (overlay-start erc--keep-place-overlay))
+  "Jump to keep-place indicator.
+For use with `keep-place-indicator' module."
+  (interactive
+   (unless erc-keep-place-indicator-mode
+     (user-error "`erc-keep-place-indicator-mode' not enabled")))
+  (goto-char (overlay-start erc--keep-place-indicator-overlay))
   (recenter (truncate (* (window-height) 0.25)) t)
   (require 'pulse)
   (when (pulse-available-p)
-    (pulse-momentary-highlight-overlay erc--keep-place-overlay)))
+    (pulse-momentary-highlight-overlay erc--keep-place-indicator-overlay)))
 
 (defun erc-keep-place (_ignored)
   "Move point away from the last line in a non-selected ERC buffer."
@@ -275,11 +321,11 @@ erc-keep-place
     (deactivate-mark)
     (goto-char (erc-beg-of-input-line))
     (forward-line -1)
-    (when erc-keep-place-indicator
+    (when erc-keep-place-indicator-mode
       (unless (or (minibuffer-window-active-p (selected-window))
                   (and (frame-visible-p (selected-frame))
                        (get-buffer-window (current-buffer) (selected-frame))))
-        (erc-keep-place-move)))
+        (erc-keep-place-move nil)))
     ;; if `switch-to-buffer-preserve-window-point' is set,
     ;; we cannot rely on point being saved, and must commit
     ;; it to window-prev-buffers.
diff --git a/test/lisp/erc/erc-goodies-tests.el b/test/lisp/erc/erc-goodies-tests.el
new file mode 100644
index 00000000000..f08404be687
--- /dev/null
+++ b/test/lisp/erc/erc-goodies-tests.el
@@ -0,0 +1,105 @@
+;;; erc-goodies-tests.el --- Tests for erc-goodies  -*- lexical-binding:t -*-
+
+;; Copyright (C) 2023 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+;;
+;; GNU Emacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Code:
+(require 'ert-x)
+(require 'erc)
+(require 'erc-goodies)
+(declare-function erc--initialize-markers "erc" (old-point continued) t)
+
+;; Among other things, this test also asserts that a local module's
+;; minor-mode toggle is allowed to disable its mode variable as
+;; needed.
+
+(ert-deftest erc-keep-place-indicator-mode ()
+  (unless (fboundp 'erc--initialize-markers)
+    (ert-skip "Required patch set for bug#60954 not yet applied"))
+  (with-current-buffer (get-buffer-create "*erc-keep-place-indicator-mode*")
+    (erc-mode)
+    (erc--initialize-markers (point) nil)
+    (let ((assert-off
+           (lambda ()
+             (should-not erc-keep-place-indicator-mode)
+             (should-not (local-variable-p 'window-configuration-change-hook))
+             (should-not erc--keep-place-indicator-overlay)))
+          (assert-on
+           (lambda ()
+             (should erc--keep-place-indicator-overlay)
+             (should (local-variable-p 'window-configuration-change-hook))
+             (should window-configuration-change-hook)
+             (should erc-keep-place-mode)))
+          ;;
+          erc-modules)
+
+      (funcall assert-off)
+
+      (ert-info ("Value t")
+        (should (eq erc-keep-place-indicator-buffer-type t))
+        (erc-keep-place-indicator-mode +1)
+        (funcall assert-on)
+        (goto-char (point-min))
+        (should (search-forward "Enabling" nil t))
+        (should (memq 'keep-place erc-modules)))
+
+      (erc-keep-place-indicator-mode -1)
+      (funcall assert-off)
+
+      (ert-info ("Value `target'")
+        (let ((erc-keep-place-indicator-buffer-type 'target))
+          (erc-keep-place-indicator-mode +1)
+          (funcall assert-off)
+          (setq erc--target (erc--target-from-string "#chan"))
+          (erc-keep-place-indicator-mode +1)
+          (funcall assert-on)))
+
+      (erc-keep-place-indicator-mode -1)
+      (funcall assert-off)
+
+      (ert-info ("Value `server'")
+        (let ((erc-keep-place-indicator-buffer-type 'server))
+          (erc-keep-place-indicator-mode +1)
+          (funcall assert-off)
+          (setq erc--target nil)
+          (erc-keep-place-indicator-mode +1)
+          (funcall assert-on)))
+
+      ;; Populate buffer
+      (erc-display-message nil 'notice (current-buffer)
+                           "This buffer is for text that is not saved")
+      (erc-display-message nil 'notice (current-buffer)
+                           "and for lisp evaluation")
+      (should (search-forward "saved" nil t))
+      (erc-keep-place-move nil)
+      (goto-char erc-input-marker)
+
+      (ert-info ("Indicator survives reconnect")
+        (let ((erc--server-reconnecting (buffer-local-variables)))
+          (cl-letf (((symbol-function 'erc-server-connect) #'ignore))
+            (erc-open "localhost" 6667 "tester" "Tester" 'connect
+                      nil nil nil nil nil "tester" nil)))
+        (funcall assert-on)
+        (should (= (point) erc-input-marker))
+        (goto-char (overlay-start erc--keep-place-indicator-overlay))
+        (should (looking-at (rx "*** This buffer is for text")))))
+
+    (when noninteractive
+      (kill-buffer))))
+
+;;; erc-goodies-tests.el ends here
-- 
2.39.1


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-5.6-Add-option-to-show-visual-erc-keep-place-indicat.patch --]
[-- Type: text/x-patch, Size: 14436 bytes --]

From 6cc6dbbbb1e5add24bea2495cded7c2d5c5429f7 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Fri, 9 Dec 2022 22:00:59 -0800
Subject: [PATCH 1/1] [5.6] Add option to show visual erc-keep-place indicator

* lisp/erc/erc-goodies.el (erc-keep-place-indicator-style,
erc-keep-place-indicator-buffer-type,
erc-keep-place-indicator-follow): New options for anchoring kept place
visually.
(erc-keep-place-indicator-line, erc-keep-place-indicator-arrow): New
faces.
(erc--keep-place-indicator-overlay): New internal variable.
(erc--keep-place-indicator-on-window-configuration-change): New
function to subscribe to `window-configuration-change-hook' and maybe
update kept-place indicator.
(erc--keep-place-indicator-setup): New function to initialize buffer
for local module `keep-place-indicator'.
(erc-keep-place-indicator-mode, erc-keep-place-indicator-enable,
erc-keep-place-indicator-disable): New local ERC module.  Depends on
"parent" module `keep-place'.  Like `fill-wrap', this is for now also
deliberately left out of the widget menu for `erc-modules'.
(erc-keep-place-move, erc-keep-place-goto): Add new commands for
manually updating and jumping to keep-place indicator.
(erc-keep-place): Move `erc--keep-place-overlay' when applicable.
* test/lisp/erc/erc-goodies-tests.el: New file.
(Bug#59943.)
---
 lisp/erc/erc-goodies.el            | 164 ++++++++++++++++++++++++++++-
 test/lisp/erc/erc-goodies-tests.el | 105 ++++++++++++++++++
 2 files changed, 266 insertions(+), 3 deletions(-)
 create mode 100644 test/lisp/erc/erc-goodies-tests.el

diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 05a21019042..b7f7214eed9 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -34,18 +34,26 @@
 (eval-when-compile (require 'cl-lib))
 (require 'erc-common)
 
+(defvar erc--server-reconnecting)
+(defvar erc--target)
+(defvar erc--target-priors)
 (defvar erc-controls-highlight-regexp)
 (defvar erc-controls-remove-regexp)
 (defvar erc-input-marker)
 (defvar erc-insert-marker)
-(defvar erc-server-process)
-(defvar erc-modules)
 (defvar erc-log-p)
+(defvar erc-modules)
+(defvar erc-server-process)
 
+(declare-function erc-beg-of-input-line "erc" nil)
 (declare-function erc-buffer-list "erc" (&optional predicate proc))
+(declare-function erc-display-error-notice "erc" (parsed string))
 (declare-function erc-error "erc" (&rest args))
 (declare-function erc-extract-command-from-line "erc" (line))
-(declare-function erc-beg-of-input-line "erc" nil)
+
+(declare-function fringe-columns "fringe" (side &optional real))
+(declare-function pulse-available-p "pulse" nil)
+(declare-function pulse-momentary-highlight-overlay "pulse" (o &optional face))
 
 (defun erc-imenu-setup ()
   "Setup Imenu support in an ERC buffer."
@@ -160,6 +168,151 @@ keep-place
   ((add-hook 'erc-insert-pre-hook  #'erc-keep-place))
   ((remove-hook 'erc-insert-pre-hook  #'erc-keep-place)))
 
+(defcustom erc-keep-place-indicator-style t
+  "Flavor of visual indicator applied to kept place.
+For use with the `keep-place-indicator' module.  A value of `arrow'
+displays an arrow in the left fringe or margin.  When it's
+`face', ERC adds the face `erc-keep-place-indicator-line' to the
+appropriate line.  A value of t does both."
+  :group 'erc
+  :package-version '(ERC . "5.6")
+  :type '(choice (const t) (const server) (const target)))
+
+(defcustom erc-keep-place-indicator-buffer-type t
+  "ERC buffer type in which to display `keep-place-indicator'.
+A value of t means \"all\" ERC buffers."
+  :group 'erc
+  :package-version '(ERC . "5.6")
+  :type '(choice (const t) (const server) (const target)))
+
+(defcustom erc-keep-place-indicator-follow nil
+  "Whether to sync visual kept place to window's top when reading.
+For use with `erc-keep-place-indicator-mode'."
+  :group 'erc
+  :package-version '(ERC . "5.6")
+  :type 'boolean)
+
+(defface erc-keep-place-indicator-line
+  '((((class color) (min-colors 88) (background light)
+      (supports :underline (:style wave)))
+     (:underline (:color "PaleGreen3" :style wave)))
+    (((class color) (min-colors 88) (background dark)
+      (supports :underline (:style wave)))
+     (:underline (:color "PaleGreen1" :style wave)))
+    (t :underline t))
+  "Face for option `erc-keep-place-indicator-style'."
+  :group 'erc-faces)
+
+(defface erc-keep-place-indicator-arrow
+  '((((class color) (min-colors 88) (background light))
+     (:foreground "PaleGreen3"))
+    (((class color) (min-colors 88) (background dark))
+     (:foreground "PaleGreen1"))
+    (t :inherit fringe))
+  "Face for arrow value of option `erc-keep-place-indicator-style'."
+  :group 'erc-faces)
+
+(defvar-local erc--keep-place-indicator-overlay nil
+  "Overlay for `erc-keep-place-indicator-mode'.")
+
+(defun erc--keep-place-indicator-on-window-configuration-change ()
+  "Maybe sync `erc--keep-place-indicator-overlay'.
+Specifically, do so unless switching to or from another window in
+the active frame."
+  (when erc-keep-place-indicator-follow
+    (unless (or (minibuffer-window-active-p (minibuffer-window))
+                (eq (window-old-buffer) (current-buffer)))
+      (when (< (overlay-end erc--keep-place-indicator-overlay)
+               (window-start)
+               erc-insert-marker)
+        (erc-keep-place-move (window-start))))))
+
+(defun erc--keep-place-indicator-setup ()
+  "Initialize buffer for maintaining `erc--keep-place-indicator-overlay'."
+  (require 'fringe)
+  (setq erc--keep-place-indicator-overlay
+        (if-let* ((vars (or erc--server-reconnecting erc--target-priors))
+                  ((alist-get 'erc-keep-place-indicator-mode vars)))
+            (alist-get 'erc--keep-place-indicator-overlay vars)
+          (make-overlay 0 0)))
+  (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)))
+              (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))
+  (when (memq erc-keep-place-indicator-style '(t face))
+    (overlay-put erc--keep-place-indicator-overlay 'face
+                 'erc-keep-place-indicator-line)))
+
+;;;###autoload(put 'keep-place-indicator 'erc--feature 'erc-goodies)
+(define-erc-module keep-place-indicator nil
+  "`keep-place' with a fringe arrow and/or highlighted face."
+  ((unless erc-keep-place-mode
+     (unless (memq 'keep-place erc-modules)
+       ;; FIXME use `erc-button--display-error-notice-with-keys'
+       ;; to display this message when bug#60933 is ready.
+       (erc-display-error-notice
+        nil (concat
+             "Local module `keep-place-indicator' needs module `keep-place'."
+             "  Enabling now.  This will affect \C-]all\C-] ERC sessions."
+             "  Add `keep-place' to `erc-modules' to silence this message.")))
+     (erc-keep-place-mode +1))
+   (if (pcase erc-keep-place-indicator-buffer-type
+         ('target erc--target)
+         ('server (not erc--target))
+         ('t t))
+       (erc--keep-place-indicator-setup)
+     (setq erc-keep-place-indicator-mode nil)))
+  ((when erc--keep-place-indicator-overlay
+     (delete-overlay erc--keep-place-indicator-overlay)
+     (remove-hook 'window-configuration-change-hook
+                  #'erc--keep-place-indicator-on-window-configuration-change t)
+     (kill-local-variable 'erc--keep-place-indicator-overlay)))
+  'local)
+
+(defun erc-keep-place-move (pos)
+  "Move keep-place indicator to current line or POS.
+For use with `keep-place-indicator' module.  When called
+interactively, interpret POS as an offset.  Specifically, when
+POS is a raw prefix arg, like (4), move the indicator to the
+window's last line.  When it's the minus sign, put it on the
+window's first line.  Interpret an integer as an offset in lines."
+  (interactive
+   (progn
+     (unless erc-keep-place-indicator-mode
+       (user-error "`erc-keep-place-indicator-mode' not enabled"))
+     (list (pcase current-prefix-arg
+             ((and (pred integerp) v)
+              (save-excursion
+                (let ((inhibit-field-text-motion t))
+                  (forward-line v)
+                  (point))))
+             (`(,_) (1- (min erc-insert-marker (window-end))))
+             ('- (min (1- erc-insert-marker) (window-start)))))))
+  (save-excursion
+    (let ((inhibit-field-text-motion t))
+      (when pos
+        (goto-char pos))
+      (move-overlay erc--keep-place-indicator-overlay
+                    (line-beginning-position)
+                    (line-end-position)))))
+
+(defun erc-keep-place-goto ()
+  "Jump to keep-place indicator.
+For use with `keep-place-indicator' module."
+  (interactive
+   (unless erc-keep-place-indicator-mode
+     (user-error "`erc-keep-place-indicator-mode' not enabled")))
+  (goto-char (overlay-start erc--keep-place-indicator-overlay))
+  (recenter (truncate (* (window-height) 0.25)) t)
+  (require 'pulse)
+  (when (pulse-available-p)
+    (pulse-momentary-highlight-overlay erc--keep-place-indicator-overlay)))
+
 (defun erc-keep-place (_ignored)
   "Move point away from the last line in a non-selected ERC buffer."
   (when (and (not (eq (window-buffer (selected-window))
@@ -168,6 +321,11 @@ erc-keep-place
     (deactivate-mark)
     (goto-char (erc-beg-of-input-line))
     (forward-line -1)
+    (when erc-keep-place-indicator-mode
+      (unless (or (minibuffer-window-active-p (selected-window))
+                  (and (frame-visible-p (selected-frame))
+                       (get-buffer-window (current-buffer) (selected-frame))))
+        (erc-keep-place-move nil)))
     ;; if `switch-to-buffer-preserve-window-point' is set,
     ;; we cannot rely on point being saved, and must commit
     ;; it to window-prev-buffers.
diff --git a/test/lisp/erc/erc-goodies-tests.el b/test/lisp/erc/erc-goodies-tests.el
new file mode 100644
index 00000000000..f08404be687
--- /dev/null
+++ b/test/lisp/erc/erc-goodies-tests.el
@@ -0,0 +1,105 @@
+;;; erc-goodies-tests.el --- Tests for erc-goodies  -*- lexical-binding:t -*-
+
+;; Copyright (C) 2023 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+;;
+;; GNU Emacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Code:
+(require 'ert-x)
+(require 'erc)
+(require 'erc-goodies)
+(declare-function erc--initialize-markers "erc" (old-point continued) t)
+
+;; Among other things, this test also asserts that a local module's
+;; minor-mode toggle is allowed to disable its mode variable as
+;; needed.
+
+(ert-deftest erc-keep-place-indicator-mode ()
+  (unless (fboundp 'erc--initialize-markers)
+    (ert-skip "Required patch set for bug#60954 not yet applied"))
+  (with-current-buffer (get-buffer-create "*erc-keep-place-indicator-mode*")
+    (erc-mode)
+    (erc--initialize-markers (point) nil)
+    (let ((assert-off
+           (lambda ()
+             (should-not erc-keep-place-indicator-mode)
+             (should-not (local-variable-p 'window-configuration-change-hook))
+             (should-not erc--keep-place-indicator-overlay)))
+          (assert-on
+           (lambda ()
+             (should erc--keep-place-indicator-overlay)
+             (should (local-variable-p 'window-configuration-change-hook))
+             (should window-configuration-change-hook)
+             (should erc-keep-place-mode)))
+          ;;
+          erc-modules)
+
+      (funcall assert-off)
+
+      (ert-info ("Value t")
+        (should (eq erc-keep-place-indicator-buffer-type t))
+        (erc-keep-place-indicator-mode +1)
+        (funcall assert-on)
+        (goto-char (point-min))
+        (should (search-forward "Enabling" nil t))
+        (should (memq 'keep-place erc-modules)))
+
+      (erc-keep-place-indicator-mode -1)
+      (funcall assert-off)
+
+      (ert-info ("Value `target'")
+        (let ((erc-keep-place-indicator-buffer-type 'target))
+          (erc-keep-place-indicator-mode +1)
+          (funcall assert-off)
+          (setq erc--target (erc--target-from-string "#chan"))
+          (erc-keep-place-indicator-mode +1)
+          (funcall assert-on)))
+
+      (erc-keep-place-indicator-mode -1)
+      (funcall assert-off)
+
+      (ert-info ("Value `server'")
+        (let ((erc-keep-place-indicator-buffer-type 'server))
+          (erc-keep-place-indicator-mode +1)
+          (funcall assert-off)
+          (setq erc--target nil)
+          (erc-keep-place-indicator-mode +1)
+          (funcall assert-on)))
+
+      ;; Populate buffer
+      (erc-display-message nil 'notice (current-buffer)
+                           "This buffer is for text that is not saved")
+      (erc-display-message nil 'notice (current-buffer)
+                           "and for lisp evaluation")
+      (should (search-forward "saved" nil t))
+      (erc-keep-place-move nil)
+      (goto-char erc-input-marker)
+
+      (ert-info ("Indicator survives reconnect")
+        (let ((erc--server-reconnecting (buffer-local-variables)))
+          (cl-letf (((symbol-function 'erc-server-connect) #'ignore))
+            (erc-open "localhost" 6667 "tester" "Tester" 'connect
+                      nil nil nil nil nil "tester" nil)))
+        (funcall assert-on)
+        (should (= (point) erc-input-marker))
+        (goto-char (overlay-start erc--keep-place-indicator-overlay))
+        (should (looking-at (rx "*** This buffer is for text")))))
+
+    (when noninteractive
+      (kill-buffer))))
+
+;;; erc-goodies-tests.el ends here
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* bug#59943: 30.0.50; ERC 5.5+: Add visual indicator to ERC keep-place
       [not found] <87fsdndzo1.fsf@neverwas.me>
                   ` (2 preceding siblings ...)
  2023-02-20 15:33 ` J.P.
@ 2023-03-09 14:41 ` J.P.
  2023-07-14  2:03 ` J.P.
  2024-01-02 14:47 ` J.P.
  5 siblings, 0 replies; 8+ messages in thread
From: J.P. @ 2023-03-09 14:41 UTC (permalink / raw)
  To: 59943; +Cc: emacs-erc

[-- Attachment #1: Type: text/plain, Size: 47 bytes --]

v4. Push mark before moving in go-to command.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0000-v3-v4.diff --]
[-- Type: text/x-patch, Size: 1720 bytes --]

From b375774e2f114ed5295e83ac31fe130a8b92aefa Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Thu, 9 Mar 2023 06:40:58 -0800
Subject: [PATCH 0/1] *** NOT A PATCH ***

*** BLURB HERE ***

F. Jason Park (1):
  [5.6] Add option to show visual erc-keep-place indicator

 lisp/erc/erc-goodies.el            | 167 ++++++++++++++++++++++++++++-
 test/lisp/erc/erc-goodies-tests.el | 106 ++++++++++++++++++
 2 files changed, 270 insertions(+), 3 deletions(-)
 create mode 100644 test/lisp/erc/erc-goodies-tests.el

Interdiff:
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index b7f7214eed9..212e2e5340a 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -305,8 +305,11 @@ erc-keep-place-goto
   "Jump to keep-place indicator.
 For use with `keep-place-indicator' module."
   (interactive
-   (unless erc-keep-place-indicator-mode
-     (user-error "`erc-keep-place-indicator-mode' not enabled")))
+   (prog1 nil
+     (unless erc-keep-place-indicator-mode
+       (user-error "`erc-keep-place-indicator-mode' not enabled"))
+     (deactivate-mark)
+     (push-mark)))
   (goto-char (overlay-start erc--keep-place-indicator-overlay))
   (recenter (truncate (* (window-height) 0.25)) t)
   (require 'pulse)
diff --git a/test/lisp/erc/erc-goodies-tests.el b/test/lisp/erc/erc-goodies-tests.el
index f08404be687..cd5e051ca63 100644
--- a/test/lisp/erc/erc-goodies-tests.el
+++ b/test/lisp/erc/erc-goodies-tests.el
@@ -46,6 +46,7 @@ erc-keep-place-indicator-mode
              (should window-configuration-change-hook)
              (should erc-keep-place-mode)))
           ;;
+          erc-insert-pre-hook
           erc-modules)
 
       (funcall assert-off)
-- 
2.39.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-5.6-Add-option-to-show-visual-erc-keep-place-indicat.patch --]
[-- Type: text/x-patch, Size: 14561 bytes --]

From b375774e2f114ed5295e83ac31fe130a8b92aefa Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Fri, 9 Dec 2022 22:00:59 -0800
Subject: [PATCH 1/1] [5.6] Add option to show visual erc-keep-place indicator

* lisp/erc/erc-goodies.el (erc-keep-place-indicator-style,
erc-keep-place-indicator-buffer-type,
erc-keep-place-indicator-follow): New options for anchoring kept place
visually.
(erc-keep-place-indicator-line, erc-keep-place-indicator-arrow): New
faces.
(erc--keep-place-indicator-overlay): New internal variable.
(erc--keep-place-indicator-on-window-configuration-change): New
function to subscribe to `window-configuration-change-hook' and maybe
update kept-place indicator.
(erc--keep-place-indicator-setup): New function to initialize buffer
for local module `keep-place-indicator'.
(erc-keep-place-indicator-mode, erc-keep-place-indicator-enable,
erc-keep-place-indicator-disable): New local ERC module.  Depends on
"parent" module `keep-place'.  Like `fill-wrap', this is for now also
deliberately left out of the widget menu for `erc-modules'.
(erc-keep-place-move, erc-keep-place-goto): Add new commands for
manually updating and jumping to keep-place indicator.
(erc-keep-place): Move `erc--keep-place-overlay' when applicable.
* test/lisp/erc/erc-goodies-tests.el (erc-keep-place-indicator-mode):
Add test.
(Bug#59943.)
---
 lisp/erc/erc-goodies.el            | 167 ++++++++++++++++++++++++++++-
 test/lisp/erc/erc-goodies-tests.el | 106 ++++++++++++++++++
 2 files changed, 270 insertions(+), 3 deletions(-)
 create mode 100644 test/lisp/erc/erc-goodies-tests.el

diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 05a21019042..212e2e5340a 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -34,18 +34,26 @@
 (eval-when-compile (require 'cl-lib))
 (require 'erc-common)
 
+(defvar erc--server-reconnecting)
+(defvar erc--target)
+(defvar erc--target-priors)
 (defvar erc-controls-highlight-regexp)
 (defvar erc-controls-remove-regexp)
 (defvar erc-input-marker)
 (defvar erc-insert-marker)
-(defvar erc-server-process)
-(defvar erc-modules)
 (defvar erc-log-p)
+(defvar erc-modules)
+(defvar erc-server-process)
 
+(declare-function erc-beg-of-input-line "erc" nil)
 (declare-function erc-buffer-list "erc" (&optional predicate proc))
+(declare-function erc-display-error-notice "erc" (parsed string))
 (declare-function erc-error "erc" (&rest args))
 (declare-function erc-extract-command-from-line "erc" (line))
-(declare-function erc-beg-of-input-line "erc" nil)
+
+(declare-function fringe-columns "fringe" (side &optional real))
+(declare-function pulse-available-p "pulse" nil)
+(declare-function pulse-momentary-highlight-overlay "pulse" (o &optional face))
 
 (defun erc-imenu-setup ()
   "Setup Imenu support in an ERC buffer."
@@ -160,6 +168,154 @@ keep-place
   ((add-hook 'erc-insert-pre-hook  #'erc-keep-place))
   ((remove-hook 'erc-insert-pre-hook  #'erc-keep-place)))
 
+(defcustom erc-keep-place-indicator-style t
+  "Flavor of visual indicator applied to kept place.
+For use with the `keep-place-indicator' module.  A value of `arrow'
+displays an arrow in the left fringe or margin.  When it's
+`face', ERC adds the face `erc-keep-place-indicator-line' to the
+appropriate line.  A value of t does both."
+  :group 'erc
+  :package-version '(ERC . "5.6")
+  :type '(choice (const t) (const server) (const target)))
+
+(defcustom erc-keep-place-indicator-buffer-type t
+  "ERC buffer type in which to display `keep-place-indicator'.
+A value of t means \"all\" ERC buffers."
+  :group 'erc
+  :package-version '(ERC . "5.6")
+  :type '(choice (const t) (const server) (const target)))
+
+(defcustom erc-keep-place-indicator-follow nil
+  "Whether to sync visual kept place to window's top when reading.
+For use with `erc-keep-place-indicator-mode'."
+  :group 'erc
+  :package-version '(ERC . "5.6")
+  :type 'boolean)
+
+(defface erc-keep-place-indicator-line
+  '((((class color) (min-colors 88) (background light)
+      (supports :underline (:style wave)))
+     (:underline (:color "PaleGreen3" :style wave)))
+    (((class color) (min-colors 88) (background dark)
+      (supports :underline (:style wave)))
+     (:underline (:color "PaleGreen1" :style wave)))
+    (t :underline t))
+  "Face for option `erc-keep-place-indicator-style'."
+  :group 'erc-faces)
+
+(defface erc-keep-place-indicator-arrow
+  '((((class color) (min-colors 88) (background light))
+     (:foreground "PaleGreen3"))
+    (((class color) (min-colors 88) (background dark))
+     (:foreground "PaleGreen1"))
+    (t :inherit fringe))
+  "Face for arrow value of option `erc-keep-place-indicator-style'."
+  :group 'erc-faces)
+
+(defvar-local erc--keep-place-indicator-overlay nil
+  "Overlay for `erc-keep-place-indicator-mode'.")
+
+(defun erc--keep-place-indicator-on-window-configuration-change ()
+  "Maybe sync `erc--keep-place-indicator-overlay'.
+Specifically, do so unless switching to or from another window in
+the active frame."
+  (when erc-keep-place-indicator-follow
+    (unless (or (minibuffer-window-active-p (minibuffer-window))
+                (eq (window-old-buffer) (current-buffer)))
+      (when (< (overlay-end erc--keep-place-indicator-overlay)
+               (window-start)
+               erc-insert-marker)
+        (erc-keep-place-move (window-start))))))
+
+(defun erc--keep-place-indicator-setup ()
+  "Initialize buffer for maintaining `erc--keep-place-indicator-overlay'."
+  (require 'fringe)
+  (setq erc--keep-place-indicator-overlay
+        (if-let* ((vars (or erc--server-reconnecting erc--target-priors))
+                  ((alist-get 'erc-keep-place-indicator-mode vars)))
+            (alist-get 'erc--keep-place-indicator-overlay vars)
+          (make-overlay 0 0)))
+  (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)))
+              (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))
+  (when (memq erc-keep-place-indicator-style '(t face))
+    (overlay-put erc--keep-place-indicator-overlay 'face
+                 'erc-keep-place-indicator-line)))
+
+;;;###autoload(put 'keep-place-indicator 'erc--feature 'erc-goodies)
+(define-erc-module keep-place-indicator nil
+  "`keep-place' with a fringe arrow and/or highlighted face."
+  ((unless erc-keep-place-mode
+     (unless (memq 'keep-place erc-modules)
+       ;; FIXME use `erc-button--display-error-notice-with-keys'
+       ;; to display this message when bug#60933 is ready.
+       (erc-display-error-notice
+        nil (concat
+             "Local module `keep-place-indicator' needs module `keep-place'."
+             "  Enabling now.  This will affect \C-]all\C-] ERC sessions."
+             "  Add `keep-place' to `erc-modules' to silence this message.")))
+     (erc-keep-place-mode +1))
+   (if (pcase erc-keep-place-indicator-buffer-type
+         ('target erc--target)
+         ('server (not erc--target))
+         ('t t))
+       (erc--keep-place-indicator-setup)
+     (setq erc-keep-place-indicator-mode nil)))
+  ((when erc--keep-place-indicator-overlay
+     (delete-overlay erc--keep-place-indicator-overlay)
+     (remove-hook 'window-configuration-change-hook
+                  #'erc--keep-place-indicator-on-window-configuration-change t)
+     (kill-local-variable 'erc--keep-place-indicator-overlay)))
+  'local)
+
+(defun erc-keep-place-move (pos)
+  "Move keep-place indicator to current line or POS.
+For use with `keep-place-indicator' module.  When called
+interactively, interpret POS as an offset.  Specifically, when
+POS is a raw prefix arg, like (4), move the indicator to the
+window's last line.  When it's the minus sign, put it on the
+window's first line.  Interpret an integer as an offset in lines."
+  (interactive
+   (progn
+     (unless erc-keep-place-indicator-mode
+       (user-error "`erc-keep-place-indicator-mode' not enabled"))
+     (list (pcase current-prefix-arg
+             ((and (pred integerp) v)
+              (save-excursion
+                (let ((inhibit-field-text-motion t))
+                  (forward-line v)
+                  (point))))
+             (`(,_) (1- (min erc-insert-marker (window-end))))
+             ('- (min (1- erc-insert-marker) (window-start)))))))
+  (save-excursion
+    (let ((inhibit-field-text-motion t))
+      (when pos
+        (goto-char pos))
+      (move-overlay erc--keep-place-indicator-overlay
+                    (line-beginning-position)
+                    (line-end-position)))))
+
+(defun erc-keep-place-goto ()
+  "Jump to keep-place indicator.
+For use with `keep-place-indicator' module."
+  (interactive
+   (prog1 nil
+     (unless erc-keep-place-indicator-mode
+       (user-error "`erc-keep-place-indicator-mode' not enabled"))
+     (deactivate-mark)
+     (push-mark)))
+  (goto-char (overlay-start erc--keep-place-indicator-overlay))
+  (recenter (truncate (* (window-height) 0.25)) t)
+  (require 'pulse)
+  (when (pulse-available-p)
+    (pulse-momentary-highlight-overlay erc--keep-place-indicator-overlay)))
+
 (defun erc-keep-place (_ignored)
   "Move point away from the last line in a non-selected ERC buffer."
   (when (and (not (eq (window-buffer (selected-window))
@@ -168,6 +324,11 @@ erc-keep-place
     (deactivate-mark)
     (goto-char (erc-beg-of-input-line))
     (forward-line -1)
+    (when erc-keep-place-indicator-mode
+      (unless (or (minibuffer-window-active-p (selected-window))
+                  (and (frame-visible-p (selected-frame))
+                       (get-buffer-window (current-buffer) (selected-frame))))
+        (erc-keep-place-move nil)))
     ;; if `switch-to-buffer-preserve-window-point' is set,
     ;; we cannot rely on point being saved, and must commit
     ;; it to window-prev-buffers.
diff --git a/test/lisp/erc/erc-goodies-tests.el b/test/lisp/erc/erc-goodies-tests.el
new file mode 100644
index 00000000000..cd5e051ca63
--- /dev/null
+++ b/test/lisp/erc/erc-goodies-tests.el
@@ -0,0 +1,106 @@
+;;; erc-goodies-tests.el --- Tests for erc-goodies  -*- lexical-binding:t -*-
+
+;; Copyright (C) 2023 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+;;
+;; GNU Emacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Code:
+(require 'ert-x)
+(require 'erc)
+(require 'erc-goodies)
+(declare-function erc--initialize-markers "erc" (old-point continued) t)
+
+;; Among other things, this test also asserts that a local module's
+;; minor-mode toggle is allowed to disable its mode variable as
+;; needed.
+
+(ert-deftest erc-keep-place-indicator-mode ()
+  (unless (fboundp 'erc--initialize-markers)
+    (ert-skip "Required patch set for bug#60954 not yet applied"))
+  (with-current-buffer (get-buffer-create "*erc-keep-place-indicator-mode*")
+    (erc-mode)
+    (erc--initialize-markers (point) nil)
+    (let ((assert-off
+           (lambda ()
+             (should-not erc-keep-place-indicator-mode)
+             (should-not (local-variable-p 'window-configuration-change-hook))
+             (should-not erc--keep-place-indicator-overlay)))
+          (assert-on
+           (lambda ()
+             (should erc--keep-place-indicator-overlay)
+             (should (local-variable-p 'window-configuration-change-hook))
+             (should window-configuration-change-hook)
+             (should erc-keep-place-mode)))
+          ;;
+          erc-insert-pre-hook
+          erc-modules)
+
+      (funcall assert-off)
+
+      (ert-info ("Value t")
+        (should (eq erc-keep-place-indicator-buffer-type t))
+        (erc-keep-place-indicator-mode +1)
+        (funcall assert-on)
+        (goto-char (point-min))
+        (should (search-forward "Enabling" nil t))
+        (should (memq 'keep-place erc-modules)))
+
+      (erc-keep-place-indicator-mode -1)
+      (funcall assert-off)
+
+      (ert-info ("Value `target'")
+        (let ((erc-keep-place-indicator-buffer-type 'target))
+          (erc-keep-place-indicator-mode +1)
+          (funcall assert-off)
+          (setq erc--target (erc--target-from-string "#chan"))
+          (erc-keep-place-indicator-mode +1)
+          (funcall assert-on)))
+
+      (erc-keep-place-indicator-mode -1)
+      (funcall assert-off)
+
+      (ert-info ("Value `server'")
+        (let ((erc-keep-place-indicator-buffer-type 'server))
+          (erc-keep-place-indicator-mode +1)
+          (funcall assert-off)
+          (setq erc--target nil)
+          (erc-keep-place-indicator-mode +1)
+          (funcall assert-on)))
+
+      ;; Populate buffer
+      (erc-display-message nil 'notice (current-buffer)
+                           "This buffer is for text that is not saved")
+      (erc-display-message nil 'notice (current-buffer)
+                           "and for lisp evaluation")
+      (should (search-forward "saved" nil t))
+      (erc-keep-place-move nil)
+      (goto-char erc-input-marker)
+
+      (ert-info ("Indicator survives reconnect")
+        (let ((erc--server-reconnecting (buffer-local-variables)))
+          (cl-letf (((symbol-function 'erc-server-connect) #'ignore))
+            (erc-open "localhost" 6667 "tester" "Tester" 'connect
+                      nil nil nil nil nil "tester" nil)))
+        (funcall assert-on)
+        (should (= (point) erc-input-marker))
+        (goto-char (overlay-start erc--keep-place-indicator-overlay))
+        (should (looking-at (rx "*** This buffer is for text")))))
+
+    (when noninteractive
+      (kill-buffer))))
+
+;;; erc-goodies-tests.el ends here
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* bug#59943: 30.0.50; ERC 5.5+: Add visual indicator to ERC keep-place
       [not found] <87fsdndzo1.fsf@neverwas.me>
                   ` (3 preceding siblings ...)
  2023-03-09 14:41 ` J.P.
@ 2023-07-14  2:03 ` J.P.
  2024-01-02 14:47 ` J.P.
  5 siblings, 0 replies; 8+ messages in thread
From: J.P. @ 2023-07-14  2:03 UTC (permalink / raw)
  To: 59943; +Cc: emacs-erc

Reflecting back, I think the decision to tether this local module to the
global module `keep-place' was wrong. A likely usage pattern for this
feature is per-buffer activation, whether interactively or via join
hook. Such users shouldn't be asked to buy into `keep-place' everywhere.
Contrast this with `fill-wrap'. It too is a local module that depends on
a global one, but there's no clear use case for *not* wanting it in some
subset of buffers, so it's effectively global (but technically local for
maintenance reasons).

Anyway, I've gone ahead and fixed this problem [1], so that `keep-place'
and `keep-place-indicator' are completely separate but work in tandem
when `keep-place' is active. However, as implied, the local module can
also operate completely independently.

Thanks.

P.S. Don't be confused by the version in the subject line: the original
`keep-place' is new in ERC 5.6.

[1] https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=2716dd13





^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#59943: 30.0.50; ERC 5.5+: Add visual indicator to ERC keep-place
       [not found] <87fsdndzo1.fsf@neverwas.me>
                   ` (4 preceding siblings ...)
  2023-07-14  2:03 ` J.P.
@ 2024-01-02 14:47 ` J.P.
  2024-01-08  5:47   ` J.P.
  5 siblings, 1 reply; 8+ messages in thread
From: J.P. @ 2024-01-02 14:47 UTC (permalink / raw)
  To: 59943; +Cc: emacs-erc

[-- Attachment #1: Type: text/plain, Size: 918 bytes --]

From emacs -Q

  1. M-: (setopt erc-keep-place-indicator-follow t) RET
     M-x erc RET ... RET

  2. In the server buffer, do M-x erc-keep-place-indicator-mode RET

  3. Scroll "up" to hide the indicator but not so far that point moves
     beyond `erc-insert-marker'

  4. Switch away to another buffer and then back

  5. Notice the indicator fails to update

This happens because `keep-place-indicator' is a local module, and it
adds `erc--keep-place-indicator-on-window-buffer-change' to the hook
`window-buffer-change-functions' locally. But that function needs to run
in the buffer that's being switched to, which may not have the mode
enabled (and thus not have the hook member available). Subscribing to
the hook globally should fix the problem. There are also at least two
bugs affecting the integration between `keep-place-indicator' and
`keep-place'. The attached patch attempts to address these as well.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-5.6-Make-erc-send-input-lines-a-normal-function.patch --]
[-- Type: text/x-patch, Size: 1612 bytes --]

From abc5a18c96617c5040f2ffd2e286befec75c4e0f Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Mon, 1 Jan 2024 00:34:53 -0800
Subject: [PATCH 1/2] [5.6] Make erc--send-input-lines a normal function

* lisp/erc/erc.el (erc--send-input-lines): Revert portion of
174b3dd9bd78c662ce9fff78404dcfa02259d21b "Make nested input handling
more robust in ERC" that converted this from a function to a method.
Instead, defer change until it's needed, likely for bug#49860.  Also,
don't overload `insertp' because user code can legitimately set that
to a function, which we then blindly call.
---
 lisp/erc/erc.el | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 5b3d0d66941..b4f31a361c4 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -7878,14 +7878,12 @@ erc--run-send-hooks
     (user-error "Multiline command detected" ))
   lines-obj)
 
-(cl-defmethod erc--send-input-lines (lines-obj)
+(defun erc--send-input-lines (lines-obj)
   "Send lines in `erc--input-split-lines' object LINES-OBJ."
   (when (erc--input-split-sendp lines-obj)
     (dolist (line (erc--input-split-lines lines-obj))
       (when (erc--input-split-insertp lines-obj)
-        (if (functionp (erc--input-split-insertp lines-obj))
-            (funcall (erc--input-split-insertp lines-obj) line)
-          (erc-display-msg line)))
+        (erc-display-msg line))
       (erc-process-input-line (concat line "\n")
                               (null erc-flood-protect)
                               (not (erc--input-split-cmdp lines-obj))))))
-- 
2.42.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-5.6-Use-global-window-hook-for-erc-keep-place-indica.patch --]
[-- Type: text/x-patch, Size: 10490 bytes --]

From e910a462ce698d364c52438e60618fbe504d7dad Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Mon, 1 Jan 2024 23:18:54 -0800
Subject: [PATCH 2/2] [5.6] Use global window hook for erc-keep-place-indicator

* lisp/erc/erc-goodies.el
(erc--keep-place-indicator-on-window-buffer-change): Expect a frame
instead of a window argument for the only parameter, and exit early
when entering a minibuffer.
(erc--keep-place-indicator-setup): Remove function because local
modules don't need a separate setup function.
(erc-keep-place-indicator-mode, erc-keep-place-indicator-enable,
erc-keep-place-indicator-disable): Move functionality from
`erc--keep-place-indicator-setup' into enable body.  Use global
instead of local members for `erc-keep-place-mode-hook' and
`window-buffer-change-functions'.
(erc--keep-place-indicator-on-global-module): Perform necessary action
in all ERC buffers, not just the current one, where the user has
ostensibly disabled `erc-keep-place-mode'.
* test/lisp/erc/erc-goodies-tests.el
(erc-goodies-tests--assert-kp-indicator-on,
erc-goodies-tests--assert-kp-indicator-off): Change expected hook
membership from global to local.
(erc-goodies-tests--keep-place-indicator): Use new helpers from
erc-tests-common library.  (Bug#59943)
---
 lisp/erc/erc-goodies.el            | 83 ++++++++++++++++--------------
 test/lisp/erc/erc-goodies-tests.el | 18 +++----
 2 files changed, 51 insertions(+), 50 deletions(-)

diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index a0502a3b75c..ea97f2099bc 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -331,14 +331,15 @@ erc-keep-place-indicator-arrow
 (defvar-local erc--keep-place-indicator-overlay nil
   "Overlay for `erc-keep-place-indicator-mode'.")
 
-(defun erc--keep-place-indicator-on-window-buffer-change (window)
+(defun erc--keep-place-indicator-on-window-buffer-change (_)
   "Maybe sync `erc--keep-place-indicator-overlay'.
 Do so only when switching to a new buffer in the same window if
 the replaced buffer is no longer visible in another window and
 its `window-start' at the time of switching is strictly greater
 than the indicator's position."
   (when-let ((erc-keep-place-indicator-follow)
-             ((eq window (selected-window)))
+             (window (selected-window))
+             ((not (eq window (active-minibuffer-window))))
              (old-buffer (window-old-buffer window))
              ((buffer-live-p old-buffer))
              ((not (eq old-buffer (current-buffer))))
@@ -352,67 +353,69 @@ erc--keep-place-indicator-on-window-buffer-change
     (with-current-buffer old-buffer
       (erc-keep-place-move old-start))))
 
-(defun erc--keep-place-indicator-setup ()
-  "Initialize buffer for maintaining `erc--keep-place-indicator-overlay'."
-  (require 'fringe)
-  (erc--restore-initialize-priors erc-keep-place-indicator-mode
-    erc--keep-place-indicator-overlay (make-overlay 0 0))
-  (add-hook 'erc-keep-place-mode-hook
-            #'erc--keep-place-indicator-on-global-module nil t)
-  (add-hook 'window-buffer-change-functions
-            #'erc--keep-place-indicator-on-window-buffer-change 40 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 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)))
-
 ;;;###autoload(put 'keep-place-indicator 'erc--feature 'erc-goodies)
 (define-erc-module keep-place-indicator nil
   "Buffer-local `keep-place' with fringe arrow and/or highlighted face.
 Play nice with global module `keep-place' but don't depend on it.
 Expect that users may want different combinations of `keep-place'
-and `keep-place-indicator' in different buffers.  Unlike global
-`keep-place', when `switch-to-buffer-preserve-window-point' is
-enabled, don't forcibly sync point in all windows where buffer
-has previously been shown because that defeats the purpose of
-having a placeholder."
+and `keep-place-indicator' in different buffers."
   ((cond (erc-keep-place-mode)
          ((memq 'keep-place erc-modules)
           (erc-keep-place-mode +1))
          ;; Enable a local version of `keep-place-mode'.
          (t (add-hook 'erc-insert-pre-hook  #'erc-keep-place 65 t)))
+   (require 'fringe)
+   (add-hook 'window-buffer-change-functions
+             #'erc--keep-place-indicator-on-window-buffer-change 40)
+   (add-hook 'erc-keep-place-mode-hook
+             #'erc--keep-place-indicator-on-global-module 40)
    (if (pcase erc-keep-place-indicator-buffer-type
          ('target erc--target)
          ('server (not erc--target))
          ('t t))
-       (erc--keep-place-indicator-setup)
+       (progn
+         (erc--restore-initialize-priors erc-keep-place-indicator-mode
+           erc--keep-place-indicator-overlay (make-overlay 0 0))
+         (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 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)))
      (erc-keep-place-indicator-mode -1)))
   ((when erc--keep-place-indicator-overlay
      (delete-overlay erc--keep-place-indicator-overlay))
-   (remove-hook 'window-buffer-change-functions
-                #'erc--keep-place-indicator-on-window-buffer-change t)
+   (let ((buffer (current-buffer)))
+     ;; Remove global hooks unless others exist with mode enabled.
+     (unless (erc-buffer-filter (lambda ()
+                                  (and (not (eq buffer (current-buffer)))
+                                       erc-keep-place-indicator-mode)))
+       (remove-hook 'erc-keep-place-mode-hook
+                    #'erc--keep-place-indicator-on-global-module)
+       (remove-hook 'window-buffer-change-functions
+                    #'erc--keep-place-indicator-on-window-buffer-change)))
+   (when (local-variable-p 'erc-insert-pre-hook)
+     (remove-hook 'erc-insert-pre-hook  #'erc-keep-place t))
    (remove-hook 'erc-keep-place-mode-hook
                 #'erc--keep-place-indicator-on-global-module t)
-   (remove-hook 'erc-insert-pre-hook  #'erc-keep-place t)
    (kill-local-variable 'erc--keep-place-indicator-overlay))
   'local)
 
 (defun erc--keep-place-indicator-on-global-module ()
-  "Ensure `keep-place-indicator' can cope with `erc-keep-place-mode'.
-That is, ensure the local module can survive a user toggling the
-global one."
-  (if erc-keep-place-mode
-      (remove-hook 'erc-insert-pre-hook  #'erc-keep-place t)
-    (add-hook 'erc-insert-pre-hook  #'erc-keep-place 65 t)))
+  "Ensure `keep-place-indicator' survives toggling `erc-keep-place-mode'.
+Do this by simulating `keep-place' in all buffers where
+`keep-place-indicator' is enabled."
+  (erc-with-all-buffers-of-server nil (lambda () erc-keep-place-indicator-mode)
+    (if erc-keep-place-mode
+        (remove-hook 'erc-insert-pre-hook  #'erc-keep-place t)
+      (add-hook 'erc-insert-pre-hook  #'erc-keep-place 65 t))))
 
 (defun erc-keep-place-move (pos)
   "Move keep-place indicator to current line or POS.
diff --git a/test/lisp/erc/erc-goodies-tests.el b/test/lisp/erc/erc-goodies-tests.el
index bdd197fa5cb..f3de4ba4dd4 100644
--- a/test/lisp/erc/erc-goodies-tests.el
+++ b/test/lisp/erc/erc-goodies-tests.el
@@ -251,15 +251,16 @@ erc-controls-highlight--motd
 
 (defun erc-goodies-tests--assert-kp-indicator-on ()
   (should erc--keep-place-indicator-overlay)
-  (should (local-variable-p 'window-buffer-change-functions))
-  (should window-configuration-change-hook)
+  (should (memq 'erc--keep-place-indicator-on-window-buffer-change
+                window-buffer-change-functions))
   (should (memq 'erc-keep-place erc-insert-pre-hook))
   (should (eq erc-keep-place-mode
               (not (local-variable-p 'erc-insert-pre-hook)))))
 
 (defun erc-goodies-tests--assert-kp-indicator-off ()
   (should-not (local-variable-p 'erc-insert-pre-hook))
-  (should-not (local-variable-p 'window-buffer-change-functions))
+  (should-not (memq 'erc--keep-place-indicator-on-window-buffer-change
+                    window-buffer-change-functions))
   (should-not erc--keep-place-indicator-overlay))
 
 (defun erc-goodies-tests--kp-indicator-populate ()
@@ -272,12 +273,9 @@ erc-goodies-tests--kp-indicator-populate
   (goto-char erc-input-marker))
 
 (defun erc-goodies-tests--keep-place-indicator (test)
-  (with-current-buffer (get-buffer-create "*erc-keep-place-indicator-mode*")
-    (erc-mode)
-    (erc--initialize-markers (point) nil)
-    (setq erc-server-process
-          (start-process "sleep" (current-buffer) "sleep" "1"))
-    (set-process-query-on-exit-flag erc-server-process nil)
+  (erc-keep-place-mode -1)
+  (with-current-buffer (erc-tests-common-make-server-buf
+                        "*erc-keep-place-indicator-mode*")
     (let (erc-connect-pre-hook
           erc-modules)
 
@@ -294,7 +292,7 @@ erc-goodies-tests--keep-place-indicator
       (should-not (member 'erc-keep-place
                           (default-value 'erc-insert-pre-hook)))
       (should-not (local-variable-p 'erc-insert-pre-hook))
-      (kill-buffer))))
+      (erc-tests-common-kill-buffers))))
 
 (ert-deftest erc-keep-place-indicator-mode--no-global ()
   (erc-goodies-tests--keep-place-indicator
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* bug#59943: 30.0.50; ERC 5.5+: Add visual indicator to ERC keep-place
  2024-01-02 14:47 ` J.P.
@ 2024-01-08  5:47   ` J.P.
  0 siblings, 0 replies; 8+ messages in thread
From: J.P. @ 2024-01-08  5:47 UTC (permalink / raw)
  To: 59943; +Cc: emacs-erc

"J.P." <jp@neverwas.me> writes:

>>From emacs -Q
>
>   1. M-: (setopt erc-keep-place-indicator-follow t) RET
>      M-x erc RET ... RET
>
>   2. In the server buffer, do M-x erc-keep-place-indicator-mode RET
>
>   3. Scroll "up" to hide the indicator but not so far that point moves
>      beyond `erc-insert-marker'
>
>   4. Switch away to another buffer and then back
>
>   5. Notice the indicator fails to update
>
> This happens because `keep-place-indicator' is a local module, and it
> adds `erc--keep-place-indicator-on-window-buffer-change' to the hook
> `window-buffer-change-functions' locally. But that function needs to run
> in the buffer that's being switched to, which may not have the mode
> enabled (and thus not have the hook member available). Subscribing to
> the hook globally should fix the problem. There are also at least two
> bugs affecting the integration between `keep-place-indicator' and
> `keep-place'. The attached patch attempts to address these as well.

This has been installed as:

  fad2d1e2acc * Use global window hook for erc-keep-place-indicator

This bug is already closed.





^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-01-08  5:47 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <87fsdndzo1.fsf@neverwas.me>
2022-12-16 14:26 ` bug#59943: 30.0.50; ERC 5.5+: Add visual indicator to ERC keep-place J.P.
     [not found] ` <87bko3jug8.fsf@neverwas.me>
2023-02-01  2:49   ` J.P.
2023-02-20 15:33 ` J.P.
2023-03-09 14:41 ` J.P.
2023-07-14  2:03 ` J.P.
2024-01-02 14:47 ` J.P.
2024-01-08  5:47   ` J.P.
2022-12-10 15:52 J.P.

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.