cli

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CLI for R Packages

面向R包的CLI工具

When to Use What

场景与对应用法

task: Display error with context and formatting use:
cli_abort()
with inline markup and bullet lists
task: Show warning with formatting use:
cli_warn()
with inline markup
task: Display informative message use:
cli_inform()
with inline markup
task: Show progress for counted operations use:
cli_progress_bar()
with total count
task: Show simple progress steps use:
cli_progress_step()
with status messages
task: Format code or function names use:
{.code ...}
or
{.fn package::function}
task: Format file paths use:
{.file path/to/file}
task: Format package names use:
{.pkg packagename}
task: Format variable names use:
{.var variable_name}
task: Format values use:
{.val value}
task: Handle singular/plural text use:
{?s}
or
{?y/ies}
with pluralization
task: Create headers use:
cli_h1()
,
cli_h2()
,
cli_h3()
task: Create alerts use:
cli_alert_success()
,
cli_alert_danger()
,
cli_alert_warning()
,
cli_alert_info()
task: Create lists use:
cli_ul()
,
cli_ol()
,
cli_dl()
with
cli_li()
场景:显示带上下文和格式的错误信息 用法:结合内联标记和项目列表使用
cli_abort()
场景:显示带格式的警告信息 用法:结合内联标记使用
cli_warn()
场景:显示提示性消息 用法:结合内联标记使用
cli_inform()
场景:显示计数操作的进度 用法:结合总数量使用
cli_progress_bar()
场景:显示简单的进度步骤 用法:结合状态消息使用
cli_progress_step()
场景:格式化代码或函数名称 用法:使用
{.code ...}
{.fn package::function}
场景:格式化文件路径 用法:使用
{.file path/to/file}
场景:格式化包名称 用法:使用
{.pkg packagename}
场景:格式化变量名称 用法:使用
{.var variable_name}
场景:格式化数值 用法:使用
{.val value}
场景:处理单复数文本 用法:结合复数规则使用
{?s}
{?y/ies}
场景:创建标题 用法:使用
cli_h1()
cli_h2()
cli_h3()
场景:创建提示框 用法:使用
cli_alert_success()
cli_alert_danger()
cli_alert_warning()
cli_alert_info()
场景:创建列表 用法:结合
cli_li()
使用
cli_ul()
cli_ol()
cli_dl()

Inline Markup Essentials

内联标记基础

Use inline markup with
{.class content}
syntax to format text:
r
undefined
使用
{.class content}
语法的内联标记来格式化文本:
r
undefined

Basic formatting

Basic formatting

cli_text("Function {.fn mean} calculates averages") cli_text("Install package {.pkg dplyr}") cli_text("See file {.file ~/.Rprofile}") cli_text("{.var x} must be numeric, not {.obj_type_of {x}}") cli_text("Got value {.val {x}}"))
cli_text("Function {.fn mean} calculates averages") cli_text("Install package {.pkg dplyr}") cli_text("See file {.file ~/.Rprofile}") cli_text("{.var x} must be numeric, not {.obj_type_of {x}}") cli_text("Got value {.val {x}}"))

Code formatting

Code formatting

cli_text("Use {.code sum(x, na.rm = TRUE)}")
cli_text("Use {.code sum(x, na.rm = TRUE)}")

Paths and arguments

Paths and arguments

cli_text("Reading from {.path /data/file.csv}") cli_text("Set {.arg na.rm} to TRUE")
cli_text("Reading from {.path /data/file.csv}") cli_text("Set {.arg na.rm} to TRUE")

Types and classes

Types and classes

cli_text("Object is {.cls data.frame}")
cli_text("Object is {.cls data.frame}")

Emphasis

Emphasis

cli_text("This is {.emph important}") cli_text("This is {.strong critical}")
cli_text("This is {.emph important}") cli_text("This is {.strong critical}")

Fields

Fields

cli_text("The {.field name} field is required")
undefined
cli_text("The {.field name} field is required")
undefined

Vector Collapsing

向量折叠

Vectors are automatically collapsed with commas and "and":
r
pkgs <- c("dplyr", "tidyr", "ggplot2")
cli_text("Installing packages: {.pkg {pkgs}}")
#> Installing packages: dplyr, tidyr, and ggplot2

