S-plus / R lexer: add functions

Issue #412 resolved
Anonymous created an issue

It would be helpful if the S-plus/R lexer knew about built-in functions and highlighted them appropriately.

The code below may be useful: it will list the functions and other objects from the package 'base'. Other default packages like stats and utils can also examined with a change to the first line. {{{

Using search() in a new R session says that these packages are

loaded by default:

"package:stats" "package:graphics"

"package:grDevices" "package:utils" "package:datasets"

"package:methods" "package:base"

Get a list of things contained in a particular package

funlist <- objects(package:base)

Remove things that don't start with a letter

idx <- grep('^[a-zA-Z][a-zA-Z0-9._]*', funlist) funlist <- funlist[idx]

Remove things that contain arrow <-

idx <- grep('<-', funlist) funlist <- funlist[-idx]

Make a data frame to keep track of status

objectlist <- data.frame(name=funlist, primitive=FALSE, func=FALSE, object=FALSE, constant=FALSE, stringsAsFactors=F)

Check the type of each object

for (i in 1:nrow(objectlist)) { fname <- objectlist$name[i] if (exists(fname)) { obj <- get(fname) if (is.primitive(obj)) { objectlist$primitive[i] <- TRUE } if (is.function(obj)) { objectlist$func[i] <- TRUE } if (is.object(obj)) { objectlist$object[i] <- TRUE }

    # I think these are generally constants
    if (is.vector(obj)) {
        objectlist$constant[i] <- TRUE
    }


}

}

Print functions that are primitives

objectlist$name[objectlist$primitive]

Print functions that are not primitives

objectlist$name[objectlist$func & !objectlist$primitive]

Print "constants" - they're not really constants, but this

includes pi, T, F, letters

objectlist$name[objectlist$constant]

Print objects

objectlist$name[objectlist$object]

}}}

Reported by guest

Comments (7)

  1. ananelson

    Arghhhh! Attaching files deleted my comments. Well, serves me right for editing in the browser window. :-)

    I have implemented this in the style of _luabuiltins.py, using rpy2 to talk to R and get the function names using a modified version of the R script in the initial ticket.

    This is a proof of concept, I have only implemented primitive functions from package:base so far. I wanted to post this here to get feedback and so other people can test if they wish. I'll keep working on this and post a more complete patch soon.

    This adds 2 files, _rbuiltins.py which calls _rbuiltins.R via rpy2. I assume Python will just ignore a .R file sitting in pygments/lexers? It doesn't seem to cause problems for me. I have kept a separate .R file since it's easier for development/debugging than having a large string of R code in the .py file. It's nicer for syntax highlighting and CLOC and that sort of thing and the .R file can be run directly from R. If this will cause major hassle then I can just (when it's finished) move the contents of the .R file into a string in _rbuiltins.py.

  2. ananelson

    In order for this to work as intended, the SLexer will need to be tweaked to recognize a function call, e.g. data.frame(...). Because, as it's written now, there's no distinction between:

    data.frame <- c(1,2,3) # Creating a variable called data.frame

    and

    data.frame(...) # Calling a function called data.frame

    So, if people happen to name a variable with one of the built-in function names (very easy to do), this will be highlighted incorrectly.

  3. Ista Zahn

    I would like to see all function names highlighted rather than just the built in functions in the base or stats packages. And actually this is easier to do: here is the regular expression I use to highlight all function names:

    [a-zA-Z][0-9a-zA-Z._]+\s*(?=()

    Any chance this will be picked up and added to the SLexer in math.py?

  4. Log in to comment