I am trying to call a bash program herbstclient from Emacs via process-lines. I created a macro hc-call which actually calls herbstclient that is invoked by the function hc which is supposed to convert its numeric arguments into strings via stringify-numbers.
Needless to say it’s not working. Calling hc with “keybind” “Mod4-Shift-r” “reload” gives the error:
*** Eval error *** Wrong type argument: listp, stringified-args
I tried using edebug on hc and the output suggested stringify-numbers was working properly. The function errored immediately on the hc-call. Yet, when I run:
(hc-call ("keybind" "Mod4-Shift-r" "reload"))
it works as expected. I then tried:
(setq sargs (list "keybind" "Mod4-Shift-r" "reload"))
(hc-call sargs)
and I got the same error. I don’t know how to approach debugging this further. Below is all the code:
(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)))
Why would it complain stringified-args isn’t a list?
Unlike most expressions, macro arguments are passed unevaluated.
This is why
(hc-call ("keybind" "Mod4-Shift-r" "reload"))does not result in an error!It therefore follows that
(hc-call sargs)is passing the symbolsargsto the macro, rather than the list to which it would otherwise evaluate.If you wish your macro to process a variable in this way, you could change
,@argsto,@(eval args), or else conditionally processargseither way, depending on what it turns out to actually be.