(
感谢您与我们联系。
如果您报告解析输出的问题,请填写
以下模板。 由于您的自定义 CTags 配置可以
影响结果,请始终使用--options=NONE
作为第一个
运行ctags
时的选项。
否则,删除模板并从头开始编写您的问题。
示例可以帮助开发人员更好地理解您的问题。
使用 GitHub Web 界面和 Markdown 符号。
使用邮件结果破坏文本渲染,使
开发商疯了。
)
解析器名称:
用于运行 ctags 的命令行:
$ ctags -R
我在.ctags
或其他任何地方没有任何特殊配置。 这是运行此测试的新 VM。
输入文件内容: https :
您不满意的标签输出:
Universal-ctags
在某些情况下会插入无效的utf-8
字符。
您期望的标签输出:
所有有效utf-8
字符的预期标签输出。
ctags的版本:
$ ctags --version
Universal Ctags 0.0.0(3522685), Copyright (C) 2015 Universal Ctags Team
Universal Ctags is derived from Exuberant Ctags.
Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
Compiled: July 27 1018, 23:16:36
URL: https://ctags.io/
Optional compiled features: +wildcards, +regex, +iconv, +option-directory, +xpath
你如何获得 ctags 二进制文件:
(
ctags 二进制文件构建在ubuntu-16.04
VM 上,除了安装必要的库(例如automate
、 autoreconf
用于编译ctags
和编译vim
必要库外,没有其他任何修改)
)
@lilydjwg向我指出ctags
插入了无效的utf-8
字符,即使用于生成标签的文件在此处具有所有有效的utf-8
字符:
https://github.com/vim/vim/issues/3213#issuecomment -406961075
ctags
的编译版本通常效果很好。
最近发现,原来ctags
有一个错误导致
旧的Execuberant ctags
由sudo apt-get install ctags
在 Ubuntu 上安装
16.04 不插入任何无效的utf-8
字符,但如果我编译
Universal-ctags
来自源代码,并根据此处的说明安装它:
https://github.com/universal-ctags/ctags/blob/master/docs/autotools.rst ,它
将插入无效的utf-8
字符。 证据如下:
仅使用exuberant-ctags
安装sudo apt-get install ctags
:
在这篇文章中, Universal-ctags
从源代码(最新提交)编译,
使用此处的说明编译:
https://github.com/universal-ctags/ctags/blob/master/docs/autotools.rst :
这会在vim中造成很多问题,因为如果无效的utf-8
字符是
传递给vim.eval
, vim.eval
中断,这导致没有标签返回
全部。 目前,只有一种方法可以传输viml
包含的数据
变量到python-name
空间,使用vim.eval
。 所以,任何其他插件
vim 或其他地方也会有类似的问题。 @ludovicchabant对于
示例必须对他的标签文件进行后处理以阻止此类问题:
https://ludovic.chabant.com/devblog/2017/02/25/aaa-gamedev-with-vim/
此外,他必须更改ctrl-py-matcher
才能解决此问题。
https://github.com/ludovicchabant/ctrlp-py-matcher/blob/2f6947480203b734b069e5d9f69ba440db6b4698/autoload/pymatcher.py#L22
我还看到了多个其他文件也有类似的问题,但我
刚刚在这里提供了一个来缩小问题的范围。
我的猜测是这是一个错误,我不希望ctags
会这样做
设计。 这可以纠正吗,因为这曾经在 Exuberant Ctags 中工作正常
Universal-ctags 基于哪个?
参考: https :
对我来说听起来像#1275:新的pattern-length-limit
选项在任意字节位置进行切割,该位置恰好位于字符序列的中间。 参见 #163、#640 和 #1018。
可能应该实施类似https://github.com/universal-ctags/ctags/issues/1275#issuecomment -274489859 之类的东西来解决这个问题。
@alphaCTzo7G参见#1807,这是否为您正确修复了它?
@b4n ,感谢您的快速回复...
在我在这里发布的文件_identifier.py
,使用 #1805 提交, ctags
不再在任意位置插入无效字符/剪切。
在接下来的几天里,我将在我的真实系统上尝试这个 PR,看看它是否适用于我的整个存储库或发出其他错误
由于ctrlp
和ctrlp-py-matcher
是非常流行的插件,如果合并 #1807 那就太好了,这样vim
和其他文本编辑器用户可以使用ctrlp
和ctrlp-py-matcher
而不必担心这个问题。
我发现还有另一个文件引起了问题, vim.eval
,它包含无效的utf-8
字符,由grep -axv '.*' misc.html
(https:/中的misc.html
/github.com/alphaCTzo7G/test)。 我注意到ctags
会将无效的utf-8
字符插入到misc.html
的标签文件中。
ctags
检测文件中的无效字符并用@tonymec在这里建议的内容替换它们是否https :
IIUC,ctags(Exuberant ctags,我的意思是,它只是可用的 ctags 程序之一)与 Vim 分开分发(即使它的作者知道 Bram,即使它们偶尔一起工作以使 Vim 和 ctags 更好地协同工作。
从 ctags 的角度来看,将程序文本视为字节串是合理的:无论是 UTF-8、Latin1、Latin9 还是其他一些 ISO 8859 字符集,空格是 0x20,硬制表符是 0x09,换行符是 0x0A,前面可能是 0x0D,等等; 一个空字节,即 0x00,不应出现在文本文件中。 Ctags 以相同的方式处理每个程序,无论它是用哪种 ASCII 兼容编码编写的,因此它不需要关心哪个是哪个。 只有对于像 EBCDIC 这样一些古怪的字符集,它才需要将文本视为绝对非 ASCII(在 EBCDIC 中,IIRC,AI 是 0xC1-0xC9,JR 是 0xD1-0xD9,SZ 是 0xE2-0xE9,0-9 是 0xF0-0xF9 ,我不记得空格、制表符、换行符、破折号、下划线等的代码是什么;但你会发现从 ASCII 的角度来看,它真的很古怪)。
恕我直言,在 ctag 的情况下,古老的原则适用:垃圾进,垃圾出。
此致,
托尼。
@tonymec .. 有道理.. 我意识到可能还有其他标签生成程序,但universal-ctags
是最受欢迎的,在使用universal-ctags
的人中,我猜大部分是vim
用户。
所以我想知道这两个是否可行,或者您对如何处理具有非法utf-8
字符的文件有任何其他想法?
ctags
有+iconv
这个选项,它允许使用libiconv
。 在命令行中使用iconv
可以删除非法的utf8
字符。 所以我想知道如果我通过--input-enconding=utf-8
和--output-encoding=utf-8
,那么所有非法的 utf-8 字符都会被更改为合法的utf-8
字符。这在https://media.readthedocs.org/pdf/ctags/latest/ctags.pdf 的第 1.3.4 节中有解释:
Two new options have been introduced (--input-encoding=IN and --output-encoding=OUT).
Using the encoding specified with these options ctags converts input from IN to OUT. ctags uses the converted
strings when writing the pattern parts of each tag line. As a result the tags output is encoded in OUT encoding.
In addition OUT is specified at the top the tags file as the value for the TAG_FILE_ENCODING pseudo tag. The
default value of OUT is UTF-8.
NOTE: Converted input is NOT passed to language parsers. The parsers still deal with input as a byte sequence.
With --input-encoding-<LANG>=IN, you can specify a specific input encoding for LANG. It overrides the
global default value given with --input-encoding
utf8
字符。 在这种情况下,要么vim.eval
必须被修复,要么必须有一个vimL
函数可以解析和删除非法的utf-8
字符,然后将其传递给vim.eval
..@alphaCTzo7G我同意@tonymec和他的结论。
不幸的是,识别正确的编码很麻烦——我坚持
此外, ctags在这里处于一个困难的位置:许多(如果不是大多数)消费者不处理编码,并且生成的标签需要在字节级别进行匹配。 例如,grepping 标签模式甚至名称不会为您转换编码,因此标签应该在字节级别匹配文件。 当我们只关心 ASCII 时,这很容易,但我们不再那么幸运了…… UTF-8 没有得到足够早的采用。
这也适用于用占位符替换的想法:消费者可以用这样的替换字符做什么? 它至少必须以特定的方式处理它。
但是,如果您对用 U+FFFD 替换无效的 UTF-8 或剥离它们感到满意,也许您可以简单地对 ctags 的输出进行后处理?
@b4n ,感谢您的评论。 我实际上主要处理utf-8
编码的文件,并为我创建的文件编码了utf-8
。 不幸的是,正如您提到的,我确实使用了有时具有任意编码的库。
我使用vim-gutentags
,它确实提供了后处理功能。 虽然我可以手动对标签文件进行后处理以生成utf-8
字符的所有文件,但当我尝试在vim-gutentags
使用post-processing
功能时,它不起作用. 所以我认为找出一个更强大的解决方案可能会更好..但如果那不存在,我将不得不再次研究它..
要检测文件的编码,您不能使用以下选项之一背后的底层库: https :
例如enca
、 file
、 uchardet
、 enguess
? 这些都是命令行实用程序..但必须有一些库可以在内部使用ctags
可能。 我的猜测是因为编码的数量,正如你所提到的,可能永远不可能完美地预测编码,但是一个涵盖大部分编码的简单解决方案可能总比没有好..
我将尝试--input-encoding (and/or --input-encoding-<LANG>) and --output-encoding options
.. 不确定它是否会一直工作,因为很可能某些文件在同一个存储库中有不同的编码,除非ctags
弄清楚单独正确编码并以所需格式将其吐出。