全局改变编译命令

我使用Emacs与Docker进行开发。 Emacs在主机上运行一个包含代码的容器,在Docker容器内执行,testing等等。

我开始编辑一些Emacs模式并添加variables,以允许docker作为命令前缀。 因此,使用.dir-locals我可以在Docker容器中运行类似rspec命令。 但是我必须改变rspec-mode的代码才能到达那里。 我见过的所有模式都有共同点,那就是使用Emacs的compilefunction来运行它们的命令。

所以我想知道是否有机会全局扩展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-prefixcompilation-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。