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

Indentation like the R parser: 5th level and more + ignoring call continuation #395

Open
basille opened this issue Jan 28, 2017 · 11 comments

Comments

@basille
Copy link

basille commented Jan 28, 2017

This is a problem already submitted to ESS-help, but I figured it might as well be handled here (from this point, this is a formatted copy of the initial message):

I am trying to implement an indentation style that would mimic what the R parser would do (I know the R parser completely reformat the code, but I'm really focusing on indentation at the moment). For that, I have pretty much reconfigured all ESS variables regarding indentation:

(custom-set-variables
 '(ess-own-style-list
   (quote
    ((ess-indent-offset . 4)
     (ess-offset-arguments . prev-line)
     (ess-offset-arguments-newline . prev-line)
     (ess-offset-block . prev-line)
     (ess-offset-continued . straight)
     (ess-align-nested-calls)
     (ess-align-arguments-in-calls)
     (ess-align-continuations-in-calls)
     (ess-align-blocks control-flow)
     (ess-indent-from-lhs)
     (ess-indent-from-chain-start)
     (ess-indent-with-fancy-comments . t)))))

I think this gives me almost exactly what I want, except for two cases:

  1. Indentation after the 5th level

Consider the following (silly) function:

function() {
    {
        {
            {
                {
                    {
                        {
                            bla
                        }
                    }
                }
            }
        }
    }
}

After the 5th level, the R parser indents with 2 characters only :

function() {
    {
        {
            {
                {
                  {
                    {
                      bla
                    }
                  }
                }
            }
        }
    }
}

I don't think it can presently be handled by ESS… Is this something that
could be considered in the future?

  1. Continuation in calls

Setting the variable ess-align-continuations-in-calls to nil, I get:

1234567890 + (1234567890 + 1234567890 + 1234567890 + 1234567890 +
                  1234567890)

instead of:

1234567890 + (1234567890 + 1234567890 + 1234567890 + 1234567890 +
              1234567890)

as documented. However, what I really want to have is:

1234567890 + (1234567890 + 1234567890 + 1234567890 + 1234567890 +
    1234567890)

like the R parser would render, that is ignoring the call continuation
altogether. I tried setting to prev-line like for the other variables, but
it seems that this variable only accepts nil or t (which is any non-nil
value). How can I have it to ignore call continuation?

========== Side note on custom styles ============

I can see in the documentation that I should really define a new style, but
I cannot figure out how to do it based on the explanations.

==================================================

Any help on this would be greatly appreciated!
Mathieu.

@lionel-
Copy link
Member

lionel- commented Jan 28, 2017

After the 5th level, the R parser indents with 2 characters only :

I don't think it would be useful to add this to the indentation engine.

Continuation in calls

Yes it'd make sense to allow prev-line as well. The RStudio- style should behave this way too.

@basille
Copy link
Author

basille commented Jan 28, 2017

I guess it all depends how you evaluate usefulness. In this case, it is really to have a style that matches R style (as defined by the R parser), and so indentation strictly adhering R rules. So from a coding perspective, I think it makes a lot of sense (whether R rules themselves make sense is not the question here). Note that formatR indent code like that too.

Second, from a practical perspective, I think it can also be very useful: I routinely use the R parser or formatR through Elisp functions to reformat R code. I also use Aggressive indent mode, which automatically indent code. But if the coding style used for ESS does not match R (or formatR) style, then the formatting functions conflicts with aggressive-indent-mode, which will then automatically reindent after the code has been (properly) formatted.

Of course, I have no idea how complicated it would be to implement, and I'd understand that it is low priority!

Thanks in advance if you can implement prev-line for the continuation in calls!

@lionel-
Copy link
Member

lionel- commented Jan 29, 2017

I think compressing indentation levels is useful for printing code but not for coding. It creates an inconsistent layout (indent level has not the same meaning everywhere) and encourages bad code style with deeply nested logic.

@basille
Copy link
Author

basille commented Jan 29, 2017

Hey Lionel,

I think you're missing my point: I'm not saying that it's useful or even a good idea for coding, but just that it is how R itself behaves. As far as I'm concerned, I would really like it if ESS was able to provide a style that strictly adheres to R behavior. Whether it makes sense or not from a coding perspective (and this probably shouldn't be the default anyway) is irrelevant in my opinion. But I'd understand that it's low priority.

@lionel-
Copy link
Member

lionel- commented Jan 30, 2017

but just that it is how R itself behaves

The point is that the REPL behaves this way because it prints code, it does not format files.

@basille
Copy link
Author

basille commented Jan 30, 2017

I guess that's where I'm lost. I understand that the REPL print codes, but why couldn't it be used also to format code? I feel like I fail to see the difference you're making. (ideally, I'd like Emacs to be able to print and format code the same!)

@mmaechler
Copy link
Member

mmaechler commented Jan 30, 2017

I do understand @basille 's argumentation. He's not saying that this would be a generally preferable indentation. Let's view it like that:
It is the only one that is available with pure R and R packages and needs neither ESS nor Rstudio. In some circles / software development environments this is a very good reason to have it as an option or even to allow it as one coding standard. Of course we (ESS developers) do prefer different indentations and notably the flexibility to adapt to personal preferences. So I would label this issue as "wishlist" (with the implicit promise to consider accepting well-contained pull requests).

@basille
Copy link
Author

basille commented Jan 30, 2017

Thanks Martin for your feedback. Truth is that I would like to help on that, but it is currently beyond my skill set. Even though I consider myself as an advanced R user in many respects, my command of Lisp is basic to say the least, given that I'm only able to make sense of my init file, mostly using snippets stolen here and there…

If you are aware of an easy path to get started (on ESS indentation mechanisms), one that would not require you guys holding my hand constantly, I'd be willing to give it a shot (with the idea of eventually documenting a "standard R" style).

@lionel-
Copy link
Member

lionel- commented Mar 28, 2017

@basille just as a heads up, we probably won't accept a patch that makes indentation code considerably more complex just to support that feature. Also please note that we plan to switch to lexical scoping at some point, so we won't accept a patch that relies on dynamic scoping.

@mmaechler What do you mean by "pure R and R packages"? I'd be surprised to see more than a handful actual packages indented this way. I don't think this style is a standard in any circle. Nor should it ever become one, since it is for printing code in the console not for indenting actual files.

@mmaechler
Copy link
Member

I should have said "pure R": R's own "pretty printer" does exist even if you say that it is not very "pretty".
(with which I agree).

Many people study R code from print() functions to the console -- I don't very often: I download all packages in source and like to browse the source package code.... but I am 1 in 10'000 with this behavior.
For all those, it is very natural to read R code that way... so it is one definition of a natural indentation.

The plan to move (our elisp code) from dynamic to lexical scoping is quite interesting. How can this work with everyone using (setq ....) in their ~/.emacs to configure things?

@lionel-
Copy link
Member

lionel- commented Mar 29, 2017

For all those, it is very natural to read R code that way...

I do read functions from the console everyday. But again, this is for printing code in a console, not for indenting. Instead of worrying about the indentation level in deeply nested blocks, people should refactor their code so that this never occurs in practice.

How can this work with everyone using (setq ....) in their ~/.emacs to configure things?

Global variables remain global. They are not very different from dynamically scoped variable, e.g. when you use globals you get similar bytecode as with dynamic variables. So people should still be able to tweak modes almost just like before. I think many Emacs 25 modes have already switched to lexical scoping without user-visible consequences.

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

3 participants