files <- c("data.csv", "script.R")
cli_text("Found {length(files)} file{?s}: {.file {files}}")
#> Found 2 files: data.csv and script.R
向量会自动用逗号和“and”拼接:
r
pkgs <- c("dplyr", "tidyr", "ggplot2")
cli_text("Installing packages: {.pkg {pkgs}}")
#> Installing packages: dplyr, tidyr, and ggplot2

files <- c("data.csv", "script.R")
cli_text("Found {length(files)} file{?s}: {.file {files}}")
#> Found 2 files: data.csv and script.R

Escaping Braces

大括号转义

Use double braces
{{
and
}}
to escape literal braces:
r
cli_text("Use {{variable}} syntax in glue")
#> Use {variable} syntax in glue
For complete markup reference: See references/inline-markup.md for all 50+ inline classes, edge cases, nesting rules, and advanced patterns.
使用双大括号
{{
}}
来转义字面意义的大括号:
r
cli_text("Use {{variable}} syntax in glue")
#> Use {variable} syntax in glue
完整标记参考:查看references/inline-markup.md获取50+种内联类、边界情况、嵌套规则和高级用法。

Pluralization Basics

复数处理基础

Use
{?}
for pluralization with three patterns:
使用
{?}
实现三种复数处理模式:

Single Alternative

单选项模式

r
nfile <- 1
cli_text("Found {nfile} file{?s}")
#> Found 1 file

nfile <- 3
cli_text("Found {nfile} file{?s}")
#> Found 3 files
r
nfile <- 1
cli_text("Found {nfile} file{?s}")
#> Found 1 file

nfile <- 3
cli_text("Found {nfile} file{?s}")
#> Found 3 files

Two Alternatives

双选项模式

r
ndir <- 1
cli_text("Found {ndir} director{?y/ies}")
#> Found 1 directory

ndir <- 5
cli_text("Found {ndir} director{?y/ies}")
#> Found 5 directories
r
ndir <- 1
cli_text("Found {ndir} director{?y/ies}")
#> Found 1 directory

ndir <- 5
cli_text("Found {ndir} director{?y/ies}")
#> Found 5 directories

Three Alternatives (zero/one/many)

三选项模式(零/一/多)

r
nfile <- 0
cli_text("Found {nfile} file{?s}: {?no/the/the} file{?s}")
#> Found 0 files: no files

nfile <- 1
cli_text("Found {nfile} file{?s}: {?no/the/the} file{?s}")
#> Found 1 file: the file

nfile <- 3
cli_text("Found {nfile} file{?s}: {?no/the/the} file{?s}")
#> Found 3 files: the files
r
nfile <- 0
cli_text("Found {nfile} file{?s}: {?no/the/the} file{?s}")
#> Found 0 files: no files

nfile <- 1
cli_text("Found {nfile} file{?s}: {?no/the/the} file{?s}")
#> Found 1 file: the file

nfile <- 3
cli_text("Found {nfile} file{?s}: {?no/the/the} file{?s}")
#> Found 3 files: the files

Helpers: qty() and no()

辅助函数:qty() 和 no()

Use
no()
to display "no" instead of zero:
r
nfile <- 0
cli_text("Found {no(nfile)} file{?s}")
#> Found no files
Use
qty()
to set quantity explicitly:
r
nupd <- 3
ntotal <- 10
cli_text("{nupd}/{ntotal} {qty(nupd)} file{?s} {?needs/need} updates")
#> 3/10 files need updates
For advanced pluralization: See references/inline-markup.md for edge cases and complex patterns.
使用
no()
在数值为零时显示“no”而非零:
r
nfile <- 0
cli_text("Found {no(nfile)} file{?s}")
#> Found no files
使用
qty()
显式指定数量:
r
nupd <- 3
ntotal <- 10
cli_text("{nupd}/{ntotal} {qty(nupd)} file{?s} {?needs/need} updates")
#> 3/10 files need updates
高级复数处理:查看references/inline-markup.md获取边界情况和复杂模式。

CLI Conditions: Core Patterns

CLI条件:核心模式

