r-lib / styler

Non-invasive pretty printing of R code
https://styler.r-lib.org
Other
730 stars 71 forks source link

feature request: styling `switch` statements #714

Closed IndrajeetPatil closed 3 years ago

IndrajeetPatil commented 3 years ago

The tidyverse style guide states-

Screenshot 2021-01-13 at 16 25 29

styler currently produces the following output:

styler::style_text("switch(x, a = , b = 1, c = 2)")
#> switch(x, a = , b = 1, c = 2)

Created on 2021-01-13 by the reprex package (v0.3.0)

But I'd have expected it to return:

switch(x
  a = ,
  b = 1, 
  c = 2
)

The more conditions there are, the more useful this will become.

Session info ``` r devtools::session_info() #> ─ Session info ─────────────────────────────────────────────────────────────── #> setting value #> version R version 4.0.3 (2020-10-10) #> os macOS Mojave 10.14.6 #> system x86_64, darwin17.0 #> ui X11 #> language (EN) #> collate en_US.UTF-8 #> ctype en_US.UTF-8 #> tz Europe/Berlin #> date 2021-01-13 #> #> ─ Packages ─────────────────────────────────────────────────────────────────── #> package * version date lib source #> assertthat 0.2.1 2019-03-21 [1] CRAN (R 4.0.2) #> backports 1.2.1 2020-12-09 [1] CRAN (R 4.0.3) #> callr 3.5.1 2020-10-13 [1] CRAN (R 4.0.2) #> cli 2.2.0 2020-11-20 [1] CRAN (R 4.0.3) #> crayon 1.3.4 2017-09-16 [1] CRAN (R 4.0.2) #> desc 1.2.0 2018-05-01 [1] CRAN (R 4.0.2) #> devtools 2.3.2 2020-09-18 [1] CRAN (R 4.0.2) #> digest 0.6.27 2020-10-24 [1] CRAN (R 4.0.2) #> ellipsis 0.3.1 2020-05-15 [1] CRAN (R 4.0.2) #> evaluate 0.14 2019-05-28 [1] CRAN (R 4.0.1) #> fansi 0.4.1 2020-01-08 [1] CRAN (R 4.0.2) #> fs 1.5.0 2020-07-31 [1] CRAN (R 4.0.2) #> glue 1.4.2 2020-08-27 [1] CRAN (R 4.0.2) #> highr 0.8 2019-03-20 [1] CRAN (R 4.0.2) #> htmltools 0.5.1 2021-01-12 [1] CRAN (R 4.0.3) #> knitr 1.30 2020-09-22 [1] CRAN (R 4.0.2) #> lifecycle 0.2.0 2020-03-06 [1] CRAN (R 4.0.2) #> magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.0.3) #> memoise 1.1.0 2017-04-21 [1] CRAN (R 4.0.2) #> pillar 1.4.7 2020-11-20 [1] CRAN (R 4.0.3) #> pkgbuild 1.2.0 2020-12-15 [1] CRAN (R 4.0.3) #> pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.0.2) #> pkgload 1.1.0 2020-05-29 [1] CRAN (R 4.0.2) #> prettycode 1.1.0 2019-12-16 [1] CRAN (R 4.0.2) #> prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.0.2) #> processx 3.4.5 2020-11-30 [1] CRAN (R 4.0.3) #> ps 1.5.0 2020-12-05 [1] CRAN (R 4.0.3) #> purrr 0.3.4 2020-04-17 [1] CRAN (R 4.0.2) #> R.cache 0.14.0 2019-12-06 [1] CRAN (R 4.0.2) #> R.methodsS3 1.8.1 2020-08-26 [1] CRAN (R 4.0.2) #> R.oo 1.24.0 2020-08-26 [1] CRAN (R 4.0.2) #> R.utils 2.10.1 2020-08-26 [1] CRAN (R 4.0.2) #> R6 2.5.0 2020-10-28 [1] CRAN (R 4.0.2) #> remotes 2.2.0 2020-07-21 [1] CRAN (R 4.0.2) #> rlang 0.4.10 2020-12-30 [1] CRAN (R 4.0.3) #> rmarkdown 2.6 2020-12-14 [1] CRAN (R 4.0.3) #> rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.0.3) #> rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.0.3) #> sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 4.0.2) #> stringi 1.5.3 2020-09-09 [1] CRAN (R 4.0.2) #> stringr 1.4.0 2019-02-10 [1] CRAN (R 4.0.2) #> styler 1.3.2 2020-02-23 [1] CRAN (R 4.0.2) #> testthat 3.0.1 2020-12-17 [1] CRAN (R 4.0.3) #> tibble 3.0.4 2020-10-12 [1] CRAN (R 4.0.2) #> usethis 2.0.0 2020-12-10 [1] CRAN (R 4.0.3) #> vctrs 0.3.6 2020-12-17 [1] CRAN (R 4.0.3) #> withr 2.3.0 2020-09-22 [1] CRAN (R 4.0.2) #> xfun 0.20 2021-01-06 [1] CRAN (R 4.0.3) #> yaml 2.2.1 2020-02-01 [1] CRAN (R 4.0.2) #> #> [1] /Users/patil/Library/R/4.0/library #> [2] /Library/Frameworks/R.framework/Versions/4.0/Resources/library ```
lorenzwalthert commented 3 years ago

