Make erc-fill-wrap work with left-sided stamps

* etc/ERC-NEWS: Remove all mention of option `erc-timestamp-align-to'
supporting a value of `margin', which has been abandoned.  Do mention
leading white space before stamps now having stamp-related properties.
* lisp/erc/erc-backend.el (erc--reveal-prompt, erc--conceal-prompt):
New generic functions with default implementations factored out from
`erc--unhide-prompt' and `erc--hide-prompt'.
(erc--prompt-hidden-p): New internal predicate function.
(erc--unhide-prompt): Defer to `erc--reveal-prompt', and set
`erc-prompt' text property to t.
(erc--hide-prompt): Defer to `erc--conceal-prompt', and set
`erc-prompt' text property to `hidden'.
* lisp/erc/erc-compat.el (erc-compat--29-browse-url-irc): Don't
use `function-equal'.
* lisp/erc/erc-fill.el (erc-fill-wrap-margin-width,
erc-fill-wrap-margin-side): New options to control side and initial
width of `fill-wrap' margin.
(erc-fill--wrap-beginning-of-line): Fix bug involving non-string
valued `display' props.
(erc-fill-wrap-toggle-truncate-lines): New command to re-enable
`visual-line-mode' when toggling off `truncate-lines'.
(erc-fill-wrap-mode-map): Remap `toggle-truncate-lines' to
`erc-fill-wrap-toggle-truncate-lines'.
(erc-fill-wrap-mode, erc-fill-wrap-enable, erc-fill-wrap-disable):
Update doc string, persist a few local vars, and conditionally set
`erc-stamp--margin-left-p'.  When deactivating, disable
`visual-line-mode' first.
(erc-fill--wrap-continued-message-p): Use `erc-speaker' instead of
heuristics when comparing nicks between consecutive messages.
(erc-fill-wrap-nudge): Update doc string and account for left-sided
stamps.
(erc-timestamp-offset): Add comment regarding conditional guard based
on function-valued option.
* lisp/erc/erc-stamp.el (erc-timestamp-use-align-to): Remove value
variant `margin', which was originally intended to be new in ERC 5.6.
This functionality was all but useless without the internal minor mode
`erc-stamp--display-margin-mode' active.
(erc-stamp-right-margin-width): Remove unused option new in 5.6.
(erc-stamp--display-margin-force): Remove unused function.
(erc-stamp--margin-width, erc-stamp--margin-left-p): New internal
variables.
(erc-stamp--init-margins-on-connect): New function for initializing
mode-managed margin after connecting.
(erc-stamp--adjust-right-margin, erc-stamp--adjust-margin): Rename
function to latter and accommodate left-hand stamps.
(erc-stamp--inherited-props): Move definition higher up in same file.
(erc-stamp--display-margin-mode): Update function name, and adjust
setup and teardown to accommodate left-handed stamps.  Don't add
advice around `erc-insert-timestamp-function'.
(erc-stamp--last-prompt, erc-stamp--display-prompt-in-left-margin):
New function and helper var to convert a normal inserted prompt so
that it appears in the left margin.
(erc-stamp--refresh-left-margin-prompt): Helper for other modules to
quickly refresh prompt outside of insert hooks.
(erc--reveal-prompt, erc--conceal-prompt): New implementations for
when `erc-stamp--display-margin-mode' is active.
(erc-insert-timestamp-left): Convert to generic function and provide
implementation for `erc-stamp--display-margin-mode'.
(erc-stamp--omit-properties-on-folded-lines): New variable, an escape
hatch for propertizing white space before right-side stamps folded
over onto another line.
(erc-insert-timestamp-right): Don't expect `erc-timestamp-align-to' to
ever be the symbol `margin'.  Move handling for that case to one
contingent on the internal minor mode `erc-stamp--display-margin-mode'
being active.  Add text properties preceding stamps that occupy a line
by their lonesome.  See related news entry for rationale.  This is
arguably a breaking change.
* lisp/erc/erc.el (erc--refresh-prompt-hook): New hook variable for
modules to adjust prompt properties whenever it's refreshed.
(erc--refresh-prompt): Fix bug in which user-defined prompt functions
failed to hide when quitting in server buffers.  Run new hook
`erc--refresh-prompt-hook'.
(erc-display-prompt): Add comment noting that the text property
`erc-prompt' now actually matters: it's t while a session is running
and `hidden' when disconnected.
* test/lisp/erc/erc-fill-tests.el (erc-fill--left-hand-stamps): New
test.
* test/lisp/erc/erc-stamp-tests.el
(erc-stamp-tests--use-align-to--nil,
erc-stamp-tests--use-align-to--t): New functions forged from old test
bodies to allow optionally asserting pre-5.6 behavior regarding
leading white space on right-hand stamps that exist on their own line.
(erc-timestamp-use-align-to--nil, erc-timestamp-use-align-to--t):
Parameterize with compatibility flag.
(erc-timestamp-use-align-to--margin,
erc-stamp--display-margin-mode--right): Rename test to latter.
* test/lisp/erc/erc-tests.el (erc-hide-prompt): Add some assertions
for new possible value of `erc-prompt' text property.
* test/lisp/erc/resources/fill/snapshots/stamps-left-01.eld: New test
data file.  (Bug#60936)
This commit is contained in:
F. Jason Park 2023-07-14 06:12:30 -07:00
parent d09464e504
commit 63d8b2a59a
10 changed files with 352 additions and 116 deletions

View file

@ -103,11 +103,8 @@ side window. Hit '<RET>' over a nick to spawn a "/QUERY" or a
** The option 'erc-timestamp-use-align-to' is more versatile. ** The option 'erc-timestamp-use-align-to' is more versatile.
While this option has always offered to right-align stamps via the While this option has always offered to right-align stamps via the
'display' text property, it's now more effective at doing so when set 'display' text property, it's now more effective at doing so when set
to a number indicating an offset from the right edge. And when set to to a number indicating an offset from the right edge. Users of the
the symbol 'margin', it displays stamps in the right margin, although, 'log' module may want to customize 'erc-log-filter-function' to
at the moment, this is mostly intended for use by other modules, such
as 'fill-wrap', described above. For both these variants, users of
the 'log' module may want to customize 'erc-log-filter-function' to
'erc-stamp-prefix-log-filter' to avoid ragged right-hand stamps 'erc-stamp-prefix-log-filter' to avoid ragged right-hand stamps
appearing in their saved logs. appearing in their saved logs.
@ -228,7 +225,8 @@ Chiefly, 'rear-sticky' has been replaced by 'erc-command', which
records the IRC command (or numeric) associated with a message. Less records the IRC command (or numeric) associated with a message. Less
impactfully, the value of the 'field' property for ERC's prompt has impactfully, the value of the 'field' property for ERC's prompt has
changed from 't' to the more useful 'erc-prompt', although the changed from 't' to the more useful 'erc-prompt', although the
property of the same name has been retained. property of the same name has been retained and now has a value of
'hidden' when disconnected.
*** Members of insert- and send-related hooks have been reordered. *** Members of insert- and send-related hooks have been reordered.
Built-in and third-party modules rely on certain hooks for adjusting Built-in and third-party modules rely on certain hooks for adjusting
@ -261,6 +259,16 @@ Additionally, the 'stamp' module now merges its 'invisible' property
with existing ones, when present, and it includes all white space with existing ones, when present, and it includes all white space
around stamps when doing so. around stamps when doing so.
Moreover, such "propertizing" of surrounding white space now extends
to all 'stamp'-applied properties, like 'field', in all intervening
space between message text and timestamps. This constitutes a
breaking change from the perspective of detecting a timestamp's
bounds. For example, ERC has always propertized leading space before
right-sided stamps on the same line as message text but not those
folded onto the next line. This inconsistency made stamp detection
overly complex and produced uneven results when toggling stamp
visibility.
*** The role of a module's Custom group is now more clearly defined. *** The role of a module's Custom group is now more clearly defined.
Associating built-in modules with Custom groups and provided library Associating built-in modules with Custom groups and provided library
features has improved. More specifically, a module's group now enjoys features has improved. More specifically, a module's group now enjoys

View file

@ -1045,13 +1045,25 @@ Conditionally try to reconnect and take appropriate action."
;; unexpected disconnect ;; unexpected disconnect
(erc-process-sentinel-2 event buffer)))) (erc-process-sentinel-2 event buffer))))
(cl-defmethod erc--reveal-prompt ()
(remove-text-properties erc-insert-marker erc-input-marker
'(display nil)))
(cl-defmethod erc--conceal-prompt ()
(add-text-properties erc-insert-marker (1- erc-input-marker)
`(display ,erc-prompt-hidden)))
(defun erc--prompt-hidden-p ()
(and (marker-position erc-insert-marker)
(eq (get-text-property erc-insert-marker 'erc-prompt) 'hidden)))
(defun erc--unhide-prompt () (defun erc--unhide-prompt ()
(remove-hook 'pre-command-hook #'erc--unhide-prompt-on-self-insert t) (remove-hook 'pre-command-hook #'erc--unhide-prompt-on-self-insert t)
(when (and (marker-position erc-insert-marker) (when (and (marker-position erc-insert-marker)
(marker-position erc-input-marker)) (marker-position erc-input-marker))
(with-silent-modifications (with-silent-modifications
(remove-text-properties erc-insert-marker erc-input-marker (put-text-property erc-insert-marker (1- erc-input-marker) 'erc-prompt t)
'(display nil))))) (erc--reveal-prompt))))
(defun erc--unhide-prompt-on-self-insert () (defun erc--unhide-prompt-on-self-insert ()
(when (and (eq this-command #'self-insert-command) (when (and (eq this-command #'self-insert-command)
@ -1059,6 +1071,8 @@ Conditionally try to reconnect and take appropriate action."
(erc--unhide-prompt))) (erc--unhide-prompt)))
(defun erc--hide-prompt (proc) (defun erc--hide-prompt (proc)
"Hide prompt in all buffers of server.
Change value of property `erc-prompt' from t to `hidden'."
(erc-with-all-buffers-of-server proc nil (erc-with-all-buffers-of-server proc nil
(when (and erc-hide-prompt (when (and erc-hide-prompt
(or (eq erc-hide-prompt t) (or (eq erc-hide-prompt t)
@ -1072,8 +1086,9 @@ Conditionally try to reconnect and take appropriate action."
(marker-position erc-input-marker) (marker-position erc-input-marker)
(get-text-property erc-insert-marker 'erc-prompt)) (get-text-property erc-insert-marker 'erc-prompt))
(with-silent-modifications (with-silent-modifications
(add-text-properties erc-insert-marker (1- erc-input-marker) (put-text-property erc-insert-marker (1- erc-input-marker)
`(display ,erc-prompt-hidden))) 'erc-prompt 'hidden)
(erc--conceal-prompt))
(add-hook 'pre-command-hook #'erc--unhide-prompt-on-self-insert 91 t)))) (add-hook 'pre-command-hook #'erc--unhide-prompt-on-self-insert 91 t))))
(defun erc-process-sentinel (cproc event) (defun erc-process-sentinel (cproc event)

View file

@ -418,7 +418,7 @@ If START or END is negative, it counts from the end."
(require 'url-irc) (require 'url-irc)
(let* ((url (url-generic-parse-url string)) (let* ((url (url-generic-parse-url string))
(url-irc-function (url-irc-function
(if (function-equal url-irc-function 'url-irc-erc) (if (eq url-irc-function 'url-irc-erc)
(lambda (host port chan user pass) (lambda (host port chan user pass)
(erc-handle-irc-url host port chan user pass (url-type url))) (erc-handle-irc-url host port chan user pass (url-type url)))
url-irc-function))) url-irc-function)))

View file

@ -116,6 +116,25 @@ Set to nil to disable."
"The column at which a filled paragraph is broken." "The column at which a filled paragraph is broken."
:type 'integer) :type 'integer)
(defcustom erc-fill-wrap-margin-width nil
"Starting width in columns of dedicated stamp margin.
When nil, ERC normally pretends its value is one column greater
than the `string-width' of the formatted `erc-timestamp-format'.
However, when `erc-fill-wrap-margin-side' is `left' or
\"resolves\" to `left', ERC uses the width of the prompt if it's
wider on MOTD's end, which really only matters when `erc-prompt'
is a function."
:package-version '(ERC . "5.6") ; FIXME sync on release
:type '(choice (const nil) integer))
(defcustom erc-fill-wrap-margin-side nil
"Margin side to use with `erc-fill-wrap-mode'.
A value of nil means ERC should decide based on the value of
`erc-insert-timestamp-function', which does not work for
user-defined functions."
:package-version '(ERC . "5.6") ; FIXME sync on release
:type '(choice (const nil) (const left) (const right)))
(defcustom erc-fill-line-spacing nil (defcustom erc-fill-line-spacing nil
"Extra space between messages on graphical displays. "Extra space between messages on graphical displays.
This may need adjusting depending on how your faces are This may need adjusting depending on how your faces are
@ -253,9 +272,9 @@ messages less than a day apart."
(goto-char erc-input-marker) (goto-char erc-input-marker)
;; Mimic what `move-beginning-of-line' does with invisible text. ;; Mimic what `move-beginning-of-line' does with invisible text.
(when-let ((erc-fill-wrap-merge) (when-let ((erc-fill-wrap-merge)
(empty (get-text-property (point) 'display)) (prop (get-text-property (point) 'display))
((string-empty-p empty))) ((or (equal prop "") (eq 'margin (car-safe (car-safe prop))))))
(goto-char (text-property-not-all (point) (pos-eol) 'display empty))))) (goto-char (text-property-not-all (point) (pos-eol) 'display prop)))))
(defun erc-fill--wrap-end-of-line (arg) (defun erc-fill--wrap-end-of-line (arg)
"Defer to `move-end-of-line' or `end-of-visual-line'." "Defer to `move-end-of-line' or `end-of-visual-line'."
@ -278,12 +297,29 @@ is 0, reset to value of `erc-fill-wrap-visual-keys'."
('non-input nil)))) ('non-input nil))))
(message "erc-fill-wrap movement: %S" erc-fill--wrap-visual-keys)) (message "erc-fill-wrap movement: %S" erc-fill--wrap-visual-keys))
(defun erc-fill-wrap-toggle-truncate-lines (arg)
"Toggle `truncate-lines' and maybe reinstate `visual-line-mode'."
(interactive "P")
(let ((wantp (if arg
(natnump (prefix-numeric-value arg))
(not truncate-lines)))
(buffer (current-buffer)))
(if wantp
(setq truncate-lines t)
(walk-windows (lambda (window)
(when (eq buffer (window-buffer window))
(set-window-hscroll window 0)))
nil t)
(visual-line-mode +1)))
(force-mode-line-update))
(defvar-keymap erc-fill-wrap-mode-map ; Compat 29 (defvar-keymap erc-fill-wrap-mode-map ; Compat 29
:doc "Keymap for ERC's `fill-wrap' module." :doc "Keymap for ERC's `fill-wrap' module."
:parent visual-line-mode-map :parent visual-line-mode-map
"<remap> <kill-line>" #'erc-fill--wrap-kill-line "<remap> <kill-line>" #'erc-fill--wrap-kill-line
"<remap> <move-end-of-line>" #'erc-fill--wrap-end-of-line "<remap> <move-end-of-line>" #'erc-fill--wrap-end-of-line
"<remap> <move-beginning-of-line>" #'erc-fill--wrap-beginning-of-line "<remap> <move-beginning-of-line>" #'erc-fill--wrap-beginning-of-line
"<remap> <toggle-truncate-lines>" #'erc-fill-wrap-toggle-truncate-lines
"C-c a" #'erc-fill-wrap-cycle-visual-movement "C-c a" #'erc-fill-wrap-cycle-visual-movement
;; Not sure if this is problematic because `erc-bol' takes no args. ;; Not sure if this is problematic because `erc-bol' takes no args.
"<remap> <erc-bol>" #'erc-fill--wrap-beginning-of-line) "<remap> <erc-bol>" #'erc-fill--wrap-beginning-of-line)
@ -319,42 +355,57 @@ is 0, reset to value of `erc-fill-wrap-visual-keys'."
"Fill style leveraging `visual-line-mode'. "Fill style leveraging `visual-line-mode'.
This local module displays nicks overhanging leftward to a common This local module displays nicks overhanging leftward to a common
offset, as determined by the option `erc-fill-static-center'. It offset, as determined by the option `erc-fill-static-center'. It
depends on the `fill' and `button' modules and assumes the option depends on the `fill', `stamp', and `button' modules and assumes
`erc-insert-timestamp-function' is `erc-insert-timestamp-right' users who've defined their own `erc-insert-timestamp-function'
or the default `erc-insert-timestamp-left-and-right', so that it have also customized the option `erc-fill-wrap-margin-side' to an
can display right-hand stamps in the right margin. A value of explicit side. To use this module, either include `fill-wrap' in
`erc-insert-timestamp-left' is unsupported. To use it, either `erc-modules' or set `erc-fill-function' to `erc-fill-wrap'.
include `fill-wrap' in `erc-modules' or set `erc-fill-function' Manually invoking one of the minor-mode toggles is not
to `erc-fill-wrap' (recommended). You can also manually invoke recommended.
one of the minor-mode toggles if really necessary."
This module imposes various restrictions on the appearance of
timestamps. Most notably, it insists on displaying them in the
margins. Users preferring left-sided stamps may notice that ERC
also displays the prompt in the left margin, possibly truncating
or padding it to constrain it to the margin's width. When stamps
appear in the right margin, which they do by default, users may
find that ERC actually appends them to copy-as-killed messages
without an intervening space. This normally poses at most a
minor inconvenience, however users of the `log' module may prefer
a workaround provided by `erc-stamp-prefix-log-filter', which
strips trailing stamps from logged messages and instead prepends
them to every line."
((erc-fill--wrap-ensure-dependencies) ((erc-fill--wrap-ensure-dependencies)
;; Restore or initialize local state variables.
(erc--restore-initialize-priors erc-fill-wrap-mode (erc--restore-initialize-priors erc-fill-wrap-mode
erc-fill--wrap-visual-keys erc-fill-wrap-visual-keys erc-fill--wrap-visual-keys erc-fill-wrap-visual-keys
erc-fill--wrap-value erc-fill-static-center) erc-fill--wrap-value erc-fill-static-center
erc-stamp--margin-width erc-fill-wrap-margin-width
left-margin-width left-margin-width
right-margin-width right-margin-width)
(setq erc-stamp--margin-left-p
(or (eq erc-fill-wrap-margin-side 'left)
(eq (default-value 'erc-insert-timestamp-function)
#'erc-insert-timestamp-left)))
(setq erc-fill--function #'erc-fill-wrap) (setq erc-fill--function #'erc-fill-wrap)
;; Internal integrations.
(add-function :after (local 'erc-stamp--insert-date-function) (add-function :after (local 'erc-stamp--insert-date-function)
#'erc-fill--wrap-stamp-insert-prefixed-date) #'erc-fill--wrap-stamp-insert-prefixed-date)
(when (or erc-stamp-mode (memq 'stamp erc-modules))
(erc-stamp--display-margin-mode +1))
(when (or (bound-and-true-p erc-match-mode) (memq 'match erc-modules)) (when (or (bound-and-true-p erc-match-mode) (memq 'match erc-modules))
(require 'erc-match) (require 'erc-match)
(setq erc-match--hide-fools-offset-bounds t)) (setq erc-match--hide-fools-offset-bounds t))
(when erc-fill-wrap-merge (when erc-fill-wrap-merge
(add-hook 'erc-button--prev-next-predicate-functions (add-hook 'erc-button--prev-next-predicate-functions
#'erc-fill--wrap-merged-button-p nil t)) #'erc-fill--wrap-merged-button-p nil t))
(erc-stamp--display-margin-mode +1)
(visual-line-mode +1)) (visual-line-mode +1))
((when erc-stamp--display-margin-mode ((visual-line-mode -1)
(erc-stamp--display-margin-mode -1)) (erc-stamp--display-margin-mode -1)
(kill-local-variable 'erc-fill--wrap-value) (kill-local-variable 'erc-fill--wrap-value)
(kill-local-variable 'erc-fill--function) (kill-local-variable 'erc-fill--function)
(kill-local-variable 'erc-fill--wrap-visual-keys) (kill-local-variable 'erc-fill--wrap-visual-keys)
(remove-hook 'erc-button--prev-next-predicate-functions (remove-hook 'erc-button--prev-next-predicate-functions
#'erc-fill--wrap-merged-button-p t) #'erc-fill--wrap-merged-button-p t)
(remove-function (local 'erc-stamp--insert-date-function) (remove-function (local 'erc-stamp--insert-date-function)
#'erc-fill--wrap-stamp-insert-prefixed-date) #'erc-fill--wrap-stamp-insert-prefixed-date))
(visual-line-mode -1))
'local) 'local)
(defvar-local erc-fill--wrap-length-function nil (defvar-local erc-fill--wrap-length-function nil
@ -381,18 +432,21 @@ parties.")
(widen) (widen)
(when (eq 'erc-timestamp (field-at-pos m)) (when (eq 'erc-timestamp (field-at-pos m))
(set-marker m (field-end m))) (set-marker m (field-end m)))
(and (eq 'PRIVMSG (get-text-property m 'erc-command)) (and-let*
(not (eq (get-text-property m 'erc-ctcp) 'ACTION)) (((eq 'PRIVMSG (get-text-property m 'erc-command)))
(cons (get-text-property m 'erc-timestamp) ((not (eq (get-text-property m 'erc-ctcp)
(get-text-property (1+ m) 'erc-data))))) 'ACTION)))
(spr (next-single-property-change m 'erc-speaker)))
(cons (get-text-property m 'erc-timestamp)
(get-text-property spr 'erc-speaker)))))
(ts (pop props)) (ts (pop props))
((not (time-less-p (erc-stamp--current-time) ts))) ((not (time-less-p (erc-stamp--current-time) ts)))
((time-less-p (time-subtract (erc-stamp--current-time) ts) ((time-less-p (time-subtract (erc-stamp--current-time) ts)
erc-fill--wrap-max-lull)) erc-fill--wrap-max-lull))
(nick (buffer-substring-no-properties (speaker (next-single-property-change (point-min) 'erc-speaker))
(1+ (point-min)) (- (point) 2))) (nick (get-text-property speaker 'erc-speaker))
(props) (props)
((erc-nick-equal-p (car props) nick)))) ((erc-nick-equal-p props nick))))
(set-marker erc-fill--wrap-last-msg (point-min)))) (set-marker erc-fill--wrap-last-msg (point-min))))
(defun erc-fill--wrap-stamp-insert-prefixed-date (&rest args) (defun erc-fill--wrap-stamp-insert-prefixed-date (&rest args)
@ -476,8 +530,8 @@ Offer to repeat command in a manner similar to
\\`=' Increase indentation by one column \\`=' Increase indentation by one column
\\`-' Decrease indentation by one column \\`-' Decrease indentation by one column
\\`0' Reset indentation to the default \\`0' Reset indentation to the default
\\`+' Shift right margin rightward (shrink) by one column \\`+' Shift margin boundary rightward by one column
\\`_' Shift right margin leftward (grow) by one column \\`_' Shift margin boundary leftward by one column
\\`)' Reset the right margin to the default \\`)' Reset the right margin to the default
Note that misalignment may occur when messages contain Note that misalignment may occur when messages contain
@ -489,6 +543,7 @@ decorations applied by third-party modules."
(unless (get-buffer-window) (unless (get-buffer-window)
(user-error "Command called in an undisplayed buffer")) (user-error "Command called in an undisplayed buffer"))
(let* ((total (erc-fill--wrap-nudge arg)) (let* ((total (erc-fill--wrap-nudge arg))
(leftp erc-stamp--margin-left-p)
(win-ratio (/ (float (- (window-point) (window-start))) (win-ratio (/ (float (- (window-point) (window-start)))
(- (window-end nil t) (window-start))))) (- (window-end nil t) (window-start)))))
(when (zerop arg) (when (zerop arg)
@ -509,18 +564,20 @@ decorations applied by third-party modules."
(dolist (key '(?\) ?_ ?+)) (dolist (key '(?\) ?_ ?+))
(let ((a (pcase key (let ((a (pcase key
(?\) 0) (?\) 0)
(?_ (- (abs arg))) (?_ (if leftp (abs arg) (- (abs arg))))
(?+ (abs arg))))) (?+ (if leftp (- (abs arg)) (abs arg))))))
(define-key map (vector (list key)) (define-key map (vector (list key))
(lambda () (lambda ()
(interactive) (interactive)
(erc-stamp--adjust-right-margin (- a)) (erc-stamp--adjust-margin (- a) (zerop a))
(when leftp (erc-stamp--refresh-left-margin-prompt))
(recenter (round (* win-ratio (window-height)))))))) (recenter (round (* win-ratio (window-height))))))))
map) map)
t t
(lambda () (lambda ()
(message "Fill prefix: %d (%+d col%s)" (message "Fill prefix: %d (%+d col%s); Margin: %d"
erc-fill--wrap-value total (if (> (abs total) 1) "s" ""))) erc-fill--wrap-value total (if (> (abs total) 1) "s" "")
(if leftp left-margin-width right-margin-width)))
"Use %k for further adjustment" "Use %k for further adjustment"
1) 1)
(recenter (round (* win-ratio (window-height)))))) (recenter (round (* win-ratio (window-height))))))
@ -536,6 +593,7 @@ decorations applied by third-party modules."
"Get length of timestamp if inserted left." "Get length of timestamp if inserted left."
(if (and (boundp 'erc-timestamp-format) (if (and (boundp 'erc-timestamp-format)
erc-timestamp-format erc-timestamp-format
;; FIXME use a more robust test than symbol equivalence.
(eq erc-insert-timestamp-function 'erc-insert-timestamp-left) (eq erc-insert-timestamp-function 'erc-insert-timestamp-left)
(not erc-hide-timestamps)) (not erc-hide-timestamps))
(length (format-time-string erc-timestamp-format)) (length (format-time-string erc-timestamp-format))

View file

@ -281,49 +281,60 @@ This option only matters when `erc-insert-timestamp-function' is
set to `erc-insert-timestamp-right' or that option's default, set to `erc-insert-timestamp-right' or that option's default,
`erc-insert-timestamp-left-and-right'. If the value is a `erc-insert-timestamp-left-and-right'. If the value is a
positive integer, alignment occurs that many columns from the positive integer, alignment occurs that many columns from the
right edge. If the value is `margin', the stamp appears in the right edge.
right margin when visible.
Enabling this option produces a side effect in that stamps aren't Enabling this option produces a side effect in that stamps aren't
indented in saved logs. When its value is an integer, this indented in saved logs. When its value is an integer, this
option adds a space after the end of a message if the stamp option adds a space after the end of a message if the stamp
doesn't already start with one. And when its value is t, it adds doesn't already start with one. And when its value is t, it adds
a single space, unconditionally. And while this option never a single space, unconditionally."
adds a space when its value is `margin', ERC does offer a :type '(choice boolean integer)
workaround in `erc-stamp-prefix-log-filter', which strips
trailing stamps from messages and puts them before every line."
:type '(choice boolean integer (const margin))
:package-version '(ERC . "5.6")) ; FIXME sync on release :package-version '(ERC . "5.6")) ; FIXME sync on release
(defcustom erc-stamp-right-margin-width nil (defvar-local erc-stamp--margin-width nil
"Width in columns of the right margin. "Width in columns of margin for `erc-stamp--display-margin-mode'.
When this option is nil, pretend its value is one column greater Only consulted when resetting or initializing margin.")
than the `string-width' of the formatted `erc-timestamp-format'.
This option only matters when `erc-timestamp-use-align-to' is set
to `margin'."
:package-version '(ERC . "5.6") ; FIXME sync on release
:type '(choice (const nil) integer))
(defun erc-stamp--display-margin-force (orig &rest r) (defvar-local erc-stamp--margin-left-p nil
(let ((erc-timestamp-use-align-to 'margin)) "Whether `erc-stamp--display-margin-mode' uses the left margin.
(apply orig r))) During initialization, the mode respects this variable's existing
value if it already has a local binding. Otherwise, modules can
bind this to any value while enabling the mode. If it's nil, ERC
will check to see if `erc-insert-timestamp-function' is
`erc-insert-timestamp-left', interpreting the latter as a non-nil
value. It'll then coerce any non-nil value to t.")
(defun erc-stamp--adjust-right-margin (cols) (defun erc-stamp--init-margins-on-connect (&rest _)
"Adjust right margin by COLS. (let ((existing (if erc-stamp--margin-left-p
When COLS is zero, reset width to `erc-stamp-right-margin-width' left-margin-width
or one col more than the `string-width' of right-margin-width)))
`erc-timestamp-format'." (erc-stamp--adjust-margin existing 'resetp)))
(let ((width
(if (zerop cols) (defun erc-stamp--adjust-margin (cols &optional resetp)
(or erc-stamp-right-margin-width "Adjust managed margin by increment COLS.
(1+ (string-width (or erc-timestamp-last-inserted-right With RESETP, set margin's width to COLS. However, if COLS is
(erc-format-timestamp zero, set the width to a non-nil `erc-stamp--margin-width'.
(current-time) Otherwise, go with the `string-width' of `erc-timestamp-format'.
erc-timestamp-format))))) However, when `erc-stamp--margin-left-p' is non-nil and the
(+ right-margin-width cols)))) prompt is wider, use its width instead."
(setq right-margin-width width) (let* ((leftp erc-stamp--margin-left-p)
(width
(if resetp
(or (and (not (zerop cols)) cols)
erc-stamp--margin-width
(max (if leftp (string-width (erc-prompt)) 0)
(1+ (string-width
(or (if leftp
erc-timestamp-last-inserted
erc-timestamp-last-inserted-right)
(erc-format-timestamp
(current-time) erc-timestamp-format))))))
(+ (if leftp left-margin-width right-margin-width) cols))))
(set (if leftp 'left-margin-width 'right-margin-width) width)
(when (eq (current-buffer) (window-buffer)) (when (eq (current-buffer) (window-buffer))
(set-window-margins nil left-margin-width width)))) (set-window-margins nil
(if leftp width left-margin-width)
(if leftp right-margin-width width)))))
;;;###autoload ;;;###autoload
(defun erc-stamp-prefix-log-filter (text) (defun erc-stamp-prefix-log-filter (text)
@ -348,39 +359,100 @@ non-nil."
(zerop (forward-line)))) (zerop (forward-line))))
"") "")
(defvar erc-stamp--inherited-props '(line-prefix wrap-prefix))
(declare-function erc--remove-text-properties "erc" (string)) (declare-function erc--remove-text-properties "erc" (string))
;; If people want to use this directly, we can convert it into ;; Currently, `erc-insert-timestamp-right' hard codes its display
;; a local module. ;; property to use `right-margin', and `erc-insert-timestamp-left'
;; does the same for `left-margin'. However, there's no reason a
;; trailing stamp couldn't be displayed on the left and vice versa.
(define-minor-mode erc-stamp--display-margin-mode (define-minor-mode erc-stamp--display-margin-mode
"Internal minor mode for built-in modules integrating with `stamp'. "Internal minor mode for built-in modules integrating with `stamp'.
It binds `erc-timestamp-use-align-to' to `margin' around calls to Arranges for displaying stamps in a single margin, with the
`erc-insert-timestamp-function' in the current buffer, and sets variable `erc-stamp--margin-left-p' controlling which one.
the right window margin to `erc-stamp-right-margin-width'. It Provides `erc-stamp--margin-width' and `erc-stamp--adjust-margin'
also arranges to remove most text properties when a user kills to help manage the chosen margin's width. Also removes `display'
message text so that stamps will be visible when yanked." properties in killed text to reveal stamps. The invoking module
should set controlling variables, like `erc-stamp--margin-width'
and `erc-stamp--margin-left-p', before activating the mode."
:interactive nil :interactive nil
(if erc-stamp--display-margin-mode (if erc-stamp--display-margin-mode
(progn (progn
(setq fringes-outside-margins t) (setq fringes-outside-margins t)
(when (eq (current-buffer) (window-buffer)) (when (eq (current-buffer) (window-buffer))
(set-window-buffer (selected-window) (current-buffer))) (set-window-buffer (selected-window) (current-buffer)))
(erc-stamp--adjust-right-margin 0) (setq erc-stamp--margin-left-p (and erc-stamp--margin-left-p t))
(if (or erc-server-connected (not (functionp erc-prompt)))
(erc-stamp--init-margins-on-connect)
(add-hook 'erc-after-connect
#'erc-stamp--init-margins-on-connect nil t))
(add-function :filter-return (local 'filter-buffer-substring-function) (add-function :filter-return (local 'filter-buffer-substring-function)
#'erc--remove-text-properties) #'erc--remove-text-properties)
(add-function :around (local 'erc-insert-timestamp-function) (add-hook 'erc--setup-buffer-hook
#'erc-stamp--display-margin-force)) #'erc-stamp--refresh-left-margin-prompt nil t)
(when erc-stamp--margin-left-p
(add-hook 'erc--refresh-prompt-hook
#'erc-stamp--display-prompt-in-left-margin nil t)))
(remove-function (local 'filter-buffer-substring-function) (remove-function (local 'filter-buffer-substring-function)
#'erc--remove-text-properties) #'erc--remove-text-properties)
(remove-function (local 'erc-insert-timestamp-function) (remove-hook 'erc-after-connect
#'erc-stamp--display-margin-force) #'erc-stamp--init-margins-on-connect t)
(kill-local-variable 'right-margin-width) (remove-hook 'erc--refresh-prompt-hook
#'erc-stamp--display-prompt-in-left-margin t)
(remove-hook 'erc--setup-buffer-hook
#'erc-stamp--refresh-left-margin-prompt t)
(kill-local-variable (if erc-stamp--margin-left-p
'left-margin-width
'right-margin-width))
(kill-local-variable 'fringes-outside-margins) (kill-local-variable 'fringes-outside-margins)
(kill-local-variable 'erc-stamp--margin-left-p)
(kill-local-variable 'erc-stamp--margin-width)
(when (eq (current-buffer) (window-buffer)) (when (eq (current-buffer) (window-buffer))
(set-window-margins nil left-margin-width nil) (set-window-margins nil left-margin-width nil)
(set-window-buffer (selected-window) (current-buffer))))) (set-window-buffer (selected-window) (current-buffer)))))
(defun erc-insert-timestamp-left (string) (defvar-local erc-stamp--last-prompt nil)
(defun erc-stamp--display-prompt-in-left-margin ()
"Show prompt in the left margin with padding."
(when (or (not erc-stamp--last-prompt) (functionp erc-prompt)
(> (string-width erc-stamp--last-prompt) left-margin-width))
(let ((s (buffer-substring erc-insert-marker (1- erc-input-marker))))
;; Prevent #("abc" n m (display ((...) #("abc" p q (display...))))
(remove-text-properties 0 (length s) '(display nil) s)
(when (and erc-stamp--last-prompt
(>= (string-width erc-stamp--last-prompt) left-margin-width))
(let ((sm (truncate-string-to-width s (1- left-margin-width) 0 nil t)))
;; This papers over a subtle off-by-1 bug here.
(unless (equal sm s)
(setq s (concat sm (substring s -1))))))
(setq erc-stamp--last-prompt (string-pad s left-margin-width nil t))))
(put-text-property erc-insert-marker (1- erc-input-marker)
'display `((margin left-margin) ,erc-stamp--last-prompt))
erc-stamp--last-prompt)
(defun erc-stamp--refresh-left-margin-prompt ()
"Forcefully-recompute display property of prompt in left margin."
(with-silent-modifications
(unless (functionp erc-prompt)
(setq erc-stamp--last-prompt nil))
(erc--refresh-prompt)))
(cl-defmethod erc--reveal-prompt
(&context (erc-stamp--display-margin-mode (eql t))
(erc-stamp--margin-left-p (eql t)))
(put-text-property erc-insert-marker (1- erc-input-marker)
'display `((margin left-margin) ,erc-stamp--last-prompt)))
(cl-defmethod erc--conceal-prompt
(&context (erc-stamp--display-margin-mode (eql t))
(erc-stamp--margin-left-p (eql t)))
(let ((prompt (string-pad erc-prompt-hidden left-margin-width nil 'start)))
(put-text-property erc-insert-marker (1- erc-input-marker)
'display `((margin left-margin) ,prompt))))
(cl-defmethod erc-insert-timestamp-left (string)
"Insert timestamps at the beginning of the line." "Insert timestamps at the beginning of the line."
(goto-char (point-min)) (goto-char (point-min))
(let* ((ignore-p (and erc-timestamp-only-if-changed-flag (let* ((ignore-p (and erc-timestamp-only-if-changed-flag
@ -392,6 +464,22 @@ message text so that stamps will be visible when yanked."
(erc-put-text-property 0 len 'invisible erc-stamp--invisible-property s) (erc-put-text-property 0 len 'invisible erc-stamp--invisible-property s)
(insert s))) (insert s)))
(cl-defmethod erc-insert-timestamp-left
(string &context (erc-stamp--display-margin-mode (eql t)))
(unless (and erc-timestamp-only-if-changed-flag
(string-equal string erc-timestamp-last-inserted))
(goto-char (point-min))
(insert-before-markers-and-inherit
(setq erc-timestamp-last-inserted string))
(dolist (p erc-stamp--inherited-props)
(when-let ((v (get-text-property (point) p)))
(put-text-property (point-min) (point) p v)))
(erc-put-text-property (point-min) (point) 'invisible
erc-stamp--invisible-property)
(put-text-property (point-min) (point) 'field 'erc-timestamp)
(put-text-property (point-min) (point)
'display `((margin left-margin) ,string))))
(defun erc-insert-aligned (string pos) (defun erc-insert-aligned (string pos)
"Insert STRING at the POSth column. "Insert STRING at the POSth column.
@ -408,7 +496,11 @@ property to get to the POSth column."
;; Silence byte-compiler ;; Silence byte-compiler
(defvar erc-fill-column) (defvar erc-fill-column)
(defvar erc-stamp--inherited-props '(line-prefix wrap-prefix)) (defvar erc-stamp--omit-properties-on-folded-lines nil
"Skip properties before right stamps occupying their own line.
This escape hatch restores pre-5.6 behavior that left leading
white space alone (unpropertized) for right-sided stamps folded
onto their own line.")
(defun erc-insert-timestamp-right (string) (defun erc-insert-timestamp-right (string)
"Insert timestamp on the right side of the screen. "Insert timestamp on the right side of the screen.
@ -465,6 +557,9 @@ printed just after each line's text (no alignment)."
;; For compatibility reasons, the `erc-timestamp' field includes ;; For compatibility reasons, the `erc-timestamp' field includes
;; intervening white space unless a hard break is warranted. ;; intervening white space unless a hard break is warranted.
(pcase erc-timestamp-use-align-to (pcase erc-timestamp-use-align-to
((guard erc-stamp--display-margin-mode)
(put-text-property 0 (length string)
'display `((margin right-margin) ,string) string))
((and 't (guard (< col pos))) ((and 't (guard (< col pos)))
(insert " ") (insert " ")
(put-text-property from (point) 'display `(space :align-to ,pos))) (put-text-property from (point) 'display `(space :align-to ,pos)))
@ -475,11 +570,8 @@ printed just after each line's text (no alignment)."
(let ((s (+ erc-timestamp-use-align-to (string-width string)))) (let ((s (+ erc-timestamp-use-align-to (string-width string))))
(put-text-property from (point) 'display (put-text-property from (point) 'display
`(space :align-to (- right ,s))))) `(space :align-to (- right ,s)))))
('margin ((guard (>= col pos)) (newline) (indent-to pos)
(put-text-property 0 (length string) (when erc-stamp--omit-properties-on-folded-lines (setq from (point))))
'display `((margin right-margin) ,string)
string))
((guard (>= col pos)) (newline) (indent-to pos) (setq from (point)))
(_ (indent-to pos))) (_ (indent-to pos)))
(insert string) (insert string)
(dolist (p erc-stamp--inherited-props) (dolist (p erc-stamp--inherited-props)

View file

@ -2879,19 +2879,23 @@ this option to nil."
(cl-assert (< erc-insert-marker erc-input-marker)) (cl-assert (< erc-insert-marker erc-input-marker))
(cl-assert (= (field-end erc-insert-marker) erc-input-marker))))) (cl-assert (= (field-end erc-insert-marker) erc-input-marker)))))
(defvar erc--refresh-prompt-hook nil)
(defun erc--refresh-prompt () (defun erc--refresh-prompt ()
"Re-render ERC's prompt when the option `erc-prompt' is a function." "Re-render ERC's prompt when the option `erc-prompt' is a function."
(erc--assert-input-bounds) (erc--assert-input-bounds)
(when (functionp erc-prompt) (unless (erc--prompt-hidden-p)
(save-excursion (when (functionp erc-prompt)
(goto-char erc-insert-marker) (save-excursion
(set-marker-insertion-type erc-insert-marker nil) (goto-char erc-insert-marker)
;; Avoid `erc-prompt' (the named function), which appends a (set-marker-insertion-type erc-insert-marker nil)
;; space, and `erc-display-prompt', which propertizes all but ;; Avoid `erc-prompt' (the named function), which appends a
;; that space. ;; space, and `erc-display-prompt', which propertizes all but
(insert-and-inherit (funcall erc-prompt)) ;; that space.
(set-marker-insertion-type erc-insert-marker t) (insert-and-inherit (funcall erc-prompt))
(delete-region (point) (1- erc-input-marker))))) (set-marker-insertion-type erc-insert-marker t)
(delete-region (point) (1- erc-input-marker))))
(run-hooks 'erc--refresh-prompt-hook)))
(defun erc-display-line-1 (string buffer) (defun erc-display-line-1 (string buffer)
"Display STRING in `erc-mode' BUFFER. "Display STRING in `erc-mode' BUFFER.
@ -4804,7 +4808,7 @@ If FACE is non-nil, it will be used to propertize the prompt. If it is nil,
;; shall remain part of the prompt. ;; shall remain part of the prompt.
(setq prompt (propertize prompt (setq prompt (propertize prompt
'rear-nonsticky t 'rear-nonsticky t
'erc-prompt t 'erc-prompt t ; t or `hidden'
'field 'erc-prompt 'field 'erc-prompt
'front-sticky t 'front-sticky t
'read-only t)) 'read-only t))

View file

@ -340,4 +340,41 @@
(should (search-backward "ERC> " nil t)) (should (search-backward "ERC> " nil t))
(execute-kbd-macro "\C-a"))))) (execute-kbd-macro "\C-a")))))
(ert-deftest erc-fill--left-hand-stamps ()
:tags '(:unstable)
(unless (>= emacs-major-version 29)
(ert-skip "Emacs version too low, missing `buffer-text-pixel-size'"))
(let ((erc-timestamp-only-if-changed-flag nil)
(erc-insert-timestamp-function #'erc-insert-timestamp-left))
(erc-fill-tests--wrap-populate
(lambda ()
(should (= 8 left-margin-width))
(pcase-let ((`((margin left-margin) ,displayed)
(get-text-property erc-insert-marker 'display)))
(should (equal-including-properties
displayed #(" ERC>" 4 8
( read-only t
front-sticky t
field erc-prompt
erc-prompt t
rear-nonsticky t
font-lock-face erc-prompt-face)))))
(erc-fill-tests--compare "stamps-left-01")
(ert-info ("Shrink left margin by 1 col")
(erc-stamp--adjust-margin -1)
(with-silent-modifications (erc--refresh-prompt))
(should (= 7 left-margin-width))
(pcase-let ((`((margin left-margin) ,displayed)
(get-text-property erc-insert-marker 'display)))
(should (equal-including-properties
displayed #(" ERC>" 3 7
( read-only t
front-sticky t
field erc-prompt
erc-prompt t
rear-nonsticky t
font-lock-face erc-prompt-face))))))))))
;;; erc-fill-tests.el ends here ;;; erc-fill-tests.el ends here

View file

@ -56,7 +56,7 @@
(advice-remove 'erc-format-timestamp (advice-remove 'erc-format-timestamp
'ert-deftest--erc-timestamp-use-align-to))) 'ert-deftest--erc-timestamp-use-align-to)))
(ert-deftest erc-timestamp-use-align-to--nil () (defun erc-stamp-tests--use-align-to--nil (compat)
(erc-stamp-tests--insert-right (erc-stamp-tests--insert-right
(lambda () (lambda ()
@ -83,12 +83,20 @@
(erc-display-message nil 'notice (current-buffer) (erc-display-message nil 'notice (current-buffer)
"twenty characters")) "twenty characters"))
(should (search-forward-regexp (rx bol (+ "\t") (* " ") "[") nil t)) (should (search-forward-regexp (rx bol (+ "\t") (* " ") "[") nil t))
;; Field excludes leading whitespace (arguably undesirable). ;; Field includes leading whitespace.
(should (eql ?\[ (char-after (field-beginning (point))))) (should (eql (if compat ?\[ ?\n)
(char-after (field-beginning (point)))))
;; Timestamp extends to the end of the line. ;; Timestamp extends to the end of the line.
(should (eql ?\n (char-after (field-end (point))))))))) (should (eql ?\n (char-after (field-end (point)))))))))
(ert-deftest erc-timestamp-use-align-to--t () (ert-deftest erc-timestamp-use-align-to--nil ()
(ert-info ("Field starts on stamp text (compat)")
(let ((erc-stamp--omit-properties-on-folded-lines t))
(erc-stamp-tests--use-align-to--nil 'compat)))
(ert-info ("Field includes leaidng white space")
(erc-stamp-tests--use-align-to--nil nil)))
(defun erc-stamp-tests--use-align-to--t (compat)
(erc-stamp-tests--insert-right (erc-stamp-tests--insert-right
(lambda () (lambda ()
@ -110,10 +118,17 @@
(erc-display-message nil nil (current-buffer) msg))) (erc-display-message nil nil (current-buffer) msg)))
;; Indented to pos (this is arguably a bug). ;; Indented to pos (this is arguably a bug).
(should (search-forward-regexp (rx bol (+ "\t") (* " ") "[") nil t)) (should (search-forward-regexp (rx bol (+ "\t") (* " ") "[") nil t))
;; Field starts *after* leading space (arguably bad). ;; Field includes leading space.
(should (eql ?\[ (char-after (field-beginning (point))))) (should (eql (if compat ?\[ ?\n) (char-after (field-beginning (point)))))
(should (eql ?\n (char-after (field-end (point))))))))) (should (eql ?\n (char-after (field-end (point)))))))))
(ert-deftest erc-timestamp-use-align-to--t ()
(ert-info ("Field starts on stamp text (compat)")
(let ((erc-stamp--omit-properties-on-folded-lines t))
(erc-stamp-tests--use-align-to--t 'compat)))
(ert-info ("Field includes leaidng white space")
(erc-stamp-tests--use-align-to--t nil)))
(ert-deftest erc-timestamp-use-align-to--integer () (ert-deftest erc-timestamp-use-align-to--integer ()
(erc-stamp-tests--insert-right (erc-stamp-tests--insert-right
(lambda () (lambda ()
@ -140,7 +155,7 @@
(should (eql ?\s (char-after (field-beginning (point))))) (should (eql ?\s (char-after (field-beginning (point)))))
(should (eql ?\n (char-after (field-end (point))))))))) (should (eql ?\n (char-after (field-end (point)))))))))
(ert-deftest erc-timestamp-use-align-to--margin () (ert-deftest erc-stamp--display-margin-mode--right ()
(erc-stamp-tests--insert-right (erc-stamp-tests--insert-right
(lambda () (lambda ()
(erc-stamp--display-margin-mode +1) (erc-stamp--display-margin-mode +1)

View file

@ -219,6 +219,7 @@
(setq erc-hide-prompt '(server)) (setq erc-hide-prompt '(server))
(with-current-buffer "ServNet" (with-current-buffer "ServNet"
(erc--hide-prompt erc-server-process) (erc--hide-prompt erc-server-process)
(should (eq (get-text-property erc-insert-marker 'erc-prompt) 'hidden))
(should (string= ">" (get-text-property erc-insert-marker 'display)))) (should (string= ">" (get-text-property erc-insert-marker 'display))))
(with-current-buffer "#chan" (with-current-buffer "#chan"
@ -229,6 +230,7 @@
(with-current-buffer "ServNet" (with-current-buffer "ServNet"
(erc--unhide-prompt) (erc--unhide-prompt)
(should (eq (get-text-property erc-insert-marker 'erc-prompt) t))
(should-not (get-text-property erc-insert-marker 'display)))) (should-not (get-text-property erc-insert-marker 'display))))
(ert-info ("Value: channel") (ert-info ("Value: channel")
@ -242,7 +244,9 @@
(with-current-buffer "#chan" (with-current-buffer "#chan"
(should (string= ">" (get-text-property erc-insert-marker 'display))) (should (string= ">" (get-text-property erc-insert-marker 'display)))
(should (eq (get-text-property erc-insert-marker 'erc-prompt) 'hidden))
(erc--unhide-prompt) (erc--unhide-prompt)
(should (eq (get-text-property erc-insert-marker 'erc-prompt) t))
(should-not (get-text-property erc-insert-marker 'display)))) (should-not (get-text-property erc-insert-marker 'display))))
(ert-info ("Value: query") (ert-info ("Value: query")
@ -253,7 +257,9 @@
(with-current-buffer "bob" (with-current-buffer "bob"
(should (string= ">" (get-text-property erc-insert-marker 'display))) (should (string= ">" (get-text-property erc-insert-marker 'display)))
(should (eq (get-text-property erc-insert-marker 'erc-prompt) 'hidden))
(erc--unhide-prompt) (erc--unhide-prompt)
(should (eq (get-text-property erc-insert-marker 'erc-prompt) t))
(should-not (get-text-property erc-insert-marker 'display))) (should-not (get-text-property erc-insert-marker 'display)))
(with-current-buffer "#chan" (with-current-buffer "#chan"

View file

@ -0,0 +1 @@
#("\n\n[00:00]*** This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.\n[00:00]<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n[00:00]<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 9 (erc-timestamp 0 display (#4=(margin left-margin) #("[00:00]" 0 7 (invisible timestamp font-lock-face erc-timestamp-face))) field erc-timestamp wrap-prefix #1=(space :width 27) line-prefix #2=(space :width (- 27 (4)))) 9 171 (erc-timestamp 0 wrap-prefix #1# line-prefix #2#) 172 179 (erc-timestamp 0 display (#4# #("[00:00]" 0 7 (invisible timestamp font-lock-face erc-timestamp-face))) field erc-timestamp wrap-prefix #1# line-prefix #3=(space :width (- 27 (8)))) 179 180 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 180 185 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 185 187 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 187 190 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 190 303 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 303 304 (erc-timestamp 0 erc-command PRIVMSG) 304 336 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 337 344 (erc-timestamp 0 display (#4# #("[00:00]" 0 7 (invisible timestamp font-lock-face erc-timestamp-face))) field erc-timestamp wrap-prefix #1# line-prefix #5=(space :width (- 27 (6)))) 344 345 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG) 345 348 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG) 348 350 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG) 350 355 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG) 355 430 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG))