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

Magrittr pipes trigger indent on newline #321

Closed
gowerc opened this issue May 11, 2020 · 20 comments
Closed

Magrittr pipes trigger indent on newline #321

gowerc opened this issue May 11, 2020 · 20 comments

Comments

@gowerc
Copy link
Contributor

gowerc commented May 11, 2020

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(...)
@andycraig
Copy link
Collaborator

@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

@andycraig
Copy link
Collaborator

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

@renkun-ken
Copy link
Member

@gowerc REditorSupport/languageserver#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.

@gowerc
Copy link
Contributor Author

gowerc commented May 12, 2020

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 :)

@andycraig
Copy link
Collaborator

@renkun-ken I’d quite like this feature too so that it’s 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?

@andycraig
Copy link
Collaborator

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.

@gowerc
Copy link
Contributor Author

gowerc commented May 18, 2020

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...

@gowerc
Copy link
Contributor Author

gowerc commented May 18, 2020

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 ?

@andycraig
Copy link
Collaborator

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

@gowerc
Copy link
Contributor Author

gowerc commented May 19, 2020

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.

@andycraig
Copy link
Collaborator

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.

@renkun-ken
Copy link
Member

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?

@andycraig
Copy link
Collaborator

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.

@andycraig
Copy link
Collaborator

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: #321 (comment)

@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.

@gowerc
Copy link
Contributor Author

gowerc commented Nov 15, 2020

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

@andycraig
Copy link
Collaborator

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

@storopoli
Copy link

Guys I am having something strange.

My vscode-R with R LSP Client and languageserver installed in a Intel Mac and a M1 Mac. All configurations the same. I cannot get the:

"editor.formatOnType": true,
"editor.formatOnSave": true,
"editor.formatOnPaste": true

to work in the M1 and it is flawless in the Intel. Same VS Code versions and extensions installed in both systems.

@github-actions
Copy link

This issue is stale because it has been open for 365 days with no activity.

@github-actions github-actions bot added the stale label Jun 13, 2022
@github-actions
Copy link

This issue was closed because it has been inactive for 14 days since being marked as stale.

@reliscu
Copy link

reliscu commented Dec 14, 2023

Any plans to implement this capability?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants