Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@

- `style_dir()` and `style_pkg()` now apply directory exclusion recursively with
`exclude_dirs` (#676).
- `switch()` now has line breaks after every argument to match the tidyverse
style guide (#722).
- unary `+` before a function call does not give an error anymore, as before
version 1.3.0 (#697).
- cache is now correctly invalidated when style guide arguments change (#647).
Expand Down
66 changes: 44 additions & 22 deletions R/rules-line-breaks.R
Original file line number Diff line number Diff line change
Expand Up @@ -209,39 +209,61 @@ set_line_break_after_assignment <- function(pd) {
#' not cause a line break after "'('".
#' @param except_token_before A character vector with text before "')'" that do
#' not cause a line break before "')'".
#' @param force_text_before A character vector with text before "'('" that
#' forces a line break after every argument in the call.
#' @name set_line_break_if_call_is_multi_line
#' @importFrom rlang seq2
#' @keywords internal
NULL

#' @describeIn set_line_break_if_call_is_multi_line Sets line break after
#' opening parenthesis.
#' Sets line break after opening parenthesis
#'
#' @details
#' In general, every call that is multi-line has a line break after the opening
#' parenthesis. Exceptions:
#'
#' * The token right after the parenthesis is a comment, then, the line should
#' be broken after the comment only. Governed by `except_token_after`.
#' * The name of the function called is `ifelse()` or similar, where we can
#' allow the condition on the same line as the function name, and we don't
#' impose rules on the line breaks for the subsequent arguments. Governed
#' by `except_text_before`.
#' * Some calls like `switch()` statements are always forced to become multi-
#' line. Governed by `force_text_before`.
#'
#' @keywords internal
set_line_break_after_opening_if_call_is_multi_line <-
function(pd,
except_token_after = NULL,
except_text_before = NULL) {
if (!is_function_call(pd) && !is_subset_expr(pd)) {
return(pd)
}
npd <- nrow(pd)
seq_x <- seq2(3L, npd - 1L)
is_multi_line <- any(
(pd$lag_newlines[seq_x] > 0) |
(pd$token[seq_x] == "COMMENT")
set_line_break_after_opening_if_call_is_multi_line <- function(pd,
except_token_after = NULL,
except_text_before = NULL,
force_text_before = NULL) {
if (!is_function_call(pd) && !is_subset_expr(pd)) {
return(pd)
}
has_force_text_before <- pd$text[next_non_comment(pd, 0)] %in% force_text_before
if (has_force_text_before) {
break_pos <- c(
which(lag(pd$token %in% c("','", "COMMENT"))),
nrow(pd) # always break before last because this is multi-line
)
if (!is_multi_line) {
} else {
if (!any(pd$lag_newlines[seq2(3L, nrow(pd))] > 0)) {
return(pd)
}
break_pos <- find_line_break_position_in_multiline_call(pd)

exception_pos <- c(
which(pd$token %in% except_token_after),
ifelse(pd$child[[1]]$text[1] %in% except_text_before, break_pos, NA)
)
pd$lag_newlines[setdiff(break_pos, exception_pos)] <- 1L
pd
}
exception_pos <- c(
which(pd$token %in% except_token_after),
ifelse(pd$child[[1]]$text[1] %in% except_text_before, break_pos, NA)
)
pd$lag_newlines[setdiff(break_pos, exception_pos)] <- 1L
if (has_force_text_before) {
first_arg <- which(pd$token == "expr")[2]
if (lag(pd$token)[first_arg] != "COMMENT") {
pd$lag_newlines[first_arg] <- 0L
}
}
pd
}


#' Find index of the token before which the line should be broken
Expand Down
15 changes: 8 additions & 7 deletions R/style-guides.R
Original file line number Diff line number Diff line change
Expand Up @@ -142,19 +142,20 @@ tidyverse_style <- function(scope = "tokens",
# must be after style_line_break_around_curly as it remove line
# breaks again for {{.
set_line_break_around_curly_curly = set_line_break_around_curly_curly,
set_line_break_after_opening_if_call_is_multi_line = if (strict) {
partial(
set_line_break_after_opening_if_call_is_multi_line,
except_token_after = "COMMENT",
except_text_before = c("switch", "ifelse", "if_else")
)
},
set_line_break_before_closing_call = if (strict) {
partial(
set_line_break_before_closing_call,
except_token_before = "COMMENT"
)
},
set_line_break_after_opening_if_call_is_multi_line = if (strict) {
partial(
set_line_break_after_opening_if_call_is_multi_line,
except_token_after = "COMMENT",
except_text_before = c("ifelse", "if_else"), # don't modify line break here
force_text_before = c("switch") # force line break after first token
)
},
remove_line_break_in_fun_call = purrr::partial(remove_line_break_in_fun_call, strict = strict),
add_line_break_after_pipe = if (strict) add_line_break_after_pipe,
set_linebreak_after_ggplot2_plus = if (strict) set_linebreak_after_ggplot2_plus
Expand Down
31 changes: 31 additions & 0 deletions man/set_line_break_after_opening_if_call_is_multi_line.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 5 additions & 12 deletions man/set_line_break_if_call_is_multi_line.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,45 @@ call(
3
)

switch(abc,
wei9
switch(
x,
a = 2,
y = 3
)

switch(abc,
wei9

switch( #
x,
a = 2,
y = 3
)



switch(
x,
a = 2, #


y = 3
)


switch(
x,a = 2,
y = 3
)

switch(x,a = 2,
y = 3
)

switch(x,a = 2, y = 3)

switch(x,a = 2, y = 3
) #

switch(x,a = 2, y = 3 #
)

if_else(a,
Expand Down
Loading