ctags-lang-r(7)
π NAME π
ctags-lang-r β Random notes about tagging R source code with Universal Ctags π
Okay so bestie, welcome to ctags-lang-r(7) from the Universal Ctags fam. This is literally the scrapbook page where we keep all the random lore about how the R parser does its thing. No cap, it's giving niche but iconic β¨
β¨ SYNOPSIS β¨
Three little ways to get ctags looking at your R files, pick your fighter π
ctags ... --languages=+R ...
ctags ... --language-force=R ...
ctags ... --map-R=+.r ...
π¦ DESCRIPTION π¦
This man page gathers random notes about tagging R source code with Universal Ctags. That's the whole vibe β it's a notes dump, not a novel, and we love her for it π«Ά
π KINDS π
Here's the tea, bestie. If a variable gets a value returned from a well-known constructor and the variable appears for the first time in the current input file, the R parser makes a tag for that variable and attaches a kind associated with the constructor to the tag β and it does this regardless of whether the variable appears in the top-level context or inside a function. Obsessed, honestly πΈ
Well-known constructor and kind mapping:
function()β kindfunctionc()β kindvectorlist()β kindlistdata.frame()β kinddataframe
But if a variable doesn't get a value returned from one of the well-known constructors? Then the R parser attaches the globalVar or functionVar kind to the tag for the variable, depending on the context. It's giving β¨context-dependentβ¨ and honestly? Slay.
Here's an example demonstrating the usage of the kinds:
"input.r"
G <- 1
v <- c(1, 2)
l <- list(3, 4)
d <- data.frame(n = v)
f <- function(a) {
g <- function (b) a + b
w <- c(1, 2)
m <- list (3, 4)
e <- data.frame(n = w)
L <- 2
}
"output.tags" with --options=NONE --sort=no --fields=+KZ -o - input.r
G input.r /^G <- 1$/;" globalVar
v input.r /^v <- c(1, 2)$/;" vector
l input.r /^l <- list(3, 4)$/;" list
d input.r /^d <- data.frame(n = v)$/;" dataframe
n input.r /^d <- data.frame(n = v)$/;" nameattr scope:dataframe:d
f input.r /^f <- function(a) {$/;" function
g input.r /^ g <- function (b) a + b$/;" function scope:function:f
w input.r /^ w <- c(1, 2)$/;" vector scope:function:f
m input.r /^ m <- list (3, 4)$/;" list scope:function:f
e input.r /^ e <- data.frame(n = w)$/;" dataframe scope:function:f
n input.r /^ e <- data.frame(n = w)$/;" nameattr scope:dataframe:f.e
L input.r /^ L <- 2$/;" functionVar scope:function:f
Look at those scopes doing their little nested thing, scope:function:f and scope:dataframe:f.e β the way that the R parser keeps track of which function a variable lives inside is genuinely main character energy ππ₯
π SEE ALSO π
That's the whole page, bestie. Go tag some R code and feel iconic doing it. This was ctags-lang-r(7), from Universal Ctags, version 6.2.1 β mwah, bye, take care of yourself π
π¦π
π¦ where this page comes from
- ubuntu resolute: universal-ctags 6.2.1-1 Β· GPL-2.0-or-later
- ubuntu stonking: universal-ctags 6.2.1-1 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms