全局改变编译命令
我使用Emacs与Docker进行开发。 Emacs在主机上运行一个包含代码的容器,在Docker容器内执行,testing等等。
我开始编辑一些Emacs模式并添加variables,以允许docker作为命令前缀。 因此,使用.dir-locals
我可以在Docker容器中运行类似rspec
命令。 但是我必须改变rspec-mode
的代码才能到达那里。 我见过的所有模式都有共同点,那就是使用Emacs的compile
function来运行它们的命令。
所以我想知道是否有机会全局扩展compile
函数或者comint中的任何东西来添加一个前缀来运行通过Docker内部编译启动的每个外部命令。 例如rspec
将被转换为docker-compose exec app rspec
。 理想情况下,这将在一个.dir-locals
来完成,以允许项目特定的前缀。
这将导致一个更通用的解决scheme,它应该适用于任何模式而无需更改其代码。 它不会受限于Docker,而是支持任何环境,其中一些模式需要一个特殊的前缀到他们的命令。
不幸的是,我不知道如何得到这样的东西。
我现在想出了以下几点:
在我的Emacs初始化文件中,我添加了一些variables,并更改了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
移除以获得相对的文件path。
相应的.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
之前的某种forms将是一个更优雅的解决scheme。