Make A Shortcut for Anything in RStudio with shrtcts

R Markdown Source

Follow @gadenbuie  Star  Fork

RStudio’s many keyboard shortcuts take some time to learn but can save tons of typing in the long run. RStudio addins extend RStudio’s interface with small apps and actions, and you can assign customized keyboard shortcuts to trigger any addin you have installed quickly from the keyboard.

Installing an addin isn’t hard — and if you’re looking for new addins, Dean Attali’s addinslist is the place to go. But addins are installed via R packages, so if you want to create your own addin, you’ll have to create a new R package to store your addin. And if you have to create a new R package, you’ll need to think of a name for your R package. But naming is hard, and all the good words starting with or involving the letter R are already taken.

What if all you want to do is run a function from an installed package or a short bit of R code that does something useful and that makes your workflow just a little smoother?

What if you want that function to run whenever you press Control + Alt + Shift + K?

It seems like there should be an easier way to do this than to create an R package.

(Have I convinced you that you also have the same problem I do, or am I the only one?)

Introducing shrtcts

shrtcts is a small package I’ve put together with the goal of making it easier to register and manage RStudio addins without having to maintain an R package.

Getting started

First, install shrtcts.

remotes::install_github("gadenbuie/shrtcts")

Then, create a YAML file called .shrtcts.yaml and store it in your home directory1 or in a directory called .config in your home directory.

This YAML file holds your shortcuts as a YAML list. Each item looks a lot like the addins.dcf file that is used to register addins in R packages. The only difference is that the Binding entry can be any arbitrary R function or code.

- Name: Say Something Nice
  Description: A demo of cool things
  Binding: praise::praise
  Interactive: true

I’m calling this shortcut Say Something Nice and whenever it is triggered it calls praise() from the praise package.

To install your shortcut, run add_rstudio_addin() from shrtcts and restart your R session.

shrtcts::add_rstudio_shortcuts()
rstudioapi::restartSession()

You can restart your R session by clicking Session > Restart R. Now you should now be able to find the Say Something Nice addin in your addins list!

Our first RStudio shortcut!

Shortcut, meet keyboard

Assigning keyboard shortcuts to your addin shortcuts

Once you’ve installed your shortcut addins, you can then assign a keyboard shortcut to run your addin. Select Modify Keyboard Shortcuts… from the Tools menu

RStudio 'Modify Keyboard Shortcuts' item in the 'Tools' menu

and then search for your shortcut. Click on the blank space in the Shortcut column and press the keys that will be the your new shortcut. Here, I’m assigning the Say Something Nice addin to Ctrl + Shift + Alt + P.

Setting the keyboard shortcut for the 'Say Something Nice' addin

After setting the shortcut, I usually check to make sure my new keyboard shortcut doesn’t collide with a previously installed shortcut by clearing the search and sorting by the shortcut column.

A few details to keep in mind about keyboard shortcuts

There are a two things to keep in mind about using keyboard shortcuts with your shrtcts shortcuts.

First, if you re-install or update shrtcts, your currently existing keyboard shortcuts should survive the transition. Make sure that you run add_rstudio_addins() again after updating, and make sure that you re-start your R session.

Second, the order of your shortcuts in your .shrtcts.yaml file matters, unless you explicitly set the id entry to a number between 1 and 100. This means that it’s a good idea to set the id of shortcuts that you’re going to use with keyboard shortcuts.

- Name: Say Something Nice
  Description: A demo of cool things
  Binding: praise::praise
  id: 1
  Interactive: true

Adding more shortcuts

To add more shortcuts, continue adding entries in your .shrtcts.yaml file. If you don’t want to run add_rstudio_shortcuts() every time you update your shortcuts, you can add the following line in your ~/.Rprofile2.

if (interactive() & requireNamespace("shrtcts", quietly = TRUE)) {
  shrtcts::add_rstudio_shortcuts()
}

shrtcts comes with a demonstration .shrtcts.yaml file that you can use for inspiration. Print out the example YAML file contents with:

shrtcts::example_shortcuts_yaml()

Shortcuts can be arbitrary R code

Your shortcut doesn’t need to call a function in a package. In fact, you can create shortcuts that run R code simply by putting the code you want to run in the Binding entry.

Here’s an example shortcut that picks a number between 0 and 100. (Great for playing what number of am I think of?)

- Name: I'm thinking of a number...
  Binding: sample(0:100, 1)

Notice the binding is just R code (I was thinking of 53, by the way), and the only fields you need to include are the Name and the Binding.

Your shortcuts don’t need to fit on a single line either. You can use multi-line literal-style YAML blocks for your R code. In other words, add | after Binding and then indent your R code.

Here’s an example shortcut that I use occasionally to create a temporary markdown file so that I can test some markdown or R code and have the file be thrown away when I exit my R session.

- Name: New Temporary R Markdown Document
  Binding: |
    tmp <- tempfile(fileext = ".Rmd")
    rmarkdown::draft(
      tmp,
      template = "github_document",
      package = "rmarkdown",
      edit = FALSE
    )
    rstudioapi::navigateToFile(tmp)
  Interactive: false

Behind the Scenes

How does this all work? shrtcts comes with a minimal addins registry with one addin that browses to the help page ?add_rstudio_addins.

When you run add_rstudio_addins(), shrtcts rewrites it’s own addins registry using your shortcut title and description. It also assigns each shortcut in .shrtcts.yaml to an id from 1 to 100, which correspond to 100 shortcut functions in the shrtcts package. Each addin is wired to one of these functions, so when you run the associated addin shrtcts looks up the correct shortcut in your .shrtcts.yaml file and runs that shortcut.

This why you need to run add_rstudio_addins() whenever you add or modify the order of your shortcuts. Whenever this happens, shrtcts has to re-wire the addins registry to make sure everything is connect.

This is also why you need to restart your R session for the addins to be seen by RStudio. RStudio only checks for package addins when R starts up, so the R session restart triggers RStudio to refresh the addin registry.

Inspiration

shrtcts was inspired by rsam, the RStudio Addins Manager by @yonicd. There’s a lot that rsam can do — including helping you manage your keyboard shortcuts — and shrtcts is essentially an extension of rsam’s limited liability addins. rsam provides three slots for custom addins that in turn look for specially-named functions defined in the global environment. In the addins menu, these three custom addins appear as lla1, lla2, and lla3. The upside of rsam is that you don’t have to write code in YAML (huge plus!), but the downside is that the names of the addins are fixed.

shrtcts, on the other hand, rewrites its own addin registry so that you can have customized addin names and descriptions. In both packages, the number of custom addins is limited: rsam provides 3 slots, while shrtcts gives you 100.

Share Your Shortcuts

Because shrtcts stores your shortcuts in stand-alone(-ish) YAML files, you can share your shortcuts file with others (or yourself) by posting it somewhere online, for example as a Github Gist.

Here’s a small collection of shortcuts that I use and that inspired me to create this package so that I didn’t have to think of another package name.

I hope shrtcts is helpful to you! Find me on @grrrck and let me know if it is.


  1. You can find you home directory quickly using fs::path_home_r() or fs::path_home(). shrtcts will look in either location.↩︎

  2. A quick way to edit this file is by calling usethis::edit_r_profile().↩︎