ctags 和 R 正则表达式

ctags and R regex

我正在尝试将 ctags 与 R 一起使用。使用 this 我添加的答案

--langdef=R
--langmap=r:.R.r
--regex-R=/^[ \t]*"?([.A-Za-z][.A-Za-z0-9_]*)"?[ \t]*<-[ \t]function//f,Functions/
--regex-R=/^"?([.A-Za-z][.A-Za-z0-9_]*)"?[ \t]*<-[ \t][^f][^u][^n][^c][^t][^i][^o][^n]//g,GlobalVars/ 
--regex-R=/[ \t]"?([.A-Za-z][.A-Za-z0-9_]*)"?[ \t]*<-[ \t][^f][^u][^n][^c][^t][^i][^o][^n]//v,FunctionVariables

到我的 .ctags 文件。但是,当尝试使用以下 R 文件生成标签时

x <- 1
foo <- function () {
    y <- 2
    return(y)
}

只识别函数foo。我也想为变量生成标签(即上面代码中的 xy)。我应该更改 ctags 文件中的正则表达式吗?提前致谢。

这些模式似乎不正确,因为只有在为变量分配的值与 "function" 具有相同长度但不共享其任何字符时,该变量才会被识别。例如:

x <- aaaaaaaa

以下 ctags 配置应该可以正常工作:

--langdef=R
--langmap=R:.R.r
--regex-R=/^[ \t]*"?([.A-Za-z][.A-Za-z0-9_]*)"?[ \t]*<-[ \t]function[ \t]*\(//f,Functions/
--regex-R=/^"?([.A-Za-z][.A-Za-z0-9_]*)"?[ \t]*<-[ \t][^\(]+$//g,GlobalVars/
--regex-R=/[ \t]"?([.A-Za-z][.A-Za-z0-9_]*)"?[ \t]*<-[ \t][^\(]+$//v,FunctionVariables/

这里的想法是函数 必须 后跟一个括号,而变量声明则不需要。考虑到正则表达式解析器的限制,此括号必须与关键字 "function" 出现在同一行,此配置才能正常工作。

更新Universal Ctags 将包含对 R 的支持,因此请尝试一下并报告错误和缺失的功能。

原始正则表达式的问题是它不捕获短于 8 个字符的变量声明/赋值(因为正则表达式需要 8 个字符,而不是按特定顺序排列的 f-u-n-c-t-i-o-n)。

Vitor 更新的正则表达式的问题在于,它没有捕获包含括号的变量声明/赋值,这种情况在 R 中很常见。

一个被遗忘的问题是,它们都没有捕获带有 <<- 的超赋值对象(仅包含带有 <- 的局部赋值)。

当我检查 Universal Ctags repo, although pcre regex is planned to be supported as also raised in Issue 519 并且配置文件中存在注释掉的 pcre 标志时,不幸的是,在 ctags 中尚不支持 pcre 类型 positive/negative 前瞻或后视表达式。当这种支持开始时,事情会容易得多。

首先,我的解决方案考虑了“<{1,2}-”的超赋值以及赋值右侧可以包括的事实:

  • 不是 f-u-n-c-t-i-o-n 的 8 个字符的序列后跟任何字符或没有字符 (.*)
  • OR 最多 7 个任意字符的序列 (.{1,7})

我建议的正则表达式模式如下:

--langdef=R
--langmap=R:.R.r
--regex-R=/^[ \t]*"?([.A-Za-z][.A-Za-z0-9_]*)"?[ \t]*<-[ \t]function[ \t]*\(//f,Functions/
--regex-R=/^"?([.A-Za-z][.A-Za-z0-9_]*)"?[ \t]*<{1,2}-[ \t]([^f][^u][^n][^c][^t][^i][^o][^n].*|.{1,7}$)//g,GlobalVars/ 
--regex-R=/[ \t]"?([.A-Za-z][.A-Za-z0-9_]*)"?[ \t]*<{1,2}-[ \t]([^f][^u][^n][^c][^t][^i][^o][^n].*|.{1,7}$)//v,FunctionVariables/

而且我的测试表明,它捕获的对象比以前的对象多得多。

编辑: 即使这些也不会捕获声明为函数参数的变量。由于 ctags regex 进行了非贪婪搜索并且非捕获组不起作用,因此结果仍然有限。但我们至少可以捕获函数的第一个参数并将它们定义为附加类型,如 a, Arguments:

--regex-R=/.+function[ ]*\([ \t]*(,*([^,= \(\)]+)[,= ]*)//a,Arguments/