2017-09-11 2 views
1

J'utilise Emacs pour développer avec Docker. Emacs fonctionne sur l'hôte avec un volume contenant le code, qui est exécuté, testé, etc. à l'intérieur du conteneur Docker.Commande de compilation de changement global

J'ai commencé à modifier certains modes Emacs et ajouté des variables pour permettre le docker comme préfixe de commande. Donc, avec l'utilisation de .dir-locals je suis capable d'exécuter des commandes comme rspec à l'intérieur du conteneur Docker. Mais j'ai dû changer le code du rspec-mode pour y arriver. Tous les modes que j'ai vus depuis longtemps ont en commun, qu'ils utilisent la fonction compile d'Emacs pour exécuter leurs commandes.

Donc je me demande s'il y a une chance de développer globalement la fonction compile ou quoi que ce soit dans comint pour ajouter un préfixe pour exécuter chaque commande externe qui est démarrée via la compilation à l'intérieur de Docker. Par exemple. rspec serait converti en docker-compose exec app rspec. Idéalement, cela devrait être fait dans un .dir-locals pour permettre des préfixes spécifiques au projet.

Cela aboutirait à une solution beaucoup plus générale qui devrait fonctionner pour n'importe quel mode sans avoir besoin de changer de code. Il ne serait pas limité à Docker mais supporterait n'importe quel environnement, où certains modes ont besoin d'un préfixe spécial à leurs commandes.

Malheureusement, je n'ai aucune idée, comment faire fonctionner quelque chose comme ça.

+0

Je n'utilise pas de docker, mais il semble qu'il y ait une extension clochard pour cela: https://www.emacswiki.org/emacs/TrampAndDocker. On dirait que vous pourriez ouvrir un fichier ou un répertoire dans le conteneur et la commande de compilation devrait automatiquement s'exécuter là (comme avec des machines distantes sur ssh). Vérifiez également multi-compiler; J'utilise ça pour organiser les commandes de compilation. – jpkotta

+0

Je n'ai pas essayé Tramp, mais pour autant que je lis, cela supprimerait les avantages de l'édition des fichiers dans mon arbre source local. multi-compile semble intéressant, je dois y jeter un coup d'œil. Une autre approche consistait à redéfinir 'compile' pour prendre un préfixe ajouté à chaque commande. Ici, j'ai le problème, que certaines extensions utilisent des chemins de fichiers globaux, qui n'existent pas dans le conteneur Docker. Ma prochaine idée est d'ajouter une variable racine de projet '.dir-locals', qui permettra de remplacer les chemins globaux par des variables locales. –

+0

'compile' exécute' make' par défaut. Ne pouvez-vous pas faire ce que vous devez faire en écrivant un 'Makefile' approprié? – Nick

Répondre

0

je maintenant est venu avec les éléments suivants:

Dans mon fichier d'initialisation Emacs, j'ai ajouté quelques vars et changé la commande compile comme suit:

(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)) 

Alors, quand compilation-command-prefix et compilation-project-root sont donnés, le premier est utilisé comme préfixe pour command et le second est retiré de command pour obtenir les chemins de fichiers relatifs.

Le correspondant .dir-locals.el est:

((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")))))) 

Cela fonctionne pour moi, même si une sorte de crochet avant dans compile serait une solution plus élégante.