Hi!

My use case for this was to basically have a formatter for titles that would also save those in the fmt-properties, so that they can be used to generate a table of contents later. That works only as long as there are no titles within a columnar formatter. I thought it'd be nice to use the formatter state properties for that instead of relying on something like a global make-parameter variable.

(I also noticed that fmt-capture also behaves in the same way, in that the state of the producer is separate from the consumer.)

I suppose my current use could be changed to use something like doing two passes over the formatter functions, once to get all of the metadata (and then explicitly not calling something like `columnar`) and another time for the actual layout. But to me it seemed like it would make sense that at least the fmt-properties would be preserved.

I get that you don't want to keep all of the formatter state in the original state, as that would mess up the output, but to me it seemed like the properties would be sensible to keep.

Cheers
Nik


On 1/15/26 1:40 PM, Alex Shinn wrote:
Hi Niklas,

Thanks for the proposal!

The current behavior is intentional.
The columns are generated independently, interleaved,
and as each line is available it's output, updating orig-st.

Updating orig-st with the result of each column would
break the row/col numbers.  What you propose instead is
not updating the full state, but just the non-standard
properties.  I tend to think these should not persist beyond
their columns, but did you have a particular use case in
mind that wasn't behaving as expected?

--
Alex

On Wed, Jan 14, 2026 at 11:07 PM Niklas Böhm via Chicken-hackers <[email protected] <mailto:[email protected]>> wrote:

    Hello everybody, hello Alex,

    I noticed that when using `columnar` that changes to the format state
    get swallowed.  Digging into this, it's due to the copying of the state
    before creating partial output from the following lines (fmt-
    column.scm,
    l. 82f):

                     ;; gen threads through it's own state, ignore result
                     (gen (fmt-set-writer! (copy-fmt-state st) output*))

    All of the changes to `st` within the gen function will then ignored.
    Now I am not exactly sure which changes we want to preserve, but I
    believe that at least the `properties` should be kept, as they might
    contain meaningful information (which is how I discovered this bug).
    Would it make sense to preserve more information from the copied state
    or should we leave it at that?  Currently my fix (also attached)
    looks like:

             ;; gen threads through it's own state, copy over properties
             (let ([st (gen (fmt-set-writer! (copy-fmt-state st) output*))])
               (fmt-set-properties! orig-st (fmt-properties st)))


    Let me know what you think, would be happy to see this included.

    Cheers
    Nik



Reply via email to