简体   繁体   中英

Custom autocomplete functions in R possible?

I am looking to create a custom function in R that will allow the user to call the function and then it will produce an auto complete pipeline ready for them to edit, this way they can jump into quickly customizing the standard pipeline instead of copy pasting from an old script or retyping. How can I go about setting up this sort of autocomplete:

#pseudo code what I type---
seq.Date(1,2,by = "days") %>%
  pblapply(function(x){
    read.fst(list.files(as.character(x), as.data.table = T) %>%
               group_by(x) %>%
               count()
  }) %>% rbindlist()

#how can I write a function so that when I call that function, it ouputs an autocomplete
#of the above so that I can go ahead and start just customizing the code? Something like this
my_autocomplete_function = function(x) {
  print(
    "
    seq.Date(as.Date(Sys.Date()),as.Date(Sys.Date()+1),by = 'days') %>%
      pbapply::pblapply(function(x){
        fst::read.fst(list.files(as.character(x), as.data.table = T)) %>%
          #begin filtering and grouping by below custom
          group_by()


      }) %>% rbindlist()  
")
}

#I can just print the function and copy paste the text from the output in my console to my script
my_autocomplete_function()
#but I rather it just autocomplete and appear in the script if possible?

Putting text into the command line will probably be a function of the interface you are using to run R - is it plain R, Rstudio, etc?

One possibility might be to use the clipr package and put the code into the clipboard, then prompt the user to hit their "paste" button to get it on the command line. For example this function which creates a little code string:

> writecode = function(x){
    code = paste0("print(",x,")")
    clipr::write_clip(code)
    message("Code ready to paste")}

Use it like this:

> writecode("foo")
Code ready to paste

Then when I hit Ctrl-V to paste, I see this:

> print(foo)

I can then edit that line. Any string will do:

> writecode("bar")
Code ready to paste
[ctrl-V]
> print(bar)

Its one extra key for your user to press, but having a chunk of code appear on the command line with no prompting might be quite surprising for a user.

I spend my day reading the source code for utils auto completion. The linebuffer only contains the code for... one line, so that can't do fully what your looking for here, but it is quite customizable. Maybe the rstudio source code for autocompletion has more answers. Here is an example to write and activate your own custom auto completer. It is not well suited for packages as any new pacakge could overwrite the settings.

Below a

#load this function into custom.completer setting to activate
rc.options("custom.completer" = function(x) {

  #perhaps debug it, it will kill your rsession sometimes
  #browser()

  ###default completion###

  ##activating custom deactivates anything else
  #however you can run utils auto completer also like this
  #rstudio auto completation is not entirely the same as utils
  f = rc.getOption("custom.completer")
  rc.options("custom.completer" = NULL)
  #function running  base auto complete.
  #It will dump suggestion into mutable .CompletionEnv$comps
  utils:::.completeToken() #inspect this function to learn more about completion
  rc.options("custom.completer" = f)

  ###your custom part###

  ##pull this environment holding all input/output needed
  .CompletionEnv = utils:::.CompletionEnv

  #perhaps read the 'token'. Also 'linebuffer', 'start' & 'end' are also useful
  token = .CompletionEnv$token

  #generate a new completion or multiple...
  your_comps = paste0(token,c("$with_tomato_sauce","$with_apple_sauce"))

  #append your suggestions to the vanilla suggestions/completions
  .CompletionEnv$comps = c(your_comps,.CompletionEnv$comps)

  print(.CompletionEnv$comps)

  #no return used
  NULL
})
xxx<tab>

例子

NB. currently rstudio IDE will backtick quote any suggestion which is not generated by them. I want to raise an issue on that someday.

Bonus info: A.DollarNames.mys3class-method can be very useful and works with both rstudio and utils out of the box eg

#' @export
.DollarNames.mys3class = function(x, pattern = "") {
  #x is the .CompletionEnv
  c("apple","tomato")
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM