diff --git a/.github/workflows/touchstone-comment.yaml b/.github/workflows/touchstone-comment.yaml index a1ce2e5be..c3b8eea04 100644 --- a/.github/workflows/touchstone-comment.yaml +++ b/.github/workflows/touchstone-comment.yaml @@ -17,6 +17,6 @@ jobs: ${{ github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' }} steps: - - uses: lorenzwalthert/touchstone/actions/comment@add-pat + - uses: lorenzwalthert/touchstone/actions/comment@main with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/touchstone-receive.yaml b/.github/workflows/touchstone-receive.yaml index 1ef5b9c8d..bd4ee2b12 100644 --- a/.github/workflows/touchstone-receive.yaml +++ b/.github/workflows/touchstone-receive.yaml @@ -39,7 +39,7 @@ jobs: RSPM: ${{ matrix.config.rspm }} GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: lorenzwalthert/touchstone/actions/receive@add-pat + - uses: lorenzwalthert/touchstone/actions/receive@main with: cache-version: 1 benchmarking_repo: ${{ matrix.config.benchmarking_repo }} diff --git a/NEWS.md b/NEWS.md index 1facf0034..401bf68a3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -35,6 +35,9 @@ * `Warning: Unknown or uninitialised column:` was fixed (#885). * Unaligned expressions with quoted key (e.g. `c("x" = 2)`) are now correctly detected (#881). +* function calls with unequal number of token on different lines are no longer + deemed aligned if there are arbitrary spaces around the tokens on the lines + with most tokens (#902). * ensure a trailing blank line also if the input is cached (#867). * Preserve trailing blank line in roxygen examples to simplify concatenation of examples (#880). diff --git a/R/detect-alignment.R b/R/detect-alignment.R index 49093011f..5d2ef99fb 100644 --- a/R/detect-alignment.R +++ b/R/detect-alignment.R @@ -84,7 +84,10 @@ token_is_on_aligned_line <- function(pd_flat) { if (any(starting_with_comma)) { return(FALSE) } - pd_is_multi_line <- map_lgl(pd_by_line, ~ any(.x$multi_line > 0L, na.rm = TRUE)) + pd_is_multi_line <- map_lgl( + pd_by_line, + ~ any(.x$multi_line > 0L, na.rm = TRUE) + ) if (any(pd_is_multi_line)) { return(FALSE) } @@ -98,9 +101,9 @@ token_is_on_aligned_line <- function(pd_flat) { alignment_ensure_trailing_comma() # now, pd only contains arguments separated by values, ideal for iterating # over columns. - n_cols <- map_int(pd_by_line, ~ sum(.x$token == "','")) previous_line <- 0 + current_col <- 0 start_eval <- ifelse(alignment_col1_all_named(pd_by_line), 1, 2) for (column in seq2(1, max(n_cols))) { by_line <- alignment_serialize_column(pd_by_line, column) %>% @@ -109,33 +112,47 @@ token_is_on_aligned_line <- function(pd_flat) { trimws(which = "right") # check 1: match by comma # might have fewer lines in subsequent columns. - current_col <- nchar(by_line) + max_previous_col <- max(current_col) + + # first col has no leading , + current_col <- nchar(by_line) - as.integer(column > 1) if (column > 1) { - previous_line <- previous_line[intersect(names(previous_line), names(by_line))] + previous_line <- previous_line[ + intersect(names(previous_line), names(by_line)) + ] # must add previous columns, as first column might not align current_col <- current_col + previous_line } is_aligned <- length(unique(current_col)) == 1L - if (!is_aligned) { + if (!is_aligned || length(current_col) < 2) { # check 2: left aligned after , - current_col <- nchar(gsub("^(,[\\s\\t]*)[^ ]*.*$", "\\1", by_line, perl = TRUE)) + current_col <- "^(,[\\s\\t]*)[^ ]*.*$" %>% + gsub("\\1", by_line, perl = TRUE) %>% + nchar() %>% + magrittr::subtract(1) if (column > 1) { # must add previous columns, as first column might not align - current_col <- current_col + previous_line + current_col <- previous_line + current_col } - is_aligned <- length(unique(current_col)) == 1L + if (length(current_col) > 1) { + is_aligned <- length(unique(current_col)) == 1L + } else { + is_aligned <- current_col - max_previous_col == 1 + current_col <- max_previous_col + current_col + } + if (is_aligned) { # if left aligned after , start_eval <- 2 } } if (is_aligned) { - previous_line <- previous_line + nchar(by_line) + previous_line <- current_col next } - # check 3: match by = (no extra spaces around it allowed.) + # check 3: match by = (no extra spaces around it allowed) # match left aligned after = start_after_eq <- regexpr("= [^ ]", by_line) names(start_after_eq) <- names(by_line) @@ -145,14 +162,17 @@ token_is_on_aligned_line <- function(pd_flat) { if (length(start_after_eq) == 0) { return(FALSE) } - # when match via comma unsuccessful, matching by = must yield at least one = + # when match via , unsuccessful, matching by = must yield at least one = if (column == 1) { current_col <- start_after_eq } else { current_col <- start_after_eq + previous_line[intersect(names(previous_line), names(start_after_eq))] } - is_aligned <- length(unique(current_col)) == 1 && length(start_after_eq) > 1 + is_aligned <- all( + length(unique(current_col)) == 1, + length(start_after_eq) > 1 + ) if (!is_aligned) { return(FALSE) } diff --git a/tests/testthat/alignment/cols-with-one-row-in.R b/tests/testthat/alignment/cols-with-one-row-in.R new file mode 100644 index 000000000..a4d47da45 --- /dev/null +++ b/tests/testthat/alignment/cols-with-one-row-in.R @@ -0,0 +1,16 @@ +c( + "x", "z", + "cgjhg", "thi", "z" +) + + +c( + "x", "z", + "cgjhg", "thi", "z" +) + + +c( + "x", "y", "z", "m", "n", "o", "p", + "c", "d" +) diff --git a/tests/testthat/alignment/cols-with-one-row-in_tree b/tests/testthat/alignment/cols-with-one-row-in_tree new file mode 100644 index 000000000..f821af25e --- /dev/null +++ b/tests/testthat/alignment/cols-with-one-row-in_tree @@ -0,0 +1,73 @@ +ROOT (token: short_text [lag_newlines/spaces] {pos_id}) + ¦--expr: c( + [0/0] {1} + ¦ ¦--expr: c [0/0] {3} + ¦ ¦ °--SYMBOL_FUNCTION_CALL: c [0/0] {2} + ¦ ¦--'(': ( [0/2] {4} + ¦ ¦--expr: "x" [1/0] {6} + ¦ ¦ °--STR_CONST: "x" [0/0] {5} + ¦ ¦--',': , [0/7] {7} + ¦ ¦--expr: "z" [0/0] {9} + ¦ ¦ °--STR_CONST: "z" [0/0] {8} + ¦ ¦--',': , [0/2] {10} + ¦ ¦--expr: "cgjh [1/0] {12} + ¦ ¦ °--STR_CONST: "cgjh [0/0] {11} + ¦ ¦--',': , [0/1] {13} + ¦ ¦--expr: "thi" [0/0] {15} + ¦ ¦ °--STR_CONST: "thi" [0/0] {14} + ¦ ¦--',': , [0/1] {16} + ¦ ¦--expr: "z" [0/0] {18} + ¦ ¦ °--STR_CONST: "z" [0/0] {17} + ¦ °--')': ) [1/0] {19} + ¦--expr: c( + [3/0] {20} + ¦ ¦--expr: c [0/0] {22} + ¦ ¦ °--SYMBOL_FUNCTION_CALL: c [0/0] {21} + ¦ ¦--'(': ( [0/2] {23} + ¦ ¦--expr: "x" [1/0] {25} + ¦ ¦ °--STR_CONST: "x" [0/0] {24} + ¦ ¦--',': , [0/7] {26} + ¦ ¦--expr: "z" [0/0] {28} + ¦ ¦ °--STR_CONST: "z" [0/0] {27} + ¦ ¦--',': , [0/2] {29} + ¦ ¦--expr: "cgjh [1/0] {31} + ¦ ¦ °--STR_CONST: "cgjh [0/0] {30} + ¦ ¦--',': , [0/2] {32} + ¦ ¦--expr: "thi" [0/0] {34} + ¦ ¦ °--STR_CONST: "thi" [0/0] {33} + ¦ ¦--',': , [0/1] {35} + ¦ ¦--expr: "z" [0/0] {37} + ¦ ¦ °--STR_CONST: "z" [0/0] {36} + ¦ °--')': ) [1/0] {38} + °--expr: c( + [3/0] {39} + ¦--expr: c [0/0] {41} + ¦ °--SYMBOL_FUNCTION_CALL: c [0/0] {40} + ¦--'(': ( [0/2] {42} + ¦--expr: "x" [1/0] {44} + ¦ °--STR_CONST: "x" [0/0] {43} + ¦--',': , [0/1] {45} + ¦--expr: "y" [0/0] {47} + ¦ °--STR_CONST: "y" [0/0] {46} + ¦--',': , [0/1] {48} + ¦--expr: "z" [0/0] {50} + ¦ °--STR_CONST: "z" [0/0] {49} + ¦--',': , [0/2] {51} + ¦--expr: "m" [0/0] {53} + ¦ °--STR_CONST: "m" [0/0] {52} + ¦--',': , [0/1] {54} + ¦--expr: "n" [0/0] {56} + ¦ °--STR_CONST: "n" [0/0] {55} + ¦--',': , [0/2] {57} + ¦--expr: "o" [0/0] {59} + ¦ °--STR_CONST: "o" [0/0] {58} + ¦--',': , [0/1] {60} + ¦--expr: "p" [0/0] {62} + ¦ °--STR_CONST: "p" [0/0] {61} + ¦--',': , [0/2] {63} + ¦--expr: "c" [1/0] {65} + ¦ °--STR_CONST: "c" [0/0] {64} + ¦--',': , [0/1] {66} + ¦--expr: "d" [0/0] {68} + ¦ °--STR_CONST: "d" [0/0] {67} + °--')': ) [1/0] {69} diff --git a/tests/testthat/alignment/cols-with-one-row-out.R b/tests/testthat/alignment/cols-with-one-row-out.R new file mode 100644 index 000000000..30893a93e --- /dev/null +++ b/tests/testthat/alignment/cols-with-one-row-out.R @@ -0,0 +1,16 @@ +c( + "x", "z", + "cgjhg", "thi", "z" +) + + +c( + "x", "z", + "cgjhg", "thi", "z" +) + + +c( + "x", "y", "z", "m", "n", "o", "p", + "c", "d" +) diff --git a/tests/testthat/alignment/named-in.R b/tests/testthat/alignment/named-in.R index 1349ffae6..3a4eacf4e 100644 --- a/tests/testthat/alignment/named-in.R +++ b/tests/testthat/alignment/named-in.R @@ -57,7 +57,7 @@ call( # algorithm: aligned. human: aligned. call( x = 1, - xy = 2, n = 33, z = "333" + xy = 2, n = 33, z = "333" ) # algorithm: aligned. human: aligned. diff --git a/tests/testthat/alignment/named-in_tree b/tests/testthat/alignment/named-in_tree index 90283b1c8..2a569ab09 100644 --- a/tests/testthat/alignment/named-in_tree +++ b/tests/testthat/alignment/named-in_tree @@ -255,8 +255,8 @@ ROOT (token: short_text [lag_newlines/spaces] {pos_id}) ¦ ¦--EQ_SUB: = [0/1] {254} ¦ ¦--expr: 2 [0/0] {256} ¦ ¦ °--NUM_CONST: 2 [0/0] {255} - ¦ ¦--',': , [0/3] {257} - ¦ ¦--SYMBOL_SUB: n [0/4] {258} + ¦ ¦--',': , [0/1] {257} + ¦ ¦--SYMBOL_SUB: n [0/1] {258} ¦ ¦--EQ_SUB: = [0/1] {259} ¦ ¦--expr: 33 [0/0] {261} ¦ ¦ °--NUM_CONST: 33 [0/0] {260} diff --git a/tests/testthat/alignment/named-out.R b/tests/testthat/alignment/named-out.R index 7fda760a3..5fd8e9507 100644 --- a/tests/testthat/alignment/named-out.R +++ b/tests/testthat/alignment/named-out.R @@ -57,7 +57,7 @@ call( # algorithm: aligned. human: aligned. call( x = 1, - xy = 2, n = 33, z = "333" + xy = 2, n = 33, z = "333" ) # algorithm: aligned. human: aligned.