Potentially also dplyr::case_when() and purrr::when().

IndrajeetPatil commented 3 years ago

Happy to open another issue for this, but first wanted to run by you whether you think styler should preserve the aligning of the RHS of the formula here?

Or should it actually be styling case_when in this format by default? Definitely improves the legibility of the code when the replacement values are all aligned.

styler::style_text(
  'starwars %>%
  select(name:mass, gender, species) %>%
  mutate(
    type = case_when(
      height > 200 | mass > 200 ~ "large",
      species == "Droid"        ~ "robot",
      TRUE                      ~ "other"
    )
  )'
)
#> starwars %>%
#>   select(name:mass, gender, species) %>%
#>   mutate(
#>     type = case_when(
#>       height > 200 | mass > 200 ~ "large",
#>       species == "Droid" ~ "robot",
#>       TRUE ~ "other"
#>     )
#>   )

Created on 2021-02-15 by the reprex package (v1.0.0)

lorenzwalthert commented 3 years ago

Good point. Alignment seems to work with =, but not with ~:

styler::style_text(
  'starwars %>%
  select(name:mass, gender, species) %>%
  mutate(
    type = c(
      a     = "large",
      bvv   = "robot",
      naot  = "other"
    )
  )'
)
#> starwars %>%
#>   select(name:mass, gender, species) %>%
#>   mutate(
#>     type = c(
#>       a     = "large",
#>       bvv   = "robot",
#>       naot  = "other"
#>     )
#>   )

Created on 2021-02-15 by the reprex package (v1.0.0)

I think we should first implement alignment detection for ~ to avoid styling around ~ in your case, then optionally thinking about line breaks. I updated https://github.com/r-lib/styler/issues/258 to track the alignment around ~. I'll open a new issue for the other two cases.

IndrajeetPatil commented 3 years ago

Not sure if this deserves a separate issue. I wanted to check with you first about what you think about this, since I couldn't find any styling guidelines for this context.

Do you think the following

styler::style_text(
  'switch(type,
  "x" = "1",
  "y" = ifelse(cond1,
         "2",
         ifelse(cond2, "3", "4")
        ),
  "z" = "5"
  )'
)
#> switch(type,
#>   "x" = "1",
#>   "y" = ifelse(cond1,
#>     "2",
#>     ifelse(cond2, "3", "4")
#>   ),
#>   "z" = "5"
#> )

Created on 2021-07-01 by the reprex package (v2.0.0)

should instead be styled to?

#> switch(type,
#>   "x" = "1",
#>   "y" = ifelse(cond1,
#>            "2",
#>            ifelse(cond2, "3", "4")
#>         ),
#>   "z" = "5"
#> )

That is, none of the action elements should cross over to case elements?

lorenzwalthert commented 3 years ago

I think the normal indention rules should apply, so I think current output is as desired.