首页 > 解决方案 > 如何在emacs-lisp中将变量约束为正?

问题描述

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

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

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

这种行为可以实现吗?

标签: variablesemacsnumbers

解决方案


您可以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您可以向and添加错误处理timer-slower——但在这种情况下,我认为如果用户在 elisp 中设置值,我会相信用户知道他们在做什么。


为了完整性:Emacs 26.1 确实引入了add-variable-watcherwhich 可用于捕获 'invalid' setq,但老实说,我认为将其用于如此微不足道的目的是不合理的。customizeUI 是断言此类事情的正确位置。


推荐阅读