Exuberant Ctags不会在Windows上正确排除文件

时间:2017-01-31 21:34:43

标签: windows ctags exuberant-ctags

执行 Ctags 时如此

ctags -V -R --exclude=*.js

没有正确排除*.js文件,正如您在日志中看到的那样

Reading initial options from command line
  Option: --exclude=*.js
adding exclude pattern: *.js
Reading command line arguments
OPENING app.js as JavaScript language file
sorting tag file

以下是 Ctags 版本:

Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
  Compiled: Jul  9 2009, 17:05:35
  Addresses: <dhiebert@users.sourceforge.net>, http://ctags.sourceforge.net
  Optional compiled features: +win32, +regex, +internal-sort

我试过用双引号和单引号来围绕这个模式,它仍然无法正常工作。

如何在Windows上通过 Ctags 解析目录树中的文件时排除*.js个文件?

1 个答案:

答案 0 :(得分:3)

Exuberants Ctags Manual描述了选项--exclude

  

...如果C编译器的运行时库提供了适当的支持,那么pattern可能包含Unix(...)中常见的shell通配符(不是正则表达式)。您可以通过检查--version选项的输出来确定您的平台上是否有shell通配符,其中包括&#34; +通配符&#34;在已编译的功能列表中;否则,使用简单的文本比较将模式与文件名匹配。

接下来看看ctags.exectags.exe --version上的最后一行输出:

  

可选的编译功能:+ win32,+ regex,+ internal-sort

没有+wildcards。这意味着根据手册,Windows上使用的*.js不支持ctags.exe之类的通配符模式。

在提供多种解决方案之前,让我们一起开始使用-R -V-V -R启动选项列表。

Ctags 输出ctags -V -R首先完成内部初始化并列出

  • 安装了哪些解析器,
  • 哪些文件被解释为头文件,
  • 设置了哪种语言映射,
  • 使用默认排除模式和
  • 搜索哪些目录和文件以加载默认选项。

但是在使用-R -V启动选项列表时,不会输出内部初始化。

因此,当对内部初始化不感兴趣时​​,请在命令行中指定-V不作为第一个选项。

要了解所使用的命令及其在下面的批处理代码中的工作方式,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • del /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • set /?
  • setlocal /?

另请阅读Microsoft文章Using command redirection operators,了解>>2>nul以及2^>nul的说明,其中重定向运算符>使用插入字符进行转义{<1}}在解析 FOR 命令行时被解释为文字字符,但在执行 DIR 命令行时被解释为重定向运算符 FOR


解决方案1:完全排除语言JavaScript

排除* .js文件的一个解决方案是使用命令行完全排除语言JavaScript:

^


解决方案2:在命令行上指定要排除的每个* .js文件的名称

另一个解决方案是使用批处理文件,该文件将当前目录树中找到的每个* .js文件的名称与选项ctags.exe -R -V --languages=-JavaScript 一起添加到命令行:

--exclude

仅指定文件扩展名没有(相对)路径的文件名就足够了,因为在创建标记文件时应忽略所有* .js文件,而与* .js文件所在的目录无关。

编写代码是为了避免命令行重复,以保持命令行尽可能短。

命令 FOR 忽略具有隐藏文件属性集的* .js文件以及隐藏属性集的目录。但 Ctags 不会忽略隐藏属性集的文件和文件夹。使用命令 DIR 的以下代码可用于在隐藏文件夹中为隐藏的* .js文件和* .js文件添加排除选项。

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "ExcludeOptions="

for /R %%I in (*.js) do (
    if not defined JS_%%~nxI (
        set "JS_%%~nxI=1"
        set "ExcludeOptions=!ExcludeOptions! "--exclude=%%~nxI""
    )
)

ctags.exe -R -V%ExcludeOptions%
endlocal

这种解决方案的一个小缺点:
不排除文件名中带有感叹号的* .js文件,因为在展开@echo off setlocal EnableExtensions EnableDelayedExpansion set "ExcludeOptions=" for /F "delims=" %%I in ('dir /A-D /B /S *.js 2^>nul') do ( if not defined JS_%%~nxI ( set "JS_%%~nxI=1" set "ExcludeOptions=!ExcludeOptions! "--exclude=%%~nxI"" ) ) ctags.exe -R -V%ExcludeOptions% endlocal 后,文件名中删除了一个感叹号,两个惊叹号之间的字符串被完全删除或替换为匹配的值因启用延迟扩展而导致环境变量。


解决方案3:使用临时创建的列表文件,其中包含要排除的所有* .js文件的名称

在许多* .js文件中,最好将文件名写入临时列表文件, Ctags 从中读取要排除的文件的名称。

%%~nxI

此解决方案不需要延迟扩展,因此也适用于文件名中包含感叹号的* .js文件。

