Emacs元编程,动态定义方法

eig*_*tor 3 emacs macros elisp metaprogramming

我正在尝试定义一些帮助函数,以便从emacs中快速跳转到不同的项目.我开始定义一个宏如下

(defmacro project-alias (name path)
  `(defun ,name ()
     (interactive)
     (cd ,path)))
Run Code Online (Sandbox Code Playgroud)

这很好用我也(project-alias foo "~/bar")没问题.当我尝试将此宏应用于元组列表时,问题就出现了.

(setq projects '((foo . "~/foo")
                 (bar . "~/bar")))

(dolist (p projects)
  (project-alias (car p) (cdr p)))
Run Code Online (Sandbox Code Playgroud)

上面的代码错误

Debugger entered--Lisp error: (wrong-type-argument symbolp (car p))
  defalias((car p) (lambda nil (interactive) (cd (cdr p))))
Run Code Online (Sandbox Code Playgroud)

我已经尝试将第一个参数作为字符串传递并调用intern以获得符号表示而没有任何乐趣,我也尝试定义我的宏来接受字符串形式,这也不起作用

我究竟做错了什么?

Dre*_*rew 5

如果您使用宏涉及评估性别以产生名称和路径,那么它需要评估性别:

(defmacro project-alias (name path)
  `(defun ,(eval name) () (interactive) (cd ,(eval path))))
Run Code Online (Sandbox Code Playgroud)

或者,使用一个函数:

(defun project-alias (name path)
  (eval `(defun ,name () (interactive) (cd ,path))))
Run Code Online (Sandbox Code Playgroud)