Use cli conditions instead of base R for better formatting:
使用cli条件替代基础R函数,实现更优的格式化效果:

cli_abort() - Formatted Errors

cli_abort() - 格式化错误信息

r
undefined
r
undefined

Before (base R)

Before (base R)

stop("File not found: ", path)
stop("File not found: ", path)

After (cli)

After (cli)

cli_abort("File {.file {path}} not found")
cli_abort("File {.file {path}} not found")

With bullets for context

With bullets for context

check_file <- function(path) { if (!file.exists(path)) { cli_abort(c( "File not found", "x" = "Cannot read {.file {path}}", "i" = "Check that the file exists" )) } }
undefined
check_file <- function(path) { if (!file.exists(path)) { cli_abort(c( "File not found", "x" = "Cannot read {.file {path}}", "i" = "Check that the file exists" )) } }
undefined

cli_warn() - Formatted Warnings

cli_warn() - 格式化警告信息

r
undefined
r
undefined

Before (base R)

Before (base R)

warning("Column ", col, " has missing values")
warning("Column ", col, " has missing values")

After (cli)

After (cli)

cli_warn("Column {.field {col}} has missing values")
cli_warn("Column {.field {col}} has missing values")

With context

With context

cli_warn(c( "Data quality issues detected", "!" = "Column {.field {col}} has {n_missing} missing value{?s}", "i" = "Consider using {.fn tidyr::drop_na}" ))
undefined
cli_warn(c( "Data quality issues detected", "!" = "Column {.field {col}} has {n_missing} missing value{?s}", "i" = "Consider using {.fn tidyr::drop_na}" ))
undefined

cli_inform() - Formatted Messages

cli_inform() - 格式化提示消息

r
undefined
r
undefined

Before (base R)

Before (base R)

message("Processing ", n, " files")
message("Processing ", n, " files")

After (cli)

After (cli)

cli_inform("Processing {n} file{?s}")
cli_inform("Processing {n} file{?s}")

With structure

With structure

cli_inform(c( "v" = "Successfully loaded {.pkg dplyr}", "i" = "Version {packageVersion('dplyr')}" ))
undefined
cli_inform(c( "v" = "Successfully loaded {.pkg dplyr}", "i" = "Version {packageVersion('dplyr')}" ))
undefined

Bullet Types

项目符号类型

  • "x"
    - Error/problem (red X)
  • "!"
    - Warning (yellow !)
  • "i"
    - Information (blue i)
  • "v"
    - Success (green checkmark)
  • "*"
    - Bullet point
  • ">"
    - Arrow/pointer
For advanced error design: See references/conditions.md for error design principles, rlang integration, testing strategies, and real-world patterns.
  • "x"
    - 错误/问题(红色叉号)
  • "!"
    - 警告(黄色感叹号)
  • "i"
    - 提示信息(蓝色i)
  • "v"
    - 成功(绿色对勾)
  • "*"
    - 项目符号
  • ">"
    - 箭头/指针
高级错误设计:查看references/conditions.md获取错误设计原则、rlang集成、测试策略和实际场景模式。

Basic Progress Indicators

基础进度指示器

Simple Progress Steps

简单进度步骤

r
process_data <- function() {
  cli_progress_step("Loading data")
  data <- load_data()

  cli_progress_step("Cleaning data")
  clean <- clean_data(data)

  cli_progress_step("Analyzing data")
  analyze(clean)
}
r
process_data <- function() {
  cli_progress_step("Loading data")
  data <- load_data()

  cli_progress_step("Cleaning data")
  clean <- clean_data(data)

  cli_progress_step("Analyzing data")
  analyze(clean)
}

Basic Progress Bar

基础进度条

r
process_files <- function(files) {
  cli_progress_bar("Processing files", total = length(files))

  for (file in files) {
    process_file(file)
    cli_progress_update()
  }
}
r
process_files <- function(files) {
  cli_progress_bar("Processing files", total = length(files))

  for (file in files) {
    process_file(file)
    cli_progress_update()
  }
}

Auto-Cleanup

自动清理

