(defcustom erc-fill-wrap-merge-indicator nil
"Indicator to help distinguish between merged messages.
Only matters when the option `erc-fill-wrap-merge' is enabled.
-If the first element is the symbol `pre', ERC uses this option to
-generate a replacement for the speaker's name tag. If the first
-element is `post', ERC affixes a short string to the end of the
-previous message. In either case, the second element should be a
-character, like ?>, and the last element a valid face. In
-special cases, you may also specify a cons of either
-aforementioned symbol and a string, which tells ERC not to manage
-the process for you. If unsure, try either of the first two
-presets, both of which replace a continued speaker's name with a
-dot-product-like character in a `shadow'-like face.
+If the value is a cons of a character, like ?>, and a valid face,
+ERC generates a replacement for the speaker's name tag. The
+first two presets replace a continued speaker's name with a
+bullet-like character in `shadow' face.
Note that as of ERC 5.6, this option is still experimental, and
changing its value mid-session is not yet supported (though, if
:type
'(choice (const nil)
(const :tag "Leading MIDDLE DOT (U+00B7) as speaker"
- (pre #xb7 erc-fill-wrap-merge-indicator-face))
+ (#xb7 . erc-fill-wrap-merge-indicator-face))
(const :tag "Leading MIDDLE DOT (U+00B7) sans gap"
- (pre . #("\u00b7" 0 1 (font-lock-face
- erc-fill-wrap-merge-indicator-face))))
+ #("\u00b7"
+ 0 1 (font-lock-face erc-fill-wrap-merge-indicator-face)))
(const :tag "Leading RIGHT-ANGLE BRACKET (>) as speaker"
- (pre ?> erc-fill-wrap-merge-indicator-face))
- (const :tag "Trailing PARAGRAPH SIGN (U+00B6)"
- (post #xb6 erc-fill-wrap-merge-indicator-face))
- (const :tag "Trailing TILDE (~)"
- (post ?~ erc-fill-wrap-merge-indicator-face))
- (cons :tag "User-provided string (advanced)"
- (choice (const pre) (const post)) string)
- (list :tag "User-provided character-face pairing"
- (choice (const pre) (const post)) character face)))
+ (?> . erc-fill-wrap-merge-indicator-face))
+ (string :tag "User-provided string (advanced)")
+ (cons :tag "User-provided character-face pairing" character face)))
(defun erc-fill--wrap-move (normal-cmd visual-cmd &rest args)
(apply (pcase erc-fill--wrap-visual-keys
" warning. See Info:\"(erc) Modules\" for more."
(mapcar (lambda (s) (format "`%s'" s)) missing-deps)))))
+(defun erc-fill--wrap-massage-legacy-indicator-type ()
+ "Migrate obsolete 5.6-git `erc-fill-wrap-merge-indicator' format."
+ (pcase erc-fill-wrap-merge-indicator
+ (`(post . ,_)
+ (erc--warn-once-before-connect 'erc-fill-wrap-mode
+ "The option `erc-fill-wrap-merge-indicator' has changed. Unfortunately,"
+ " the `post' variant and related presets are no longer available."
+ " Setting to nil for the current session. Apologies for the disruption."
+ (setq erc-fill-wrap-merge-indicator nil)))
+ (`(pre . ,(and (pred stringp) string))
+ (erc--warn-once-before-connect 'erc-fill-wrap-mode
+ "The format of option `erc-fill-wrap-merge-indicator' has changed"
+ " from a cons of (pre . STRING) to STRING. Please update your settings."
+ " Changing temporarily to \"" string "\" for the current session.")
+ (setq erc-fill-wrap-merge-indicator string))
+ (`(pre ,(and (pred characterp) char) ,face)
+ (erc--warn-once-before-connect 'erc-fill-wrap-mode
+ "The format of option `erc-fill-wrap-merge-indicator' has changed"
+ " from (pre CHAR FACE) to a cons of (CHAR . FACE). Please update"
+ " when possible. Changing temporarily to %S for the current session."
+ (setq erc-fill-wrap-merge-indicator (cons char face))))))
+
;;;###autoload(put 'fill-wrap 'erc--feature 'erc-fill)
(define-erc-module fill-wrap nil
"Fill style leveraging `visual-line-mode'.
specifically, disable its minor mode, `erc-scrolltobottom-mode',
via `erc-fill-wrap-mode-hook'."
((erc-fill--wrap-ensure-dependencies)
+ (when erc-fill-wrap-merge-indicator
+ (erc-fill--wrap-massage-legacy-indicator-type))
(erc--restore-initialize-priors erc-fill-wrap-mode
erc-fill--wrap-visual-keys erc-fill-wrap-visual-keys
erc-fill--wrap-value erc-fill-static-center
(kill-local-variable 'erc-fill--wrap-last-msg)
(kill-local-variable 'erc--inhibit-prompt-display-property-p)
(kill-local-variable 'erc-fill--wrap-merge-indicator-pre)
- (kill-local-variable 'erc-fill--wrap-merge-indicator-post)
(remove-hook 'erc--refresh-prompt-hook
#'erc-fill--wrap-indent-prompt)
(remove-hook 'erc-button--prev-next-predicate-functions
"Whether to dedent speakers in CTCP \"ACTION\" lines.")
(defvar-local erc-fill--wrap-merge-indicator-pre nil)
-(defvar-local erc-fill--wrap-merge-indicator-post nil)
-
-;; To support `erc-fill-line-spacing' with the "post" variant, we'd
-;; need to use a new "replacing" `display' spec value for each
-;; insertion, and add a sentinel property alongside it atop every
-;; affected newline, e.g., (erc-fill-eol-display START-POS), where
-;; START-POS is the position of the newline in the replacing string.
-;; Then, upon spotting this sentinel in `erc-fill' (and maybe
-;; `erc-fill-wrap-refill-buffer'), we'd add `line-spacing' to the
-;; corresponding `display' replacement, starting at START-POS.
-(defun erc-fill--wrap-insert-merged-post ()
- "Add `display' property at end of previous line."
- (save-excursion
- (goto-char (point-min))
- (save-restriction
- (widen)
- (cl-assert (= ?\n (char-before (point))))
- (unless erc-fill--wrap-merge-indicator-post
- (let ((option (cdr erc-fill-wrap-merge-indicator)))
- (setq erc-fill--wrap-merge-indicator-post
- (if (stringp option)
- (concat option
- (and (not (string-suffix-p "\n" option)) "\n"))
- (propertize (concat (string (car option)) "\n")
- 'font-lock-face (cadr option))))))
- (unless (eq (field-at-pos (- (point) 2)) 'erc-timestamp)
- (put-text-property (1- (point)) (point)
- 'display erc-fill--wrap-merge-indicator-post)))
- 0))
(defun erc-fill--wrap-insert-merged-pre ()
"Add `display' property in lieu of speaker."
(put-text-property (point-min) (point) 'display
(car erc-fill--wrap-merge-indicator-pre))
(cdr erc-fill--wrap-merge-indicator-pre))
- (let* ((option (cdr erc-fill-wrap-merge-indicator))
+ (let* ((option erc-fill-wrap-merge-indicator)
(s (if (stringp option)
(concat option)
(concat (propertize (string (car option))
- 'font-lock-face (cadr option))
+ 'font-lock-face (cdr option))
" "))))
(put-text-property (point-min) (point) 'display s)
(cdr (setq erc-fill--wrap-merge-indicator-pre
(put-text-property (point-min) (point)
'display "")
(if erc-fill-wrap-merge-indicator
- (pcase (car erc-fill-wrap-merge-indicator)
- ('pre (erc-fill--wrap-insert-merged-pre))
- ('post (erc-fill--wrap-insert-merged-post)))
+ (erc-fill--wrap-insert-merged-pre)
0))
(t
(erc-fill--wrap-measure (point-min) (point))))))))
With REPAIRP, destructively fill gaps and re-merge speakers."
(goto-char start)
(cl-assert (null erc-fill--wrap-rejigger-last-message))
- (setq erc-fill--wrap-merge-indicator-pre nil
- erc-fill--wrap-merge-indicator-post nil)
+ (setq erc-fill--wrap-merge-indicator-pre nil)
(let (erc-fill--wrap-rejigger-last-message)
(while-let
(((< (point) finish))
(ert-deftest erc-fill-wrap--merge-action/indicator-pre ()
:tags `(:unstable
,@(and (getenv "ERC_TESTS_GRAPHICAL") '(:erc--graphical)))
- (let ((erc-fill-wrap-merge-indicator '(pre ?> shadow)))
+ (let ((erc-fill-wrap-merge-indicator '(?> . shadow)))
(erc-fill-wrap-tests--merge-action "merge-wrap-indicator-pre-01")))
-;; One crucial thing this test asserts is that the indicator is
-;; omitted when the previous line ends in a stamp.
-(ert-deftest erc-fill-wrap--merge-action/indicator-post ()
- :tags `(:unstable
- ,@(and (getenv "ERC_TESTS_GRAPHICAL") '(:erc--graphical)))
- (let ((erc-fill-wrap-merge-indicator '(post ?~ shadow)))
- (erc-fill-wrap-tests--merge-action "merge-wrap-indicator-post-01")))
-
(ert-deftest erc-fill-line-spacing ()
:tags `(:unstable
,@(and (getenv "ERC_TESTS_GRAPHICAL") '(:erc--graphical)))
rear-nonsticky t
font-lock-face erc-prompt-face))))))))))
+(ert-deftest erc-fill--wrap-massage-legacy-indicator-type ()
+ (let (calls
+ erc-fill-wrap-merge-indicator)
+ (cl-letf (((symbol-function 'erc--warn-once-before-connect)
+ (lambda (_ &rest args) (push args calls))))
+ ;; List of (pre CHAR FACE) becomes (CHAR . FACE).
+ (let ((erc-fill-wrap-merge-indicator
+ '(pre #xb7 erc-fill-wrap-merge-indicator-face)))
+ (erc-fill--wrap-massage-legacy-indicator-type)
+ (should (equal erc-fill-wrap-merge-indicator
+ '(#xb7 . erc-fill-wrap-merge-indicator-face)))
+ (should (string-search "(pre CHAR FACE)" (nth 1 (pop calls)))))
+
+ ;; Cons of (CHAR . STRING) becomes STRING.
+ (let ((erc-fill-wrap-merge-indicator '(pre . "\u00b7")))
+ (erc-fill--wrap-massage-legacy-indicator-type)
+ (should (equal erc-fill-wrap-merge-indicator "\u00b7"))
+ (should (string-search "(pre . STRING)" (nth 1 (pop calls)))))
+
+ ;; Anything with a CAR of `post' becomes nil.
+ (let ((erc-fill-wrap-merge-indicator
+ '(post #xb6 erc-fill-wrap-merge-indicator-face)))
+ (erc-fill--wrap-massage-legacy-indicator-type)
+ (should-not erc-fill-wrap-merge-indicator)
+ (should (string-search "no longer available" (nth 1 (pop calls)))))
+ (let ((erc-fill-wrap-merge-indicator '(post . "\u00b7")))
+ (erc-fill--wrap-massage-legacy-indicator-type)
+ (should-not erc-fill-wrap-merge-indicator)
+ (should (string-search "no longer available" (nth 1 (pop calls))))))))
+
;;; erc-fill-tests.el ends here