diff options
| author | Stefan Monnier | 2019-05-06 12:37:00 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2019-05-06 12:37:00 -0400 |
| commit | 63091313490beee4c5ed9767195c2a3df98f0332 (patch) | |
| tree | 407991a7dc880293885e121fa40e823148aeb74e /src | |
| parent | f0c0b2cea3ffea7e3c53ff24c58e7a08ac40babb (diff) | |
| download | emacs-63091313490beee4c5ed9767195c2a3df98f0332.tar.gz emacs-63091313490beee4c5ed9767195c2a3df98f0332.zip | |
* lisp/custom.el: Avoid adding vars to load-history multiple times
Avoid the abuse of (eval `(defvar ...)) which tends to end up
adding redundant entries in `load-history`, as discussed in
https://lists.gnu.org/r/help-gnu-emacs/2019-03/msg00237.html
(custom-initialize-default): Don't add to load-history.
(custom-declare-variable): Use internal--define-uninitialized-variable
and only add the var to load-history once. Do it before calling
`initialize` so the special-variable-p flag is set.
* src/eval.c (Finternal__define_uninitialized_variable): New function.
(Fdefvar, Fdefconst): Use it.
(syms_of_eval): Defsubr' it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/src/eval.c b/src/eval.c index 3fd9a40a3a2..567c32e0d75 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -715,6 +715,25 @@ DEFUN ("set-default-toplevel-value", Fset_default_toplevel_value, | |||
| 715 | return Qnil; | 715 | return Qnil; |
| 716 | } | 716 | } |
| 717 | 717 | ||
| 718 | DEFUN ("internal--define-uninitialized-variable", | ||
| 719 | Finternal__define_uninitialized_variable, | ||
| 720 | Sinternal__define_uninitialized_variable, 1, 2, 0, | ||
| 721 | doc: /* Define SYMBOL as a variable, with DOC as its docstring. | ||
| 722 | This is like `defvar' and `defconst' but without affecting the variable's | ||
| 723 | value. */) | ||
| 724 | (Lisp_Object symbol, Lisp_Object doc) | ||
| 725 | { | ||
| 726 | XSYMBOL (symbol)->u.s.declared_special = true; | ||
| 727 | if (!NILP (doc)) | ||
| 728 | { | ||
| 729 | if (!NILP (Vpurify_flag)) | ||
| 730 | doc = Fpurecopy (doc); | ||
| 731 | Fput (symbol, Qvariable_documentation, doc); | ||
| 732 | } | ||
| 733 | LOADHIST_ATTACH (symbol); | ||
| 734 | return Qnil; | ||
| 735 | } | ||
| 736 | |||
| 718 | DEFUN ("defvar", Fdefvar, Sdefvar, 1, UNEVALLED, 0, | 737 | DEFUN ("defvar", Fdefvar, Sdefvar, 1, UNEVALLED, 0, |
| 719 | doc: /* Define SYMBOL as a variable, and return SYMBOL. | 738 | doc: /* Define SYMBOL as a variable, and return SYMBOL. |
| 720 | You are not required to define a variable in order to use it, but | 739 | You are not required to define a variable in order to use it, but |
| @@ -754,32 +773,25 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) | |||
| 754 | { | 773 | { |
| 755 | if (!NILP (XCDR (tail)) && !NILP (XCDR (XCDR (tail)))) | 774 | if (!NILP (XCDR (tail)) && !NILP (XCDR (XCDR (tail)))) |
| 756 | error ("Too many arguments"); | 775 | error ("Too many arguments"); |
| 776 | Lisp_Object exp = XCAR (tail); | ||
| 757 | 777 | ||
| 758 | tem = Fdefault_boundp (sym); | 778 | tem = Fdefault_boundp (sym); |
| 779 | tail = XCDR (tail); | ||
| 759 | 780 | ||
| 760 | /* Do it before evaluating the initial value, for self-references. */ | 781 | /* Do it before evaluating the initial value, for self-references. */ |
| 761 | XSYMBOL (sym)->u.s.declared_special = true; | 782 | Finternal__define_uninitialized_variable (sym, CAR (tail)); |
| 762 | 783 | ||
| 763 | if (NILP (tem)) | 784 | if (NILP (tem)) |
| 764 | Fset_default (sym, eval_sub (XCAR (tail))); | 785 | Fset_default (sym, eval_sub (exp)); |
| 765 | else | 786 | else |
| 766 | { /* Check if there is really a global binding rather than just a let | 787 | { /* Check if there is really a global binding rather than just a let |
| 767 | binding that shadows the global unboundness of the var. */ | 788 | binding that shadows the global unboundness of the var. */ |
| 768 | union specbinding *binding = default_toplevel_binding (sym); | 789 | union specbinding *binding = default_toplevel_binding (sym); |
| 769 | if (binding && EQ (specpdl_old_value (binding), Qunbound)) | 790 | if (binding && EQ (specpdl_old_value (binding), Qunbound)) |
| 770 | { | 791 | { |
| 771 | set_specpdl_old_value (binding, eval_sub (XCAR (tail))); | 792 | set_specpdl_old_value (binding, eval_sub (exp)); |
| 772 | } | 793 | } |
| 773 | } | 794 | } |
| 774 | tail = XCDR (tail); | ||
| 775 | tem = Fcar (tail); | ||
| 776 | if (!NILP (tem)) | ||
| 777 | { | ||
| 778 | if (!NILP (Vpurify_flag)) | ||
| 779 | tem = Fpurecopy (tem); | ||
| 780 | Fput (sym, Qvariable_documentation, tem); | ||
| 781 | } | ||
| 782 | LOADHIST_ATTACH (sym); | ||
| 783 | } | 795 | } |
| 784 | else if (!NILP (Vinternal_interpreter_environment) | 796 | else if (!NILP (Vinternal_interpreter_environment) |
| 785 | && (SYMBOLP (sym) && !XSYMBOL (sym)->u.s.declared_special)) | 797 | && (SYMBOLP (sym) && !XSYMBOL (sym)->u.s.declared_special)) |
| @@ -827,19 +839,12 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) | |||
| 827 | docstring = XCAR (XCDR (XCDR (args))); | 839 | docstring = XCAR (XCDR (XCDR (args))); |
| 828 | } | 840 | } |
| 829 | 841 | ||
| 842 | Finternal__define_uninitialized_variable (sym, docstring); | ||
| 830 | tem = eval_sub (XCAR (XCDR (args))); | 843 | tem = eval_sub (XCAR (XCDR (args))); |
| 831 | if (!NILP (Vpurify_flag)) | 844 | if (!NILP (Vpurify_flag)) |
| 832 | tem = Fpurecopy (tem); | 845 | tem = Fpurecopy (tem); |
| 833 | Fset_default (sym, tem); | 846 | Fset_default (sym, tem); /* FIXME: set-default-toplevel-value? */ |
| 834 | XSYMBOL (sym)->u.s.declared_special = true; | 847 | Fput (sym, Qrisky_local_variable, Qt); /* FIXME: Why? */ |
| 835 | if (!NILP (docstring)) | ||
| 836 | { | ||
| 837 | if (!NILP (Vpurify_flag)) | ||
| 838 | docstring = Fpurecopy (docstring); | ||
| 839 | Fput (sym, Qvariable_documentation, docstring); | ||
| 840 | } | ||
| 841 | Fput (sym, Qrisky_local_variable, Qt); | ||
| 842 | LOADHIST_ATTACH (sym); | ||
| 843 | return sym; | 848 | return sym; |
| 844 | } | 849 | } |
| 845 | 850 | ||
| @@ -4198,6 +4203,7 @@ alist of active lexical bindings. */); | |||
| 4198 | defsubr (&Sdefvaralias); | 4203 | defsubr (&Sdefvaralias); |
| 4199 | DEFSYM (Qdefvaralias, "defvaralias"); | 4204 | DEFSYM (Qdefvaralias, "defvaralias"); |
| 4200 | defsubr (&Sdefconst); | 4205 | defsubr (&Sdefconst); |
| 4206 | defsubr (&Sinternal__define_uninitialized_variable); | ||
| 4201 | defsubr (&Smake_var_non_special); | 4207 | defsubr (&Smake_var_non_special); |
| 4202 | defsubr (&Slet); | 4208 | defsubr (&Slet); |
| 4203 | defsubr (&SletX); | 4209 | defsubr (&SletX); |