我使用 Emacs 与 Docker 一起开发。 Emacs 在主机上运行,其卷包含代码,在 Docker 容器内执行、测试等。
我开始编辑一些 Emacs 模式并添加变量以允许 docker 作为命令前缀。所以使用 .dir-locals
我可以运行 rspec
之类的命令在 Docker 容器内。但我不得不更改 rspec-mode
的代码到那里。我见过的所有模式都有一个共同点,它们使用 Emacs 的 compile
函数来运行他们的命令。
所以我想知道是否有机会在全局范围内扩展 compile
函数或其他任何内容来为运行每个外部命令添加一个前缀,这些命令是通过 Docker 内部的编译启动的。例如。 rspec
将转换为 docker-compose exec app rspec
.理想情况下,这将在 .dir-locals
中完成。允许项目特定的前缀。
这将产生一个更通用的解决方案,该解决方案适用于任何模式,无需更改其代码。它不仅限于 Docker,还支持任何环境,其中某些模式需要为其命令添加特殊前缀。
不幸的是,我不知道如何让这样的东西运行。
最佳答案
我现在想出了以下内容:
在我的 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
中有某种之前的钩子(Hook)。将是一个更优雅的解决方案。
关于docker - 全局更改编译命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46161782/