aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2024-01-31 18:56:43 -0500
committerStefan Monnier2024-02-02 13:07:53 -0500
commite9a668274e441645aed28e8c353187dfed35fcae (patch)
tree3c2e2701ce973c49e31895dabbc1a0a1ea84bdfb /src
parente2d1ac2f258a069f950d4df80c8096bfa34081fc (diff)
downloademacs-e9a668274e441645aed28e8c353187dfed35fcae.tar.gz
emacs-e9a668274e441645aed28e8c353187dfed35fcae.zip
bytecomp.el: Rewrite the way we print dynamic docstrings
We used to print dynamic docstrings "manually" for two reasons: - References should look like `(#$ . POS)` but `prin1` was unable to print just `#$` for an sexp. - `make-docfile` needed to find those docstrings and the object to which they belonged. The second point is moot now that we don't use `make-docfile` on `.elc` files. So this patch lifts the first restriction, using `print-number-table`. The rest of the patch then simplifies and regularises the bytecompiler's generation of dynamic docstrings, which can now also easily be done for "inner" defvars and other places. * src/print.c (print_preprocess, print_object): Handle strings in `print-number-table`. (Vprint_number_table): Improve docstring. * lisp/emacs-lisp/bytecomp.el: (byte-compile--list-with-n): New function. (byte-compile--docstring-style-warn): Rename from `byte-compile-docstring-style-warn` and change calling convention. (byte-compile--\#$, byte-compile--docstrings): New vars. (byte-compile-close-variables): Bind them. (byte-compile--docstring): New function. (byte-compile-from-buffer): Set `byte-compile--\#$`. (byte-compile-output-file-form): Use `byte-compile--\#$` instead of special casing specific forms. (byte-compile--output-docform-recurse, byte-compile-output-docform): Delete functions. (byte-compile-file-form-autoload, byte-compile-file-form-defalias) (byte-compile-file-form-defvar-function, byte-compile-lambda): Use `byte-compile--docstring` and `byte-compile--list-with-n`. (byte-compile--declare-var): Add optional `not-toplevel` arg. (byte-compile-defvar): Add `toplevel` arg. Use `byte-compile--docstring`. (byte-compile-file-form-defvar): Delegate to `byte-compile-defvar`. (byte-compile--custom-declare-face): New function. Use it for `custom-declare-face`. (byte-compile-file-form-defmumble): Use `byte-compile-output-file-form` * src/doc.c (Fdocumentation_stringp): New function. (syms_of_doc): Defsubr it. (store_function_docstring): Remove left-over code from when we used DOC for the docstring of some Lisp files. * lisp/cus-face.el (custom-declare-face): Accept dynamic docstrings. * lisp/faces.el (face-documentation): Handle dynamic docstrings. * lisp/help-fns.el (describe-face): Simplify accordingly.
Diffstat (limited to 'src')
-rw-r--r--src/doc.c58
-rw-r--r--src/print.c19
2 files changed, 31 insertions, 46 deletions
diff --git a/src/doc.c b/src/doc.c
index a451b468ef2..b5a9ed498af 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -357,6 +357,20 @@ reread_doc_file (Lisp_Object file)
357 return 1; 357 return 1;
358} 358}
359 359
360DEFUN ("documentation-stringp", Fdocumentation_stringp, Sdocumentation_stringp,
361 1, 1, 0,
362 doc: /* Return non-nil if OBJECT is a well-formed docstring object.
363OBJECT can be either a string or a reference if it's kept externally. */)
364 (Lisp_Object object)
365{
366 return (STRINGP (object)
367 || FIXNUMP (object) /* Reference to DOC. */
368 || (CONSP (object) /* Reference to .elc. */
369 && STRINGP (XCAR (object))
370 && FIXNUMP (XCDR (object)))
371 ? Qt : Qnil);
372}
373
360DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0, 374DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0,
361 doc: /* Return the documentation string of FUNCTION. 375 doc: /* Return the documentation string of FUNCTION.
362Unless a non-nil second argument RAW is given, the 376Unless a non-nil second argument RAW is given, the
@@ -502,46 +516,13 @@ store_function_docstring (Lisp_Object obj, EMACS_INT offset)
502 /* If it's a lisp form, stick it in the form. */ 516 /* If it's a lisp form, stick it in the form. */
503 if (CONSP (fun) && EQ (XCAR (fun), Qmacro)) 517 if (CONSP (fun) && EQ (XCAR (fun), Qmacro))
504 fun = XCDR (fun); 518 fun = XCDR (fun);
505 if (CONSP (fun))
506 {
507 Lisp_Object tem = XCAR (fun);
508 if (EQ (tem, Qlambda) || EQ (tem, Qautoload)
509 || (EQ (tem, Qclosure) && (fun = XCDR (fun), 1)))
510 {
511 tem = Fcdr (Fcdr (fun));
512 if (CONSP (tem) && FIXNUMP (XCAR (tem)))
513 /* FIXME: This modifies typically pure hash-cons'd data, so its
514 correctness is quite delicate. */
515 XSETCAR (tem, make_fixnum (offset));
516 }
517 }
518 /* Lisp_Subrs have a slot for it. */ 519 /* Lisp_Subrs have a slot for it. */
519 else if (SUBRP (fun) && !SUBR_NATIVE_COMPILEDP (fun)) 520 if (SUBRP (fun) && !SUBR_NATIVE_COMPILEDP (fun))
520 { 521 XSUBR (fun)->doc = offset;
521 XSUBR (fun)->doc = offset; 522 else
522 }
523
524 /* Bytecode objects sometimes have slots for it. */
525 else if (COMPILEDP (fun))
526 { 523 {
527 /* This bytecode object must have a slot for the 524 AUTO_STRING (format, "Ignoring DOC string on non-subr: %S");
528 docstring, since we've found a docstring for it. */ 525 CALLN (Fmessage, format, obj);
529 if (PVSIZE (fun) > COMPILED_DOC_STRING
530 /* Don't overwrite a non-docstring value placed there,
531 * such as the symbols used for Oclosures. */
532 && VALID_DOCSTRING_P (AREF (fun, COMPILED_DOC_STRING)))
533 ASET (fun, COMPILED_DOC_STRING, make_fixnum (offset));
534 else
535 {
536 AUTO_STRING (format,
537 (PVSIZE (fun) > COMPILED_DOC_STRING
538 ? "Docstring slot busy for %s"
539 : "No docstring slot for %s"));
540 CALLN (Fmessage, format,
541 (SYMBOLP (obj)
542 ? SYMBOL_NAME (obj)
543 : build_string ("<anonymous>")));
544 }
545 } 526 }
546} 527}
547 528
@@ -776,6 +757,7 @@ compute the correct value for the current terminal in the nil case. */);
776 doc: /* If nil, a nil `text-quoting-style' is treated as `grave'. */); 757 doc: /* If nil, a nil `text-quoting-style' is treated as `grave'. */);
777 /* Initialized by ‘main’. */ 758 /* Initialized by ‘main’. */
778 759
760 defsubr (&Sdocumentation_stringp);
779 defsubr (&Sdocumentation); 761 defsubr (&Sdocumentation);
780 defsubr (&Ssubr_documentation); 762 defsubr (&Ssubr_documentation);
781 defsubr (&Sdocumentation_property); 763 defsubr (&Sdocumentation_property);
diff --git a/src/print.c b/src/print.c
index c6a3dba3163..c2beff0ed55 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1412,7 +1412,7 @@ print_preprocess (Lisp_Object obj)
1412 && SYMBOLP (obj) 1412 && SYMBOLP (obj)
1413 && !SYMBOL_INTERNED_P (obj))) 1413 && !SYMBOL_INTERNED_P (obj)))
1414 { /* OBJ appears more than once. Let's remember that. */ 1414 { /* OBJ appears more than once. Let's remember that. */
1415 if (!FIXNUMP (num)) 1415 if (SYMBOLP (num)) /* In practice, nil or t. */
1416 { 1416 {
1417 print_number_index++; 1417 print_number_index++;
1418 /* Negative number indicates it hasn't been printed yet. */ 1418 /* Negative number indicates it hasn't been printed yet. */
@@ -2265,6 +2265,11 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
2265 goto next_obj; 2265 goto next_obj;
2266 } 2266 }
2267 } 2267 }
2268 else if (STRINGP (num))
2269 {
2270 strout (SDATA (num), SCHARS (num), SBYTES (num), printcharfun);
2271 goto next_obj;
2272 }
2268 } 2273 }
2269 2274
2270 print_depth++; 2275 print_depth++;
@@ -2554,11 +2559,6 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
2554 goto next_obj; 2559 goto next_obj;
2555 case PVEC_SUB_CHAR_TABLE: 2560 case PVEC_SUB_CHAR_TABLE:
2556 { 2561 {
2557 /* Make each lowest sub_char_table start a new line.
2558 Otherwise we'll make a line extremely long, which
2559 results in slow redisplay. */
2560 if (XSUB_CHAR_TABLE (obj)->depth == 3)
2561 printchar ('\n', printcharfun);
2562 print_c_string ("#^^[", printcharfun); 2562 print_c_string ("#^^[", printcharfun);
2563 int n = sprintf (buf, "%d %d", 2563 int n = sprintf (buf, "%d %d",
2564 XSUB_CHAR_TABLE (obj)->depth, 2564 XSUB_CHAR_TABLE (obj)->depth,
@@ -2664,7 +2664,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
2664 /* With the print-circle feature. */ 2664 /* With the print-circle feature. */
2665 Lisp_Object num = Fgethash (next, Vprint_number_table, 2665 Lisp_Object num = Fgethash (next, Vprint_number_table,
2666 Qnil); 2666 Qnil);
2667 if (FIXNUMP (num)) 2667 if (!(NILP (num) || EQ (num, Qt)))
2668 { 2668 {
2669 print_c_string (" . ", printcharfun); 2669 print_c_string (" . ", printcharfun);
2670 obj = next; 2670 obj = next;
@@ -2928,7 +2928,10 @@ This variable should not be set with `setq'; bind it with a `let' instead. */);
2928 DEFVAR_LISP ("print-number-table", Vprint_number_table, 2928 DEFVAR_LISP ("print-number-table", Vprint_number_table,
2929 doc: /* A vector used internally to produce `#N=' labels and `#N#' references. 2929 doc: /* A vector used internally to produce `#N=' labels and `#N#' references.
2930The Lisp printer uses this vector to detect Lisp objects referenced more 2930The Lisp printer uses this vector to detect Lisp objects referenced more
2931than once. 2931than once. If an entry contains a number, then the corresponding key is
2932referenced more than once: a positive sign indicates that it's already been
2933printed, and the absolute value indicates the number to use when printing.
2934If an entry contains a string, that string is printed instead.
2932 2935
2933When you bind `print-continuous-numbering' to t, you should probably 2936When you bind `print-continuous-numbering' to t, you should probably
2934also bind `print-number-table' to nil. This ensures that the value of 2937also bind `print-number-table' to nil. This ensures that the value of