all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Juanma Barranquero <lekktu@gmail.com>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: Emacs developers <emacs-devel@gnu.org>
Subject: Re: master 49192e9: Strip "(fn...)" from output of `describe-mode' (bug#38222)
Date: Sat, 23 Nov 2019 22:12:27 +0100	[thread overview]
Message-ID: <CAAeL0ST13bod+ho4H_fSfC4_Vf4EdRM_jqUSj56vginr8rmWdQ@mail.gmail.com> (raw)
In-Reply-To: <jwv4kyvy4b7.fsf-monnier+emacs@gnu.org>


[-- Attachment #1.1: Type: text/plain, Size: 1181 bytes --]

On Fri, Nov 22, 2019 at 10:45 PM Stefan Monnier <monnier@iro.umontreal.ca>
wrote:

> And if it's just t it could always return a pair.
> Sounds good.

Please take a look.

The patches do not include info changes, because help-split-fundoc is not
documented. Should this change, once accepted, be mentioned in NEWS?

BTW, other than the discussed new feature, I've added the following tiny,
sort of incompatible change:

 Before:
- DEF = non-symbol => usage = "(anonymous ARGS...)"
- DEF = symbol s => usage = "(s ARGS...)"

Now:
- DEF = non-symbol OR nil => "(anonymous ARGS...)"
- DEF = other symbol s => "(s ARGS...)"

When callers are not interested in the usage they can already pass a
non-symbol, like "" or 0, but perusing the sources, 3 out of 14 uses of
help-split-fundoc pass nil, and none of them passes a non-symbol.

Treating nil like "don't care" saves two function calls over the current
code (which passes nil through help--docstring-quote), and DEF is
documented as "the function whose usage we're looking for", so
nil = "don't care" makes more sense than "" or 0.

I can revert this part of the patch (is a one-liner), if you're worried
about the incompatibility.

[-- Attachment #1.2: Type: text/html, Size: 2158 bytes --]

[-- Attachment #2: 0001-Make-help-split-fundoc-more-flexible-about-what-retu.patch --]
[-- Type: application/octet-stream, Size: 6123 bytes --]

From 0351f8c2b61624eb9952957dd54655e533cfe573 Mon Sep 17 00:00:00 2001
From: Juanma Barranquero <lekktu@gmail.com>
Date: Sat, 23 Nov 2019 21:33:32 +0100
Subject: [PATCH 1/2] Make help-split-fundoc more flexible about what returns

* lisp/help.el (help-split-fundoc): New arg SECTION to return
only the usage or doc parts of the docstring, or both even if
there is no usage.

* test/lisp/help-tests.el: New file.
---
 lisp/help.el            | 44 ++++++++++++++++++++------------
 test/lisp/help-tests.el | 56 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+), 16 deletions(-)
 create mode 100644 test/lisp/help-tests.el

diff --git a/lisp/help.el b/lisp/help.el
index 22f35df1de..06264ae2f3 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -1380,27 +1380,39 @@ help--docstring-quote
 ;; But for various reasons, they are more widely needed, so they were
 ;; moved to this file, which is preloaded.  https://debbugs.gnu.org/17001
 
-(defun help-split-fundoc (docstring def)
+(defun help-split-fundoc (docstring def &optional section)
   "Split a function DOCSTRING into the actual doc and the usage info.
-Return (USAGE . DOC) or nil if there's no usage info, where USAGE info
-is a string describing the argument list of DEF, such as
-\"(apply FUNCTION &rest ARGUMENTS)\".
-DEF is the function whose usage we're looking for in DOCSTRING."
+Return (USAGE . DOC), where USAGE is a string describing the argument
+list of DEF, such as \"(apply FUNCTION &rest ARGUMENTS)\".
+DEF is the function whose usage we're looking for in DOCSTRING.
+With SECTION nil, return nil if there is no usage info; conversely,
+SECTION t means to return (USAGE . DOC) even if there's no usage info.
+When SECTION is \\='usage or \\='doc, return only that part."
   ;; Functions can get the calling sequence at the end of the doc string.
   ;; In cases where `function' has been fset to a subr we can't search for
   ;; function's name in the doc string so we use `fn' as the anonymous
   ;; function name instead.
