mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2026-09-10 07:46:51 -04:00
(custom-declare-variable): Check values previously set via setopt
Rename `custom-check-value` to `custom-check-values` and make it hold a list of values whose type-check is pending. Check it in `custom-declare-variable` rather than `custom-initialize-reset` to fix bug#81372. * lisp/custom.el (custom-initialize-reset): Don't type check previous setopt values. (custom-declare-variable): Do it here instead. Change warning message to clarify that the erroneous value was provided in some earlier setopt call. * lisp/cus-edit.el (setop--set): Push to the `custom-check-values` only if we can't do the type check yet, to avoid duplicate warnings (and memory leaks). (setopt--set-local): Fix indentation and add FIXMEs.
This commit is contained in:
parent
65b1e84397
commit
7e9e10d984
|
|
@ -1098,10 +1098,12 @@ even if it doesn't match the type.)
|
|||
(defun setopt--set (variable value)
|
||||
(custom-load-symbol variable)
|
||||
;; Check that the type is correct.
|
||||
(when-let* ((type (get variable 'custom-type)))
|
||||
(unless (widget-apply (widget-convert type) :match value)
|
||||
(warn "Value does not match %S's type `%S': %S" variable type value)))
|
||||
(put variable 'custom-check-value (list value))
|
||||
(let* ((type (get variable 'custom-type)))
|
||||
(if (not (or type (get variable 'standard-value)))
|
||||
;; `custom-declare-variable' has not run yet. Postpone the check.
|
||||
(push value (get variable 'custom-check-values))
|
||||
(unless (widget-apply (widget-convert type) :match value)
|
||||
(warn "Value does not match %S's type `%S': %S" variable type value))))
|
||||
(funcall (or (get variable 'custom-set) #'set-default) variable value))
|
||||
|
||||
;;;###autoload
|
||||
|
|
@ -1157,24 +1159,28 @@ Consult `setopt-local-type-mismatch'."
|
|||
(let ((accept t))
|
||||
;; Check that the type is correct.
|
||||
(when-let* ((type (get variable 'custom-type)))
|
||||
;; FIXME: If the var hasn't been initialized yet, `type' is nil and we
|
||||
;; skip the type check altogether. Use `custom-check-values'?
|
||||
(unless (widget-apply (widget-convert type) :match value)
|
||||
(let ((msg (format-message
|
||||
"Value does not match %S's type `%S': %S"
|
||||
variable type value)))
|
||||
(cond
|
||||
;; Fall through and try anyway.
|
||||
((eq setopt-local-type-mismatch 'accept))
|
||||
;; Silently discard the mismatched value.
|
||||
((eq setopt-local-type-mismatch 'discard)
|
||||
(setq accept nil))
|
||||
;; Prompt to accept or discard the value.
|
||||
(setopt-local-type-mismatch
|
||||
(setq accept (eq ?a (car
|
||||
(read-multiple-choice msg
|
||||
'((?a "accept" "Accept")
|
||||
(?d "discard" "Discard")))))))
|
||||
(t
|
||||
(warn msg))))))
|
||||
;; FIXME: It's weird to do this `setopt-local-type-mismatch`
|
||||
;; control for `setopt-local' and not for `setopt'.
|
||||
(cond
|
||||
;; Fall through and try anyway.
|
||||
((eq setopt-local-type-mismatch 'accept))
|
||||
;; Silently discard the mismatched value.
|
||||
((eq setopt-local-type-mismatch 'discard)
|
||||
(setq accept nil))
|
||||
;; Prompt to accept or discard the value.
|
||||
(setopt-local-type-mismatch
|
||||
(setq accept (eq ?a (car (read-multiple-choice
|
||||
msg
|
||||
'((?a "accept" "Accept")
|
||||
(?d "discard" "Discard")))))))
|
||||
(t
|
||||
(warn msg))))))
|
||||
(when accept
|
||||
(condition-case _
|
||||
(funcall (or (get variable 'custom-set)
|
||||
|
|
|
|||
|
|
@ -91,20 +91,6 @@ The value is either the symbol's current value
|
|||
(as obtained using the `:get' function), if any,
|
||||
or the value in the symbol's `saved-value' property if any,
|
||||
or (last of all) the value of EXP."
|
||||
;; If this value has been set with `setopt' (for instance in
|
||||
;; ~/.emacs), we didn't necessarily know the type of the user option
|
||||
;; then. So check now, and issue a warning if it's wrong.
|
||||
(let ((value (get symbol 'custom-check-value)))
|
||||
(when value
|
||||
(let ((type (get symbol 'custom-type)))
|
||||
(when (and type
|
||||
(boundp symbol)
|
||||
(eq (car value) (symbol-value symbol))
|
||||
;; Check that the type is correct.
|
||||
(not (widget-apply (widget-convert type)
|
||||
:match (car value))))
|
||||
(warn "Value `%S' for `%s' does not match type %s"
|
||||
value symbol type)))))
|
||||
(funcall (or (get symbol 'custom-set) #'set-default-toplevel-value)
|
||||
symbol
|
||||
(condition-case nil
|
||||
|
|
@ -245,6 +231,18 @@ set to nil, as the value is no longer rogue."
|
|||
;; as set the special-variable-p flag.
|
||||
(internal--define-uninitialized-variable symbol doc)
|
||||
(put symbol 'custom-requests requests)
|
||||
;; If this value has been set with `setopt' (for instance in
|
||||
;; ~/.emacs), we didn't necessarily know the type of the user option
|
||||
;; then. So check now, and issue a warning if it's wrong.
|
||||
(dolist (value (prog1 (nreverse (get symbol 'custom-check-values))
|
||||
(put symbol 'custom-check-values nil)))
|
||||
(let ((type (get symbol 'custom-type)))
|
||||
(when (and type
|
||||
;; Check that the type is correct.
|
||||
(not (widget-apply (widget-convert type)
|
||||
:match (car value))))
|
||||
(warn "Value previously set by setopt did not match %S's type %S:\n%S"
|
||||
symbol type value))))
|
||||
;; Do the actual initialization.
|
||||
(unless custom-dont-initialize
|
||||
(funcall initialize symbol default)
|
||||
|
|
|
|||
Loading…
Reference in a new issue