Aha, I have the solution! Put this somewhere in your
(define-advice current-fill-column (:filter-return (rtn) protrusion)
"Advice to allow hanging punctuation when filling text."
;; Get the character after the proposed cutoff point
(let ((end-char (char-after (1+ rtn))))
(if (and end-char
;; Check if character is in the “punctuation” syntax table…
(or (eq (char-syntax end-char) ?.)
;; …or is any of these characters (feel free to add more)
(memq end-char (string-to-list ".,!?;:-"))))
;; If so, return the original value, plus one.
;; Otherwise, do nothing and return the original value.
I’ve tested this with
fill-paragraph, and it should work for all the fill functions (since they all use
current-fill-column when processing each line). I hope you like it! 😇