我想在Elisp中创建一个DSL,如下所示:
(install
;; do install
)
(uninstall
;; do uninstall
)
但是,由于Elisp具有全局 namespace ,所以这不是一个好主意。像这样的函数加上前缀,真是太丑了。
(package-install
;; do install
)
(package-uninstall
;; do uninstall
)
因此,我认为所有命令都可以包装在这样的命令调用中,这是一个折衷方案:
(commands
(install
;; do install
)
(uninstall
;; do uninstall
)
;; ...
)
但是由于我不想在全局 namespace 中安装并安装而不是,因此我不得不在命令宏中用所有可能出现的命令替换前缀名称,例如:
(defmacro commands (&rest body)
(mapcar
(lambda (exp)
(setcar exp (intern (concat "package-" (symbol-name (car exp)))))
(setcdr exp (list (cons 'progn (cdr exp)))))
body)
`(progn ,@body))
(commands
(install
;; do install
)
(uninstall
;; do uninstall
)
;; ...
)
这似乎是一个hack。另外,如果有任何嵌套命令,它将无法正常工作。
有什么好的解决方案吗?还是要走的路?
谢谢!
最佳答案
在本地定义install
和 friend 如何?这不会隐藏标准函数,但是看起来并不像您真正追求的那样。
(defmacro commands (&rest body)
`(flet ((install (&rest args) (apply 'package-install args))
(uninstall (&rest args) (apply 'package-uninstall args)))
,@body))
当然,您希望自动生成该
flet
参数列表。您确实需要在某处(可能使用(feature-symbols 'package)
)列出包元素的列表。