Вызов сложной конвейерной находки в 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 в комментариях я наконец смог разобраться в проблеме.

Были две проблемы с тем, что я делал:

  1. Я использовал решение bash с командной оболочкой ms-dos. DOS "find" - это совершенно другая команда, чем Unix find, поэтому вполне логично, что она жаловалась на свои параметры.
  2. Обычное цитирование вопросов. У моего 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, чем я хочу посвятить этой проблеме.

Другие вопросы по тегам