9

Recently, R witnessed the smart introduction of the piping operator %>% or then operator in code which I use quite frequently nowadays. I wonder if this has already been implemented in the newest version of ESS. If not, it shouldn't be a problem to come up with elisp code to write a function for it. I need to implement this so that it will print that operator %>% and then jumps to a new indented line.

MWE

library(ggplot2)
library(dplyr)    
diamonds %>%
      filter(cut=="Ideal") %>%
      ggplot(aes(price)) +
      geom_histogram() +
      facet_wrap (~ color)

My elisp trial - in .init.el or .emacs file:

(defun then_R_operator ()
  "%>% operator or 'then' pipe operator"
  (interactive)
  (insert " %>%") ; note the space before the first %
  (reindent-then-newline-and-indent))
(global-set-key (kbd "C-%") 'then_R_operator)  

It works, but I want to check if there is something wrong with it or are there any suggestions to improve it (being a newbie in elisp). How to restrict this only to ESS mode?

Note
I realized that font-locking of %>% can be done by enabling ess-fl-keyword:operatorsfrom the ESS menu.

5
  • I'd take care for the space character with (just-one-space 1) before the pipe. You want use the ess-mode-map (and propably the inferior-ess-mode-map) to set the key with (define-key ess-mode-map (kbd "C-%") 'then_R_operator).
    – mutbuerger
    Commented Feb 7, 2015 at 14:24
  • thanks! what is the difference between the two: inferior... and ess-mode...?
    – doctorate
    Commented Feb 7, 2015 at 14:52
  • ess-mode activates itself when editing, e.g., .R files.inferior-ess-mode activates when running an interactive R process inside Emacs (i.e. through the R command or with C-c C-z which calls ess-switch-to-inferior-or-script-buffer).
    – undostres
    Commented Feb 7, 2015 at 17:50
  • @undostres thanks. do u mean if I want to define a key for this operator in the inferior... this will let me use it in the interactive R console, which is inside Emacs? if yes then I think it would be better to define keys for both ess-mode and inferior, right?
    – doctorate
    Commented Feb 7, 2015 at 18:01
  • @doctorate Yes.
    – undostres
    Commented Feb 7, 2015 at 20:52

2 Answers 2

13

thanks to mutbuerger for the helpful comments. Currently, I use this for this operator to work with ESS only.

(defun then_R_operator ()
  "R - %>% operator or 'then' pipe operator"
  (interactive)
  (just-one-space 1)
  (insert "%>%")
  (reindent-then-newline-and-indent))
(define-key ess-mode-map (kbd "C-%") 'then_R_operator)
(define-key inferior-ess-mode-map (kbd "C-%") 'then_R_operator)
2

You can define a key binding for %>% with use-package:

(use-package ess
  :bind (:map ess-r-mode-map
         ("C-c >" . " %>% ")
         :map inferior-ess-r-mode-map
         ("C-c >" . " %>% ")))
1
  • You don't need use-package to do this. You can set the key with define-key, global-set-key, local-set-key, or however you like. Example: (local-set-key (kbd "C-c >") " %>% ").
    – Dan
    Commented Jun 3, 2021 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.