1

我正在尝试通过process-lines从 Emacs调用 bash 程序herbstclient。我创建了一个宏 hc-call,它实际上调用了由函数 hc 调用的herbstclient,该函数应该通过 stringify-numbers 将其数字参数转换为字符串。

不用说它不起作用。用 "keybind" "Mod4-Shift-r" "reload" 调用 hc 会出现错误:

 *** Eval error ***  Wrong type argument: listp, stringified-args

我尝试在 hc 上使用 edebug 并且输出建议 stringify-numbers 工作正常。该函数在 hc 调用时立即出错。然而,当我运行时:

(hc-call ("keybind" "Mod4-Shift-r" "reload"))

它按预期工作。然后我尝试了:

(setq sargs (list "keybind" "Mod4-Shift-r" "reload"))
(hc-call sargs)

我得到了同样的错误。我不知道如何进一步调试。以下是所有代码:

(defmacro hc-call (args)
  "Call herbstclient to with the given arguments."
   `(process-lines "herbstclient" ,@args))

(defun stringify-numbers (args)
  "Take a list of random arguments with a mix of numbers and
  strings and convert just the numbers to strings."
  (let (stringified-args)
    (dolist (arg args)
      (if (numberp arg)
          (setq stringified-args (cons (number-to-string arg) stringified-args))
        (setq stringified-args (cons arg stringified-args))))
    (nreverse stringified-args)))

(defun hc (&rest args)
  "Pass arguments to herbstclient in a bash process."
  (let ((stringified-args (stringify-numbers args)))
    (hc-call stringified-args)))

为什么它会抱怨 stringified-args 不是列表?

4

2 回答 2

2

hc-call应该是一个函数,沿着

(defun hc-call (args)
  "Call herbstclient to with the given arguments."
  (apply #'process-lines "herbstclient" args))

顺便说一句,当我在这里时:

  (if (numberp arg)
      (setq stringified-args (cons (number-to-string arg) stringified-args))
    (setq stringified-args (cons arg stringified-args))))

写得更好

  (setq stringified-args (cons (if (numberp arg) (number-to-string arg) arg) stringified-args))))

或者

  (push (if (numberp arg) (number-to-string arg) arg) stringified-args)))
于 2012-12-19T04:52:35.037 回答
1

与大多数表达式不同,宏参数是通过unevaluate传递的。

这就是为什么(hc-call ("keybind" "Mod4-Shift-r" "reload"))不会导致错误!

因此,(hc-call sargs)将符号传递sargs给宏,而不是它将评估的列表。

如果您希望您的宏以这种方式处理变量,您可以更改,@args,@(eval args),或者有条件地处理args任何一种方式,具体取决于实际结果。

于 2012-12-19T03:47:31.443 回答