bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#67677: 30.0.50; ERC 5.6: Use templates for formatting chat messages


From: J.P.
Subject: bug#67677: 30.0.50; ERC 5.6: Use templates for formatting chat messages
Date: Fri, 12 Jan 2024 08:19:15 -0800
User-agent: Gnus/5.13 (Gnus v5.13)

Earlier work for this bug extended ERC's existing template catalog
system with an internal framework for dictating (hopefully more
explicitly and resolutely) how messages materialize in chat buffers.
Modules can make use of this framework to shape most aspects of message
formatting, which opens the door to radically contrasting styles, such
as "multi-part" messages with header/body/footer sections and messages
with integrated time stamps (meaning you can finally ditch that blessed
`stamp' module for good).

However, this approach remains awkward when it comes to

  1. minor modifications

  2. modularity itself (keeping modules loosely coupled)

At present, making use of the framework involves defining an entire
format catalog (although inheritance helps a bit in this regard). But
the boilerplate issue really begins to compound when trying to integrate
with other modules because the process is somewhat dependent on defining
yet more catalogs to serve the various combinations, and more still if
trying to keep things abstract.

To alleviate some of this awkwardness and cut down on the verbosity, I'm
proposing we introduce a more practical extension to this framework.
It'll be reserved for internal use at first, but with an eye toward
eventual export (likely in 5.7). The basic idea is that we define a
single abnormal hook per speaker catalog that runs just prior to
insertion, and we allow its members to influence the parameters passed
to `format-spec'. And, we do so in a convenient and structured (and
reusable) way, so members don't have to twiddle plists in search of a
single ingredient to manually splice into format strings based on the
verdict of some flimsy heuristic.

I'm tentatively calling this hook system "msgfspc" (one word), short for
"message format-spec." It works by defining a struct to accompany each
hook, with slots based on the catalog's common set of template
specifiers. Subscribing code then has the freedom to modify the template
itself and add or subtract specifiers as needed by mutating the struct
instance for that particular formatting pass. The client API looks like
this:

  ;; Module activation body

  (add-hook 'erc-msgfspec-speaker-hook
            #my-maybe-transform-on-msgfspec-speaker nil t)
  (setq my-state "foo")
  
  ;; Top level of package

  (defun my-maybe-transform-on-msgfspec-speaker (spec)
    (pcase spec

      ;; Modify an outgoing message template.

      ((cl-struct erc-msgfspec-speaker
                  (key (or 'input-chan-privmsg 'input-query-privmsg)))
       (erc-msgfspec-insert-spec-after
        spec ?n ?i (propertize "%i" 'font-lock-face 'my-face))
       (push `(?i . ,my-state) (erc-msgfspec-alist spec)))
  
      ;; Modify an incoming message body.

      ((cl-struct erc-msgfspec-speaker
                  (key (or 'chan-privmsg 'query-privmsg))
                  (\?m msg))
       (setf (erc-msgfspec-speaker-?m spec)
             (decode-coding-string (my-transform-message msg)
                                   'utf-8)))))

  ;; Note that at present, all the "erc-foo" symbols above are actually
  ;; "erc--foo" (internal)

There's at least one unfortunate aspect to the API scheme above: the
buffer where the working version of a template resides isn't current
when hooks run. This happens because members still need access to local
state in the ERC buffer where the actual insertion takes place. I've
experimented a bit with using the virtual buffer facility (via
`buffer-swap-text') to get around this, and it appears to work great
(even seemingly shaving a second or two off runs of ERC's extended test
suite). However, I'm quite reticent to introduce something I've never
used before and almost never see in the wild. Thus, this approach will
have to wait pending further investigation.

The current version of the proposed implementation can be found in the
second of the attached patches. The first is from bug#68265 but included
here because the associated demo addressing a real-world use case
requires both. Please see that bug's recent posts for links and
instructions.

Thanks.

Attachment: 0000-v1-v2.diff
Description: Text Data

Attachment: 0001-5.6-Add-replacement-text-field-to-erc-input-struct.patch
Description: Text Data

Attachment: 0002-5.6-Expose-catalog-specific-message-formatter-in-ERC.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]