Weekly Emacs tip #22 — ESS = Emacs + R
Back in 2010, as I started my postdoc at the Erasmus Medical Center in Rotterdam, I got introduced to R. Given that I was used to writing all my code in Emacs, it was obvious that I would write my R code there. I remember briefly looking into Tinn-R for the courses we would teach, and at that time, RStudio didn’t exist yet. It turned out, however, that Emacs had ESS — “Emacs Speaks Statistics”.
ESS is a package for statistical programming languages, mainly R, S and SAS. It provides two types of modes:
- “regular” modes: modes for editing source code
- so-called “inferior modes”: used when interacting directly with the language process
For example, when editing a .R
file with R source code, I’m in ess-r-mode
, which is the “regular” mode for editing R source code. The great thing about Emacs and ESS, however, is that one can also open an interactive R session directly in Emacs. Simply run M-x R
(or click on the R button in the menu bar when in a .R
file) and a new (Emacs) window will open with an R session, as shown in the screenshot. This R terminal is the regular R terminal you would get when running R
from the Linux command line. The mode of this interactive R session is the inferior-ess-r-mode
. One thing to remember in interactive R sessions is that C-p
, arrow-up, C-n
, and arrow-down scroll through the buffer (so you can easily copy code or output, for example) and do not cycle through command history. To do that, use M-p
and M-n
(which are used for similar purposes in other places in Emacs as well, as well as in Zsh, for example). Another keybinding to remember is M-r
, which starts a (regexp) search through the R command history. It’s an interactive search, so the first match will immediately show and you can use C-r
and C-s
to search forward or backward for the earlier/later occurrences of the search term. Very helpful!
As in other IDEs, you can send the code in your R source code buffer to the interactive R session. For example, C-c C-b
sends the whole buffer to the R session, C-<return>
sends the current line (or region if a there is a selection) which is a convenient way to step line-by-line through a piece of R code. Also, if you make a plot (like the ggplot2-based myPlot
in the screenshot below), a plot window will open up, just like in a non-Emacs R session.

Figure 1: An Emacs ESS session showing some R code on the left and an interactive R session on the right.
I recommend to have a look at the entries in the “ESS” menu that gets added to the menu bar when an ESS mode is active, it contains a bunch of handy features and keyboard shortcuts. For example, hitting C-c C-z
in an R code buffer switches to the corresponding R session (yes, you can have multiple interactive R sessions open at the same time, each in their own buffer) and back, as the name of the function it calls implies: ess-switch-to-inferior-or-script-buffer
. Another thing you can see there is the “Tracebug” submenu from where you can set (conditional) breakpoints, watch variables, etc. for interactive debugging. I won’t go into detail about that here, that will be for a future tip.
One thing I will mention, though, is that if you use Tramp to edit an R file on a remote machine, opening an interactive R session will also run on that machine (assuming R is installed on the remote machine). This can be really handy when analysing large datasets that eat a bunch of RAM, for example.
At first glance, one thing may be missing that is featured prominently in e.g. RStudio, and that is a variable/object browser. While ESS doesn’t show one when you start an R session, it does exist and you can open it by running M-x ess-rdired
. As shown in the screenshot below, this opens an interactive list of R objects. Hitting Enter on any of them will open a view of that object (which may not be a good idea for very large datasets).

Figure 2: The same buffer with R code, but this time with the ess-rdired
list on the right.
Of course, I don’t use vanilla ESS. This is the use-package
-based configuration in my ~/.emacs
:
(use-package ess-r-mode :init (require 'ess-site) :custom ;; Don't indent single # comments to col 40 and don't require double ;; ## for comments at the regular indent level. (ess-indent-with-fancy-comments nil) ;; Start R in the default folder without asking (ess-ask-for-ess-directory nil) (inferior-R-args "--no-save") (ess-style 'RStudio-) ;; Tell ESS R which keywords to use syntax highlighting for. AFAIK ;; you can't change a single one and keep the others to their ;; defaults. You have to set them all in the list. My ;; personalisation is that I set ess-fl-keyword:fun-calls and ;; ess-fl-keyword:operators to t (ess-R-font-lock-keywords '((ess-R-fl-keyword:keywords . t) (ess-R-fl-keyword:constants . t) (ess-R-fl-keyword:modifiers . t) (ess-R-fl-keyword:fun-defs . t) (ess-R-fl-keyword:assign-ops . t) (ess-R-fl-keyword:%op% . t) (ess-fl-keyword:fun-calls . t) (ess-fl-keyword:numbers) (ess-fl-keyword:operators t) (ess-fl-keyword:delimiters) (ess-fl-keyword:=) (ess-R-fl-keyword:F&T)) ) )
The most notable customisations are:
- By default ESS starts comments with double
##
, indenting with a single#
automatically moves the start of that comment to column 40. I don’t want that. - By default, starting an interactive R session asks for the directory where the session should be started. I have found that I (almost) always want to start that R session in the directory where I opened my
.R
file, so there’s no need to ask me. - The
ess-style
variable tells ESS to follow the Tidyverse code style. - By default syntax highlighting is off for operators (
+
,-
, etc., but also|>
) and function names. I want those to be highlighted. Unfortunately, one can’t just change those two from the defaults. Instead the full list of variables for syntax highlighted keywords must be listed, including the ones that you didn’t want to change. Hence the long list iness-R-font-lock-keywords
.
No Comments