R6 icon indicating copy to clipboard operation
R6 copied to clipboard

Generator object should provide completions for instances of the class

Open wch opened this issue 9 years ago • 10 comments

As discussed in rstudio/shiny#657, it would be helpful if a generator object had a way of providing completions for instances of the class.

@kevinushey if you have any recommendations for the interface, please let me know.

wch avatar Mar 04 '15 22:03 wch

Just to set the stage -- we want to get the set of completions valid for the various binary operators, e.g. $, [, [[, or even ?, ~, @ if their use ever gained some meaning for R6.

We could have a function like R6::.instanceCompletions(generator, operator) which takes a generator and the operator that we want completions for ("$", "[", and so on.)

Does that sound appropriate? Are there other contexts where we might want R6 completions for an instance object, or other 'special symbols' in R6 we might want to provide completions for (e.g. self)?

It would be excellent if the returned completions could also give the type of object returned -- in RStudio, we have icons that denote the 'type' of completion and if we were to query completions in this manner it would be good to get those types as well. We have this in RStudio: https://github.com/rstudio/rstudio/blob/master/src/cpp/session/modules/SessionRCompletions.R#L38-L69, but we could also just simply convert whatever type R6 returns to that set of types.

kevinushey avatar Mar 05 '15 00:03 kevinushey

@kevinushey A tangential issue for completions: A generator object has a method called $new(...), which in turn invokes $public_methods$initialize(...).

For example, to get the set of useful completions for shiny:::ShinySession$new(), you'd really want to get the completions for shiny:::ShinySession$public_methods$initialize()

wch avatar Jun 24 '15 20:06 wch

I was just playing around with .DollarNames, and it seems to work with an R6 class in R at the console, but not in RStudio. For example:

library(R6)
MyClass <- R6Class("MyClass",
  public = list(x = 1, y = 2, z = 3)
)

.DollarNames.MyClass <- function(x, pattern = "") {
  all_names <- ls(x, all.names, pattern = pattern)
  
  # Filter out "z"
  setdiff(all_names, "z")
}

m <- MyClass$new()
# Press tab after typing the following:
m$
# In R at the terminal, it prints "m$clone  m$x      m$y"
# In RStudio, it shows clone, x, y, z, and .__enclos_env__

@kevinushey Do you know why it's not working in RStudio?

wch avatar May 04 '17 00:05 wch

I think you can close this issue in favour of #122

hadley avatar Jul 17 '17 17:07 hadley

@hadley This is slightly different, I think. The issue is when you want to have completions for an object that's not actually instantiated yet. For example, in Shiny, the session object is only instantiated when you run an app, but it would still be useful to have completions when working on the code (and the app isn't running).

wch avatar Jul 17 '17 18:07 wch

How would you declare that the yet-to-be-created session object is of class Session?

hadley avatar Jul 17 '17 18:07 hadley

Shiny's a bit of a special case -- RStudio would just know that a session inside a Shiny app's server function would be a ShinySession object.

But in the general case, it would be nice to have completions for this when you're editing code but not running it:

A <- mypkg::MyClass$new()
A$ <tab>

wch avatar Jul 17 '17 18:07 wch

@wch I already get completions for that case

hadley avatar Jul 17 '17 20:07 hadley

For this to work, RStudio would need someway to recognise that a <- foo$new() implies that a has class foo$classname.

@kevinushey is there any existing support for this sort of inference? (it would also be straightforward to implement for S4 slot. Implementing for S3 would require some sort of annotation.)

hadley avatar Jul 17 '17 20:07 hadley

Unfortunately no, this is not supported yet.

kevinushey avatar Jul 17 '17 20:07 kevinushey