Emacs Lisp:如何使用交互式(用于条件参数)?

3
我想根据用户对第一个问题的回答,向其询问第二个问题。
(defun something (a b)
  (interactive
   (list
    (read-number "First num: ")
    (read-number "Second num: ")))
  (message "a is %s and b is %s" a b))

所以我需要一种测试输入值的方法:
(defun something-else (a &optional b)
  (interactive
   (list
    (read-number "First num: ")
    (if (< a 2)
        (read-number "Second num: "))))
  (message "a is %s" a))

但是。
if: Symbol's value as variable is void: a

问题:如何以真正互动的方式使用 interactive

2个回答

4
(defun xtest (a &optional b)
  (interactive
   (let (a b)
     (setq a (read-number "First: "))
     (if (< a 2)
         (setq b (read-number "Second: ")))
     (list a b)))

  (message "a is %s b is %s" a b))

1
太好了。为有点笨拙的“匿名”交互式声明增添了优雅。我已经思考这个问题多年,谢谢! - yPhil
在这个例子中,我发现使用 setq 更易读。另一个答案已经在使用 let* 了。 - knarf

4

interactive表单解释为一种子程序,它将参数值列表作为返回值传递。您可以使用类似let的表单来定义本地变量。

(defun something-else (a &optional b)
  (interactive
   (let* ((a-local (read-number "First num: "))
          (b-local (when (< a-local 2)
             (read-number "Second num: "))))
     (list a-local b-local)))
  (message "a is %s, b is %s" a b))

在上面的例子中,a-localb-local是你选择的变量名,并且它们是局部于包含的let*表单的变量。在let*中星号表示对a-local进行求值的表达式(read-number "First num: ")被分配给a-local之前,对b-local进行求值的表达式(when (< a-local 2) (read-number "Second num: "))会被评估。请注意,HTML标记已保留。

不错。我最终使用了这个表单*来避免泄漏全局符号。 - yPhil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接