Suba recursivamente para encontrar Makefile e compilar

9

O problema M-x compileé que, se Makefilenão estiver no diretório atual, ele falhará.

Eu gostaria de ter uma função que sobe recursivamente para encontrar um Makefilee executar a makepartir deste diretório.

Eu já vi essa pergunta , mas é específica do caminho e é algo que tenho que pensar em executar.

Florian Margaine
fonte
Se você estiver usando, projectileexistem maneiras de compilar projectile-project-root. Por exemplo, github.com/abo-abo/helm-make
abo-abo
@ abo-abo Eu não tinha tentado projétil! Parece que projectile-compile-projectfaz o que eu quero. Mas eu gostaria de ter algo sem essa dependência, se possível.
Florian Margaine
obrigado, projectile-compile-project funciona para mim
netawater

Respostas:

14

Você está procurando a função locate-dominating-file. Aqui está a documentação do emacs para esta função:

(locate-dominating-file FILE NAME)

Procure a hierarquia de FILEdiretórios em um diretório que contenha NAME. Pare no primeiro diretório pai que contém um arquivo NAMEe retorne o diretório. Retorne nilse não for encontrado. Em vez de uma string, NAMEtambém pode ser um predicado pegando um argumento (um diretório) e retornando um valor diferente de zero se esse diretório for o que estamos procurando.

Usando isso, a resposta da abo-abo pode ser reduzida para

(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
fonte
Agradável! Essa função faz uma coisa semelhante ao meu loop, mas de uma maneira bem documentada e de manipulação de casos extremos. Vou me certificar de adicioná-lo à minha lista de receitas, obrigado.
abo-abo
Agradável! O vim tem uma função semelhante chamada findfile, fiquei surpreso que o emacs não a tivesse.
Florian Margaine
Não há algo semelhante ao lisp let? Você está correndo locate-dominating-fileduas vezes.
Florian Margaine 17/01/2015
@FlorianMargaine Sim, você poderia usar let. Eu estava escrevendo a resposta diretamente sem testar e percebi isso era menos provável que tenha parênteses extraviado :)
Pradhan
Eu gostaria de poder votar mais nesta resposta. Obrigado.
Erik
6

Compilação recursiva, sem dependências anexadas:

(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
fonte
Impressionante! Isto é exatamente o que eu queria.
Florian Margaine 17/01/2015
OK, tenha cuidado com a condição final do loop. Se você estiver no Windows, poderá obter um loop infinito.
abo-abo
Pergunta secundária: por que você está usando with-temp-buffer?
Florian Margaine
Sim, eu não ligo para janelas, mas obrigado por mencionar.
Florian Margaine
Eu uso with-temp-buffer, porque default-directoryé local de buffer. Não quero alterá-lo para o arquivo atual.
abo-abo 17/01