Progress bars auto-close when the function exits:
r
process <- function() {
  cli_progress_bar("Working", total = 100)
  for (i in 1:100) {
    Sys.sleep(0.01)
    cli_progress_update()
  }
  # No need to call cli_progress_done() - auto-closes
}
For advanced progress: See references/progress.md for nested progress, custom formats, parallel processing, all progress variables, and Shiny integration.
进度条会在函数退出时自动关闭:
r
process <- function() {
  cli_progress_bar("Working", total = 100)
  for (i in 1:100) {
    Sys.sleep(0.01)
    cli_progress_update()
  }
  # No need to call cli_progress_done() - auto-closes
}
高级进度处理:查看references/progress.md获取嵌套进度条、自定义格式、并行处理、所有进度变量和Shiny集成。

Semantic CLI Elements

语义化CLI元素

Headers

标题

r
cli_h1("Main Section")
cli_h2("Subsection")
cli_h3("Detail")
r
cli_h1("Main Section")
cli_h2("Subsection")
cli_h3("Detail")

Alerts

提示框

r
cli_alert_success("Operation completed successfully")
cli_alert_danger("Critical error occurred")
cli_alert_warning("Potential issue detected")
cli_alert_info("Additional information available")
r
cli_alert_success("Operation completed successfully")
cli_alert_danger("Critical error occurred")
cli_alert_warning("Potential issue detected")
cli_alert_info("Additional information available")

Text and Code

文本与代码

r
undefined
r
undefined

Regular text with markup

Regular text with markup

cli_text("This is formatted text with {.emph emphasis}")
cli_text("This is formatted text with {.emph emphasis}")

Code blocks

Code blocks

cli_code(c( "library(dplyr)", "mtcars %>% filter(mpg > 20)" ))
cli_code(c( "library(dplyr)", "mtcars %>% filter(mpg > 20)" ))

Verbatim text (no formatting)

Verbatim text (no formatting)

cli_verbatim("This is displayed exactly as-is: {not interpolated}")
undefined
cli_verbatim("This is displayed exactly as-is: {not interpolated}")
undefined

Lists

列表

r
undefined
r
undefined

Unordered list

Unordered list

cli_ul() cli_li("First item") cli_li("Second item") cli_end()
cli_ul() cli_li("First item") cli_li("Second item") cli_end()

Ordered list

Ordered list

cli_ol() cli_li("First step") cli_li("Second step") cli_end()
cli_ol() cli_li("First step") cli_li("Second step") cli_end()

Definition list

Definition list

cli_dl() cli_li(c(name = "The name field")) cli_li(c(email = "The email address")) cli_end()
undefined
cli_dl() cli_li(c(name = "The name field")) cli_li(c(email = "The email address")) cli_end()
undefined

Common Workflows

常见工作流

Base R to CLI Migration

从基础R迁移到CLI

r
undefined
r
undefined

Before: Base R error handling

Before: Base R error handling

validate_input <- function(x, y) { if (!is.numeric(x)) { stop("x must be numeric") } if (length(y) == 0) { stop("y cannot be empty") } if (length(x) != length(y)) { stop("x and y must have the same length") } }
validate_input <- function(x, y) { if (!is.numeric(x)) { stop("x must be numeric") } if (length(y) == 0) { stop("y cannot be empty") } if (length(x) != length(y)) { stop("x and y must have the same length") } }

After: CLI error handling

After: CLI error handling

validate_input <- function(x, y) { if (!is.numeric(x)) { cli_abort(c( "{.arg x} must be numeric", "x" = "You supplied a {.cls {class(x)}} vector", "i" = "Use {.fn as.numeric} to convert" )) }
if (length(y) == 0) { cli_abort(c( "{.arg y} cannot be empty", "i" = "Provide at least one element" )) }
if (length(x) != length(y)) { cli_abort(c( "{.arg x} and {.arg y} must have the same length", "x" = "{.arg x} has length {length(x)}", "x" = "{.arg y} has length {length(y)}" )) } }
undefined
validate_input <- function(x, y) { if (!is.numeric(x)) { cli_abort(c( "{.arg x} must be numeric", "x" = "You supplied a {.cls {class(x)}} vector", "i" = "Use {.fn as.numeric} to convert" )) }
if (length(y) == 0) { cli_abort(c( "{.arg y} cannot be empty", "i" = "Provide at least one element" )) }
if (length(x) != length(y)) { cli_abort(c( "{.arg x} and {.arg y} must have the same length", "x" = "{.arg x} has length {length(x)}", "x" = "{.arg y} has length {length(y)}" )) } }
undefined

