Вызов сложной конвейерной находки в Emacs eshell-command
Я пытаюсь сделать что-то простое: создать функцию Emacs для создания файла TAGS для меня. Есть простые инструкции для этого здесь
(defun create-tags (dir-name)
"Create tags file."
(interactive "DDirectory: ")
(eshell-command
(format "find %s -type f -name \"*.[ch]\" | etags -" dir-name)))
Проблема в том, что мне нужны файлы "cpp" вместо "c". Это означает, что моя команда поиска должна измениться на это:
find %s -type f -iname "*.cpp" -or -iname "*.h"
Это прекрасно работает в командной строке. У меня проблема в том, что eshell, похоже, совсем не нравится. Когда я выполняю эту функцию, я продолжаю получать:File not found - "*.h": Invalid argument
,
Ответ на этот вопрос предполагает, что правильное использование shell-quote-argument
может решить подобные проблемы, но я не смог найти решение, которое работает. Например, это приводит к той же ошибке:
(format "find %s -type f -iname %s -or -iname %s | etags -"
dir-name
(shell-quote-argument "*.cpp")
(shell-quote-argument "*.h"))
2 ответа
Вы пытаетесь использовать синтаксис posix с Windows find
команда. Это неправильно по двум причинам:
- Конечно, вы не можете надеяться, что он поддерживает синтаксис из другой ОС.
- Windows
find
действует какgrep
использоватьdir
вместо.
Надеюсь, это поможет вам.
С большой помощью от sds и Daniele в комментариях я наконец смог разобраться в проблеме.
Были две проблемы с тем, что я делал:
- Я использовал решение bash с командной оболочкой ms-dos. DOS "find" - это совершенно другая команда, чем Unix find, поэтому вполне логично, что она жаловалась на свои параметры.
- Обычное цитирование вопросов. У моего etags exe было место на пути. Я попытался исправить это с помощью аргумента shell-quote-аргумента, но в оболочке MS-DOS все, что нужно сделать, это поместить в аргумент экранированные кавычки. Вам по-прежнему необходимо вручную избегать любых обратных слешей, а оболочке DOS требуются те пути к файлам.
Для интересующихся рабочая команда под Windows:
(defun create-tags (dir-name)
"Create tags file."
(interactive "DDirectory: ")
(shell-command
(format "cd %s & dir /b /s *.h *.cpp | %s -"
dir-name
(shell-quote-argument "C:\\Program Files\\Emacs\\emacs-25.0\\bin\\etags.exe"))))
Единственная странность заключается в том, что когда Emacs запрашивает у вас каталог, вы должны обязательно предоставить ему тот, который может обработать оболочка DOS. ~/dirname
не будет работать. Вероятно, есть решение для этого, для кого-то с лучшим emacs-fu, чем я хочу посвятить этой проблеме.