在Emacs eshell-command中调用复杂的管道查找

时间:2017-05-10 21:44:59

标签: windows emacs find interactive-shell

我正在尝试做一些看似简单的事情:创建一个Emacs函数来为我创建一个TAGS文件。执行此操作有简单的说明here

(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命令必须更改为:

find %s -type f -iname "*.cpp" -or -iname "*.h"

在命令行上运行良好。我遇到的问题是,eshell似乎根本不喜欢这样。当我执行此功能时,我会继续: File not found - "*.h": Invalid argument

this question的答案表明正确使用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 个答案:

答案 0 :(得分:1)

您正在尝试将posix语法与Windows find命令一起使用。这有两个原因:

  • 当然,你不能指望它支持来自不同操作系统的语法。
  • Windows find的行为类似于grep,而是使用dir

希望它能帮到你。

答案 1 :(得分:1)

在评论中得到了sds和Daniele的大力帮助,我终于弄明白了这个问题。

我正在做的事情有两个问题:

  1. 我正在使用带有ms-dos命令shell的bash解决方案。 DOS"找到"是一个完全不同于Unix发现的命令,所以它很有意义地抱怨它的参数。
  2. 通常的引用问题。我的etags exe在它的路径上有一个空间。我尝试使用shell-quote-argument修复此问题,但是对于MS-DOS shell,所有这一切都是在参数周围放置转义引号。您仍然必须手动转义任何反斜杠,并且DOS shell需要其文件路径中的那些。
  3. 对于那些感兴趣的人,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 shell可以处理的目录。 ~/dirname无效。对于那些拥有更好的emacs-fu的人而言,我可能已经解决了这个问题。