Montez récursivement pour trouver Makefile et compiler

9

Le problème M-x compileest que si le Makefilen'est pas dans le répertoire courant, il échoue.

J'aimerais avoir une fonction qui monte récursivement pour trouver un Makefileet exécuter à makepartir de ce répertoire.

J'ai vu cette question , mais elle est spécifique au chemin, et c'est quelque chose que je dois penser à exécuter.

Florian Margaine
la source
Si vous utilisez, projectileil existe des moyens de compiler à partir de projectile-project-root. Par exemple, github.com/abo-abo/helm-make
abo-abo
@ abo-abo Je n'avais pas essayé de projectile! Il semble que ça projectile-compile-projectfasse ce que je veux. Mais j'aimerais avoir quelque chose sans cette dépendance, si possible.
Florian Margaine
merci, projectile-compile-project fonctionne pour moi
netawater

Réponses:

15

Vous recherchez la fonction locate-dominating-file. Voici la documentation emacs pour cette fonction:

(locate-dominating-file FILE NAME)

Recherchez la hiérarchie de répertoires à partir FILEd'un répertoire contenant NAME. Arrêtez-vous au premier répertoire parent contenant un fichier NAMEet retournez le répertoire. Retour nilsi non trouvé. Au lieu d'une chaîne, NAMEpeut également être un prédicat prenant un argument (un répertoire) et renvoyant une valeur non nulle si ce répertoire est celui que nous recherchons.

En utilisant cela, la réponse d'abo-abo peut être raccourcie en

(defun desperately-compile ()
  "Traveling up the path, find a Makefile and `compile'."
  (interactive)
  (when (locate-dominating-file default-directory "Makefile")
  (with-temp-buffer
    (cd (locate-dominating-file default-directory "Makefile"))
    (compile "make -k"))))
Pradhan
la source
Agréable! Cette fonction fait une chose similaire à ma boucle, mais d'une manière bien documentée et de gestion de cas de bord. Je ferai en sorte de l'ajouter à ma liste de recettes, merci.
abo-abo
Agréable! vim a une fonction similaire nommée findfile, j'ai été surpris qu'emacs ne l'ait pas.
Florian Margaine du
N'y a-t-il pas quelque chose de similaire à celui de Lisp let? Vous courez locate-dominating-filedeux fois.
Florian Margaine
@FlorianMargaine Oui, vous pouvez utiliser let. Je tapais la réponse directement sans tester et je pensais que cela était moins susceptible d'avoir des parenthèses égarées :)
Pradhan
Je souhaiterais pouvoir voter davantage sur cette réponse. Je vous remercie.
Erik
6

Compilation récursive, sans dépendances attachées:

(defun desperately-compile ()
  "Traveling up the path, find a Makefile and `compile'."
  (interactive)
  (with-temp-buffer
    (while (and (not (file-exists-p "Makefile"))
                (not (equal "/" default-directory)))
      (cd ".."))
    (when (file-exists-p "Makefile")
      (compile "make -k"))))
abo-abo
la source
Impressionnant! C'est exactement ce que je voulais.
Florian Margaine
OK, faites juste attention à l'état de fin de la boucle. Si vous êtes sous Windows, vous pourriez obtenir une boucle sans fin.
abo-abo
Question secondaire: pourquoi utilisez-vous with-temp-buffer?
Florian Margaine
Oui, je ne me soucie pas des fenêtres, mais merci de l'avoir mentionné.
Florian Margaine
J'utilise with-temp-buffer, car default-directoryest tampon-local. Je ne veux pas le changer pour le fichier actuel.
abo-abo