Как заставить переменную быть положительной в emacs-lisp? - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть настраиваемая переменная timer-granularity, используемая для увеличения / уменьшения периода таймера каждый раз, когда пользователь вызывает что-то вроде (timer-faster) или (timer-slower). Однако, если пользователь устанавливает timer-granularity на отрицательное число, то вызов (timer-slower) на самом деле сделает таймер быстрее!

Я бы хотел ограничить значение этой переменной так, чтобы было ошибкой пытаться установить его на значение, меньшее некоторого порога, например

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

Достижимо ли это поведение?

Ответы [ 2 ]

0 голосов
/ 04 апреля 2019

Аналогично ответу @ phils - вы можете сделать то же самое напрямую, без определения нового :type:

(defcustom foo 42
  "Foo..."
  :type '(restricted-sexp
          :match-alternatives ((lambda (x) (and (natnump x)  (not (zerop x)))))))
0 голосов
/ 17 сентября 2018

Вы можете 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 является правильным местом для утверждения таких вещей.

...