Идите рекурсивно, чтобы найти Makefile и скомпилировать


9

Проблема в M-x compileтом, что если его Makefileнет в текущем каталоге, он завершается ошибкой.

Я хотел бы иметь функцию, которая рекурсивно идет вверх, чтобы найти Makefileи запустить makeиз этого каталога.

Я видел этот вопрос , но он зависит от пути, и мне нужно подумать о беге.


Если вы используете, projectileесть способы компиляции из projectile-project-root. Например, github.com/abo-abo/helm-make
abo-abo

@ abo-abo Я не пробовал снаряд! Кажется, что projectile-compile-projectделает то, что я хочу. Но я бы хотел иметь что-то без этой зависимости, если это возможно.
Флориан Маргейн

спасибо, у меня работает projectile-compile-project
netawater

Ответы:


15

Вы ищете функцию locate-dominating-file. Вот документация по emacs для этой функции:

(locate-dominating-file FILE NAME)

Ищите иерархию каталогов из FILEдиректории, содержащей NAME. Остановитесь на первом родительском каталоге, содержащем файл NAME, и верните каталог. Вернуть, nilесли не найдено. Вместо строки NAMEтакже может быть предикатом, принимающим один аргумент (каталог) и возвращающим ненулевое значение, если этот каталог является тем, который мы ищем.

Используя это, ответ abo-abo может быть сокращен до

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

Ницца! Эта функция делает то же самое, что и мой цикл, но хорошо документировано и обрабатывает крайний случай. Я обязательно добавлю его в свой список рецептов, спасибо.
Або-або

Ницца! vim имеет похожую функцию findfile, я был удивлен, что в emacs ее нет.
Флориан Маргейн

Есть ли что-то похожее на Лисп let? Ты бежишь locate-dominating-fileдважды.
Флориан Маргейн

@FlorianMargaine Да, вы можете использовать let. Я набирал ответ напрямую, не тестируя, и решил, что это вряд ли приведет к неправильным скобкам :)
Прадхан

Хотел бы я больше проголосовать за этот ответ. Спасибо.
Эрик

6

Рекурсивная компиляция без каких-либо зависимостей:

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

Потрясающие! Это именно то, что я хотел.
Флориан Маргейн

Хорошо, просто будьте осторожны с конечным условием цикла. Если вы работаете в Windows, вы можете получить бесконечный цикл.
Або-або

Дополнительный вопрос: почему вы используете with-temp-buffer?
Флориан Маргейн

Да, меня не волнуют окна, но спасибо, что упомянули об этом.
Флориан Маргейн

Я использую with-temp-buffer, потому что default-directoryэто локальный буфер. Я не хочу менять его для текущего файла.
Або-або
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.