From 7baac8331ec2bbf6cf59bbe00b950eb38b923aaa Mon Sep 17 00:00:00 2001 From: taekop Date: Fri, 2 Oct 2026 13:46:11 +0900 Subject: [PATCH] Respect width in ansi_collapse(style = "head") when no element fits --- NEWS.md | 3 +++ R/glue.R | 2 +- tests/testthat/test-collapsing.R | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 1de8df2fe..2731f85b2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -40,6 +40,9 @@ * Fix issues with `ansi_strwrap()` having `\r` in the string (#667) +* `ansi_collapse(style = "head")` no longer exceeds `width` when not even + the first element fits (#570, @taekop). + # cli 3.6.6 * New `{.num}` and `{.bytes}` inline styles to format numbers diff --git a/R/glue.R b/R/glue.R index 84b2b6db9..fefd9d70c 100644 --- a/R/glue.R +++ b/R/glue.R @@ -245,7 +245,7 @@ collapse_head <- function(x, sep, sep2, last, trunc, width, ellipsis) { } else if (well == width) { return(ellipsis) } else if (well + wsep >= width) { - return(paste0(ansi_strtrim(x[1L], width, ellipsis = ""), ellipsis)) + return(paste0(ansi_strtrim(x[1L], width - well, ellipsis = ""), ellipsis)) } else { return(paste0( ansi_strtrim(x[1L], max(width - well - wsep, 0L), ellipsis = ellipsis), diff --git a/tests/testthat/test-collapsing.R b/tests/testthat/test-collapsing.R index 0ae11c2b8..4b9e6fdc8 100644 --- a/tests/testthat/test-collapsing.R +++ b/tests/testthat/test-collapsing.R @@ -189,6 +189,22 @@ test_that("ansi_collapse with width trimming", { }) }) +test_that("ansi_collapse with style = 'head' never exceeds width (#570)", { + x <- c("loooooooong", "healthy live the Penguin") + expect_equal(ansi_collapse(x, width = 4, style = "head"), "l...") + expect_equal(ansi_collapse(x, width = 5, style = "head"), "lo...") + expect_equal( + ansi_collapse(x, width = 2, style = "head", ellipsis = "\u2026"), + "l\u2026" + ) + for (width in 0:30) { + expect_lte( + ansi_nchar(ansi_collapse(x, width = width, style = "head")), + width + ) + } +}) + test_that("ansi_collapse produces consistent truncation results", { expect_equal( ansi_collapse(1:2, trunc = 1, style = "head"),