Subject: 31.0.50; Ungrammatical sentence from describe-function

From: Stephen Berman <[email-masked]>
Date: Thu, 18 Sep 2025 18:41:16 +0200

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:

diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index e9601d52e33..e71978fe3ba 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -1161,15 +1161,17 @@ 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= type "interpreted-function") "an " beg)
+                            typ-str))))))
     (with-current-buffer standard-output
       (insert description))
 
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index e9601d52e33..9faee1bb959 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -1170,6 +1170,8 @@ help-fns-function-description-header
 		                           (symbol-name type) nil
 		                           'type 'help-type
 		                           'help-args (list type))))))))))
+    (when (string-match "\\(a\\) interpreted-function" description)
+      (setq description (replace-match "an" nil t description 1)))
     (with-current-buffer standard-output
       (insert description))
 
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index e9601d52e33..52fab0ab37f 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -317,7 +317,10 @@ describe-function
         (describe-function-1 function)
         (with-current-buffer standard-output
           (help-fns--setup-xref-backend)
-
+          (save-excursion
+            (goto-char (point-min))
+            (when (re-search-forward "\\(a\\) interpreted-function" nil t)
+              (replace-match "an" nil t nil 1)))
           ;; Return the text we displayed.
           (buffer-string))))))

Of these three I prefer the first, since it directly generates the
correct string, while the other two change an incorrect string to the
correct one.

While all three are ad hoc fixes, I think the undoubted complexity of a
more general fix is unjustified here, because (unless I've overlooked
something) `interpreted-function' is the only function type symbol
returned by `cl-type-of' in `help-fns-function-description-header' that
results in the problem (since it begins with a vowel).

In GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
 3.24.49, cairo version 1.18.4) of 2025-09-18 built on strobelfs2
Repository revision: 3415fa15e4f0a146d1f08df981dc9894bf2ff320
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12101016
System Description: Linux From Scratch r12.3-20

Configured using:
 'configure -C 'CFLAGS=-Og -g3' PKG_CONFIG_PATH=/opt/qt6/lib/pkgconfig'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
LCMS2 LIBSYSTEMD LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG
RSVG SECCOMP SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER
WEBP X11 XDBE XIM XINERAMA XINPUT2 XPM XRANDR GTK3 ZLIB