Subject: [PATCH] Refactor repunctuate-sentences to accommodate corner case.

From: André A. Gomes <[email-masked]>
Date: Sat, 30 Jul 2022 21:06:16 +0300

Tags: patch

Hi Emacs,

Please find the patch below.

In GNU Emacs 29.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.30, cairo version 1.16.0)
Windowing system distributor 'The X.Org Foundation', version 11.0.12101004
System Description: Guix System

Configured using:
 'configure
 CONFIG_SHELL=/gnu/store/4y5m9lb8k3qkb1y9m02sw9w9a6hacd16-bash-minimal-5.1.8/bin/bash
 SHELL=/gnu/store/4y5m9lb8k3qkb1y9m02sw9w9a6hacd16-bash-minimal-5.1.8/bin/bash
 --prefix=/gnu/store/7a6fnkqrxb0chmvj63f7ddr6wg3pq9g5-emacs-next-29.0.50-1.0a5477b
 --enable-fast-install --with-modules --with-cairo
 --disable-build-details'

>From c57f51b7bfec3e3e5c9c2f680d7936c3e546bb28 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20A=2E=20Gomes?= <[email-masked]>
Date: Sat, 30 Jul 2022 21:01:38 +0300
Subject: [PATCH] Refactor repunctuate-sentences to accommodate corner case.

It now gracefully handles the case when abbreviations such as e.g. or
i.e. are used in sentences.
---
 lisp/textmodes/paragraphs.el            | 32 +++++++++++++------------
 test/lisp/textmodes/paragraphs-tests.el |  5 ++--
 2 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/lisp/textmodes/paragraphs.el b/lisp/textmodes/paragraphs.el
index cd726ad4776..89624b66318 100644
--- a/lisp/textmodes/paragraphs.el
+++ b/lisp/textmodes/paragraphs.el
@@ -506,29 +506,31 @@ It is advised to use `add-function' on this to add more filters,
 for example, `(looking-back (rx (or \"e.g.\" \"i.e.\") \" \") 5)'
 with a set of predefined abbreviations to skip from adding two spaces.")
 
-(defun repunctuate-sentences (&optional no-query start end)
-  "Put two spaces at the end of sentences from point to the end of buffer.
-It works using `query-replace-regexp'.  In Transient Mark mode,
-if the mark is active, operate on the contents of the region.
-Second and third arg START and END specify the region to operate on.
-If optional argument NO-QUERY is non-nil, make changes without asking
-for confirmation.  You can use `repunctuate-sentences-filter' to add
-filters to skip occurrences of spaces that don't need to be replaced."
-  (interactive (list nil
-                     (if (use-region-p) (region-beginning))
-                     (if (use-region-p) (region-end))))
-  (let ((regexp "\\([]\"')]?\\)\\([.?!]\\)\\([]\"')]?\\) +")
-        (to-string "\\1\\2\\3  "))
+(defun repunctuate-sentences (&optional no-query)
+  "Put two spaces at the end of sentences.
+
+In Transient Mark mode, if the mark is active, operate on the
+contents of the region.  If optional argument NO-QUERY is
+non-nil, make changes without asking for confirmation.
+
+Use `repunctuate-sentences-filter' to add filters to skip
+occurrences of spaces that don't need to be replaced."
+  (interactive "P")
+  (let ((beg (if (use-region-p) (region-beginning) (point-min)))
+        (end (if (use-region-p) (region-end) (point-max)))
+        (case-fold-search nil)
+        (regexp "\\([]\"')]?\\)\\([.?!]\\)\\([]\"')]?\\) +\\([\"')[:upper:]]\\)")
+        (to-string "\\1\\2\\3  \\4"))
     (if no-query
         (progn
-          (when start (goto-char start))
+          (goto-char beg)
           (while (re-search-forward regexp end t)
             (replace-match to-string)))
       (unwind-protect
           (progn
             (add-function :after-while isearch-filter-predicate
                           repunctuate-sentences-filter)
-            (query-replace-regexp regexp to-string nil start end))
+            (query-replace-regexp regexp to-string nil beg end))
         (remove-function isearch-filter-predicate
                          repunctuate-sentences-filter)))))
 
diff --git a/test/lisp/textmodes/paragraphs-tests.el b/test/lisp/textmodes/paragraphs-tests.el
index e54b459b20e..53735b4bf4b 100644
--- a/test/lisp/textmodes/paragraphs-tests.el
+++ b/test/lisp/textmodes/paragraphs-tests.el
@@ -101,10 +101,11 @@
 
 (ert-deftest paragraphs-tests-repunctuate-sentences ()
   (with-temp-buffer
-    (insert "Just. Some. Sentences.")
+    (insert "Just. Some. Sentences. Yet another, e.g. this one.")
     (goto-char (point-min))
     (repunctuate-sentences t)
-    (should (equal (buffer-string) "Just.  Some.  Sentences."))))
+    (should (equal (buffer-string)
+                   "Just.  Some.  Sentences.  Yet another, e.g. this one."))))
 
 (ert-deftest paragraphs-tests-backward-sentence ()
   (with-temp-buffer
-- 
2.37.1

-- 
André A. Gomes
"You cannot even find the ruins..."