aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2012-11-08 23:10:16 -0500
committerStefan Monnier2012-11-08 23:10:16 -0500
commit57618ecf3358e49ab3c380330e82ca8d2078cc63 (patch)
treecb031b879ebeb162179f5718c015f70a5e31c755
parent67dd8ad119474d5c403e3410b4465baef2647609 (diff)
downloademacs-57618ecf3358e49ab3c380330e82ca8d2078cc63.tar.gz
emacs-57618ecf3358e49ab3c380330e82ca8d2078cc63.zip
New property dynamic-docstring-function for docstrings.
* src/doc.c (Fdocumentation): Handle new property dynamic-docstring-function to replace the old ad-advice-info. * lisp/emacs-lisp/advice.el: Use new dynamic docstrings. (ad-make-advised-definition-docstring, ad-advised-definition-p): Use dynamic-docstring-function instead of ad-advice-info. (ad--make-advised-docstring): New function extracted from ad-make-advised-docstring. (ad-make-advised-docstring): Use it. * lisp/progmodes/sql.el (sql--make-help-docstring): New function, extracted from sql-help. (sql-help): Use it with dynamic-docstring-function.
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/ChangeLog10
-rw-r--r--lisp/emacs-lisp/advice.el22
-rw-r--r--lisp/progmodes/sql.el47
-rw-r--r--src/ChangeLog5
-rw-r--r--src/doc.c35
6 files changed, 71 insertions, 52 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 2b56ea9f540..bb8bcd6cb56 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -29,6 +29,10 @@ so we will look at it and add it to the manual.
29* New Modes and Packages in Emacs 24.4 29* New Modes and Packages in Emacs 24.4
30* Incompatible Lisp Changes in Emacs 24.4 30* Incompatible Lisp Changes in Emacs 24.4
31* Lisp changes in Emacs 24.4 31* Lisp changes in Emacs 24.4
32
33** Docstrings can be made dynamic by adding a `dynamic-docstring-function'
34text-property on the first char.
35
32* Changes in Emacs 24.4 on non-free operating systems 36* Changes in Emacs 24.4 on non-free operating systems
33 37
34 38
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index b54a3e281af..f0af63ac094 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,15 @@
12012-11-09 Stefan Monnier <monnier@iro.umontreal.ca> 12012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * emacs-lisp/advice.el: Use new dynamic docstrings.
4 (ad-make-advised-definition-docstring, ad-advised-definition-p):
5 Use dynamic-docstring-function instead of ad-advice-info.
6 (ad--make-advised-docstring): New function extracted from
7 ad-make-advised-docstring.
8 (ad-make-advised-docstring): Use it.
9 * progmodes/sql.el (sql--make-help-docstring): New function, extracted
10 from sql-help.
11 (sql-help): Use it with dynamic-docstring-function.
12
3 * env.el (env--substitute-vars-regexp): Don't use rx (for bootstrap). 13 * env.el (env--substitute-vars-regexp): Don't use rx (for bootstrap).
4 14
52012-11-08 Stefan Monnier <monnier@iro.umontreal.ca> 152012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el
index bd85238e23e..33805836db2 100644
--- a/lisp/emacs-lisp/advice.el
+++ b/lisp/emacs-lisp/advice.el
@@ -2414,13 +2414,15 @@ Like `interactive-form', but also works on pieces of advice."
2414 (if (ad-interactive-form definition) 1 0)) 2414 (if (ad-interactive-form definition) 1 0))
2415 (cdr (cdr (ad-lambda-expression definition))))))) 2415 (cdr (cdr (ad-lambda-expression definition)))))))
2416 2416
2417(defun ad-make-advised-definition-docstring (function) 2417(defun ad-make-advised-definition-docstring (_function)
2418 "Make an identifying docstring for the advised definition of FUNCTION. 2418 "Make an identifying docstring for the advised definition of FUNCTION.
2419Put function name into the documentation string so we can infer 2419Put function name into the documentation string so we can infer
2420the name of the advised function from the docstring. This is needed 2420the name of the advised function from the docstring. This is needed
2421to generate a proper advised docstring even if we are just given a 2421to generate a proper advised docstring even if we are just given a
2422definition (see the code for `documentation')." 2422definition (see the code for `documentation')."
2423 (propertize "Advice doc string" 'ad-advice-info function)) 2423 (eval-when-compile
2424 (propertize "Advice doc string" 'dynamic-docstring-function
2425 #'ad--make-advised-docstring)))
2424 2426
2425(defun ad-advised-definition-p (definition) 2427(defun ad-advised-definition-p (definition)
2426 "Return non-nil if DEFINITION was generated from advice information." 2428 "Return non-nil if DEFINITION was generated from advice information."
@@ -2429,7 +2431,7 @@ definition (see the code for `documentation')."
2429 (ad-compiled-p definition)) 2431 (ad-compiled-p definition))
2430 (let ((docstring (ad-docstring definition))) 2432 (let ((docstring (ad-docstring definition)))
2431 (and (stringp docstring) 2433 (and (stringp docstring)
2432 (get-text-property 0 'ad-advice-info docstring))))) 2434 (get-text-property 0 'dynamic-docstring-function docstring)))))
2433 2435
2434(defun ad-definition-type (definition) 2436(defun ad-definition-type (definition)
2435 "Return symbol that describes the type of DEFINITION." 2437 "Return symbol that describes the type of DEFINITION."
@@ -2752,6 +2754,13 @@ Example: `(ad-map-arglists '(a &rest args) '(w x y z))' will return
2752(require 'help-fns) ;For help-split-fundoc and help-add-fundoc-usage. 2754(require 'help-fns) ;For help-split-fundoc and help-add-fundoc-usage.
2753 2755
2754(defun ad-make-advised-docstring (function &optional style) 2756(defun ad-make-advised-docstring (function &optional style)
2757 (let* ((origdef (ad-real-orig-definition function))
2758 (origdoc
2759 ;; Retrieve raw doc, key substitution will be taken care of later:
2760 (ad-real-documentation origdef t)))
2761 (ad--make-advised-docstring origdoc function style)))
2762
2763(defun ad--make-advised-docstring (origdoc function &optional style)
2755 "Construct a documentation string for the advised FUNCTION. 2764 "Construct a documentation string for the advised FUNCTION.
2756It concatenates the original documentation with the documentation 2765It concatenates the original documentation with the documentation
2757strings of the individual pieces of advice which will be formatted 2766strings of the individual pieces of advice which will be formatted
@@ -2761,9 +2770,6 @@ strings corresponds to before/around/after and the individual ordering
2761in any of these classes." 2770in any of these classes."
2762 (let* ((origdef (ad-real-orig-definition function)) 2771 (let* ((origdef (ad-real-orig-definition function))
2763 (origtype (symbol-name (ad-definition-type origdef))) 2772 (origtype (symbol-name (ad-definition-type origdef)))
2764 (origdoc
2765 ;; Retrieve raw doc, key substitution will be taken care of later:
2766 (ad-real-documentation origdef t))
2767 (usage (help-split-fundoc origdoc function)) 2773 (usage (help-split-fundoc origdoc function))
2768 paragraphs advice-docstring ad-usage) 2774 paragraphs advice-docstring ad-usage)
2769 (setq usage (if (null usage) t (setq origdoc (cdr usage)) (car usage))) 2775 (setq usage (if (null usage) t (setq origdoc (cdr usage)) (car usage)))
@@ -2780,7 +2786,9 @@ in any of these classes."
2780 (propertize 2786 (propertize
2781 ;; separate paragraphs with blank lines: 2787 ;; separate paragraphs with blank lines:
2782 (mapconcat 'identity (nreverse paragraphs) "\n\n") 2788 (mapconcat 'identity (nreverse paragraphs) "\n\n")
2783 'ad-advice-info function))) 2789 ;; FIXME: what is this for?
2790 'dynamic-docstring-function
2791 #'ad--make-advised-docstring)))
2784 (help-add-fundoc-usage origdoc usage))) 2792 (help-add-fundoc-usage origdoc usage)))
2785 2793
2786(defun ad-make-plain-docstring (function) 2794(defun ad-make-plain-docstring (function)
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el
index 3d5abc4df62..64b87d9e436 100644
--- a/lisp/progmodes/sql.el
+++ b/lisp/progmodes/sql.el
@@ -2802,8 +2802,12 @@ each line with INDENT."
2802 doc)) 2802 doc))
2803 2803
2804;;;###autoload 2804;;;###autoload
2805(defun sql-help () 2805(eval
2806 "Show short help for the SQL modes. 2806 ;; FIXME: This dynamic-docstring-function trick doesn't work for byte-compiled
2807 ;; functions, because of the lazy-loading of docstrings, which strips away
2808 ;; text properties.
2809 '(defun sql-help ()
2810 #("Show short help for the SQL modes.
2807 2811
2808Use an entry function to open an interactive SQL buffer. This buffer is 2812Use an entry function to open an interactive SQL buffer. This buffer is
2809usually named `*SQL*'. The name of the major mode is SQLi. 2813usually named `*SQL*'. The name of the major mode is SQLi.
@@ -2834,32 +2838,23 @@ anything. The name of the major mode is SQL.
2834In this SQL buffer (SQL mode), you can send the region or the entire 2838In this SQL buffer (SQL mode), you can send the region or the entire
2835buffer to the interactive SQL buffer (SQLi mode). The results are 2839buffer to the interactive SQL buffer (SQLi mode). The results are
2836appended to the SQLi buffer without disturbing your SQL buffer." 2840appended to the SQLi buffer without disturbing your SQL buffer."
2841 0 1 (dynamic-docstring-function sql--make-help-docstring))
2837 (interactive) 2842 (interactive)
2843 (describe-function 'sql-help)))
2838 2844
2839 ;; Insert references to loaded products into the help buffer string 2845(defun sql--make-help-docstring (doc _fun)
2840 (let ((doc (documentation 'sql-help t)) 2846 "Insert references to loaded products into the help buffer string."
2841 changedp) 2847
2842 (setq changedp nil) 2848 ;; Insert FREE software list
2843 2849 (when (string-match "^\\(\\s-*\\)[\\\\][\\\\]FREE\\s-*\n" doc 0)
2844 ;; Insert FREE software list 2850 (setq doc (replace-match (sql-help-list-products (match-string 1 doc) t)
2845 (when (string-match "^\\(\\s-*\\)[\\\\][\\\\]FREE\\s-*\n" doc 0) 2851 t t doc 0)))
2846 (setq doc (replace-match (sql-help-list-products (match-string 1 doc) t) 2852
2847 t t doc 0) 2853 ;; Insert non-FREE software list
2848 changedp t)) 2854 (when (string-match "^\\(\\s-*\\)[\\\\][\\\\]NONFREE\\s-*\n" doc 0)
2849 2855 (setq doc (replace-match (sql-help-list-products (match-string 1 doc) nil)
2850 ;; Insert non-FREE software list 2856 t t doc 0)))
2851 (when (string-match "^\\(\\s-*\\)[\\\\][\\\\]NONFREE\\s-*\n" doc 0) 2857 doc)
2852 (setq doc (replace-match (sql-help-list-products (match-string 1 doc) nil)
2853 t t doc 0)
2854 changedp t))
2855
2856 ;; If we changed the help text, save the change so that the help
2857 ;; sub-system will see it
2858 (when changedp
2859 (put 'sql-help 'function-documentation doc)))
2860
2861 ;; Call help on this function
2862 (describe-function 'sql-help))
2863 2858
2864(defun sql-read-passwd (prompt &optional default) 2859(defun sql-read-passwd (prompt &optional default)
2865 "Read a password using PROMPT. Optional DEFAULT is password to start with." 2860 "Read a password using PROMPT. Optional DEFAULT is password to start with."
diff --git a/src/ChangeLog b/src/ChangeLog
index 42c63b21e95..9bd6ccec017 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
12012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * doc.c (Fdocumentation): Handle new property
4 dynamic-docstring-function to replace the old ad-advice-info.
5
12012-11-09 Paul Eggert <eggert@cs.ucla.edu> 62012-11-09 Paul Eggert <eggert@cs.ucla.edu>
2 7
3 * fns.c (Qeql, hashtest_eq): Now static. 8 * fns.c (Qeql, hashtest_eq): Now static.
diff --git a/src/doc.c b/src/doc.c
index 9ead1addfba..1d3d1e64442 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -21,7 +21,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21#include <config.h> 21#include <config.h>
22 22
23#include <sys/types.h> 23#include <sys/types.h>
24#include <sys/file.h> /* Must be after sys/types.h for USG*/ 24#include <sys/file.h> /* Must be after sys/types.h for USG. */
25#include <fcntl.h> 25#include <fcntl.h>
26#include <unistd.h> 26#include <unistd.h>
27 27
@@ -42,7 +42,7 @@ static ptrdiff_t get_doc_string_buffer_size;
42 42
43static unsigned char *read_bytecode_pointer; 43static unsigned char *read_bytecode_pointer;
44 44
45/* readchar in lread.c calls back here to fetch the next byte. 45/* `readchar' in lread.c calls back here to fetch the next byte.
46 If UNREADFLAG is 1, we unread a byte. */ 46 If UNREADFLAG is 1, we unread a byte. */
47 47
48int 48int
@@ -338,15 +338,9 @@ string is passed through `substitute-command-keys'. */)
338 338
339 doc = Qnil; 339 doc = Qnil;
340 340
341 if (SYMBOLP (function))
342 {
343 Lisp_Object tem = Fget (function, Qfunction_documentation);
344 if (!NILP (tem))
345 return Fdocumentation_property (function, Qfunction_documentation,
346 raw);
347 }
348
349 fun = Findirect_function (function, Qnil); 341 fun = Findirect_function (function, Qnil);
342 if (CONSP (fun) && EQ (XCAR (fun), Qmacro))
343 fun = XCDR (fun);
350 if (SUBRP (fun)) 344 if (SUBRP (fun))
351 { 345 {
352 if (XSUBR (fun)->doc == 0) 346 if (XSUBR (fun)->doc == 0)
@@ -400,8 +394,6 @@ string is passed through `substitute-command-keys'. */)
400 else 394 else
401 return Qnil; 395 return Qnil;
402 } 396 }
403 else if (EQ (funcar, Qmacro))
404 return Fdocumentation (Fcdr (fun), raw);
405 else 397 else
406 goto oops; 398 goto oops;
407 } 399 }
@@ -411,16 +403,19 @@ string is passed through `substitute-command-keys'. */)
411 xsignal1 (Qinvalid_function, fun); 403 xsignal1 (Qinvalid_function, fun);
412 } 404 }
413 405
414 /* Check for an advised function. Its doc string 406 /* Check for a dynamic docstring. These come with
415 has an `ad-advice-info' text property. */ 407 a dynamic-docstring-function text property. */
416 if (STRINGP (doc)) 408 if (STRINGP (doc))
417 { 409 {
418 Lisp_Object innerfunc; 410 Lisp_Object func
419 innerfunc = Fget_text_property (make_number (0), 411 = Fget_text_property (make_number (0),
420 intern ("ad-advice-info"), 412 intern ("dynamic-docstring-function"),
421 doc); 413 doc);
422 if (! NILP (innerfunc)) 414 if (!NILP (func))
423 doc = call1 (intern ("ad-make-advised-docstring"), innerfunc); 415 /* Pass both `doc' and `function' since `function' can be needed, and
416 finding `doc' can be annoying: calling `documentation' is not an
417 option because it would infloop. */
418 doc = call2 (func, doc, function);
424 } 419 }
425 420
426 /* If DOC is 0, it's typically because of a dumped file missing 421 /* If DOC is 0, it's typically because of a dumped file missing
@@ -528,6 +523,8 @@ store_function_docstring (Lisp_Object obj, ptrdiff_t offset)
528 { 523 {
529 tem = Fcdr (Fcdr (fun)); 524 tem = Fcdr (Fcdr (fun));
530 if (CONSP (tem) && INTEGERP (XCAR (tem))) 525 if (CONSP (tem) && INTEGERP (XCAR (tem)))
526 /* FIXME: This modifies typically pure hash-cons'd data, so its
527 correctness is quite delicate. */
531 XSETCAR (tem, make_number (offset)); 528 XSETCAR (tem, make_number (offset));
532 } 529 }
533 else if (EQ (tem, Qmacro)) 530 else if (EQ (tem, Qmacro))