r-lib / R6

Encapsulated object-oriented programming for R
https://R6.r-lib.org
Other
407 stars 56 forks source link

Add tab completion to R6 objects #55

Closed thomasp85 closed 9 years ago

thomasp85 commented 9 years ago

This PR adds automatic tab completion of R6 derived objects as a convenience for users and developers. Not super important but definitely a nice-to-have :-)

wch commented 9 years ago

Thanks, this will be useful. Unfortunately, with these modifications, R6 doesn't pass R CMD check.

I think to fix it:

wch commented 9 years ago

@kevinushey do you have thoughts about replacing the utils:::findMatches() function with something else, perhaps something that RStudio is using?

thomasp85 commented 9 years ago

Sorry for the half-baked PR regarding the imports - I'll fix that. Regarding the note I think there is a strong case for it as it also how it is implemented in utils:

> utils:::.DollarNames.list
function (x, pattern = "") 
{
    findMatches(pattern, names(x))
}
<bytecode: 0x1105207c0>
<environment: namespace:utils>
wch commented 9 years ago

I don't think that the CRAN maintainers will be convinced that, just because a function in utils calls an internal function, that a function from another package should be allowed to call that function. They're generally pretty strict about those things.

thomasp85 commented 9 years ago

You're probably more knowledgable on the sentiment of the CRAN maintainers than me, so I'll take your word on it.

kevinushey commented 9 years ago

In RStudio, all we use for R6 classes and objects (as they are just environments under the hood) is:

completions <- ls(object, all.names = TRUE)

Then, for (fuzzy) matching, we use:

.rs.startsWith(tolower(completions), tolower(token))

where .rs.startsWith is implemented as:

.rs.startsWith <- function (strings, string) 
{
    if (!length(string)) 
        string <- ""
    n <- nchar(string)
    (nchar(strings) >= n) & (substring(strings, 1, n) == string)
}

It seems like it would be easy enough to adapt this to the .DollarNames interface, although you might need to do some voodoo to construct the right regular expression.

thomasp85 commented 9 years ago

Looking at the internals of findMatches, as well as findFuzzyMatches and findExactMatches which drives it under the hood, there is nothing preventing a copy-paste of the code. This sets a sad precedence for code reuse though... I'll try to hear why it is not exported in the first place and get back, before we have to reinvent the wheel in every package that requires a new tab completion scheme...

wch commented 9 years ago

There is the issue of licensing... R6 is MIT, while R itself is GPL 2 or 3. I don't think it's possible to simply cut and paste the code while respecting the R license.

kevinushey commented 9 years ago

The internals of findExactMatches is literally just a call to grep so just use that.

thomasp85 commented 9 years ago

@kevinushey Strange - I remember trying to use grep on refClasses before I knew about findMatches, and it didn't play well with RStudio - half-finished methods would get erased when additional characters were typed... Now it seems fine though..?

I'll revert to using grep and save the trouble of asking Core

wch commented 9 years ago

This no longer is necessary, as tab completion appears to just work now. See https://github.com/wch/R6/issues/43#issuecomment-114224019