From f4fbb991b79d550b2faba0c14be7439dfea52e1b Mon Sep 17 00:00:00 2001 From: James Laird-Smith Date: Mon, 4 Aug 2025 09:18:29 +0100 Subject: [PATCH] New bullet styles for TODOs and questions --- NEWS.md | 3 ++ R/bullets.R | 6 +++- R/themes.R | 8 +++++ tests/testthat/_snaps/bullets.md | 60 +++++++++++++++++++++++++------- tests/testthat/test-bullets.R | 12 +++++-- 5 files changed, 73 insertions(+), 16 deletions(-) diff --git a/NEWS.md b/NEWS.md index d874a0108..b5109e522 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,9 @@ * New `{.num}` and `{.bytes}` inline styles to format numbers and bytes (@m-muecke, #644, #588, #643). + +* New bullet styles for TODOs ("[]") and questions ("?") + (@jameslairdsmith, #779). # cli 3.6.5 diff --git a/R/bullets.R b/R/bullets.R index 008d10713..3f86ce88e 100644 --- a/R/bullets.R +++ b/R/bullets.R @@ -22,6 +22,8 @@ #' * `x`: Item with a ref cross, like [cli_alert_danger()]. #' * `!`: Item with a yellow exclamation mark, like [cli_alert_warning()]. #' * `i`: Info item, like [cli_alert_info()]. +#' * `[]`: TODO item. +#' * `?`: Question item. #' #' You can define new item type by simply defining theming for the #' corresponding `bullet-` classes. @@ -35,7 +37,9 @@ #' "v" = "success", #' "x" = "danger", #' "!" = "warning", -#' "i" = "info" +#' "i" = "info", +#' "[]"= "TODO", +#' "?" = "question #' )) #' ``` #' diff --git a/R/themes.R b/R/themes.R index 0c913d7f4..8394d460d 100644 --- a/R/themes.R +++ b/R/themes.R @@ -149,6 +149,14 @@ builtin_theme <- function(dark = getOption("cli.theme_dark", "auto")) { "text-exdent" = 2, before = function(x) paste0(col_cyan(symbol$info), " ") ), + ".bullets .bullet-?" = list( + "text-exdent" = 2, + before = function(x) paste0(col_red(symbol$fancy_question_mark), " ") + ), + ".bullets .bullet-[]" = list( + "text-exdent" = 2, + before = function(x) paste0(col_red(symbol$checkbox_off), " ") + ), ".bullets .bullet-*" = list( "text-exdent" = 2, before = function(x) paste0(col_cyan(symbol$bullet), " ") diff --git a/tests/testthat/_snaps/bullets.md b/tests/testthat/_snaps/bullets.md index 5894a74d8..cbde86276 100644 --- a/tests/testthat/_snaps/bullets.md +++ b/tests/testthat/_snaps/bullets.md @@ -2,7 +2,7 @@ Code cli_bullets(c("noindent", ` ` = "space", v = "success", x = "danger", `!` = "warning", - i = "info", `*` = "bullet", `>` = "arrow")) + i = "info", `*` = "bullet", `>` = "arrow", `[]` = "TODO", `?` = "question")) Message noindent space @@ -12,12 +12,14 @@ i info * bullet > arrow + [ ] TODO + (?) question # bullets [ansi] Code cli_bullets(c("noindent", ` ` = "space", v = "success", x = "danger", `!` = "warning", - i = "info", `*` = "bullet", `>` = "arrow")) + i = "info", `*` = "bullet", `>` = "arrow", `[]` = "TODO", `?` = "question")) Message noindent space @@ -27,12 +29,14 @@ i info * bullet > arrow + [ ] TODO + (?) question # bullets [unicode] Code cli_bullets(c("noindent", ` ` = "space", v = "success", x = "danger", `!` = "warning", - i = "info", `*` = "bullet", `>` = "arrow")) + i = "info", `*` = "bullet", `>` = "arrow", `[]` = "TODO", `?` = "question")) Message noindent space @@ -42,12 +46,14 @@ ℹ info • bullet → arrow + ☐ TODO + ❓ question # bullets [fancy] Code cli_bullets(c("noindent", ` ` = "space", v = "success", x = "danger", `!` = "warning", - i = "info", `*` = "bullet", `>` = "arrow")) + i = "info", `*` = "bullet", `>` = "arrow", `[]` = "TODO", `?` = "question")) Message noindent space @@ -57,13 +63,16 @@ ℹ info • bullet → arrow + ☐ TODO + ❓ question # bullets glue [plain] Code cli_bullets(c("noindent {.key {1:3}}", ` ` = "space {.key {1:3}}", v = "success {.key {1:3}}", x = "danger {.key {1:3}}", `!` = "warning {.key {1:3}}", i = "info {.key {1:3}}", - `*` = "bullet {.key {1:3}}", `>` = "arrow {.key {1:3}}")) + `*` = "bullet {.key {1:3}}", `>` = "arrow {.key {1:3}}", `[]` = "TODO {.key {1:3}}", + `?` = "question {.key {1:3}}")) Message noindent [1], [2], and [3] space [1], [2], and [3] @@ -73,13 +82,16 @@ i info [1], [2], and [3] * bullet [1], [2], and [3] > arrow [1], [2], and [3] + [ ] TODO [1], [2], and [3] + (?) question [1], [2], and [3] # bullets glue [ansi] Code cli_bullets(c("noindent {.key {1:3}}", ` ` = "space {.key {1:3}}", v = "success {.key {1:3}}", x = "danger {.key {1:3}}", `!` = "warning {.key {1:3}}", i = "info {.key {1:3}}", - `*` = "bullet {.key {1:3}}", `>` = "arrow {.key {1:3}}")) + `*` = "bullet {.key {1:3}}", `>` = "arrow {.key {1:3}}", `[]` = "TODO {.key {1:3}}", + `?` = "question {.key {1:3}}")) Message noindent [1], [2], and [3] space [1], [2], and [3] @@ -89,13 +101,16 @@ i info [1], [2], and [3] * bullet [1], [2], and [3] > arrow [1], [2], and [3] + [ ] TODO [1], [2], and [3] + (?) question [1], [2], and [3] # bullets glue [unicode] Code cli_bullets(c("noindent {.key {1:3}}", ` ` = "space {.key {1:3}}", v = "success {.key {1:3}}", x = "danger {.key {1:3}}", `!` = "warning {.key {1:3}}", i = "info {.key {1:3}}", - `*` = "bullet {.key {1:3}}", `>` = "arrow {.key {1:3}}")) + `*` = "bullet {.key {1:3}}", `>` = "arrow {.key {1:3}}", `[]` = "TODO {.key {1:3}}", + `?` = "question {.key {1:3}}")) Message noindent [1], [2], and [3] space [1], [2], and [3] @@ -105,13 +120,16 @@ ℹ info [1], [2], and [3] • bullet [1], [2], and [3] → arrow [1], [2], and [3] + ☐ TODO [1], [2], and [3] + ❓ question [1], [2], and [3] # bullets glue [fancy] Code cli_bullets(c("noindent {.key {1:3}}", ` ` = "space {.key {1:3}}", v = "success {.key {1:3}}", x = "danger {.key {1:3}}", `!` = "warning {.key {1:3}}", i = "info {.key {1:3}}", - `*` = "bullet {.key {1:3}}", `>` = "arrow {.key {1:3}}")) + `*` = "bullet {.key {1:3}}", `>` = "arrow {.key {1:3}}", `[]` = "TODO {.key {1:3}}", + `?` = "question {.key {1:3}}")) Message noindent [1], [2], and [3] space [1], [2], and [3] @@ -121,12 +139,14 @@ ℹ info [1], [2], and [3] • bullet [1], [2], and [3] → arrow [1], [2], and [3] + ☐ TODO [1], [2], and [3] + ❓ question [1], [2], and [3] # bullets wrapping [plain] Code cli_bullets(c(txt, ` ` = txt, v = txt, x = txt, `!` = txt, i = txt, `*` = txt, - `>` = txt)) + `>` = txt, `[]` = txt, `?` = txt)) Message This is some text that is longer than the width. This is some text that is longer than the width. This is some text that is longer than the width. @@ -144,12 +164,16 @@ longer than the width. This is some text that is longer than the width. > This is some text that is longer than the width. This is some text that is longer than the width. This is some text that is longer than the width. + [ ] This is some text that is longer than the width. This is some text that is + longer than the width. This is some text that is longer than the width. + (?) This is some text that is longer than the width. This is some text that is + longer than the width. This is some text that is longer than the width. # bullets wrapping [ansi] Code cli_bullets(c(txt, ` ` = txt, v = txt, x = txt, `!` = txt, i = txt, `*` = txt, - `>` = txt)) + `>` = txt, `[]` = txt, `?` = txt)) Message This is some text that is longer than the width. This is some text that is longer than the width. This is some text that is longer than the width. @@ -167,12 +191,16 @@ longer than the width. This is some text that is longer than the width. > This is some text that is longer than the width. This is some text that is longer than the width. This is some text that is longer than the width. + [ ] This is some text that is longer than the width. This is some text that is + longer than the width. This is some text that is longer than the width. + (?) This is some text that is longer than the width. This is some text that is + longer than the width. This is some text that is longer than the width. # bullets wrapping [unicode] Code cli_bullets(c(txt, ` ` = txt, v = txt, x = txt, `!` = txt, i = txt, `*` = txt, - `>` = txt)) + `>` = txt, `[]` = txt, `?` = txt)) Message This is some text that is longer than the width. This is some text that is longer than the width. This is some text that is longer than the width. @@ -190,12 +218,16 @@ longer than the width. This is some text that is longer than the width. → This is some text that is longer than the width. This is some text that is longer than the width. This is some text that is longer than the width. + ☐ This is some text that is longer than the width. This is some text that is + longer than the width. This is some text that is longer than the width. + ❓ This is some text that is longer than the width. This is some text that is + longer than the width. This is some text that is longer than the width. # bullets wrapping [fancy] Code cli_bullets(c(txt, ` ` = txt, v = txt, x = txt, `!` = txt, i = txt, `*` = txt, - `>` = txt)) + `>` = txt, `[]` = txt, `?` = txt)) Message This is some text that is longer than the width. This is some text that is longer than the width. This is some text that is longer than the width. @@ -213,4 +245,8 @@ longer than the width. This is some text that is longer than the width. → This is some text that is longer than the width. This is some text that is longer than the width. This is some text that is longer than the width. + ☐ This is some text that is longer than the width. This is some text that is + longer than the width. This is some text that is longer than the width. + ❓ This is some text that is longer than the width. This is some text that is + longer than the width. This is some text that is longer than the width. diff --git a/tests/testthat/test-bullets.R b/tests/testthat/test-bullets.R index dfc291992..8a166e803 100644 --- a/tests/testthat/test-bullets.R +++ b/tests/testthat/test-bullets.R @@ -10,7 +10,9 @@ test_that_cli("bullets", { "!" = "warning", "i" = "info", "*" = "bullet", - ">" = "arrow" + ">" = "arrow", + "[]"= "TODO", + "?" = "question" ))) }) @@ -23,7 +25,9 @@ test_that_cli("bullets glue", { "!" = "warning {.key {1:3}}", "i" = "info {.key {1:3}}", "*" = "bullet {.key {1:3}}", - ">" = "arrow {.key {1:3}}" + ">" = "arrow {.key {1:3}}", + "[]"= "TODO {.key {1:3}}", + "?" = "question {.key {1:3}}" ))) }) @@ -37,6 +41,8 @@ test_that_cli("bullets wrapping", { "!" = txt, "i" = txt, "*" = txt, - ">" = txt + ">" = txt, + "[]"= txt, + "?" = txt ))) })