I wrote the following which loops over a region and inserts newlines. Instead of using forward-sentence
which didn't work for me, I use re-search-forward "[.?!][]\"')}]*\\( \\)"
, which finds all sentences followed only by two spaces (the regexp is a modified sentence-end
). The newline is made using newline-and-indent
.
(defun fill-sentences-in-paragraph ()
"Put a newline at the end of each sentence in paragraph."
(interactive)
(save-excursion
(mark-paragraph)
(call-interactively 'fill-sentences-in-region)))
(defun fill-sentences-in-region (start end)
"Put a newline at the end of each sentence in region."
(interactive "*r")
(call-interactively 'unfill-region)
(save-excursion
(goto-char start)
(while (re-search-forward "[.?!][]\"')}]*\\( \\)" end t)
(newline-and-indent))))
To be able to fix improperly formatted text such as the example "chat chat chat...", fill-sentences-in-region
first calls unfill-region
which gets rid of sentence-breaking whitespace:
(defun unfill-region (beg end)
"Unfill the region, joining text paragraphs into a
single logical line. This is useful, e.g., for use
with 'visual-line-mode'."
(interactive "*r")
(let ((fill-column (point-max)))
(fill-region beg end)))
I use visual-line-mode
and replace my default paragraph fill M-q
to fill-sentences-in-paragraph
with (global-set-key "\M-q" 'fill-sentences-in-paragraph)
.