Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request: include support for R package magrittr #96

Closed
uhkeller opened this issue May 27, 2014 · 11 comments

Comments

Projects
None yet
8 participants
@uhkeller
Copy link

commented May 27, 2014

The R package magrittr defines the pipe-forwarding binary operator %>% that makes for much more readable code in my experience. It would be nice if ESS could provide support for this operator by a) providing a key binding for it and b) highlighting it as it does other operators.

@mmaechler

This comment has been minimized.

Copy link
Member

commented May 27, 2014

Sorry, dear UH, but I pretty strongly disagree that ESS itself should start providing support for such things... There won't be an end if we start here...
OTOH, we may think of providing hooks for ESS extensions.. that you could provide and would be responsible for maintaining.

@gaborcsardi

This comment has been minimized.

Copy link

commented Jun 24, 2014

Here is some code for

  1. providing a key binding for %>%,
  2. highlighting it, and
  3. writing it as a nice unicode triple arrow character.

This is how it looks:
https://raw.githubusercontent.com/gaborcsardi/dot-emacs/master/screenshot-2.png

;; Pretty arrows and magrittr pipes in R
(defvar pretty-alist
  (cl-pairlis '() '()))
(add-to-list 'pretty-alist '("%>%" . "⇛"))
(add-to-list 'pretty-alist '("<-" . "⇐"))
(defun pretty-things ()
  (mapc
   (lambda (x)
     (let ((word (car x))
           (char (cdr x)))
       (font-lock-add-keywords
        nil
        `((,(concat "\\(^\\|[^a-zA-Z0-9]\\)\\(" word "\\)[a-zA-Z]")
            (0 (progn
                 (decompose-region (match-beginning 2) (match-end 2))
                 nil)))))
       (font-lock-add-keywords
        nil
        `((,(concat "\\(^\\|[^a-zA-Z0-9]\\)\\(" word "\\)[^a-zA-Z]")
            (0 (progn
                 (compose-region (match-beginning 2) (match-end 2)
                  ,char)
                 nil)))))))
   pretty-alist))

(add-hook 'R-mode-hook
      (lambda ()
        (font-lock-add-keywords nil
                 '(("\\(%>%\\)" 1
                    font-lock-builtin-face t)))))

(define-key ess-mode-map [(super .)] "%>%")
@vspinu

This comment has been minimized.

Copy link
Member

commented Aug 10, 2014

I tend to agree with Martin. This seems like a good idea for a more general package "pretty-things". magrittr is used pretty marginally and I would not include such a general feature for its sake only. Your code is also not in the final production shape and more work need to be done to properly integrate into ESS smart operators, font-locking and customization system.

On the other hand I like the idea of lambda and composition that would make R even more functional than it is. I think you guys should try and push pipe and lambda to R core. It would make a great addition. I would also like to see threading macros (like -> and ->> in clojure).

To wrap up, we would prefer to wait and see. If magrittr takes off and gets some traction we would be happy to reconsider.

@vspinu vspinu closed this Aug 10, 2014

@mmaechler

This comment has been minimized.

Copy link
Member

commented Aug 11, 2014

Actually, I have learned quite a bit more about the issue in the mean time, notably about the relative importance of magrittr notably in the "Hadleyverse". I'm reopening therefore (with an excuse to @Vitoshka ; I should have taken up the issue myself..)

@mmaechler mmaechler reopened this Aug 11, 2014

@gtuckerkellogg

This comment has been minimized.

Copy link

commented Jan 29, 2015

magrittr is important in the Hadleyverse in part because other packages like dplyr also adopt the pipe. While the highlighting @gaborcsardi showed above works, can anyone suggest some elisp to indent after %>% properly in ESS? Right now ESS indentation of a pipeline looks like

library(dplyr)
foo <-  filter(mtcars, gear > 3) %>%
        filter(cyl < 6) %>%
            filter(carb == 2)

That is, every use of %>% increases the indentation. The examples I've seen documenting %>% keep all the pipes at a single level, that is:

