Subject: bug#78561: [PATCH] Add semantic linefeed support for paragraph filling

From: Roi Martin <[email-masked]>
Date: Mon, 16 Jun 2025 12:14:46 +0200

Eli Zaretskii <[email-masked]> writes:

>> Then, what's better?  Should we remove the following paragraph from the
>> doc string of `fill-paragraph-semlf'?
>> 
>>   You can use this function as the value of ‘fill-paragraph-function’, so
>>   ‘fill-paragraph’ and other filling commands will use it.
>> 
>> Or should we return t in `fill-paragraph-semlf'?
>
> I don't know.  Is returning fill-prefix useful in some important cases?

That's hard to say until we decide how to "wire" the semantic-linefeed
functions with the generic functions already provided by fill.el.  For
instance, coming back to some of the comments done by Stefan,

- How do we fill the paragraphs within the active region?  Should we add
  a new `fill-region-function' variable and provide a
  `fill-region-semlf' function?  Should we have a way to tell fill.el to
  use a custom `fill-region-as-paragraph' function?
- How do we change how major modes fill a paragraph or a region?  For
  instance, in the case of org-mode, how do we combine org-mode's
  fill-paragraph logic with semantic linefeeds?  Should the major mode
  be in charge of providing this feature leveraging the existing
  semantic-linefeed functions?  Should the user change a set of hooks?
  What if the major mode already sets this hooks?

Besides that, `fill-paragraph-semlf' calls `fill-forward-paragraph'
internally, so it already takes into account what the major mode defines
as paragraph.  And, `fill-region-as-paragraph-semlf' calls
`fill-region-as-paragraph' internally, so if we add a hook to customize
this function, it would take that into account.

I guess the safest call for now is to provide `fill-paragraph-semlf' and
`fill-region-as-paragraph-semlf' as commands that users or major modes
can call directly.  What these functions return should make sense in
isolation and, once we know how we want to wire everything together, we
can adapt them to the defined protocols providing wrappers or using
lambdas.  For instance,

  (defun fill-paragraph-function-semlf (&optional justify)
    "Fill paragraph at or after point using semantic linefeeds.
  This is a suitable value for `fill-paragraph-function'.
  
  For more details about semantic linefeeds, see `fill-paragraph-semlf'."
    (fill-paragraph-semlf justify)
    t)

That `fill-paragraph-semlf' returns the `fill-prefix' used to fill the
paragraph seems sound if we expect this function to be used by other
filling functions and matches the behavior of `fill-region-as-paragraph'
and `fill-paragraph' (when `fill-paragraph-function' is nil).

What do you think?  Sorry, but I'm still wrapping my head around all the
nuances of the filling code and how major modes make use of it.

        Roi