Subject: Re: bug#79469: 31.0.50; Ungrammatical sentence from describe-function

From: Stephen Berman <[email-masked]>
Date: Thu, 18 Sep 2025 23:27:21 +0200

On Thu, 18 Sep 2025 19:55:24 +0300 Eli Zaretskii <[email-masked]> wrote:

>> Date: Thu, 18 Sep 2025 18:41:16 +0200
>> From:  Stephen Berman via "Bug reports for GNU Emacs,
>>  the Swiss army knife of text editors" <[email-masked]>
>> 
>> Calling `describe-function' on a noninteractive non-byte-compiled
>> function produces an ungrammatical sentence in the *Help* buffer:
>> 
>> 0. emacs -Q
>> 1. Load a non-byte-compiled file that contains a noninteractive function
>>    definition, e.g. edt-user.el from the Emacs "etc" directory.
>> 2. Call `describe-function' on a noninteractive function from that file,
>>    e.g. `C-h f edt-setup-user-bindings RET'.
>> ==> The *Help* buffer now begins with this sentence:
>> 
>> edt-setup-user-bindings is a interpreted-function in
>> ‘~/src/emacs/emacs-master/etc/edt-user.el’.
>> 
>> It should say "...is an interpreted-function...".
>> 
>> Here are three possible fixes:
>
> Thanks.
>
> I think this splits hair, but if we want to do that, let's do it
> right: instead of hard-coding specific words, implement a function
> that produces "a" or "an" depending on the following word.  Because
> tomorrow someone will add yet another function qualifier, and what
> will we do then? add one more hard-coded phrase?

How's this?

diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index e9601d52e33..d54e02dfef2 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -1161,15 +1161,19 @@ help-fns-function-description-header
 		      (setq elts (cdr-safe elts)))
 		    (concat beg (if is-full "keymap" "sparse keymap"))))
 		 (t
-		  (concat beg (format "%s"
-		                      (if (and (consp def) (symbolp (car def)))
-		                          (car def)
-		                        (let ((type (or (oclosure-type def)
-		                                        (cl-type-of def))))
-		                          (make-text-button
-		                           (symbol-name type) nil
-		                           'type 'help-type
-		                           'help-args (list type))))))))))
+                  (let* ((type (or (oclosure-type def) (cl-type-of def)))
+                         (typ-str
+                          (format "%s"
+		                  (if (and (consp def) (symbolp (car def)))
+                                      (car def)
+                                    (make-text-button
+                                       (symbol-name type) nil
+                                       'type 'help-type
+                                       'help-args (list type))))))
+                    (concat (if (string-match-p "\\`[aeiou]" (symbol-name type))
+                                "an "
+                              beg)
+                            typ-str))))))
     (with-current-buffer standard-output
       (insert description))

Steve Berman