diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5fc7575..7c9021c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -14,11 +14,9 @@ jobs:
     strategy:
       matrix:
         emacs_version:
-        - 25.1
-        - 25.2
-        - 25.3
         - 26.3
         - 27.2
+        - 28.2
 
     steps:
     - name: Setup GNU Emacs
diff --git a/NEWS.md b/NEWS.md
index 24fef1e..4e60b36 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,12 +1,30 @@
 # numpydoc.el NEWS -- history of user visible changes
 
+## Unreleased
+
+### Changes
+
+- Emit a useful warning if function signature parsing fails
+  ([#18](https://github.com/douglasdavis/numpydoc.el/pull/18)).
+
+## 0.9 (July 24, 2023)
+
+### Changes
+
+- Add new `defcustom`: `numpydoc-auto-fill-paragraphs`, which when set
+  to `t` (the default) will enable automatic paragraph filling for
+  (somewhat) long descriptions.
+  ([#16](https://github.com/douglasdavis/numpydoc.el/pull/16)).
+
 ## 0.8 (March 20, 2023)
 
 ### Changes
 
 - Add support for customizing ignored function arguments (function
-  `Parameters` section). Contributed by
-  [@pakelly](https://github.com/pakelley) in #13.
+  `Parameters` section) with new `defcustom`:
+  `numpydoc-ignored-params`. Contributed by
+  [@pakelly](https://github.com/pakelley) in
+  [#13](https://github.com/douglasdavis/numpydoc.el/pull/13).
 
 ## 0.7 (March 4, 2022)
 
diff --git a/README.md b/README.md
index 4ca3291..3c2d8f6 100644
--- a/README.md
+++ b/README.md
@@ -135,6 +135,11 @@ RET numpydoc</kbd>
   All function parameters with names listed here will be ignored
   when generating a docstring.
   </dd>
+  <dt>numpydoc-auto-fill-paragraphs</dt>
+  <dd>
+  If <code>t</code> text that is inserted in a prompt will be
+  automatically paragraph-filled.
+  </dd>
 </dl>
 
 ## Examples
diff --git a/numpydoc.el b/numpydoc.el
index 87954b4..198cd9c 100644
--- a/numpydoc.el
+++ b/numpydoc.el
@@ -6,7 +6,7 @@
 ;; Maintainer: Doug Davis <ddavis@ddavis.io>
 ;; URL: https://github.com/douglasdavis/numpydoc.el
 ;; SPDX-License-Identifier: GPL-3.0-or-later
-;; Version: 0.8
+;; Version: 0.9
 ;; Package-Requires: ((emacs "25.1") (s "1.12.0") (dash "2.18.0"))
 ;; Keywords: convenience
 
@@ -133,6 +133,13 @@ when generating a docstring."
   :group 'numpydoc
   :type '(repeat string))
 
+(defcustom numpydoc-auto-fill-paragraphs t
+  "Flag to control automatic paragraph filling.
+If set to t text that is inserted in a prompt will be automatically
+paragraph-filled."
+  :group 'numpydoc
+  :type 'boolean)
+
 ;;; package implementation code.
 
 (cl-defstruct numpydoc--def
@@ -249,35 +256,38 @@ This function assumes the cursor to be in the function body."
 (defun numpydoc--parse-def (buffer-substr)
   "Parse the BUFFER-SUBSTR; return instance of numpydoc--def."
   (save-excursion
-    (let* ((fnsig buffer-substr)
-           ;; trimmed string of the function signature
-           (trimmed (s-collapse-whitespace fnsig))
-           ;; split into parts (args and return type)
-           (parts (s-split "->" trimmed))
-           ;; raw return
-           (rawret (if (nth 1 parts)
-                       (s-trim (nth 1 parts))
-                     nil))
-           ;; save return type as a string (or nil)
-           (rtype (when rawret
-                    (substring rawret 0 (1- (length rawret)))))
-           ;; raw signature without return type as a string
-           (rawsig (cond (rtype (substring (s-trim (car parts)) 0 -1))
-                         (t (substring (s-trim (car parts)) 0 -2))))
-           ;; function args as strings
-           (rawargs (-map #'s-trim
-                          (numpydoc--split-args
-                           (substring rawsig
-                                      (1+ (string-match-p (regexp-quote "(")
-                                                          rawsig))))))
-           ;; function args as a list of structures (remove some special cases)
-           (args (-remove (lambda (x)
-                            (-contains-p numpydoc-ignored-params
-                                         (numpydoc--arg-name x)))
-                          (-map #'numpydoc--arg-str-to-struct rawargs)))
-           ;; look for exceptions in the function body
-           (exceptions (numpydoc--find-exceptions)))
-      (make-numpydoc--def :args args :rtype rtype :raises exceptions))))
+    (condition-case nil
+        (progn
+          (let* ((fnsig buffer-substr)
+                 ;; trimmed string of the function signature
+                 (trimmed (s-collapse-whitespace fnsig))
+                 ;; split into parts (args and return type)
+                 (parts (s-split "->" trimmed))
+                 ;; raw return
+                 (rawret (if (nth 1 parts)
+                             (s-trim (nth 1 parts))
+                           nil))
+                 ;; save return type as a string (or nil)
+                 (rtype (when rawret
+                          (substring rawret 0 (1- (length rawret)))))
+                 ;; raw signature without return type as a string
+                 (rawsig (cond (rtype (substring (s-trim (car parts)) 0 -1))
+                               (t (substring (s-trim (car parts)) 0 -2))))
+                 ;; function args as strings
+                 (rawargs (-map #'s-trim
+                                (numpydoc--split-args
+                                 (substring rawsig
+                                            (1+ (string-match-p (regexp-quote "(")
+                                                                rawsig))))))
+                 ;; function args as a list of structures (remove some special cases)
+                 (args (-remove (lambda (x)
+                                  (-contains-p numpydoc-ignored-params
+                                               (numpydoc--arg-name x)))
+                                (-map #'numpydoc--arg-str-to-struct rawargs)))
+                 ;; look for exceptions in the function body
+                 (exceptions (numpydoc--find-exceptions)))
+            (make-numpydoc--def :args args :rtype rtype :raises exceptions)))
+      (error "Failed to parse function signature (bad Python syntax)."))))
 
 (defun numpydoc--has-existing-docstring-p ()
   "Check for an existing docstring.
@@ -391,7 +401,8 @@ This function assumes the cursor to be in the function body."
           (unless (string-empty-p ld)
             (insert "\n")
             (numpydoc--insert indent ld)
-            (numpydoc--fill-last-insertion)
+            (when numpydoc-auto-fill-paragraphs
+              (numpydoc--fill-last-insertion))
             (insert "\n")))
       (insert "\n")
       (numpydoc--insert indent tmpl)
@@ -429,7 +440,8 @@ This function assumes the cursor to be in the function body."
                                                element))
                         tmpd))))
     (numpydoc--insert indent desc)
-    (numpydoc--fill-last-insertion)
+    (when numpydoc-auto-fill-paragraphs
+      (numpydoc--fill-last-insertion))
     (insert "\n")))
 
 (defun numpydoc--insert-parameters (indent fnargs)
@@ -466,7 +478,8 @@ This function assumes the cursor to be in the function body."
                                 (if (numpydoc--prompt-p)
                                     (read-string "Description for return: ")
                                   tmpr)))
-      (numpydoc--fill-last-insertion)
+      (when numpydoc-auto-fill-paragraphs
+        (numpydoc--fill-last-insertion))
       (insert "\n"))))
 
 (defun numpydoc--insert-exceptions (indent fnexcepts)