foo <-  filter(mtcars, gear > 3) %>%
        filter(cyl < 6) %>%
        filter(carb == 2)

If support for %>% is under consideration for ESS, it would be great to address the indentation at the same time.

@vspinu

This comment has been minimized.

Copy link
Member

commented Jan 29, 2015

Have a look at ess-first-continued-statement-offset and ess-continued-statement-offset. I have

foo <-
    filter(mtcars, gear > 3) %>%
      filter(cyl < 6) %>%
      filter(carb == 2)

With the following style:

(add-to-list 'ess-style-alist
             '(my-style
               (ess-indent-level . 4)
               (ess-first-continued-statement-offset . 2)
               (ess-continued-statement-offset . 0)
               (ess-brace-offset . -4)
               (ess-expression-offset . 4)
               (ess-else-offset . 0)
               (ess-close-brace-offset . 0)
               (ess-brace-imaginary-offset . 0)
               (ess-continued-brace-offset . 0)
               (ess-arg-function-offset . 4)
           (ess-arg-function-offset-new-line . '(4))
               ))

(setq ess-default-style 'my-style)
@gtuckerkellogg

This comment has been minimized.

Copy link

commented Jan 31, 2015

Fantastic, thanks!

@kwstat

This comment has been minimized.

Copy link

commented Feb 24, 2015

For what it's worth...with key-chord-mode, I make it easier to type the pipe operator by using two quick ">" keystrokes:

(require 'key-chord)
(key-chord-mode 1)
(key-chord-define-global ">>" "%>%")

@vspinu vspinu closed this in c92de55 Mar 12, 2015

@vspinu

This comment has been minimized.

Copy link
Member

commented Mar 12, 2015

I have added ess-R-fl-keyword:%op% to the ESS>font-lock menu and corresponding ess-%op%-face.

As to the binding, smart operators is not ESS's business. I am experimenting with key-combo now. It it implements ess-smart-underscore cycling idea on a much larger scale and looks very promisin . This is what I have right now:

(require 'key-combo)

(defvar key-combo-ess-default
  (append key-combo-common-default
      '((">"  . (" > " " %>% "))
        ("$"  . ("$" " %$% "))
        ("<>" . " %<>% ")
        ("*"  . ("*" " * "))
        ("^"  . ("^" " ^ "))
        ("/"  . ("/" " / "))
        ("~" . " ~ ")
        (":" . (":" "::" ":::"))
        (":="  . " := ") ; data.table
        ;; ("inn" . " %in% ") ; doesn't work
        ("->"  . " -> "))))

(key-combo-define-hook '(ess-mode-hook inferior-ess-mode-hook)
               'ess-key-combo-load-default
               key-combo-ess-default)
@dahtah

This comment has been minimized.

Copy link
Contributor

commented Mar 31, 2016

Using key-combo is a really good solution. The above didn't quite work on my setup, though (Emacs 24.4.1). Here's a working version:

(require 'key-combo)

(key-combo-mode 1)

(add-hook 'ess-mode-hook
        '(lambda()
           (key-combo-mode t)))

(add-hook 'inferior-ess-mode-hook
        '(lambda()
           (key-combo-mode t)))

(defvar key-combo-ess-default
      '((">"  . (" > " " %>% "))
        ("$"  . ("$" " %$% "))
        ("<>" . " %<>% ")
        ("*"  . ("*" " * "))
    ("%" . ("%" "%*%" "%%"))
        ("^"  . ("^" " ^ "))
        ("/"  . ("/" " / "))
        ("~" . " ~ ")
        (":" . (":" "::" ":::"))
        (":="  . " := ") ; data.table
        ("->"  . " -> ")))

(key-combo-define-hook '(ess-mode-hook inferior-ess-mode-hook)
               'ess-key-combo-load-default
               key-combo-ess-default)

@sumanstats

This comment has been minimized.

Copy link

commented Dec 26, 2017

Simple solution is to put this line in your init.el file:

(global-set-key (kbd "C-S-m") (lambda () (interactive) (insert "%>%")))

It will provide the same binding as rstudio for pipe operator of magrittr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.