如何在emacs-lisp中约束变量为正数?

问题描述 投票:1回答:2

我有一个可自定义的变量timer-granularity,用于在每次用户调用(timer-faster)(timer-slower)之类的时候增加/减少计时器的周期。但是,如果用户将timer-granularity设置为负数,则调用(timer-slower)实际上会使计时器更快!

我想约束这个变量的值,以便尝试将其设置为小于某个阈值的任何值,这是错误的,例如

(setq timer-granularity 0.3)  ;; okay
(setq timer-granularity -1)  ;; error!

这种行为是否可以实现?

emacs lisp elisp
2个回答
5
投票

你可以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-fastertimer-slower - 但在这种情况下,我认为我只是相信用户知道如果他们在elisp中设置值,他们正在做什么。


为了完整性:Emacs 26.1确实引入了add-variable-watcher,可以用来捕捉'无效'setq,但老实说,我不认为将它用于这样一个微不足道的目的是合理的。 customize UI是断言这些事情的正确位置。


0
投票

与@ phils的答案类似 - 您可以直接执行相同的操作,而无需定义新的:type

(defcustom foo 42
  "Foo..."
  :type '(restricted-sexp
          :match-alternatives ((lambda (x) (and (natnump x)  (not (zerop x)))))))
© www.soinside.com 2019 - 2024. All rights reserved.