How to avoid unwanted macro distribution failures in emacs macros?

I have defined this macro:

(defmacro with-current-directory (directory &rest body)
  "Set the working directory temporarily set to DIRECTORY and run BODY.
DIRECTORY is expanded"
  `(let ((default-directory
          ,(file-name-as-directory
            (expand-file-name (eval directory)))))
     ,@body))

      

which I use in some lisp functions that are loaded when emacs is opened. I always get these warnings:

Eager macro-expansion failure: (void-variable repo-dir)
Eager macro-expansion failure: (wrong-type-argument stringp nil)

      

I understand this is because these variables are not defined at boot time, and emacs is trying to evaluate them. My question is, how can I avoid these warnings. Is there a way to define a macro to prevent this from happening? I cannot figure out how to use the value of the variable and not the symbol of the variable itself.

+3


source to share


2 answers


Like this:

`(let ((default-directory
        (file-name-as-directory (expand-file-name ,directory))))

      



Since it directory

is not a value, but a lisp expression that will evaluate to a value, you need to insert (using the comma operator) the expression in the macro extension. If you put a comma in front of the call file-name-as-directory

, you should be able to compute the directory while expanding the macro based only on expression tokens, which you cannot do if directory

the variable name is referenced.

+5


source


Looks like some beat me up. Take a look at the other answer.

You shouldn't evaluate the file name extension at extension time. Also, the eval call shouldn't be there. The only thing that needs to happen when expanding macros is setting the directory value inside the return expression. Remove eval and place a comma in front of the directory.



Nice to know that anytime you use eval you are probably wrong

+1


source







All Articles