跳到主要内容
ansicode
Ruby

在 Ruby 中使用 ANSI 转义码

Ruby 的双引号字符串支持 `\e` 作为 ESC 字面(无需写 `\x1b` 或 `\033`),`puts` / `print` / `STDOUT.write` 在所有平台都按字节透传。Ruby 3.0+ 在 Windows 上自动为标准流启用 `ENABLE_VIRTUAL_TERMINAL_PROCESSING`,因此 `\e[31m` 在 Conhost 与 Windows Terminal 上无需 `colorama` 类适配层即可生效。 人体工学方面:`colorize` 在 `String` 上注入链式颜色方法(`"oops".red.bold`);`term-ansicolor`(Florian Frank 的经典 gem —— `pry`、`rspec` 的底层)同时提供模块调用(`Term::ANSIColor.red(...)`)与混入两种形态;`pastel`(TTY 工具包)将 SGR 辅助封装在独立模块,自动检测 `NO_COLOR` 与 `CLICOLOR_FORCE`,不污染 `String`。完整 TUI 请用 TTY 工具包其余组件 —— `tty-prompt`、`tty-spinner`、`tty-cursor`、`tty-progressbar`。

推荐库

  • colorize

    在 `String` 上注入链式颜色方法 —— `"oops".red.bold.on_white`。下载量约 3000 万,单脚本与 Rakefile 输出的首选。支持 8 个命名颜色 + 通过 `colorize(color: :red, mode: :bold, background: :white)` 使用扩展调色板。

  • term-ansicolor

    Florian Frank 的经典 gem(自 2009 起维护)—— 既支持模块调用(`Term::ANSIColor.red("text")`),也支持混入风格(`include Term::ANSIColor; red("text")`)。`pry`、`rspec`、`cucumber` 及大量 Ruby CLI 工具的底层。1.7.0 起遵守 `NO_COLOR`。

  • pastel

    模块内封装的 SGR 辅助 —— `Pastel.new.red.bold("oops")`,不污染 `String`。TTY 工具包推荐的颜色层;`Pastel.new(enabled: nil)` 自动通过 `tty?` + `NO_COLOR` + `CLICOLOR_FORCE` 检测能力。支持装饰器(`pastel.decorate("text", :red, :bold)`)以及 256 色 `on_<color>` 链式调用。

  • tty-prompt

    交互式提示 —— `select`、`ask`、`multi_select`、`mask`(密码)、`yes?`/`no?`,外观抛光、支持键盘导航。与 `tty-spinner`、`tty-progressbar`、`tty-cursor` 配套构成完整 TUI 栈。Hanami、Pry、Bundler 风格安装器与 Foreman 都在用。

常用写法

直接 puts —— \e 是 Ruby 的 ESC 字面
puts "\e[1;31merror:\e[0m permission denied"
用 colorize 实现链式颜色
require 'colorize'

puts "error:".red.bold + " permission denied"
puts "ok".green
puts "deprecated".yellow.on_black
用 pastel 做能力感知样式 —— NO_COLOR / CLICOLOR_FORCE
require 'pastel'

# Pastel.new(enabled: nil) auto-detects:
#   STDOUT.tty? AND NO_COLOR not set AND CLICOLOR != '0'
#   CLICOLOR_FORCE=1 forces colour even when redirected.
pastel = Pastel.new

puts "#{pastel.red.bold('error:')} permission denied"
puts pastel.decorate('lavender truecolor', :on_blue, :bold)

# Disable globally — e.g. in CI:
plain = Pastel.new(enabled: false)
puts plain.red('this prints as plain text')
原地进度 —— CR + EL + 隐藏光标
STDOUT.print "\e[?25l"               # hide cursor
at_exit { STDOUT.print "\e[?25h" }   # restore on any exit path

100.times do |i|
  # \r returns to col 1, \e[K erases to end of line
  STDOUT.print "\r\e[K#{i + 1}% complete"
  STDOUT.flush
  sleep 0.02
end
puts

相关序列

其他语言