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

时间:2018-09-16 21:13:04

标签: emacs lisp elisp

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

我想限制此变量的值,以便尝试将其设置为小于某个阈值的任何错误,例如

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

这种行为可以实现吗?

2 个答案:

答案 0 :(得分: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是断言此类事情的正确位置。

答案 1 :(得分:0)

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

(defcustom foo 42
  "Foo..."
  :type '(restricted-sexp
          :match-alternatives ((lambda (x) (and (natnump x)  (not (zerop x)))))))