开发者

Exuberant Ctags with R

开发者 https://www.devze.com 2023-02-06 10:29 出处:网络
Is there any documented use of ctags with R? Would this be useful? Would it be difficult to implement? Specifically, I\'ve just star开发者_运维问答ted using Vim.

Is there any documented use of ctags with R? Would this be useful? Would it be difficult to implement?

Specifically, I've just star开发者_运维问答ted using Vim. It would be cool to be able to write an R function in one file, use the function in another file (e.g., an Rnw file, test file, or some other script), and be able to use Ctrl+] to navigate to the function source.

Update: I've since stumbled on the rtags function. It is suggested below that it works with vim.


This is a modification of Henrico's answer, and may be implemented by copying and pasting the following code into one's ~/.ctags files. Henrico's code did not work for indented functions, but the following code does.

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

This allows variables to be recognized with ctags as well as functions. If you're using the taglist vim addon, then, it allows you to distinguish between global variables and other variables. Also, if you're using taglist, then you will need to paste the following in your vimrc.

let tlist_r_settings = 'R;f:Functions;g:GlobalVariables;v:FunctionVariables'


This is the content of my .ctags file in my home directory. I found it somewhere on the internet. Using this you can generate a tags-file for vim.

 --langdef=Splus
 --langmap=Splus:.s.S.R.r.q
 --regex-Splus=/^[ \t]+"?([.A-Za-z][.A-Za-z0-9_]*)"?[\t]*<-[\t]*function/\1/
 --regex-Splus=/^"?([.A-Za-z][.A-Za-z0-9_]*)"?[ \t]*<-/\1/


Probably you can read how to add support for a new language to ctags.


rtags() is the best to way to generate tags for R codes from what I see so far, since it will take all different ways of assignments in consideration, such as:

ok = c("<-", "=", "<<-", "assign",
       "setGeneric", "setGroupGeneric", "setMethod",
       "setClass", "setClassUnion")

An example of using rtags():

path <- "~/path/to/project"
rtags(path=path,
      pattern = "[.]*\\.[RrSs]$",
      keep.re = ".", # the value ('/R/') in the help page will only run through the codes in R/ folder.
      verbose = TRUE,
      ofile = file.path(path, 'TAGS'),
      append = FALSE,
      recursive = TRUE)


As mentioned by other rtags() + etags2ctags() can generate a tagsfile for vim (see :h tags-and-searches). You can create a custom command for vim so that it run rtags() in R using Rscript. To do so put this in your .vimrc:

:command! Rtags :!Rscript -e 'rtags(path="./", recursive=TRUE, ofile="RTAGS")' -e 'etags2ctags("RTAGS", "rtags")' -e 'unlink("RTAGS")'
set tags+=rtags

Now when you do :Rtags vim will run the external process Rscript (it has to be in the PATH of course) and evaluate rtags(path="./", recursive=TRUE, ofile="RTAGS");etags2ctags("RTAGS", "rtags");unlink("RTAGS"). rtags() will generate an RTAGS file in Emacs tags format then etags2ctags() will transform that into an rtags file which vim can read. unlink() deletes the RTAGS file since it's not needed for vim.

The set tags+=rtags makes vim to search for an rtags file in addition to the usual tags file (See :h tags-and-searches)


Universal-ctags has an R parser.

$ cat input.r
add <- function (x, y) {
    3 -> z
    return(x + y + z)
}
add (3, 4)
$ ./ctags --quiet --options=NONE -o - --kinds-R='*' --fields=+S input.r
add input.r /^add <- function (x, y) {$/;"  f   signature:(x, y)
x   input.r /^add <- function (x, y) {$/;"  z   function:add
y   input.r /^add <- function (x, y) {$/;"  z   function:add
z   input.r /^    3 -> z$/;"    v   function:add

In addition, the ctags implementation supports R6Class and S4Class.


Actually, I think rtags() works in vim.

I use the nvim-r plugin (available at https://www.vim.org/scripts/script.php?script_id=2628), and have the following in my ~/.vimrc file:

:command! Rtags :!Rscript -e 'rtags(path="./", recursive=TRUE, ofile="TAGS")'

With this setup, using :Rtags in vim rebuilds the tags, and then e.g. g] when the mouse is over a word finds the definitions for that word.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号