我使用Emacs与Docker一起开发。 Emacs在主机上运行,其中包含代码的卷,该代码在Docker容器内执行,测试等。
我开始编辑一些Emacs模式并添加变量以允许docker作为命令前缀。因此,使用.dir-locals
,我可以在Docker容器中运行rspec
之类的命令。但我不得不改变rspec-mode
的代码来实现目标。我见过的所有模式都有共同之处,即他们使用Emacs的compile
函数来运行他们的命令。
所以我想知道是否有机会全局扩展compile
函数或comint中的任何内容来添加运行每个外部命令的前缀,该命令是通过Docker内部的编译启动的。例如。 rspec
将转换为docker-compose exec app rspec
。理想情况下,这将在.dir-locals
中完成,以允许项目特定的前缀。
这将产生更通用的解决方案,该解决方案适用于任何模式而无需更改其代码。它不仅限于Docker,而是支持任何环境,其中某些模式需要为其命令提供特殊的前缀。
不幸的是,我不知道如何运行这样的东西。
答案 0 :(得分:0)
我现在想出了以下内容:
在我的Emacs初始化文件中,我添加了一些变量并更改了compile
命令,如下所示:
(defvar compilation-command-prefix nil
"Using environments like docker, this can be used to
add a command prefix which is executed before each compile command.
Last given char in most cases should be whitespace.")
(defvar compilation-project-root nil
"When set to a projecet root dir, parameters which contain that dir
get subsituted, which makes them relative to the root path.")
(defun compile (command &optional comint)
(interactive
(list
(let ((command (eval compile-command)))
(if (or compilation-read-command current-prefix-arg)
(compilation-read-command command)
command))
(consp current-prefix-arg)))
(unless (equal command (eval compile-command))
(setq compile-command command))
(save-some-buffers (not compilation-ask-about-save)
compilation-save-buffers-predicate)
(setq-default compilation-directory default-directory)
(compilation-start (concat compilation-command-prefix (replace-regexp-in-string compilation-project-root "" command)) comint))
因此,当给出compilation-command-prefix
和compilation-project-root
时,第一个用作command
的前缀,第二个用于command
以获取相对文件路径。
相应的.dir-locals.el
是:
((nil
. ((compilation-command-prefix . "/usr/local/bin/docker-compose exec app ")
(eval setq compilation-project-root
(replace-regexp-in-string "~" (getenv "HOME") (locate-dominating-file default-directory ".dir-locals.el"))))))
这对我来说很有用,即使compile
中的某种挂钩会更优雅的解决方案。