我有一个可自定义的变量timer-granularity
,用于在每次用户调用(timer-faster)
或(timer-slower)
之类的时候增加/减少计时器的周期。但是,如果用户将timer-granularity
设置为负数,则调用(timer-slower)
实际上会使计时器更快!
我想约束这个变量的值,以便尝试将其设置为小于某个阈值的任何值,这是错误的,例如
(setq timer-granularity 0.3) ;; okay
(setq timer-granularity -1) ;; error!
这种行为是否可以实现?
你可以setq
任何东西(无论是否合理),但你当然可以添加验证到customize
界面。例如。:
(define-widget 'integer-positive 'integer
"Value must be a positive integer."
:validate (lambda (widget)
(let ((value (widget-value widget)))
(when (or (not (integerp value)) (<= value 0))
(widget-put widget :error "Must be a positive integer")
widget))))
(defcustom foo 1 "Positive int"
:type 'integer-positive)
您可以将错误处理添加到timer-faster
和timer-slower
- 但在这种情况下,我认为我只是相信用户知道如果他们在elisp中设置值,他们正在做什么。
为了完整性:Emacs 26.1确实引入了add-variable-watcher
,可以用来捕捉'无效'setq
,但老实说,我不认为将它用于这样一个微不足道的目的是合理的。 customize
UI是断言这些事情的正确位置。
与@ phils的答案类似 - 您可以直接执行相同的操作,而无需定义新的:type
:
(defcustom foo 42
"Foo..."
:type '(restricted-sexp
:match-alternatives ((lambda (x) (and (natnump x) (not (zerop x)))))))