diff options
author | F. Jason Park <jp@neverwas.me> | 2024-09-26 21:34:25 -0700 |
---|---|---|
committer | F. Jason Park <jp@neverwas.me> | 2024-10-11 16:13:09 -0700 |
commit | 9906e34f973f15c0f96ebcfcc6ea4d1144bc6e8f (patch) | |
tree | 2795b2a25ad4fb637424e6c46ee80ed64b768371 /lisp/erc/erc-nicks.el | |
parent | 1de2c86317356dbbf5e7f935d3889b2698bc30f6 (diff) | |
download | emacs-9906e34f973f15c0f96ebcfcc6ea4d1144bc6e8f.tar.gz emacs-9906e34f973f15c0f96ebcfcc6ea4d1144bc6e8f.tar.bz2 emacs-9906e34f973f15c0f96ebcfcc6ea4d1144bc6e8f.zip |
Crystallize erc-nicks-track-faces behavior
* etc/ERC-NEWS: Mention changes to `erc-track-faces-normal-list' and
`erc-track-faces-priority-list'. Also mention new choice variant for
option `erc-nicks-track-faces', although that's arguably just a bug fix
because it makes good on previously unrealized behavior implied by the
doc strings.
* lisp/erc/erc-nicks.el (erc-nicks-skip-faces): Remove faces applied by
the `match' module, namely, `erc-current-nick-face', `erc-pal-face', and
`erc-fool-face'. That module runs its hooks after `button' on
`erc-insert-modify-hook', and because `nicks' piggybacks on `button', it
can never encounter those faces while assaying.
(erc-nicks-track-faces): Update doc, and introduce new `t' value choice.
(erc-nicks-mode, erc-nicks-disable): Update removals from
`erc-track--alt-normals-function' to reflect recent renamings.
(erc-nicks--reject-uninterned-faces): Use helper.
(erc-nicks--oursp, erc-nicks--ours-p): Rename former to latter to
respect project style guidelines regarding predicates.
(erc-nicks-track-normal-max-rank): New variable.
(erc-nicks--check-normals, erc-nicks--assess-track-faces): Rename former
to latter, and change purpose to checking for "normals" membership,
ranks position, and incumbent face ownership. Remove unused CONTENDERS
parameter. Additionally, change behavior to consider replacing the
current mode-line face when it's not `nicks' owned if it's explicitly
ranked lower than `erc-default-face'.
(erc-nicks--track-prioritize, erc-nicks--track-always): New
complementary functions implementing the t and `prioritize' variants of
`erc-nicks-track-faces'. Both make use of the factored-out
`erc-nicks--check-normals' logic.
(erc-nicks--setup-track-integration): Add `erc-nicks--track-always' to
`erc-track--alt-normals-function' when `erc-track-normal-faces' is t.
* lisp/erc/erc-track.el (erc-track--massage-nick-button-faces): Change
type of symbol property `erc-track--obsolete-faces' for options
`erc-track-faces-priority-list' and friends from a boolean to an alist.
(erc-track-faces-priority-list): Add new face for buttonized speakers.
(erc-track-faces-normal-list): Add new face for buttonized speakers.
Also add `erc-notice-face'.
(erc-track--priority-faces): New local variable to cache ranked faces
and complement `erc-track--normal-faces'.
(erc-track--setup): Initialize new `erc-track--priority-faces' variable,
and refactor.
(erc-track--alt-normals-function): Doc.
(erc-track--select-mode-line-face): Update expected type of `ranks'
parameter.
(erc-track-modified-channels): Fix wrong-type bug occurring when
`erc-track-ignore-normal-contenders-p' and
`erc-track-priority-faces-only' are both non-nil. Also fix subtle
compatibility oversight regarding an empty face list returned by
`erc-track--collect-faces-in'.
* test/lisp/erc/erc-nicks-tests.el: Load helpers and fixtures library.
(erc-nicks-tests--track-faces): New function.
(erc-nicks-track-faces/prioritize, erc-nicks-track-faces/defer)
(erc-nicks-track-faces/nil, erc-nicks-track-faces/t): New tests.
* test/lisp/erc/erc-track-tests.el
(erc-track-tests--select-mode-line-face): Update expected type of mocked
parameter.
(erc-track-tests--modified-channels/baseline): New function.
(erc-track-modified-channels/baseline)
(erc-track-modified-channels/baseline/mention)
(erc-track-modified-channels/baseline/ignore)
(erc-track-modified-channels/baseline/mention/ignore)
(erc-track-modified-channels/priority-only-all/baseline)
(erc-track-modified-channels/priority-only-all/sans-notice): New tests.
* test/lisp/erc/resources/erc-tests-common.el
(erc-tests-common-track-modified-channels)
(erc-tests-common-track-modified-channels-sans-setup): New functions.
(Bug67767)
Diffstat (limited to 'lisp/erc/erc-nicks.el')
-rw-r--r-- | lisp/erc/erc-nicks.el | 92 |
1 files changed, 63 insertions, 29 deletions
diff --git a/lisp/erc/erc-nicks.el b/lisp/erc/erc-nicks.el index a0d6d17d732..6282242f4ac 100644 --- a/lisp/erc/erc-nicks.el +++ b/lisp/erc/erc-nicks.el @@ -89,10 +89,10 @@ ERC only considers this option during module activation, so users should adjust it before connecting." :type '(repeat string)) -(defcustom erc-nicks-skip-faces '( erc-notice-face erc-current-nick-face - erc-my-nick-face erc-pal-face erc-fool-face) +(defcustom erc-nicks-skip-faces '(erc-notice-face erc-my-nick-face) "Faces to avoid highlighting atop." - :type (erc--with-dependent-type-match (repeat face) erc-match)) + :type '(repeat face) + :package-version '(ERC . "5.6.1")) (defcustom erc-nicks-backing-face erc-button-nickname-face "Face to mix with generated one for emphasizing non-speakers." @@ -175,17 +175,20 @@ like \"@%-012n\"." (defcustom erc-nicks-track-faces 'prioritize "Show nick faces in the `track' module's portion of the mode line. -A value of nil means don't show nick faces at all. A value of -`defer' means have `track' consider nick faces only after those -ranked faces in `erc-track-faces-normal-list'. This has the -effect of \"alternating\" between a ranked \"normal\" and a nick. -The value `prioritize' means have `track' consider nick faces to -be \"normal\" unless the current speaker is the same as the -previous one, in which case pretend the value is `defer'. Like -most options in this module, updating the value mid-session is -not officially supported, although cycling \\[erc-nicks-mode] may -be worth a shot." - :type '(choice (const nil) (const defer) (const prioritize))) +A value of nil means don't show `nicks'-managed faces at all. A value +of t means treat them as non-\"normal\" faces ranked at or below +`erc-default-face'. This has the effect of always showing them while +suppressing the \"alternating\" behavior normally associated with +`erc-track-faces-normal-list' (including between the speaker and nicks +mentioned in the message body.) A value of `defer' means treat nicks as +unranked normals to favor alternating between them and ranked normals. +A value of `prioritize' exhibits the same alternating effect as `defer' +when speakers stay the same but allows a new speaker's face to +impersonate a ranked normal so that adjacent speakers alternate among +themselves before deferring to non-face normals. Like most options in +this module, updating the value mid-session is not officially supported, +although cycling \\[erc-nicks-mode] may be worth a shot." + :type '(choice boolean (const defer) (const prioritize))) (defvar erc-nicks--max-skip-search 3 ; make this an option? "Max number of faces to visit when testing `erc-nicks-skip-faces'.") @@ -597,7 +600,9 @@ Abandon search after examining LIMIT faces." (remove-function (local 'erc-button--modify-nick-function) #'erc-nicks--highlight-button) (remove-function (local 'erc-track--alt-normals-function) - #'erc-nicks--check-normals) + #'erc-nicks--track-prioritize) + (remove-function (local 'erc-track--alt-normals-function) + #'erc-nicks--track-always) (remove-hook 'erc-track-mode-hook #'erc-nicks--setup-track-integration t) (setf (alist-get "Edit face" erc-button--nick-popup-alist nil 'remove #'equal) @@ -724,31 +729,57 @@ Expect PREFIX to be something like \"ansi-color-\" or \"font-lock-\"." ((facep next)) ((not (intern-soft next)))) (setq candidate (cdr candidate))) - (if (and (consp candidate) (not (cdr candidate))) (car candidate) candidate)) + (erc--solo candidate)) -(define-inline erc-nicks--oursp (face) +(define-inline erc-nicks--ours-p (face) + "Return uninterned `nicks'-created face if FACE is a known list of faces." (inline-quote (and-let* ((sym (car-safe ,face)) ((symbolp sym)) ((get sym 'erc-nicks--key))) sym))) -(defun erc-nicks--check-normals (current contender contenders normals) - "Return a viable `nicks'-owned face from NORMALS in CONTENDERS. -But only do so if the CURRENT face is also one of ours and in -NORMALS and if the highest ranked CONTENDER among new faces is -`erc-default-face'." - (and-let* (((eq contender 'erc-default-face)) - ((or (null current) (gethash current normals))) - (spkr (or (null current) (erc-nicks--oursp current)))) +(defvar erc-nicks-track-normal-max-rank 'erc-default-face + "Highest priority normal face still eligible to alternate with `nicks' faces. +Must appear in both `erc-track-faces-priority-list' and +`erc-track-faces-normal-list'.") + +(defun erc-nicks--assess-track-faces (current contender ranks normals) + "Return symbol face for CURRENT or t, to mean CURRENT is replaceable. +But only do so if CURRENT and CONTENDER are either nil or \"normal\" +faces ranking at or below `erc-nicks-track-normal-max-rank'. See +`erc-track--select-mode-line-face' for the expected types of RANKS and +NORMALS. Expect a non-nil CONTENDER to always be ranked." + (and-let* + (((or (null contender) (gethash contender normals))) + ((or (null current) (gethash current normals))) + (threshold (gethash erc-nicks-track-normal-max-rank (car ranks))) + ((or (null contender) (<= threshold (gethash contender (car ranks))))) + ((or (erc-nicks--ours-p current) + (null current) + (<= threshold (or (gethash current (car ranks)) 0))))))) + +(defun erc-nicks--track-prioritize (current contender contenders ranks normals) + "Return a viable non-CURRENT `nicks' face among CONTENDERS. +See `erc-track--select-mode-line-face' for parameter types." + (when-let + ((spkr (erc-nicks--assess-track-faces current contender ranks normals))) (catch 'contender - (dolist (candidate (cdr contenders) contender) + (dolist (candidate (cdr contenders)) (when-let (((not (equal candidate current))) - ((gethash candidate normals)) - (s (erc-nicks--oursp candidate)) + (s (erc-nicks--ours-p candidate)) ((not (eq s spkr)))) (throw 'contender candidate)))))) +(defun erc-nicks--track-always (current contender contenders ranks normals) + "Return a viable `nicks' face, possibly CURRENT, among CONTENDERS. +See `erc-track--select-mode-line-face' for parameter types." + (when (erc-nicks--assess-track-faces current contender ranks normals) + (catch 'contender + (dolist (candidate (reverse (cdr contenders))) + (when (erc-nicks--ours-p candidate) + (throw 'contender candidate)))))) + (defun erc-nicks--setup-track-integration () "Restore traditional \"alternating normal\" face functionality to mode-line." (when (bound-and-true-p erc-track-mode) @@ -756,7 +787,10 @@ NORMALS and if the highest ranked CONTENDER among new faces is ;; Variant `defer' is handled elsewhere. ('prioritize (add-function :override (local 'erc-track--alt-normals-function) - #'erc-nicks--check-normals)) + #'erc-nicks--track-prioritize)) + ('t + (add-function :override (local 'erc-track--alt-normals-function) + #'erc-nicks--track-always)) ('nil (add-function :override (local 'erc-track--face-reject-function) #'erc-nicks--reject-uninterned-faces))))) |