Skip to content

Commit a069046

Browse files
Merge pull request #536 from lorenzwalthert/feature-curly-for-mutliline-fun-dec
- Function declarations should gain braces for body if strict = TRUE (#536).
2 parents 850cc73 + 3acf603 commit a069046

21 files changed

+829
-36
lines changed

NEWS.md

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,35 @@
22

33
## Breaking changes
44

5-
* `style_file()` now correctly styles multiple files from different
6-
directories. We no longer display the file name of the styled file, but
7-
the absolute path. This is also reflected in the invisible return value of the
8-
function (#522).
9-
* `style_file()` and friends do not write content back to a file when
10-
styling does not cause any changes in the file. This means the modification
11-
date of files styled is only changed when the content is changed (#532).
5+
* `style_file()` now correctly styles multiple files from different directories.
6+
We no longer display the file name of the styled file, but the absolute path.
7+
This is also reflected in the invisible return value of the function (#522).
8+
9+
* `style_file()` and friends do not write content back to a file when styling
10+
does not cause any changes in the file. This means the modification date of
11+
files styled is only changed when the content is changed (#532).
1212

1313
## New features
1414

15-
* curlyl-curly (`{{`) syntactic sugar introduced with rlang 0.4.0 is now
16-
explicitly handled, as opposed previously where it was just treated as two
15+
* curlyl-curly (`{{`) syntactic sugar introduced with rlang 0.4.0 is now
16+
explicitly handled, as opposed previously where it was just treated as two
1717
consequtive curly braces (#528).
18-
* `style_pkg()`, `style_dir()` and the Addins can now style `.Rprofile`, and
18+
19+
* `style_pkg()`, `style_dir()` and the Addins can now style `.Rprofile`, and
1920
hidden files are now also styled (#530).
2021

2122
## Minor improvements and fixes
2223

2324
* escape characters in roxygen code examples are now correctly escaped (#512).
24-
* style selection Addin now preserves line break when the last line selected is
25+
26+
* style selection Addin now preserves line break when the last line selected is
2527
an entire line (#520).
28+
2629
* style file Addin can now properly handle cancelling (#511).
30+
31+
* The body of a multi-line function declaration is now indented correctly for
32+
`strict = FALSE` and also wrapped in curly braces for `strict = TRUE` (#536).
33+
2734
* advice for contributors in `CONTRIBUTING.md` was updated (#508).
2835

2936
## Adaption
@@ -41,8 +48,8 @@ This is primarily a maintenance release upon the request of the CRAN team
4148
- Users can now control style configurations for styler Addins (#463, #500),
4249
using the `Set style` Addin. See `?styler::styler_addins` for details.
4350

44-
- `return()` is now always put in braces and put on a new line when used in
45-
a conditional statement (#492).
51+
- `return()` is now always put in braces and put on a new line when used in a
52+
conditional statement (#492).
4653

4754
- `%>%` almost always causes a line break now for `strict = TRUE` (#503).
4855

@@ -55,20 +62,20 @@ This is primarily a maintenance release upon the request of the CRAN team
5562
- indention in roxygen code example styling (#455) and EOF spacing (#469) was
5663
fixed.
5764

58-
- indention for for loop edge case (#457) and comments in pipe chain (#482)
59-
were fixed.
65+
- indention for for loop edge case (#457) and comments in pipe chain (#482) were
66+
fixed.
6067

6168
- line-break styling around comma is improved (#479).
6269

63-
- bug that can cause an error when the variable `text` in any name space
64-
before styler on the search path was defined and did not have length 1 is
65-
fixed (#484).
70+
- bug that can cause an error when the variable `text` in any name space before
71+
styler on the search path was defined and did not have length 1 is fixed
72+
(#484).
6673

6774
- slightly confusing warning about empty strings caused with roxygen code
6875
examples and Rmd was removed.
6976

70-
- right apostrophe to let package pass R CMD Check in strict Latin-1
71-
locale was removed (#490, reason for release).
77+
- right apostrophe to let package pass R CMD Check in strict Latin-1 locale was
78+
removed (#490, reason for release).
7279

7380
## Adaption of styler
7481

R/indent.R

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,19 @@ indent_without_paren <- function(pd, indent_by = 2) {
8787
#' definitions without parenthesis.
8888
#' @keywords internal
8989
indent_without_paren_for_while_fun <- function(pd, indent_by) {
90+
91+
tokens <- c("FOR", "WHILE", "FUNCTION")
9092
nrow <- nrow(pd)
91-
if (!(pd$token[1] %in% c("FOR", "WHILE", "FUNCTION"))) {
93+
if (!(pd$token[1] %in% tokens)) {
9294
return(pd)
9395
}
9496
if (is_curly_expr(pd$child[[nrow]])) {
9597
return(pd)
9698
}
99+
100+
if (pd$newlines[length(pd$newlines) - 1] == 0 ) {
101+
return(pd)
102+
}
97103
pd$indent[nrow] <- indent_by
98104
pd
99105
}
@@ -103,19 +109,33 @@ indent_without_paren_for_while_fun <- function(pd, indent_by) {
103109
#' @keywords internal
104110
indent_without_paren_if_else <- function(pd, indent_by) {
105111
expr_after_if <- next_non_comment(pd, which(pd$token == "')'")[1])
112+
is_if <- pd$token[1] %in% "IF"
106113
has_if_without_curly <-
107-
pd$token[1] %in% "IF" && pd$child[[expr_after_if]]$token[1] != "'{'"
108-
if (has_if_without_curly) {
114+
is_if && pd$child[[expr_after_if]]$token[1] != "'{'"
115+
if (!is_if) {
116+
return(pd)
117+
}
118+
needs_indention_now <- pd$lag_newlines[next_non_comment(pd, which(pd$token == "')'"))] > 0
119+
120+
if (needs_indention_now) {
109121
pd$indent[expr_after_if] <- indent_by
110122
}
111123

124+
125+
112126
else_idx <- which(pd$token == "ELSE")
127+
if (length(else_idx) == 0) {
128+
return(pd)
129+
}
113130
expr_after_else_idx <- next_non_comment(pd, else_idx)
114131
has_else_without_curly_or_else_chid <-
115132
any(pd$token == "ELSE") &&
116133
pd$child[[expr_after_else_idx]]$token[1] != "'{'" &&
117134
pd$child[[expr_after_else_idx]]$token[1] != "IF"
118-
if (has_else_without_curly_or_else_chid) {
135+
136+
needs_indention_now <- pd$lag_newlines[next_non_comment(pd, which(pd$token == "ELSE"))] > 0
137+
138+
if (has_else_without_curly_or_else_chid && needs_indention_now) {
119139
pd$indent[seq(else_idx + 1, nrow(pd))] <- indent_by
120140
}
121141
pd
@@ -212,7 +232,10 @@ needs_indention <- function(pd,
212232
#' @importFrom rlang seq2
213233
#' @keywords internal
214234
#' @examples
215-
#' style_text("call(named = c, \nnamed = b)", strict = FALSE)
235+
#' style_text(c(
236+
#' "call(named = c,",
237+
#' "named = b)"
238+
#' ), strict = FALSE)
216239
needs_indention_one <- function(pd,
217240
potential_trigger_pos,
218241
other_trigger_tokens) {

R/rules-other.R

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ add_brackets_in_pipe_one <- function(pd, pos) {
3333
#' braces. Used for unindention.
3434
#' @keywords internal
3535
#' @importFrom purrr when
36-
wrap_if_else_while_for_multi_line_in_curly <- function(pd, indent_by = 2) {
36+
wrap_if_else_while_for_fun_multi_line_in_curly <- function(pd, indent_by = 2) {
3737
key_token <- when(
3838
pd,
3939
is_cond_expr(.) ~ "')'",
4040
is_while_expr(.) ~ "')'",
41-
is_for_expr(.) ~ "forcond"
41+
is_for_expr(.) ~ "forcond",
42+
is_function_dec(.) ~ "')'"
4243
)
4344
if (length(key_token) > 0) {
4445
pd <- pd %>%
@@ -56,7 +57,7 @@ wrap_if_else_while_for_multi_line_in_curly <- function(pd, indent_by = 2) {
5657

5758
#' Wrap a multi-line statement in curly braces
5859
#'
59-
#' @inheritParams wrap_if_else_while_for_multi_line_in_curly
60+
#' @inheritParams wrap_if_else_while_for_fun_multi_line_in_curly
6061
#' @inheritParams wrap_subexpr_in_curly
6162
#' @param key_token The token that comes right before the token that contains
6263
#' the expression to be wrapped (ignoring comments). For if and while loops,
@@ -125,7 +126,7 @@ wrap_subexpr_in_curly <- function(pd,
125126
stretch_out = c(!to_be_wrapped_starts_with_comment, TRUE),
126127
space_after = space_after
127128
)
128-
new_expr$indent <- pd$indent[last(ind_to_be_wrapped)] - indent_by
129+
new_expr$indent <- max(pd$indent[last(ind_to_be_wrapped)] - indent_by, 0)
129130
new_expr_in_expr <- new_expr %>%
130131
wrap_expr_in_expr() %>%
131132
remove_attributes(c("token_before", "token_after"))

R/style-guides.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ tidyverse_style <- function(scope = "tokens",
155155
resolve_semicolon,
156156
add_brackets_in_pipe,
157157
remove_terminal_token_before_and_after,
158-
wrap_if_else_while_for_multi_line_in_curly =
159-
if (strict) wrap_if_else_while_for_multi_line_in_curly
158+
wrap_if_else_while_for_fun_multi_line_in_curly =
159+
if (strict) wrap_if_else_while_for_fun_multi_line_in_curly
160160
)
161161
}
162162

man/needs_indention_one.Rd

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/wrap_if_else_while_for_multi_line_in_curly.Rd renamed to man/wrap_if_else_while_for_fun_multi_line_in_curly.Rd

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/indention_multiple/fun_for_new_line-out.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
function()
1+
function() {
22
NULL
3+
}
34

45
for (i in 1:3)
56
{

tests/testthat/indention_operators/function-multiline-no-braces-in_tree

Lines changed: 102 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
g <- function(k)
2+
NULL
3+
4+
5+
g <- function(k) h(
6+
NULL
7+
)
8+
9+
10+
g <- function(k) h( # y
11+
NULL # x
12+
)
13+
14+
g <- function(k) h( # y
15+
NULL
16+
)
17+
18+
19+
g <- function(k) h(
20+
NULL # 3jkö
21+
)
22+
23+
g <- function(k) h(
24+
if (TRUE)
25+
x
26+
)

0 commit comments

Comments
 (0)