使用elisp中的函数,宏和bash调用混合调试代码

时间:2012-12-19 03:03:42

标签: emacs elisp

我正试图通过herbstclient从Emacs拨打bash程序process-lines。我创建了一个宏hc调用,它实际上调用了由函数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不是列表?

2 个答案:

答案 0 :(得分: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)))

答案 1 :(得分:1)

与大多数表达式不同,宏参数传递未评估

这就是(hc-call ("keybind" "Mod4-Shift-r" "reload"))不会导致错误的原因!

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

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