Subject: bug#78927: closed (Re: bug#78927: [PATCH] Update `fill-region-as-paragraph-semlf' to follow fill.el protocols)

From: [email-masked] (GNU bug Tracking System)
Date: Mon, 30 Jun 2025 21:35:02 +0000

Your bug report

#78927: [PATCH] Update `fill-region-as-paragraph-semlf' to follow fill.el protocols

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
78927: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=78927
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#78927: [PATCH] Update `fill-region-as-paragraph-semlf' to follow fill.el protocols
From: Stefan Monnier <[email-masked]>
To: Roi Martin <[email-masked]>
Cc: [email-masked], Eli Zaretskii <[email-masked]>
Date: Mon, 30 Jun 2025 17:34:06 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

> I've attached a new version of the patch.  It addresses Stefan's
> comments and reimplements the `fill-paragraph-semlf' function using
> `fill-paragraph' and `fill-region-as-paragraph-function'.

Thanks, pushed,

        Stefan

Subject: [PATCH] Update `fill-region-as-paragraph-semlf' to follow fill.el protocols
From: Roi Martin <[email-masked]>
To: [email-masked]
Date: Mon, 30 Jun 2025 13:09:57 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Tags: patch

This patch updates the `fill-region-as-paragraph-semlf' function to
follow the `fill-region-as-paragraph-function' protocol.  This allows to
delete the `fill-paragraph-semlf' function, which is replaced by
`fill-paragraph' combined with assigning
`fill-region-as-paragraph-semlf' to `fill-region-as-paragraph-function'.

Stefan, I also took the opportunity to remove the `with-restriction'
call from `fill-region-as-paragraph-semlf', as discussed in:

https://debbugs.gnu.org/cgi/bugreport.cgi?bug=78561#47

Given that `fill-paragraph-semlf' is not part of any stable release of
GNU Emacs, I guess it is fine to remove it.  Is this a fair assumption?

        Roi

>From 964fc161e32a05d8b252d09b0c6f5fabbc4aa19a Mon Sep 17 00:00:00 2001
From: Roi Martin <[email-masked]>
Date: Tue, 17 Jun 2025 19:21:18 +0200
Subject: [PATCH] Update `fill-region-as-paragraph-semlf' to follow fill.el
 protocols

Update the `fill-region-as-paragraph-semlf' function to follow the
`fill-region-as-paragraph-function' protocol.  This allows to delete the
`fill-paragraph-semlf' function, which is replaced by `fill-paragraph'
combined with assigning `fill-region-as-paragraph-semlf' to
`fill-region-as-paragraph-function'.
* lisp/textmodes/fill.el (fill-region-as-paragraph-semlf): Make this
function compatible with `fill-region-as-paragraph-function'.  Remove
call to `with-restriction'.
(fill-paragraph-semlf): Delete function.
* test/lisp/textmodes/fill-tests.el (fill-tests--fill-paragraph-semlf):
Add helper function.
(fill-test-semlf-fill-region): Add test.
(fill-test-fill-paragraph-semlf): Remove test.
(fill-test-fill-paragraph-semlf-fill-paragraph-function)
(fill-test-semlf-fill-paragraph, fill-test-fill-paragraph-semlf-justify)
(fill-test-semlf-justify)
(fill-test-fill-paragraph-semlf-sentence-end-double-space)
(fill-test-semlf-sentence-end-double-space)
(fill-test-fill-paragraph-semlf-fill-column, fill-test-semlf-fill-column)
(fill-test-fill-paragraph-semlf-punctuation-marks)
(fill-test-semlf-punctuation-marks, fill-test-fill-paragraph-semlf-twice)
(fill-test-semlf-twice, fill-test-fill-paragraph-semlf-fill-prefix)
(fill-test-semlf-fill-prefix)
(fill-test-fill-paragraph-semlf-indented-block)
(fill-test-semlf-indented-block, fill-test-fill-paragraph-semlf-revert)
(fill-test-semlf-revert, fill-test-fill-paragraph-semlf-emacs-lisp-mode)
(fill-test-semlf-emacs-lisp-mode, fill-test-fill-paragraph-semlf-c-mode)
(fill-test-semlf-c-mode, fill-test-fill-paragraph-semlf-org-mode)
(fill-test-semlf-org-mode, fill-test-fill-paragraph-semlf-markdown-mode)
(fill-test-semlf-markdown-mode): Remove reference to
`fill-paragraph-semlf' from test names.
* test/lisp/textmodes/fill-resources/semlf-fill-region.erts: Add test
data.
* test/lisp/textmodes/fill-resources/semlf-fill-paragraph-function.erts:
Delete file.
* test/lisp/textmodes/fill-resources/semlf-emacs-lisp-mode.erts: Remove
newlines around indented block.
* doc/lispref/text.texi (Filling): Highlight that
`fill-region-as-paragraph-function' changes the behavior of
`fill-paragraph'.
---
 doc/lispref/text.texi                         |   9 +-
 lisp/textmodes/fill.el                        |  90 +++++----------
 .../fill-resources/semlf-emacs-lisp-mode.erts |   8 +-
 .../semlf-fill-paragraph-function.erts        |  12 --
 .../fill-resources/semlf-fill-region.erts     |  25 +++++
 test/lisp/textmodes/fill-tests.el             | 104 ++++++++++--------
 6 files changed, 122 insertions(+), 126 deletions(-)
 delete mode 100644 test/lisp/textmodes/fill-resources/semlf-fill-paragraph-function.erts
 create mode 100644 test/lisp/textmodes/fill-resources/semlf-fill-region.erts

diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index fe3863db810d..b01df8512b72 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -1848,10 +1848,11 @@ Filling
 
 @defvar fill-region-as-paragraph-function
 This variable provides a way to override how functions like
-@code{fill-region} fill text.  Its value should be a function, which
-should accept the arguments defined by @code{fill-region-as-paragraph}
-and return the fill prefix used for filling.  The default value of this
-variable is @code{fill-region-as-paragraph-default}.
+@code{fill-paragraph} and @code{fill-region} fill text.  Its value
+should be a function, which should accept the arguments defined by
+@code{fill-region-as-paragraph} and return the fill prefix used for
+filling.  The default value of this variable is
+@code{fill-region-as-paragraph-default}.
 @end defvar
 
 @defvar use-hard-newlines
diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el
index bb10890141d6..87568c14c62b 100644
--- a/lisp/textmodes/fill.el
+++ b/lisp/textmodes/fill.el
@@ -1641,7 +1641,12 @@ fill-region-as-paragraph-semlf
 
 Return the `fill-prefix' used for filling.
 