-  (when (and docstring (string-match "\n\n(fn\\(\\( .*\\)?)\\)\\'" docstring))
-    (let ((doc (unless (zerop (match-beginning 0))
-		 (substring docstring 0 (match-beginning 0))))
-	  (usage-tail (match-string 1 docstring)))
-      (cons (format "(%s%s"
-		    ;; Replace `fn' with the actual function name.
-		    (if (symbolp def)
-			(help--docstring-quote (format "%S" def))
-		      'anonymous)
-		    usage-tail)
-	    doc))))
+  (let* ((found (and docstring
+                     (string-match "\n\n(fn\\(\\( .*\\)?)\\)\\'" docstring)))
+         (doc (if found
+                  (and (memq section '(t nil doc))
+                       (not (zerop (match-beginning 0)))
+                       (substring docstring 0 (match-beginning 0)))
+                docstring))
+         (usage (and found
+                     (memq section '(t nil usage))
+                     (let ((tail (match-string 1 docstring)))
+                       (format "(%s%s"
+                               ;; Replace `fn' with the actual function name.
+                               (if (and (symbolp def) def)
+                                   (help--docstring-quote (format "%S" def))
+                                 'anonymous)
+                               tail)))))
+    (pcase section
+      (`nil (and usage (cons usage doc)))
+      (`t (cons usage doc))
+      (`usage usage)
+      (`doc doc))))
 
 (defun help-add-fundoc-usage (docstring arglist)
   "Add the usage info to DOCSTRING.
diff --git a/test/lisp/help-tests.el b/test/lisp/help-tests.el
new file mode 100644
index 0000000000..28dd8830e4
--- /dev/null
+++ b/test/lisp/help-tests.el
@@ -0,0 +1,56 @@
+;;; help-tests.el --- Tests for help.el  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2019 Free Software Foundation, Inc.
+
+;; Author: Juanma Barranquero <lekktu@gmail.com>
+;; Keywords: help, internal
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+
+(ert-deftest help-split-fundoc-SECTION ()
+  "Test new optional arg SECTION."
+  (let* ((doc "Doc first line.\nDoc second line.")
+         (usg "\n\n(fn ARG1 &optional ARG2)")
+         (full (concat doc usg))
+         (usage "(t ARG1 &optional ARG2)"))
+    ;; Docstring has both usage and doc
+    (should (equal (help-split-fundoc full t nil)    `(,usage . ,doc)))
+    (should (equal (help-split-fundoc full t t)      `(,usage . ,doc)))
+    (should (equal (help-split-fundoc full t 'usage)  usage))
+    (should (equal (help-split-fundoc full t 'doc)    doc))
+    ;; Docstring has no usage, only doc
+    (should (equal (help-split-fundoc doc t nil)      nil))
+    (should (equal (help-split-fundoc doc t t)       `(nil . ,doc)))
+    (should (equal (help-split-fundoc doc t 'usage)  nil))
+    (should (equal (help-split-fundoc doc t 'doc)    doc))
+    ;; Docstring is only usage, no doc
+    (should (equal (help-split-fundoc usg t nil)     `(,usage . nil)))
+    (should (equal (help-split-fundoc usg t t)       `(,usage . nil)))
+    (should (equal (help-split-fundoc usg t 'usage)  usage))
+    (should (equal (help-split-fundoc usg t 'doc)    nil))
+    ;; Docstring is null
+    (should (equal (help-split-fundoc nil t nil)     nil))
+    (should (equal (help-split-fundoc nil t t)       '(nil)))
+    (should (equal (help-split-fundoc nil t 'usage)  nil))
+    (should (equal (help-split-fundoc nil t 'doc)    nil))))
+
+(provide 'help-tests)
+
+;;; help-tests.el ends here
-- 
2.23.0.windows.1


[-- Attachment #3: 0002-Rework-previous-change-to-fix-bug-38222.patch --]
[-- Type: application/octet-stream, Size: 1696 bytes --]

From 19e2c488062fb81645f90e791da227f79be45611 Mon Sep 17 00:00:00 2001
From: Juanma Barranquero <lekktu@gmail.com>
Date: Sat, 23 Nov 2019 21:46:03 +0100
Subject: [PATCH 2/2] Rework previous change to fix bug#38222

* lisp/help.el (help--doc-without-fn): Remove.
(describe-mode): Use help-split-fundoc instead.
---
 lisp/help.el | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/lisp/help.el b/lisp/help.el
index 06264ae2f3..c4402ece4e 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -878,10 +878,6 @@ describe-key
             (princ ", which is ")
 	    (describe-function-1 defn)))))))
 \f
-(defun help--doc-without-fn (mode)
-  ;; Remove the (fn...) thingy at the end of the docstring
-  (replace-regexp-in-string "\n\n(fn[^)]*?)\\'" "" (documentation mode)))
-
 (defun describe-mode (&optional buffer)
   "Display documentation of current major mode and minor modes.
 A brief summary of the minor modes comes first, followed by the
@@ -955,7 +951,8 @@ describe-mode
 				     "no indicator"
 				   (format "indicator%s"
 					   indicator))))
-		  (princ (help--doc-without-fn mode-function)))
+		  (princ (help-split-fundoc (documentation mode-function)
+                                            nil 'doc)))
 		(insert-button pretty-minor-mode
 			       'action (car help-button-cache)
 			       'follow-link t
@@ -985,7 +982,7 @@ describe-mode
                                     nil t)
 		(help-xref-button 1 'help-function-def mode file-name)))))
 	(princ ":\n")
-	(princ (help--doc-without-fn major-mode)))))
+	(princ (help-split-fundoc (documentation major-mode) nil 'doc)))))
   ;; For the sake of IELM and maybe others
   nil)
 
-- 
2.23.0.windows.1


  reply	other threads:[~2019-11-23 21:12 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20191119101930.28082.63466@vcs0.savannah.gnu.org>
     [not found] ` <20191119101931.EA4E2209BF@vcs0.savannah.gnu.org>
2019-11-19 13:54   ` master 49192e9: Strip "(fn...)" from output of `describe-mode' (bug#38222) Stefan Monnier
2019-11-19 18:47     ` Juanma Barranquero
2019-11-19 19:22       ` Stefan Monnier
2019-11-19 19:45         ` Juanma Barranquero
2019-11-19 20:05           ` Stefan Monnier
2019-11-19 20:25             ` Juanma Barranquero
2019-11-19 20:56               ` Stefan Monnier
2019-11-19 21:26                 ` Drew Adams
2019-11-22 20:00                 ` Juanma Barranquero
2019-11-22 21:45                   ` Stefan Monnier
2019-11-23 21:12                     ` Juanma Barranquero [this message]
2019-11-23 22:08                       ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAAeL0ST13bod+ho4H_fSfC4_Vf4EdRM_jqUSj56vginr8rmWdQ@mail.gmail.com \
    --to=lekktu@gmail.com \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.