14

我最近放弃了鼠标驱动的、特定于平台的 GUI 编辑器,完全致力于 vim。到目前为止的体验非常棒,但是在谈到 Javascript 时我被困住了。

广受欢迎的 taglist 实用程序(使用 Exuberant Ctags)非常适合除 Javascript 之外的所有内容。由于语言过于自由的形式和结构,当我打开 taglist 时,它只能获取少数几个函数——只有那些以以下格式定义的函数:

function FUNCNAME (arg1, arg2) {

但没有定义如下变量或函数对象:

var myFunc = function (arg1, arg2) {

所以我google了一下,找到了以下ctags的定义集,我把它放在我的~/.ctags文件中:

--langdef=js
--langmap=js:.js
--regex-js=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\{/\1/,object/
--regex-js=/([A-Za-z0-9._$()]+)[ \t]*[:=][ \t]*function[ \t]*\(/\1/,function/
--regex-js=/function[ \t]+([A-Za-z0-9._$]+)[ \t]*([^])])/\1/,function/
--regex-js=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\[/\1/,array/
--regex-js=/([^= ]+)[ \t]*=[ \t]*[^""]'[^'']*/\1/,string/
--regex-js=/([^= ]+)[ \t]*=[ \t]*[^'']"[^""]*/\1/,string/

之后,从命令行运行 ctags 非常棒。它找到了我需要它找到的每一个函数和对象。

问题是 taglist.vim 插件没有看到这些新结果。当我在 vim 中打开我的 javascript 文件并点击 :TlistToggle 时,我得到了与以前完全相同的少数几个函数。我按 'u' 来更新列表,但没有任何效果。

挖掘 taglist.vim,我发现了这个:

" java language
let s:tlist_def_java_settings = 'java;p:package;c:class;i:interface;' .
                               \ 'f:field;m:method'

" javascript language
let s:tlist_def_javascript_settings = 'javascript;f:function'

...这意味着我们只查看 ctags 实用程序用于 javascript 的一种特定类型的输出。不幸的是,我对 taglist 或 vim 的了解还不够(还),无法发现我可以做出哪些改变来让所有那些美妙的 ctags 命令行结果显示在 vim 中。

帮助表示赞赏!

4

6 回答 6

21

知道了!我研究了 taglist.vim 代码一段时间,这就是我发现的:

taglist.vim 强制 ctags 使用与 vim 相同的文件类型。因此,即使我通过 google 找到的 ~/.ctags 片段将我急需的定义分配给新的“js”语言并将其应用于以 .js 结尾的文件,taglist 仍在强制 ctags 使用“JavaScript”文件类型vim 正在使用 -- 它已经内置在 ctags 中。

解决方案是将 ~/.ctags 文件从我上面发布的内容更改为:

--regex-JavaScript=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*new[ \t]+Object\(/\1/o,object/
--regex-JavaScript=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\{/\1/o,object/
--regex-JavaScript=/([A-Za-z0-9._$()]+)[ \t]*[:=][ \t]*function[ \t]*\(/\1/f,function/
--regex-JavaScript=/function[ \t]+([A-Za-z0-9._$]+)[ \t]*\([^\]\)]*\)/\1/f,function/
--regex-JavaScript=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*new[ \t]+Array\(/\1/a,array/
--regex-JavaScript=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\[/\1/a,array/
--regex-JavaScript=/([^= ]+)[ \t]*=[ \t]*[^""]'[^'']*/\1/s,string/
--regex-JavaScript=/([^= ]+)[ \t]*=[ \t]*[^'']"[^""]*/\1/s,string/

它直接改变了预先存在的 JavaScript 语言定义,而不是在 ctags 中创建新的语言定义。现在,当 taglib 强制 vim 的注册文件类型时,使用新的定义。之前发布的 ~/.ctags 行中还缺少 Al 在他的回答中提到的“亲切”字母,因此这些也包含在我的更新版本中。

从那里,将以下内容放入您的 ~/.vimrc 以激活新类型:

let g:tlist_javascript_settings = 'javascript;s:string;a:array;o:object;f:function'

总而言之,新的正则表达式行并不完美——它们肯定需要一些调整以避免大量误报,并且分离出常量等可能会很好。但现在,至少,我有能力做到这一点:)。

编辑:添加了关于如何在不编辑插件的情况下激活类型的说明,并大大改进了主要的 ctags 函数正则表达式以避免一些误报。

编辑 2:向 ctags 正则表达式添加了更多数组和对象定义。

于 2009-11-24T18:38:28.110 回答
3

我在谷歌搜索中看到了这篇文章,虽然你的发现非常好,但我认为我们可以改进它们。这是对您的解决方案进行一些黑客攻击的结果:

.ctags

--regex-JavaScript=/^var[ \t]+([a-zA-Z0-9_$]+) = \[/\1/a,array/
--regex-JavaScript=/^var[ \t]+([a-zA-Z0-9_$]+) = \{/\1/o,object/
--regex-JavaScript=/^var[ \t]+([a-zA-Z0-9_$]+) = (^{^[)+/\1/r,var/
--regex-JavaScript=/^[ \t]*(this\.)?([A-Za-z0-9_$()]+)[ \t]*[:=][ \t]*function[ \t]*\(\)/\2/u,function/
--regex-JavaScript=/^[ \t]*function ([a-z0-9]+[A-Za-z0-9_]*)/\1/u,function/
--regex-JavaScript=/^[ \t]*([A-Za-z0-9]+)\.prototype\.([a-z0-9]+[A-Za-z0-9_]*)/\1 : \2/u,function/
--regex-JavaScript=/^[ \t]*function ([A-Z]+[A-Za-z0-9_]*)/\1/o,object/

.vimrc

let g:tlist_javascript_settings = 'javascript;r:var;s:string;a:array;o:object;u:function'

这消除了更多误报,并添加了更多功能,作为摆脱一些更成问题的正则表达式的权衡。如果我发现我需要更多,我会继续更新。

编辑:我现在一切都很好;我觉得这个结果是可靠的。唯一的主要缺陷是它不适用于逗号分隔的变量定义。这似乎特别讨厌。也许改天。:)

另请注意,我更改了 .vimrc。这不是因为我是个怪胎;这是因为不知何故 taglist 或 ctags 或其他东西设置了一些默认值,如果你不更改它,那么你会在函数和变量方面得到很多双打,这真的让我发疯(我非常注意细节。 . :P)

编辑:更多调整。它现在接受原型函数声明,并且不做其他一些愚蠢的事情。

于 2010-09-17T18:43:42.103 回答
2

最佳实践解决方案是使用 Mozilla 的DoctorJS(以前称为jsctags),它也是在 Vim 中获取 JavaScript 源代码浏览/标签列表的非常新颖、简洁和简单的方法。

有关更多信息,请参阅我对这个问题的回答

享受。:)

于 2011-05-05T07:21:36.730 回答
1

我没有太多使用 javascript 或 taglist,但是通过查看:help taglist-extend,看起来你的定义(上面列出的)将 javascript 输出重命名为 js,所以你可能需要类似的东西(在你的 vimrc 中):

let tlist_js_settings = 'js;f:function;m:method'

这是假设 ctags 'kind' 是 'f' 代表函数和 'm' 代表方法。查看您的标签文件并查看“种类”列的外观。例如,我的 C 代码标签文件包括以下行:

ADC_CR1_AWDCH_0 .\LibraryModules\CMSIS\Headers\stm32f10x.h  2871;"  d

这是#define一个符号ADC_CR1_AWDCH_0,它在第 2871 行列出的文件中。'd' 是定义名称的 ctags 'kind'。希望这会给你足够的帮助。

顺便说一句,我不确定覆盖是否会正常工作,因此可能值得将您的文件命名为“myfile.mjs”并将您的 langmap 更改为js:.mjs直到它正常工作。然后至少你会知道你的问题是否与文件的错误识别或实际的解析有关。

于 2009-11-24T17:07:36.170 回答
1

嗨,感谢 Tom Frost 的问题和研究,我认为您最终答案的第 4 行正则表达式存在一些问题:

--regex-JavaScript=/function[ \t]+([A-Za-z0-9._$]+)[ \t]*\([^\]\)]*\)/\1/f,function/

对我不起作用,我拉了一下,现在可以了:

--regex-JavaScript=/function[ \t]+([A-Za-z0-9._$]+)[ \t]*\([^\)]*\)/\1/f,function/

PD。此处发布的其他答案的正则表达式至少对我来说根本不起作用:-?

于 2010-11-27T11:00:26.167 回答
1

为了避免来自 ctags 的内置 javascript 支持的重复条目,我在原始帖子中定义了“js”语言,并帮助 taglist 使用 ctags。我还确保从一些不太有用的位(引号、“this.”、“.prototype”)中删除标记名。我不使用对象/数组/字符串/var 正则表达式,但很容易将我的正则表达式与其他建议结合起来。

〜/ .ctags:

--langdef=js
--langmap=js:.js
--regex-js=/["']?(this\.)?([A-Za-z0-9_$]+)["']?((\.prototype)?(\.[A-Za-z0-9_$]+))?[ \t]*[:=][ \t]*function/\2\5/f,function/
--regex-js=/function[ \t]+([A-Za-z0-9_$]+)/\1/f,function/

~/.vimrc:

let g:tlist_javascript_settings = 'js;f:function'
于 2010-12-11T01:13:03.213 回答