-For more details about semantic linefeeds, see `fill-paragraph-semlf'."
+This function can be assigned to `fill-region-as-paragraph-function' to
+override how functions like `fill-paragraph' and `fill-region' fill
+text.
+
+For more details about semantic linefeeds, see `https://sembr.org/' and
+`https://rhodesmill.org/brandon/2012/one-sentence-per-line/'."
   (interactive (progn
 		 (barf-if-buffer-read-only)
 		 (list (region-beginning)
@@ -1651,67 +1656,32 @@ fill-region-as-paragraph-semlf
     (setq justify 'full))
 
   (let ((from (min from to))
-        (to (max from to))
+        (to (copy-marker (max from to) t))
         pfx)
     (goto-char from)
-    (with-restriction (line-beginning-position) to
-      (let ((fill-column (point-max)))
-        (setq pfx (or (save-excursion
-                        (fill-region-as-paragraph-default (point)
-                                                          (point-max)
-                                                          nil
-                                                          nosqueeze
-                                                          squeeze-after))
-                      "")))
-      (while (not (eobp))
-        (let ((fill-prefix pfx))
-	  (fill-region-as-paragraph-default (point)
-				            (progn (forward-sentence) (point))
-				            justify
-                                            nosqueeze
-                                            squeeze-after))
-        (when (and (> (point) (line-beginning-position))
-		   (< (point) (line-end-position)))
-	  (delete-horizontal-space)
-	  (insert "\n")
-	  (insert pfx))))
-    (unless (eobp) (forward-char 1))
+    (let ((fill-column (point-max)))
+      (setq pfx (or (save-excursion
+                      (fill-region-as-paragraph-default (point)
+                                                        (marker-position to)
+                                                        nil
+                                                        nosqueeze
+                                                        squeeze-after))
+                    "")))
+    (while (< (point) (marker-position to))
+      (let ((fill-prefix pfx))
+	(fill-region-as-paragraph-default (point)
+				          (min (marker-position to)
+                                               (save-excursion
+                                                 (forward-sentence)
+                                                 (point)))
+				          justify
+                                          t))
+      (when (and (> (point) (line-beginning-position))
+		 (< (point) (line-end-position))
+                 (< (point) (marker-position to)))
+	(delete-horizontal-space)
+	(insert "\n")
+	(insert pfx)))
     pfx))
 
-(defun fill-paragraph-semlf (&optional justify)
-  "Fill paragraph at or after point using semantic linefeeds.
-Refill text putting a newline character after each sentence, calling
-`forward-sentence' to find the ends of sentences.  If
-`sentence-end-double-space' is non-nil, period followed by one space is
-not the end of a sentence.
-
-If JUSTIFY is non-nil (interactively, with prefix argument), justify as
-well.  The variable `fill-column' controls the width for filling.
-
-Return the `fill-prefix' used for filling.
-
-You can use this function as the value of `fill-paragraph-function', so
-`fill-paragraph' and other filling commands will use it.
-
-For more details about semantic linefeeds, see `https://sembr.org/' and
-`https://rhodesmill.org/brandon/2012/one-sentence-per-line/'."
-  (interactive (progn
-		 (barf-if-buffer-read-only)
-		 (list (if current-prefix-arg 'full))))
-  (unless (memq justify '(t nil none full center left right))
-    (setq justify 'full))
-
-  (save-excursion
-    (let ((to (progn
-		(fill-forward-paragraph 1)
-		(backward-word)
-		(end-of-line)
-		(point)))
-	  (from (progn
-		  (fill-forward-paragraph -1)
-		  (forward-word)
-		  (beginning-of-line)
-		  (point))))
-      (fill-region-as-paragraph-semlf from to justify))))
-
 ;;; fill.el ends here
diff --git a/test/lisp/textmodes/fill-resources/semlf-emacs-lisp-mode.erts b/test/lisp/textmodes/fill-resources/semlf-emacs-lisp-mode.erts
index fe71ee32c1aa..1623b0dcf8aa 100644
--- a/test/lisp/textmodes/fill-resources/semlf-emacs-lisp-mode.erts
+++ b/test/lisp/textmodes/fill-resources/semlf-emacs-lisp-mode.erts
@@ -59,12 +59,12 @@ the comment.
 ;; eiusmod tempor.  Incididunt ut labore et dolore magna aliqua. Ut
 ;; enim ad minim veniam, quis nostrud exercitation ullamco laboris
 ;; nisi ut.
-
+;;
 ;; 	|Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
 ;; 	do eiusmod tempor.  Incididunt ut labore et dolore magna
 ;; 	aliqua. Ut enim ad minim veniam, quis nostrud exercitation
 ;; 	ullamco laboris nisi ut.
-
+;;
 ;; Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
 ;; eiusmod tempor.  Incididunt ut labore et dolore magna aliqua. Ut
 ;; enim ad minim veniam, quis nostrud exercitation ullamco laboris
@@ -74,12 +74,12 @@ the comment.
 ;; eiusmod tempor.  Incididunt ut labore et dolore magna aliqua. Ut
 ;; enim ad minim veniam, quis nostrud exercitation ullamco laboris
 ;; nisi ut.
-
+;;
 ;; 	Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
 ;; 	do eiusmod tempor.
 ;; 	Incididunt ut labore et dolore magna aliqua. Ut enim ad minim
 ;; 	veniam, quis nostrud exercitation ullamco laboris nisi ut.
-
+;;
 ;; Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
 ;; eiusmod tempor.  Incididunt ut labore et dolore magna aliqua. Ut
 ;; enim ad minim veniam, quis nostrud exercitation ullamco laboris
diff --git a/test/lisp/textmodes/fill-resources/semlf-fill-paragraph-function.erts b/test/lisp/textmodes/fill-resources/semlf-fill-paragraph-function.erts
deleted file mode 100644
index 467e7401cf50..000000000000
--- a/test/lisp/textmodes/fill-resources/semlf-fill-paragraph-function.erts
+++ /dev/null
@@ -1,12 +0,0 @@
-Name: fill-paragraph-function
-
-=-=
-Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
-eiusmod tempor.  Incididunt ut labore et dolore magna aliqua. Ut enim
-ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut.
-=-=
-Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
-eiusmod tempor.
-Incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
-quis nostrud exercitation ullamco laboris nisi ut.
-=-=-=
diff --git a/test/lisp/textmodes/fill-resources/semlf-fill-region.erts b/test/lisp/textmodes/fill-resources/semlf-fill-region.erts
new file mode 100644
index 000000000000..231019a082a4
--- /dev/null
+++ b/test/lisp/textmodes/fill-resources/semlf-fill-region.erts
@@ -0,0 +1,25 @@
+Point-Char: |
+
+Name: fill-region-as-paragraph-function
+
+=-=
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.  Incididunt ut labore et dolore magna aliqua.
+
+|Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.  Incididunt ut labore et dolore magna aliqua.
+
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.  Incididunt ut labore et dolore magna aliqua.
+
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.  Incididunt ut labore et dolore magna aliqua.
+=-=
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.  Incididunt ut labore et dolore magna aliqua.
+
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+eiusmod tempor.
+Incididunt ut labore et dolore magna aliqua.
+
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+eiusmod tempor.
+Incididunt ut labore et dolore magna aliqua.
+
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.  Incididunt ut labore et dolore magna aliqua.
+=-=-=
diff --git a/test/lisp/textmodes/fill-tests.el b/test/lisp/textmodes/fill-tests.el
index 310d374a7adb..40ef907586fe 100644
--- a/test/lisp/textmodes/fill-tests.el
+++ b/test/lisp/textmodes/fill-tests.el
@@ -147,103 +147,115 @@ fill-test-fill-region-as-paragraph-semlf
                            (beginning-of-line)
                            (point))))))
 
-(ert-deftest fill-test-fill-paragraph-semlf ()
-  "Test the `fill-paragraph-semlf' function."
-  (ert-test-erts-file (ert-resource-file "semlf.erts")
+(ert-deftest fill-test-semlf-fill-region ()
+  "Test `fill-region' with `fill-region-as-paragraph-semlf'."
+  (ert-test-erts-file (ert-resource-file "semlf-fill-region.erts")
                       (lambda ()
-			(fill-paragraph-semlf))))
+			(setq-local fill-region-as-paragraph-function
+                                    #'fill-region-as-paragraph-semlf)
+			(fill-region
+                         (point)
+                         (progn
+                           (goto-char (point-max))
+                           (forward-line -1)
+                           (beginning-of-line)
+                           (point))))))
 
-(ert-deftest fill-test-fill-paragraph-semlf-fill-paragraph-function ()
-  "Test `fill-paragraph-semlf' as `fill-paragraph-function'."
-  (ert-test-erts-file (ert-resource-file "semlf-fill-paragraph-function.erts")
+(defun fill-tests--fill-paragraph-semlf (&optional justify region)
+  "Call `fill-paragraph' using `fill-region-as-paragraph-semlf'."
+  (let ((fill-region-as-paragraph-function #'fill-region-as-paragraph-semlf))
+    (fill-paragraph justify region)))
+
+(ert-deftest fill-test-semlf-fill-paragraph ()
+  "Test `fill-paragraph' with `fill-region-as-paragraph-semlf'."
+  (ert-test-erts-file (ert-resource-file "semlf.erts")
                       (lambda ()
-			(setq-local fill-paragraph-function #'fill-paragraph-semlf)
-			(fill-paragraph))))
+			(fill-tests--fill-paragraph-semlf))))
 
-(ert-deftest fill-test-fill-paragraph-semlf-justify ()
-  "Test the JUSTIFY parameter of the `fill-paragraph-semlf' function."
+(ert-deftest fill-test-semlf-justify ()
+  "Test semantic-linefeed filling with text justification."
   (ert-test-erts-file (ert-resource-file "semlf-justify.erts")
                       (lambda ()
-			(fill-paragraph-semlf 'justify))))
+			(fill-tests--fill-paragraph-semlf 'justify))))
 
-(ert-deftest fill-test-fill-paragraph-semlf-sentence-end-double-space ()
-  "Test the `fill-paragraph-semlf' function with `sentence-end-double-space'."
+(ert-deftest fill-test-semlf-sentence-end-double-space ()
+  "Test semantic-linefeed filling with `sentence-end-double-space'."
   (ert-test-erts-file (ert-resource-file "semlf-sentence-end-double-space.erts")
                       (lambda ()
 			(setq-local sentence-end-double-space nil)
-			(fill-paragraph-semlf))))
+			(fill-tests--fill-paragraph-semlf))))
 
-(ert-deftest fill-test-fill-paragraph-semlf-fill-column ()
-  "Test the `fill-paragraph-semlf' function with `fill-column'."
+(ert-deftest fill-test-semlf-fill-column ()
+  "Test semantic-linefeed filling with `fill-column'."
   (ert-test-erts-file (ert-resource-file "semlf-fill-column.erts")
                       (lambda ()
 			(setq-local fill-column 35)
-			(fill-paragraph-semlf))))
+			(fill-tests--fill-paragraph-semlf))))
 
-(ert-deftest fill-test-fill-paragraph-semlf-punctuation-marks ()
-  "Test the `fill-paragraph-semlf' function with different punctuation marks."
+(ert-deftest fill-test-semlf-punctuation-marks ()
+  "Test semantic-linefeed filling with different punctuation marks."
   (ert-test-erts-file (ert-resource-file "semlf-punctuation-marks.erts")
                       (lambda ()
-			(fill-paragraph-semlf))))
+			(fill-tests--fill-paragraph-semlf))))
 
-(ert-deftest fill-test-fill-paragraph-semlf-twice ()
-  "Test to run the `fill-paragraph-semlf' function twice."
+(ert-deftest fill-test-semlf-twice ()
+  "Test filling the same text twice using semantic linefeeds."
   (ert-test-erts-file (ert-resource-file "semlf-twice.erts")
                       (lambda ()
 			(goto-char (point-min))
-			(fill-paragraph-semlf)
+			(fill-tests--fill-paragraph-semlf)
 			(goto-char (point-min))
-			(fill-paragraph-semlf))))
+			(fill-tests--fill-paragraph-semlf))))
 
-(ert-deftest fill-test-fill-paragraph-semlf-fill-prefix ()
-  "Test the `fill-paragraph-semlf' function with different fill prefixes."
+(ert-deftest fill-test-semlf-fill-prefix ()
+  "Test semantic-linefeed filling with different fill prefixes."
   (ert-test-erts-file (ert-resource-file "semlf-fill-prefix.erts")
                       (lambda ()
-			(fill-paragraph-semlf))))
+			(fill-tests--fill-paragraph-semlf))))
 
-(ert-deftest fill-test-fill-paragraph-semlf-indented-block ()
-  "Test the `fill-paragraph-semlf' function with an indented block."
+(ert-deftest fill-test-semlf-indented-block ()
+  "Test semantic-linefeed filling with an indented block."
   (ert-test-erts-file (ert-resource-file "semlf-indented-block.erts")
                       (lambda ()
-			(fill-paragraph-semlf))))
+			(fill-tests--fill-paragraph-semlf))))
 
-(ert-deftest fill-test-fill-paragraph-semlf-revert ()
-  "Test that the `fill-paragraph-semlf' function can be reverted."
+(ert-deftest fill-test-semlf-revert ()
+  "Test that semantic-linefeed filling can be reverted."
   (ert-test-erts-file (ert-resource-file "semlf-revert.erts")
                       (lambda ()
                         (fill-paragraph)
-			(fill-paragraph-semlf)
+                        (fill-tests--fill-paragraph-semlf)
                         (fill-paragraph))))
 
-(ert-deftest fill-test-fill-paragraph-semlf-emacs-lisp-mode ()
-  "Test the `fill-paragraph-semlf' function with `emacs-lisp-mode'."
+(ert-deftest fill-test-semlf-emacs-lisp-mode ()
+  "Test semantic-linefeed filling with `emacs-lisp-mode'."
   (ert-test-erts-file (ert-resource-file "semlf-emacs-lisp-mode.erts")
                       (lambda ()
 			(emacs-lisp-mode)
-			(fill-paragraph-semlf))))
+			(fill-tests--fill-paragraph-semlf))))
 
