diff --git a/R/glue.R b/R/glue.R index 3cc96688b..22ba1d069 100644 --- a/R/glue.R +++ b/R/glue.R @@ -130,8 +130,15 @@ collapse_head_notrim <- function(x, trunc, sep, sep2, last, ellipsis) { lnx <- length(x) - if (lnx == 1L) return(x) - if (lnx == 2L) return(paste0(x, collapse = sep2)) + if (lnx == 1L) + return(x) + if (lnx == 2L) { + # Handle the case where last is changed and sep2 is not + if (sep2 == " and " & last != ", and ") + return(paste0(x, collapse = last)) + else + return(paste0(x, collapse = sep2)) + } if (lnx <= trunc) { # no truncation return(paste0( diff --git a/tests/testthat/_snaps/collapsing.md b/tests/testthat/_snaps/collapsing.md index 6d5583385..e9b5421f9 100644 --- a/tests/testthat/_snaps/collapsing.md +++ b/tests/testthat/_snaps/collapsing.md @@ -455,3 +455,22 @@ Output [1] "a, b, c, d, e, f, g, h, i, and j" +# Issue #681 + + Code + v <- cli::cli_vec(c("foo", "bar", "foobar"), style = list(`vec-last` = ", or ")) + cli::cli_text("Must be one of: {v}.") + Message + Must be one of: foo, bar, or foobar. + Code + v <- cli::cli_vec(c("foo", "bar"), style = list(`vec-last` = " or ")) + cli::cli_text("Must be one of: {v}.") + Message + Must be one of: foo or bar. + Code + v <- cli::cli_vec(c("foo", "bar"), style = list(`vec-last` = " or ", + `vec-sep2` = " xor ")) + cli::cli_text("Must be one of: {v}.") + Message + Must be one of: foo xor bar. + diff --git a/tests/testthat/test-collapsing.R b/tests/testthat/test-collapsing.R index 4923dcc3e..2a567cc5c 100644 --- a/tests/testthat/test-collapsing.R +++ b/tests/testthat/test-collapsing.R @@ -197,3 +197,30 @@ test_that("ansi_collapse uses `sep2` for length-two inputs", { expect_equal(ansi_collapse(1:2, trunc = 2, style = "head"), "1 and 2") }) + + +test_that("Issue #681", { + expect_equal(ansi_collapse(1:2, last = " or "), "1 or 2") + expect_equal(ansi_collapse(1:2, sep2 = " and ", last = " or "), "1 or 2") + expect_equal(ansi_collapse(1:2, sep2 = " xor ", last = " or "), "1 xor 2") + + expect_snapshot({ + v <- cli::cli_vec( + c("foo", "bar", "foobar"), + style = list("vec-last" = ", or ") + ) + cli::cli_text("Must be one of: {v}.") + + v <- cli::cli_vec( + c("foo", "bar"), + style = list("vec-last" = " or ") + ) + cli::cli_text("Must be one of: {v}.") + + v <- cli::cli_vec( + c("foo", "bar"), + style = list("vec-last" = " or ", "vec-sep2" = " xor ") + ) + cli::cli_text("Must be one of: {v}.") + }) +})