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.

Drew
  • 77,472
  • 10
  • 114
  • 243
doctorate
  • 1,829
  • 17
  • 40
  • 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 Feb 07 '15 at 14:24
  • thanks! what is the difference between the two: inferior... and ess-mode...? – doctorate Feb 07 '15 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 Feb 07 '15 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 Feb 07 '15 at 18:01
  • @doctorate Yes. – undostres Feb 07 '15 at 20:52

2 Answers2

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)
doctorate
  • 1,829
  • 17
  • 40
1

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 >" . " %>% ")))
aparkerlue
  • 317
  • 2
  • 8
  • 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 Jun 03 '21 at 16:23