-(ert-deftest fill-test-fill-paragraph-semlf-c-mode ()
-  "Test the `fill-paragraph-semlf' function with `c-mode'."
+(ert-deftest fill-test-semlf-c-mode ()
+  "Test semantic-linefeed filling with `c-mode'."
   (ert-test-erts-file (ert-resource-file "semlf-c-mode.erts")
                       (lambda ()
 			(c-mode)
-			(fill-paragraph-semlf))))
+			(fill-tests--fill-paragraph-semlf))))
 
-(ert-deftest fill-test-fill-paragraph-semlf-org-mode ()
-  "Test the `fill-paragraph-semlf' function with `org-mode'."
+(ert-deftest fill-test-semlf-org-mode ()
+  "Test semantic-linefeed filling with `org-mode'."
   (ert-test-erts-file (ert-resource-file "semlf-org-mode.erts")
                       (lambda ()
 			(org-mode)
-			(fill-paragraph-semlf))))
+			(fill-tests--fill-paragraph-semlf))))
 
 (declare-function markdown-mode "markdown-mode")
-(ert-deftest fill-test-fill-paragraph-semlf-markdown-mode ()
-  "Test the `fill-paragraph-semlf' function with `markdown-mode'."
+(ert-deftest fill-test-semlf-markdown-mode ()
+  "Test semantic-linefeed filling with `markdown-mode'."
   (skip-unless (functionp 'markdown-mode))
   (ert-test-erts-file (ert-resource-file "semlf-markdown-mode.erts")
                       (lambda ()
 			(markdown-mode)
-			(fill-paragraph-semlf))))
+			(fill-tests--fill-paragraph-semlf))))
 
 (provide 'fill-tests)
 
-- 
2.49.0