再次几乎与上面的代码相同,不忽略隐藏文件属性设置或隐藏文件夹中的* .js文件:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ExcludeListFile=%TEMP%\ExcludeList.tmp"
del "%ExcludeListFile%" 2>nul

for /R %%I in (*.js) do (
    if not defined JS_%%~nxI (
        set "JS_%%~nxI=1"
        echo %%~nxI>>"%ExcludeListFile%"
    )
)

set "ExcludeOption="
if exist "%ExcludeListFile%" set "ExcludeOption= "--exclude=@%ExcludeListFile%""

ctags.exe -R -V%ExcludeOption%

del "%ExcludeListFile%" 2>nul
endlocal


解决方案4:使用临时创建的列表文件以及要解析的所有文件

在命令行上指定要使用通配符模式解析的文件应该足够了,因为这是为Windows编译的 Ctags 支持的。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ExcludeListFile=%TEMP%\ExcludeList.tmp"
del "%ExcludeListFile%" 2>nul

for /F "delims=" %%I in ('dir /A-D /B /S *.js 2^>nul') do (
    if not defined JS_%%~nxI (
        set "JS_%%~nxI=1"
        echo %%~nxI>>"%ExcludeListFile%"
    )
)

set "ExcludeOption="
if exist "%ExcludeListFile%" set "ExcludeOption= "--exclude=@%ExcludeListFile%""

ctags.exe -R -V%ExcludeOption%

del "%ExcludeListFile%" 2>nul
endlocal

此命令行应导致解析当前目录的整个目录树中的所有* .htm和* .html文件。 * .html也与此通配符模式匹配,因为短8.3名称用于* .html文件,文件扩展名为HTM。默认情况下,在搜索与通配符模式匹配的文件时使用的Windows内核函数会始终在长文件名和短文件名上应用模式,以确定模式是否与文件名匹配。

可以在命令行中指定多个文件扩展名,而不仅仅是C / C ++中的一个文件扩展名:

ctags.exe -R -V *.htm

但问题是 Ctags 版本5.8不会搜索与此通配符模式匹配的文件的递归,尽管指定了选项ctags.exe -R -V *.c *.cpp *.h 。看起来编译器添加的启动代码已经用于创建-R搜索已经匹配通配符模式的文件,因此 Ctags ctags.exe函数获取带参数的参数列表{ {1}}已被多个参数替换,每个参数包含与当前文件夹中的通配符模式匹配的文件名。

在Unix / Linux上,像main这样没有用引号括起来的通配符模式会导致用当前目录中的所有文件名替换这两个模式,这两个模式由shell匹配(sh,bash,ksh ,. ..)在调用 Ctags 可执行文件之前。

换句话说,指定要在命令行上解析的文件类型不起作用递归,因此这里没有解决方案,因为*.htm显然需要递归解析文件。

但正在创建一个临时列表文件,其文件名带有文件扩展名和要解析的所有文件的完整路径,并在命令行中指定此列表文件的文件名。

首先忽略因使用*.htm *.html而隐藏属性集的文件和目录:

-R

其次,由于使用for /R

,还包括隐藏目录中的隐藏文件和文件
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "IncludeListFile=%TEMP%\IncludeList.tmp"
del "%IncludeListFile%" 2>nul

for /R %%I in (*.htm) do echo %%I>>"%IncludeListFile%"

if exist "%IncludeListFile%" (
    ctags.exe -L "%IncludeListFile%" -V
    del "%IncludeListFile%" 2>nul
)
endlocal

在两个批处理代码中,单个通配符模式dir /A-D可以替换为空格分隔的通配符模式列表,其中@echo off setlocal EnableExtensions DisableDelayedExpansion set "IncludeListFile=%TEMP%\IncludeList.tmp" del "%IncludeListFile%" 2>nul for /F "delims=" %%I in ('dir /A-D /B /ON /S *.htm 2^>nul') do echo %%I>>"%IncludeListFile%" if exist "%IncludeListFile%" ( ctags.exe -L "%IncludeListFile%" -V del "%IncludeListFile%" 2>nul ) endlocal *.htm类似?或更复杂的模式

DIR 选项*导致按名称 DIR 按名称对每个文件夹的文件名进行排序,这在NTFS驱动器上不是必需的新技术文件系统返回始终按名称排序的文件名列表,以调用Windows内核函数,但FAT(文件分配表)驱动器(FAT16,FAT32,exFAT)则不会。这在这里并不重要,但是当按名称排序时,查看已处理的文件比在当前驱动器的文件系统上更容易。

此解决方案包含一个临时列表文件,其中包含要解析的文件的文件名,是文本编辑器和IDE使用的方法,内置支持 Ctags