Error Message with Rich Context

带丰富上下文的错误消息

r
check_required_columns <- function(data, required_cols) {
  actual_cols <- names(data)
  missing_cols <- setdiff(required_cols, actual_cols)

  if (length(missing_cols) > 0) {
    cli_abort(c(
      "Required column{?s} missing from data",
      "x" = "Missing {length(missing_cols)} column{?s}: {.field {missing_cols}}",
      "i" = "Data has {length(actual_cols)} column{?s}: {.field {actual_cols}}",
      "i" = "Add the missing column{?s} or check for typos"
    ))
  }

  invisible(data)
}
r
check_required_columns <- function(data, required_cols) {
  actual_cols <- names(data)
  missing_cols <- setdiff(required_cols, actual_cols)

  if (length(missing_cols) > 0) {
    cli_abort(c(
      "Required column{?s} missing from data",
      "x" = "Missing {length(missing_cols)} column{?s}: {.field {missing_cols}}",
      "i" = "Data has {length(actual_cols)} column{?s}: {.field {actual_cols}}",
      "i" = "Add the missing column{?s} or check for typos"
    ))
  }

  invisible(data)
}

Function with Progress Bar

带进度条的函数

r
process_files <- function(files, verbose = TRUE) {
  n <- length(files)

  if (verbose) {
    cli_progress_bar(
      format = "Processing {cli::pb_bar} {cli::pb_current}/{cli::pb_total} [{cli::pb_eta}]",
      total = n
    )
  }

  results <- vector("list", n)

  for (i in seq_along(files)) {
    results[[i]] <- process_file(files[[i]])

    if (verbose) {
      cli_progress_update()
    }
  }

  results
}
r
process_files <- function(files, verbose = TRUE) {
  n <- length(files)

  if (verbose) {
    cli_progress_bar(
      format = "Processing {cli::pb_bar} {cli::pb_current}/{cli::pb_total} [{cli::pb_eta}]",
      total = n
    )
  }

  results <- vector("list", n)

  for (i in seq_along(files)) {
    results[[i]] <- process_file(files[[i]])

    if (verbose) {
      cli_progress_update()
    }
  }

  results
}

Resources & Advanced Topics

资源与高级主题

Reference Files

参考文档

  • references/inline-markup.md - Complete catalog of inline classes organized by category, advanced patterns, nesting rules, and real-world examples
  • references/conditions.md - Advanced error design patterns, rlang integration, testing with testthat snapshots, migration guide, and anti-patterns
  • references/progress.md - Nested progress bars, custom formats, all progress variables, parallel processing, Shiny integration, and debugging
  • references/themes.md - Complete theming system with CSS-like selectors, container functions, color palettes, custom themes, and accessibility
  • references/ansi-operations.md - ANSI string operations (align, columns, nchar, etc.), hyperlinks, color detection, testing CLI output, and troubleshooting
  • references/inline-markup.md - 按类别整理的完整内联类目录、高级模式、嵌套规则和实际场景示例
  • references/conditions.md - 高级错误设计模式、rlang集成、testthat快照测试、迁移指南和反模式
  • references/progress.md - 嵌套进度条、自定义格式、所有进度变量、并行处理、Shiny集成和调试
  • references/themes.md - 完整的主题系统,包含类CSS选择器、容器函数、调色板、自定义主题和可访问性
  • references/ansi-operations.md - ANSI字符串操作(对齐、列、字符数等)、超链接、颜色检测、CLI输出测试和故障排除

External Resources

外部资源

Related Packages

相关包

  • rlang - Condition handling and error objects integrate with cli
  • glue - String interpolation powers cli's
    {}
    syntax
  • testthat - Snapshot testing for cli output
  • rlang - 条件处理和错误对象与cli集成
  • glue - 字符串插值为cli的
    {}
    语法提供支持
  • testthat - 用于cli输出的快照测试