summaryrefslogtreecommitdiff
path: root/lisp/help.el
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2015-06-11 10:23:46 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2015-06-11 10:24:38 -0700
commitb2205626370071bc85dc07b043c833bc50c0baec (patch)
tree9f317202483e1a28bd75cd4faddb521d708006d2 /lisp/help.el
parenteda386fc71419a6ec33f2f5fe73d7cb7ce51c028 (diff)
downloademacs-b2205626370071bc85dc07b043c833bc50c0baec.tar.gz
Fix quoting of help for functions with odd names
While investigating Bug#20759, I discovered other quoting problems: C-h f mishandled characters like backslash and quote in function names. This fix changes the behavior so that 'C-h f pcase RET' now generates "... (\` QPAT) ..." instead of "... (` QPAT) ...", because '(format "%S" '(` FOO))' returns "(\\` FOO)". A comment in src/lread.c's read1 function says that the backslash will be needed starting in Emacs 25, which implies that 'format' is correct and the old pcase documention was wrong to omit the backslash. * lisp/emacs-lisp/nadvice.el (advice--make-docstring): * lisp/help-fns.el (help-fns--signature): * lisp/help.el (help-add-fundoc-usage): * lisp/progmodes/elisp-mode.el (elisp-function-argstring): Use help--make-usage-docstring rather than formatting help-make-usage. * lisp/emacs-lisp/pcase.el (pcase--make-docstring): Return raw docstring. * lisp/help-fns.el (help-fns--signature): New arg RAW, to return raw docstring. Take more care to distinguish raw from cooked dstrings. (describe-function-1): Let help-fns--signature substitute command keys. * lisp/help.el (help--docstring-quote): New function. (help-split-fundoc): Use it, to quote funny characters more systematically. (help--make-usage): Rename from help-make-usage, since this should be private. Leave an obsolete alias for the old name. (help--make-usage-docstring): New function. * test/automated/help-fns.el (help-fns-test-funny-names): New test.
Diffstat (limited to 'lisp/help.el')
-rw-r--r--lisp/help.el31
1 files changed, 23 insertions, 8 deletions
diff --git a/lisp/help.el b/lisp/help.el
index fd5cbc66ab2..b766cd0e983 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -1349,6 +1349,11 @@ the help window if the current value of the user option
(princ msg)))))
+(defun help--docstring-quote (string)
+ "Return a doc string that represents STRING.
+The result, when formatted by ‘substitute-command-keys’, should equal STRING."
+ (replace-regexp-in-string "['\\`]" "\\\\=\\&" string))
+
;; The following functions used to be in help-fns.el, which is not preloaded.
;; But for various reasons, they are more widely needed, so they were
;; moved to this file, which is preloaded. http://debbugs.gnu.org/17001
@@ -1364,12 +1369,17 @@ DEF is the function whose usage we're looking for in DOCSTRING."
;; 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))
- (cons (format "(%s%s"
- ;; Replace `fn' with the actual function name.
- (if (symbolp def) def "anonymous")
- (match-string 1 docstring))
- (unless (zerop (match-beginning 0))
- (substring docstring 0 (match-beginning 0))))))
+ (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
+ (substring (format "%S" (list def)) 1 -1))
+ 'anonymous)
+ usage-tail)
+ doc))))
(defun help-add-fundoc-usage (docstring arglist)
"Add the usage info to DOCSTRING.
@@ -1387,7 +1397,7 @@ ARGLIST can also be t or a string of the form \"(FUN ARG1 ARG2 ...)\"."
(if (and (stringp arglist)
(string-match "\\`([^ ]+\\(.*\\))\\'" arglist))
(concat "(fn" (match-string 1 arglist) ")")
- (format "%S" (help-make-usage 'fn arglist))))))
+ (help--make-usage-docstring 'fn arglist)))))
(defun help-function-arglist (def &optional preserve-names)
"Return a formal argument list for the function DEF.
@@ -1442,7 +1452,7 @@ the same names as used in the original source code, when possible."
"[Arg list not available until function definition is loaded.]")
(t t)))
-(defun help-make-usage (function arglist)
+(defun help--make-usage (function arglist)
(cons (if (symbolp function) function 'anonymous)
(mapcar (lambda (arg)
(if (not (symbolp arg)) arg
@@ -1454,6 +1464,11 @@ the same names as used in the original source code, when possible."
(t (intern (upcase name)))))))
arglist)))
+(define-obsolete-function-alias 'help-make-usage 'help--make-usage "25.1")
+
+(defun help--make-usage-docstring (fn arglist)
+ (help--docstring-quote (format "%S" (help--make-usage fn arglist))))
+
(provide 'help)