Skip to content

Instantly share code, notes, and snippets.

@Torvaney
Last active May 30, 2018 18:30
Show Gist options
  • Save Torvaney/ae6a9afdc77c598b1857a0808a46cfcd to your computer and use it in GitHub Desktop.
Save Torvaney/ae6a9afdc77c598b1857a0808a46cfcd to your computer and use it in GitHub Desktop.
Adding special "commands" to an R session.

I recently tried hacking some custom "commands" into the R REPL. I thought the method was fun and interesting enough to be worth sharing.

Background

In other language REPLs/interactive prompts, there are often a couple of special commands. Some of the more common ones are exit (to exit the session) and clear (to clear the buffer).

I often find myself instinctively attempting to use these in R. Of course, they do not exist in R. To terminate the R session, one can use quit(...) or q(...), but this requires typing brackets, as well as a "no" if you want to avoid that annoying "save workspace?" prompt.

exit

Rather than put up with a couple of extra key presses, I decided to do something about it. I came up with a workaround (ab)using the P in REPL (Read-Eval-Print-Loop) and R's S3 methods:

exit <- structure(list(), class = "exit_command")
print.exit_command <- function(...) {
  cat(glue::glue("Bye! {emo::ji('wave')}\n\n"))
  q("no")
}

This creates a new object named exit, that terminates the current R session when print(exit) is called:

clear

As I mentioned at the beginning, I don't just want to exit the session like this, I also want to be able to clear the buffer at will. To do this, we can do something similar to our exit "command":

clear <- structure(list(), class = "clear_command")
print.clear_command <- function(...) {
  # Clear console in both R and RStudio:
  # From: https://stackoverflow.com/questions/14260340/function-to-clear-the-console-in-r-and-rstudio
  purrr::walk(c("\f", "\033[2J", "\033[0;0H"), cat)
}

Here, I've placed it in my .Rprofile, so it's loaded automatically when the R session is started:

It's starting to get a little tedious typing this out each time to add a command. I think we can generalise it a little bit:

create_command <- function(name, fn) {
  class_name <- paste0("command_", name)
  obj <- structure(list(), class = class_name)
  
  assign(name, obj, env = parent.env(environment())) 
  assign(paste0("print.", class_name), fn, env = parent.env(environment())) 
}

create_command("exit", function(...) q("no"))
create_command("clear", function(...) purrr::walk(c("\f", "\033[2J", "\033[0;0H"), cat))

Now we can easily add special R commands to our heart's content!

Of course, whether we should be adding all these commands is perhaps a different question...


NB for a saner way to get rid of the annoying "Save workspace data?" prompt R gives, I added the following to my .bash_profile:

alias R="$(/usr/bin/which R) --no-save --no-restore-data"
alias r="$(/usr/bin/which r) --no-save --no-restore-data"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment