Vscode-r: Magrittr pipes trigger indent on newline

Created on 11 May 2020  路  16Comments  路  Source: Ikuyadeu/vscode-R

Not sure if this is the right place for this request, please delete if not !

Would it be possible to get magrittr's pipes %>% to be treated akin to brackets where an automatic indent happens if you press enter on a line whose last symbol is the pipes?

i.e.
having

iris %>% mutate(...)

and pressing enter after the %>% but before the mutate(...) would result in

iris %>%
    mutate(...)

At the moment when I do this it just comes out as:

iris %>%
mutate(...)
feature-request

Most helpful comment

@gowerc https://github.com/REditorSupport/languageserver/pull/209 implements on-type-formatting on user input at expression-level based on a backward parsing strategy. With editor.formatOnType = true and vscode-r-lsp and languageserver installed, the formatting is exactly what you want.

All 16 comments

@gowerc Thank you for the suggestion! This would be a good feature.

The slightly tricky thing here is that the indentation should not increase with subsequent pipes:

# BAD
iris %>%
    mutate(...) %>%
        select(...)

# GOOD
iris %>%
    mutate(...) %>%
    select(...)

Hopefully we can do it using onEnterRules here: https://github.com/Ikuyadeu/vscode-R/blob/725c1a873440d004ec47af847912665a82aa8ad5/src/extension.ts#L165

Actually looks like indentNextLinePattern might be the key here, as it applies to the next line only: https://code.visualstudio.com/api/references/vscode-api#IndentationRule

@gowerc https://github.com/REditorSupport/languageserver/pull/209 implements on-type-formatting on user input at expression-level based on a backward parsing strategy. With editor.formatOnType = true and vscode-r-lsp and languageserver installed, the formatting is exactly what you want.

Thanks @renkun-ken ,

This indeed does work. Only caveat would be that it also comes with the automatic formatting as well (i.e. converting 1+1 to 1 + 1) which I'm not sure if I want or not yet. There is also a noticeable twitch/jump from pressing enter to the code being re-formatted into position.

This this does what I need so thank you very much :)

@andycraig , I still think it would be nice to have an editor specific solution to this (if you have the desire to implement it) but I do have a workaround now so feel free to close the ticket if you are not interested :)

@renkun-ken I鈥檇 quite like this feature too so that it鈥檚 there even when editor.formatOnType is false. I would guess any performance hit from formatting coming from both VS Code and the language server should be negligible when editor.formatOnType is true but what do you think?

I thought this would be a matter of adding this to r-configuration.json:

"indentationRules": {
    "indentNextLinePattern": "%>%"
}

But when I do that and type

iris %>%

and hit enter, this is the result:

iris %>%
#' 

So it seems that the indentation rule is erroneously triggering the onEnterRules rule from extension.ts. Not sure if that's me misusing one of them, or from a VS Code bug.

I tried the following in r-configuration.json which nearly works but not quite :(

"indentationRules": {
        "increaseIndentPattern": "^.*\\{[^}\"']*$|^.*\\([^\\)\"']*$",
        "decreaseIndentPattern": "^\\s*(\\s*\\/[*].*[*]\\/\\s*)*[})]",
        "indentNextLinePattern" : "%>%\\s*$",
        "unIndentedLinePattern" : "^\\s+.*%>%\\s*$"
    },

The results were:

2020-05-18 12 08 27

I'm struggling to think of a pattern that would work in both cases. I tried only using the indentNextLinePattern but as you feared it just continuously indented...

Perhaps as a half way house solution we could try this ?

A new enter rule which indents on lines that contain <- but ends in %>%

            {
               action: { indentAction: IndentAction.Indent},
               beforeText: /<-.*%>%\s*$/,
            }

2020-05-18 14 03 01

Its not perfect but should cover the main usecases ?

@gowerc Thank you for working on this! I'll have a proper look this weekend.

Just to add my findings so far though (as it's not overly well documented)

You can set the following in the configuration.json file:

increaseIndentPattern - Permanently increases the indent counter by 1
decreaseIndentPattern - Permanently decreases the indent counter by 1
indentNextLinePattern - Adds 1 to the indent count for just the next line
unIndentedLinePattern - Stops line from being considered for evaluation by the other pattern rules (thus preserving the current indent regardless of its pattern)

You can then also set additional on-enter rules which are well documented, though one thing I noticed is that any indentation that is added here i.e. IndentAction.Indent overwrites The indentation rules set in the configuration.json file.

The problem I was running into is that there is no meaningful way to distinguish the first use of the pipe (to thus do the initial indent) from subsequent uses of the pipe. I tried to play around with multiple line regex's using (?m) however it doesn't look like vscode supports these :(
Thus I settled on just defining an on-enter rule for use of the <- and %>% as this more likely characterises the like first usage of the pipe.

A new enter rule which indents on lines that contain <- but ends in %>%

I think this is probably the best option for now but I want to have a little bit more of a think/experiment before we incorporate it.

I'm curious about how the text edits are handled if editor.formatOnType is enabled and languageserver also performs on-type-formatting and indention, and vscode-R also makes some indention?

I've had a bit more of a think and haven't come up with anything else. I think it would be okay to incorporate this provided there's no conflict between vscode-R formatting and languageserver formatting when editor.formatOnType is enabled. I haven't checked whether that's the case.

It would be good to have indentation for parenthesis, brackets and braces specified in r-configuration.json to address #435

The open question is whether it will work properly together with format on type: https://github.com/Ikuyadeu/vscode-R/issues/321#issuecomment-633177496

@gowerc Are you interested in doing some testing of how automatic indentation works together with format on type? If not I can work on this.

Apologies but I just don't have time at the moment to assist :(

@gowerc No problem, thank you for all your research! I will do some testing and see if I can get Reindent Lines working.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andycraig picture andycraig  路  4Comments

MaTo04 picture MaTo04  路  5Comments

michaelHL picture michaelHL  路  4Comments

JimmyZJX picture JimmyZJX  路  3Comments

Dee-L picture Dee-L  路  5Comments