Subject: bug#79212: 31.0.50; Malformed C-h m output

From: Eshel Yaron <[email-masked]>
Date: Mon, 11 Aug 2025 15:01:09 +0200

Eli Zaretskii <[email-masked]> writes:

>> Date: Sun, 10 Aug 2025 20:32:16 +0200
>> From:  Eshel Yaron via "Bug reports for GNU Emacs,
>>  the Swiss army knife of text editors" <[email-masked]>
>> 
>> With emacs -Q, evaluate the following form:
>> 
>>   (define-derived-mode foo-mode nil "Foo" "Major mode for bar.")
>> 
>> Now switch to a new buffer (C-x b foo RET) and put it in foo-mode with
>> M-x foo-mode, and then hit C-h m to describe the current major mode.
>> 
>> The Help buffer starts with the following malformed line:
>> 
>>   The major mode is Foo modeMajor mode for bar.
>> 
>> Whereas I would expect something like:
>> 
>>   The major mode is Foo mode.
>> 
>>   Major mode for bar.
>> 
>> The following diff seems to do the trick:
>> 
>> diff --git a/lisp/help-fns.el b/lisp/help-fns.el
>> index 9cd30107002..5f4734fb69d 100644
>> --- a/lisp/help-fns.el
>> +++ b/lisp/help-fns.el
>> @@ -2252,13 +2252,14 @@ describe-mode
>>                     (lambda (_)
>>                       (describe-function major))))
>>            (insert " mode")
>> -          (when-let* ((file-name (find-lisp-object-file-name major nil)))
>> -	    (insert (format " defined in %s:\n\n"
>> -                            (buttonize
>> -                             (help-fns-short-filename file-name)
>> -                             (lambda (_)
>> -                               (help-function-def--button-function
>> -                                major file-name))))))
>> +          (if-let* ((file-name (find-lisp-object-file-name major nil)))
>> +	      (insert (format " defined in %s:\n\n"
>> +                              (buttonize
>> +                               (help-fns-short-filename file-name)
>> +                               (lambda (_)
>> +                                 (help-function-def--button-function
>> +                                  major file-name)))))
>> +            (insert ".\n\n"))
>>            (insert (help-split-fundoc (documentation major) nil 'doc)
>>                    (with-current-buffer buffer
>>                      (help-fns--list-local-commands)))
>
> Thanks, but do we really need to have two copies of \n\n?  And why
> there's no colon if the mode is not defined in any file?

Good points, here's a slightly DRYer diff:

diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index 9cd30107002..e9601d52e33 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -2253,13 +2253,14 @@ describe-mode
                      (describe-function major))))
           (insert " mode")
           (when-let* ((file-name (find-lisp-object-file-name major nil)))
-	    (insert (format " defined in %s:\n\n"
+	    (insert (format " defined in %s"
                             (buttonize
                              (help-fns-short-filename file-name)
                              (lambda (_)
                                (help-function-def--button-function
                                 major file-name))))))
-          (insert (help-split-fundoc (documentation major) nil 'doc)
+          (insert ":\n\n"
+                  (help-split-fundoc (documentation major) nil 'doc)
                   (with-current-buffer buffer
                     (help-fns--list-local-commands)))
           (ensure-empty-lines 1)