console

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 16, 2026 License: MIT Imports: 16 Imported by: 0

README

console

Lightweight building blocks for polished Go console output.

Go Reference Go Test Go 1.24 or newer Latest tag Coverage Go Report Card

console is a small toolkit for the output layer shared by command-line applications: semantic messages, coordinated writers, ANSI-aware text, composable layout, bordered and compact tables, trees, prompts, loaders, and progress. It is deliberately not a full-screen TUI framework. There is no event loop, raw-mode ownership, command parser, subprocess runner, or logging pipeline to adopt.

Installation

Requires Go 1.24 or newer.

go get github.com/goforj/console

Quick start

package main

import "github.com/goforj/console"

func main() {
	console.Action("Building application")
	// · Building application
	console.Infof("Environment: %s", "development")
	// · Environment: development
	console.Success("Application ready")
	// ✔ Application ready
}

Common operations are available both as package-level helpers and as methods on *Console. The examples lead with the concise package helpers, which use the process-wide default console. Libraries and applications that need isolated writers or independent runtime policy should construct an instance instead. Construction is the only naming exception: package helpers use console.NewLoader and console.NewProgress, while instances use Loader and Progress.

var output bytes.Buffer
color := false

console.SetDefault(console.New(console.Config{
	Stdout:       &output,
	Stderr:       &output,
	ColorEnabled: &color,
}))

console.Warn("Configuration is incomplete")
fmt.Print(output.String())
// ! Configuration is incomplete

Set ColorEnabled explicitly when output policy should ignore environment and TTY detection:

var output bytes.Buffer
forceColor := true
unicode := true
console.SetDefault(console.New(console.Config{
	Stdout:         &output,
	ColorEnabled:   &forceColor,
	UnicodeEnabled: &unicode,
}))
console.Success("ANSI styling is forced")
fmt.Printf("%q\n", output.String())
// "\x1b[32m✔\x1b[0m ANSI styling is forced\n"

What it provides

  • Semantic action, information, success, warning, error, fatal, and debug messages.
  • Plain printing and io.Writer adapters that coordinate with prompts and live displays.
  • Automatic ANSI color policy with NO_COLOR, CLICOLOR, CLICOLOR_FORCE, and TTY awareness.
  • ANSI-aware width, wrapping, end and middle truncation, indentation, and left/right/center padding.
  • Printing and render-only forms of sections, rules, key/value summaries, lists, boxes, tables, and trees.
  • Bordered tables by default, plus one compact form, fixed widths, alignment, wrapping, and ASCII fallbacks.
  • Line-oriented questions, defaults, confirmation, numbered choices, and non-echoed secret input.
  • Concurrency-safe loaders and determinate progress that become stable semantic lines when redirected.
  • Configurable writers, input, marks, terminal hooks, environment lookup, and exit behavior.

Design principles

  • Stay lightweight. The two focused direct dependencies are golang.org/x/term for terminal integration and github.com/rivo/uniseg for grapheme-aware cell measurement.
  • Stay line-oriented. Alternate screens, raw key events, cursor navigation, fuzzy selection, and multiple live widgets belong in a TUI package.
  • Keep output composable. Console owns presentation policy, not structured logging, command routing, or application lifecycle.
  • Prefer durable logs outside a TTY. Loaders and progress never leak carriage returns or erase sequences into redirected output.
  • Treat layout as terminal cells. ANSI sequences are zero-width; combining marks, CJK text, and common emoji are measured for console alignment.
  • Offer one strong default. Options cover common adjustments such as width, compact tables, and alignment without introducing themes or a styling matrix.
  • Make testing ordinary. Writers, input, environment lookup, terminal detection, terminal size, and process exit are injectable.
  • Fail fast on invalid wiring. SetDefault(nil) panics instead of leaving package helpers silently unusable.

Layout

Layout helpers write through a Console. Their RenderSection, RenderRule, RenderKeyValues, RenderList, RenderTree, RenderBox, and RenderTable counterparts return the same presentation without a trailing newline, ready for composition.

color := false
unicode := true
console.SetDefault(console.New(console.Config{
	ColorEnabled:   &color,
	UnicodeEnabled: &unicode,
}))

fmt.Println(console.RenderBox(
	"All services healthy.",
	console.BoxTitle("Status"),
	console.BoxWidth(26),
))
// ┌─ Status ───────────────┐
// │ All services healthy.  │
// └────────────────────────┘

Tables are bordered and content-preserving by default: columns shrink and wrap when needed. TableCompact, TableWidths, TableRightAlign, and TableCenterAlign cover the common presentation changes without exposing a theme system or a large style vocabulary. Trees intentionally have no options beyond the console's Unicode/ASCII policy.

Borders, marks, list bullets, tree connectors, progress bars, and loader frames have ASCII fallbacks. Set UnicodeEnabled to false when targeting a constrained terminal; text measurement remains Unicode-aware.

Loaders and progress

Constructing a loader or progress display has no side effects. Start claims the console's single transient line when animation is possible; another live loader or progress display receives ErrTransientActive.

var output bytes.Buffer
color := false
animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	Stdout:            &output,
	ColorEnabled:      &color,
	UnicodeEnabled:    &unicode,
	AnimationsEnabled: &animations,
}))

loader := console.NewLoader("Downloading modules")
if err := loader.Start(); err != nil {
	console.Error(err.Error())
	return
}
defer loader.Stop()

loader.Update("Verifying modules")
loader.Success("Modules ready")
fmt.Print(output.String())
// · Downloading modules
// ✔ Modules ready

On a terminal a loader animates in place, while progress uses one adaptive bar with a percentage. Narrow terminals fall back to message and percentage. With automatic policy, redirected output and conventional truthy CI environments use only a start line and the final success or error, so captured logs stay useful. AnimationsEnabled can explicitly opt a terminal back into animation.

Representative terminal snapshots are shown below; each display redraws one physical line rather than appending these frames. The last line is the exact Unicode rendering at a width of 14 cells.

⠸ Verifying modules
Packaging release [██████████████░░░░░░░░░░]  60%
Packaging… 60%

Stop, Success, Warn, and Fail are idempotent terminal operations; the first one wins. Complete output lines temporarily clear and redraw the active transient display. Partial Print/Printf output and prompts pause live output until the line completes or input returns.

After Start succeeds, immediately defer loader.Stop() or defer progress.Stop(). An explicit success or failure wins first, while the deferred stop safely releases the transient line on an early return.

Progress follows the same lifecycle: Set, Add, and Update change live state, while Step(current, message) atomically sets the absolute completed amount and message. Use Add for relative increments. Complete, Fail, or Stop finishes it, and the first terminal operation wins. Reaching the total does not implicitly report success.

Prompts

Prompts refuse to read when the configured input and output are not terminals—or when a conventional truthy CI value is present—returning ErrNonInteractive instead of unexpectedly blocking automation. Tests and intentional scripted input can opt in explicitly:

var output bytes.Buffer
interactive := true
color := false
unicode := true
console.SetDefault(console.New(console.Config{
	Stdin:              strings.NewReader("yes\n"),
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	ColorEnabled:       &color,
	UnicodeEnabled:     &unicode,
}))

confirmed, err := console.Confirm("Deploy now", false)
fmt.Printf("%q\n", output.String())
// "› Deploy now [y/N]: "
fmt.Println(confirmed, err)
// true <nil>

The prompt reader is retained for the lifetime of the console, so sequential prompts do not lose input to buffering. While a prompt waits for input, complete writes from other goroutines wait rather than overwrite the live input line.

AskSecret uses terminal password input and never falls back to an echoed line. Tests and custom terminal integrations can inject Config.ReadSecret; the returned value is never printed by the package.

Choose returns the selected value. Use ChooseIndex when the zero-based position is more useful for looking up related configuration.

Output behavior

Action, info, success, warning, and debug messages go to stdout. Error and fatal messages go to stderr. Fatal and Fatalf are the only helpers that exit; their exit function is configurable. Marks follow the capability of their destination, so error styling is decided from stderr independently of stdout.

Color selection follows this precedence:

  1. Config.ColorEnabled when set.
  2. NO_COLOR disables styling.
  3. A nonzero CLICOLOR_FORCE enables styling.
  4. CLICOLOR=0 or TERM=dumb disables styling.
  5. Otherwise the destination must expose a terminal file descriptor with ANSI support.

On Windows, ANSI support is probed without leaving console mode changed. ANSI-bearing writes temporarily enable virtual-terminal processing and restore the original mode before returning.

Debug output is enabled by a nonzero FORJ_DEBUG, APP_DEBUG, or DEBUG value unless Config.DebugEnabled overrides it.

Runnable examples

Example Command
Semantic messages and custom writers go -C examples run ./messages
Boxes, key/value rows, and tables go -C examples run ./layout
Bordered, compact, and ASCII tables go -C examples run ./tables
Redirect-safe loader lifecycle go -C examples run ./loader
Redirect-safe progress lifecycle go -C examples run ./progress
Scripted questions and confirmation go -C examples run ./prompts
Complete deployment lifecycle go -C examples run ./deploy
Actionable validation report go -C examples run ./validation
Machine stdout and status stderr go -C examples run ./ci

API index

Complete declaration documentation is available on pkg.go.dev. The links below open source-comment examples in this README. Package declarations and global helpers come first; Console methods provide the isolated equivalent, while loader and progress lifecycle methods remain on their returned values.

Group Package API Instance and lifecycle API
Boxes Box · BoxColor · BoxOption · BoxPadding · BoxTitle · BoxWidth · RenderBox Console.Box · Console.RenderBox
Layout KV · KeyValue · KeyValueMap · KeyValues · List · NumberedList · RenderKeyValueMap · RenderKeyValues · RenderList · RenderNumberedList · RenderRule · RenderSection · Rule · Section Console.KeyValueMap · Console.KeyValues · Console.List · Console.NumberedList · Console.RenderKeyValueMap · Console.RenderKeyValues · Console.RenderList · Console.RenderNumberedList · Console.RenderRule · Console.RenderSection · Console.Rule · Console.Section
Loaders Loader · NewLoader Console.Loader · Loader.Fail · Loader.Start · Loader.Stop · Loader.Success · Loader.Update · Loader.Warn
Marks ActionMark · DebugMark · ErrorMark · InfoMark · SuccessMark · WarnMark Console.ActionMark · Console.DebugMark · Console.ErrorMark · Console.InfoMark · Console.SuccessMark · Console.WarnMark
Messages Action · Actionf · Debug · Debugf · Error · Errorf · Fatal · Fatalf · Info · Infof · Success · Successf · Warn · Warnf Console.Action · Console.Actionf · Console.Debug · Console.Debugf · Console.Error · Console.Errorf · Console.Fatal · Console.Fatalf · Console.Info · Console.Infof · Console.Success · Console.Successf · Console.Warn · Console.Warnf
Output NewLine · Print · Printf · Println · StderrWriter · StdoutWriter Console.NewLine · Console.Print · Console.Printf · Console.Println · Console.StderrWriter · Console.StdoutWriter
Progress NewProgress · Progress Console.Progress · Progress.Add · Progress.Complete · Progress.Fail · Progress.Set · Progress.Start · Progress.Step · Progress.Stop · Progress.Update
Prompts Ask · AskDefault · AskSecret · Choose · ChooseIndex · Confirm · ErrNonInteractive Console.Ask · Console.AskDefault · Console.AskSecret · Console.Choose · Console.ChooseIndex · Console.Confirm
Runtime ASCIIMarks · Config · Console · Default · DefaultMarks · Marks · New · SetDefault
Styling ColorBlack · ColorBlue · ColorBoldGreen · ColorBoldWhite · ColorCyan · ColorGray · ColorGreen · ColorMagenta · ColorRed · ColorReset · ColorWhite · ColorYellow · Colorize · Style · StyleBold · StyleDim · StyleUnderline Console.Colorize · Console.Style
Tables RenderTable · Table · TableCenterAlign · TableCompact · TableOption · TableRightAlign · TableWidths Console.RenderTable · Console.Table
Terminal ErrTransientActive · IsInteractive · SupportsColor · SupportsUnicode · Width Console.IsInteractive · Console.SupportsColor · Console.SupportsUnicode · Console.Width
Text ExpandTabs · Indent · PadCenter · PadLeft · PadRight · StripANSI · Truncate · TruncateMiddle · VisibleWidth · Wrap Console.ExpandTabs · Console.Indent · Console.PadCenter · Console.PadLeft · Console.PadRight · Console.StripANSI · Console.Truncate · Console.TruncateMiddle · Console.VisibleWidth · Console.Wrap
Trees Node · RenderTree · Tree · TreeNode Console.RenderTree · Console.Tree

API examples

These examples are generated from package GoDoc comments. Package-level helpers are shown in preference to equivalent Console methods.

Boxes

Box

Box prints a box through the default console.

console.Box("ready", console.BoxTitle("Status"), console.BoxColor(""))
// ┌─ Status ┐
// │ ready   │
// └─────────┘
BoxColor

BoxColor sets the ANSI color used for borders when styling is enabled. An empty color leaves borders unstyled.

fmt.Println(console.StripANSI(console.RenderBox("healthy", console.BoxColor(console.ColorGreen))))
// ┌─────────┐
// │ healthy │
// └─────────┘
BoxOption

BoxOption configures one rendered box.

options := []console.BoxOption{
	console.BoxTitle("Status"),
	console.BoxColor(""),
}
fmt.Println(console.RenderBox("ready", options...))
// ┌─ Status ┐
// │ ready   │
// └─────────┘
BoxPadding

BoxPadding sets the horizontal padding on both sides of the content. Negative values are treated as zero, and padding is capped when necessary to fit the console width.

fmt.Println(console.RenderBox("ready", console.BoxPadding(0), console.BoxColor("")))
// ┌─────┐
// │ready│
// └─────┘
BoxTitle

BoxTitle adds a title to the top border.

fmt.Println(console.RenderBox("ready", console.BoxTitle("Status"), console.BoxColor("")))
// ┌─ Status ┐
// │ ready   │
// └─────────┘
BoxWidth

BoxWidth fixes the total visible width, including borders and padding. Values below the structural minimum expand enough to preserve a valid frame. Values less than one select an automatic width bounded by the console width. Larger values are bounded by the console width when the structural minimum permits.

fmt.Println(console.RenderBox("ready", console.BoxWidth(16), console.BoxColor("")))
// ┌──────────────┐
// │ ready        │
// └──────────────┘
RenderBox

RenderBox renders a box using the default console.

fmt.Println(console.RenderBox("complete", console.BoxColor("")))
// ┌──────────┐
// │ complete │
// └──────────┘

Layout

KV

KV creates one ordered key/value entry.

console.KeyValues(console.KV("Region", "eu-west-1"))
// Region  eu-west-1
KeyValue

KeyValue contains one ordered label and value for KeyValues.

entries := []console.KeyValue{
	{Key: "Mode", Value: "production"},
	{Key: "Port", Value: 8080},
}
console.KeyValues(entries...)
// Mode  production
// Port  8080
KeyValueMap

KeyValueMap prints a sorted key/value map through the default console.

console.KeyValueMap(map[string]any{"port": 8080, "mode": "production"})
// mode  production
// port  8080
KeyValues

KeyValues prints ordered key/value entries through the default console.

console.KeyValues(
	console.KV("Mode", "production"),
	console.KV("Port", 8080),
)
// Mode  production
// Port  8080
List

List prints an unordered list through the default console.

console.List("build", "test", "publish")
// • build
// • test
// • publish
NumberedList

NumberedList prints an ordered list through the default console.

console.NumberedList("build", "test", "publish")
// 1. build
// 2. test
// 3. publish
RenderKeyValueMap

RenderKeyValueMap renders a sorted key/value map through the default console.

fmt.Println(console.RenderKeyValueMap(map[string]any{"port": 8080, "mode": "production"}))
// mode  production
// port  8080
RenderKeyValues

RenderKeyValues renders ordered key/value entries through the default console.

fmt.Println(console.RenderKeyValues(
	console.KV("Mode", "production"),
	console.KV("Port", 8080),
))
// Mode  production
// Port  8080
RenderList

RenderList renders an unordered list through the default console.

fmt.Println(console.RenderList("build", "test"))
// • build
// • test
RenderNumberedList

RenderNumberedList renders an ordered list through the default console.

fmt.Println(console.RenderNumberedList("build", "test"))
// 1. build
// 2. test
RenderRule

RenderRule renders a horizontal rule through the default console.

previous := console.Default()
defer console.SetDefault(previous)
console.SetDefault(console.New(console.Config{Width: 16}))
fmt.Println(console.RenderRule("Next"))
// ── Next ────────
RenderSection

RenderSection renders a section heading through the default console.

fmt.Println(console.RenderSection("Deployment"))
// ◇ Deployment
Rule

Rule prints a horizontal rule through the default console.

previous := console.Default()
defer console.SetDefault(previous)
console.SetDefault(console.New(console.Config{Width: 16}))
console.Rule("Next")
// ── Next ────────
Section

Section prints a section heading through the default console.

console.Section("Deployment")
// ◇ Deployment

Loaders

Loader

Loader presents one transient activity line on terminals and stable semantic lines in redirected output. A Loader is concurrency-safe, single-use, and must be constructed with Console.Loader or NewLoader; the first call to Stop, Success, Warn, or Fail wins.

animations := false
color := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	ColorEnabled:      &color,
	UnicodeEnabled:    &unicode,
}))
var loader *console.Loader = console.NewLoader("Building application")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Building application
loader.Success("Application ready")
// ✔ Application ready
NewLoader

NewLoader constructs a loader using a snapshot of the current default console. It does not start the loader.

animations := false
color := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	ColorEnabled:      &color,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Downloading modules")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Downloading modules
loader.Success("Modules ready")
// ✔ Modules ready
Loader.Fail

Fail completes the loader with an error message on stderr. An empty message reuses the loader's current message.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Uploading release")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Uploading release
loader.Fail("Registry refused upload")
// ✖ Registry refused upload
Loader.Start

Start begins the loader and is harmless when called more than once. Animated loaders can return ErrTransientActive when another live display owns the same console.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Building application")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Building application
loader.Stop()
Loader.Stop

Stop removes the transient loader without printing a completion message.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Checking configuration")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Checking configuration
loader.Stop()
Loader.Success

Success completes the loader with a success message. An empty message reuses the loader's current message.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Publishing release")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Publishing release
loader.Success("Release published")
// ✔ Release published
Loader.Update

Update changes the loader message and immediately redraws an active animation. Updates after a terminal operation are ignored.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Downloading modules")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Downloading modules
loader.Update("Verifying modules")
loader.Success("")
// ✔ Verifying modules
Loader.Warn

Warn completes the loader with a warning message. An empty message reuses the loader's current message.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Checking optional tools")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Checking optional tools
loader.Warn("Optional tool not found")
// ! Optional tool not found

Marks

ActionMark

ActionMark returns the default console's action indicator.

fmt.Println(console.ActionMark())
// ·
DebugMark

DebugMark returns the default console's debug indicator.

fmt.Println(console.DebugMark())
// ?
ErrorMark

ErrorMark returns the default console's error indicator.

fmt.Println(console.ErrorMark())
// ✖
InfoMark

InfoMark returns the default console's informational indicator.

fmt.Println(console.InfoMark())
// ·
SuccessMark

SuccessMark returns the default console's success indicator.

fmt.Println(console.SuccessMark())
// ✔
WarnMark

WarnMark returns the default console's warning indicator.

fmt.Println(console.WarnMark())
// !

Messages

Action

Action prints an action message through the default console.

console.Action("building release")
// · building release
Actionf

Actionf prints a formatted action message through the default console.

console.Actionf("building %s", "release")
// · building release
Debug

Debug prints a diagnostic message through the default console when enabled.

debug := true
console.SetDefault(console.New(console.Config{DebugEnabled: &debug}))
console.Debug("cache miss")
// ? cache miss
Debugf

Debugf prints a formatted diagnostic message through the default console when enabled.

debug := true
console.SetDefault(console.New(console.Config{DebugEnabled: &debug}))
console.Debugf("attempt %d of %d", 1, 3)
// ? attempt 1 of 3
Error

Error prints an error message through the default console.

console.Error("deployment failed")
// ✖ deployment failed
Errorf

Errorf prints a formatted error message through the default console.

console.Errorf("deployment failed: %s", "timeout")
// ✖ deployment failed: timeout
Fatal

Fatal prints an error through the default console and exits with status 1.

console.SetDefault(console.New(console.Config{
	Exit: func(code int) { fmt.Println("exit", code) },
}))
console.Fatal("invalid configuration")
// ✖ invalid configuration
// exit 1
Fatalf

Fatalf prints a formatted error through the default console and exits with status 1.

console.SetDefault(console.New(console.Config{
	Exit: func(code int) { fmt.Println("exit", code) },
}))
console.Fatalf("invalid port: %d", 0)
// ✖ invalid port: 0
// exit 1
Info

Info prints an informational message through the default console.

console.Info("using cached dependencies")
// · using cached dependencies
Infof

Infof prints a formatted informational message through the default console.

console.Infof("using %s dependencies", "cached")
// · using cached dependencies
Success

Success prints a success message through the default console.

console.Success("release published")
// ✔ release published
Successf

Successf prints a formatted success message through the default console.

console.Successf("published %s", "v1.2.0")
// ✔ published v1.2.0
Warn

Warn prints a warning message through the default console.

console.Warn("configuration is deprecated")
// ! configuration is deprecated
Warnf

Warnf prints a formatted warning message through the default console.

console.Warnf("retrying in %d seconds", 5)
// ! retrying in 5 seconds

Output

NewLine

NewLine writes one blank line through the default console.

console.Println("before")
console.NewLine()
console.Println("after")
// before
//
// after
Print

Print writes values through the default console without adding a newline.

var output bytes.Buffer
console.SetDefault(console.New(console.Config{Stdout: &output}))
console.Print("deploying")
fmt.Printf("%q\n", output.String())
// "deploying"
Printf

Printf writes formatted output through the default console without adding a newline.

var output bytes.Buffer
console.SetDefault(console.New(console.Config{Stdout: &output}))
console.Printf("copied %d files", 3)
fmt.Printf("%q\n", output.String())
// "copied 3 files"
Println

Println writes values through the default console followed by a newline.

console.Println("deployment complete")
// deployment complete
StderrWriter

StderrWriter returns a coordinated writer using a snapshot of the current default console. Later calls to SetDefault do not retarget an existing writer.

fmt.Fprintln(console.StderrWriter(), "download failed")
// download failed
StdoutWriter

StdoutWriter returns a coordinated writer using a snapshot of the current default console. Later calls to SetDefault do not retarget an existing writer.

fmt.Fprintln(console.StdoutWriter(), "download complete")
// download complete

Progress

NewProgress

NewProgress constructs a progress display using a snapshot of the current default console. It does not start the display.

animations := false
color := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	ColorEnabled:      &color,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(2, "Deploying services")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Deploying services
progress.Add(2)
progress.Complete("Services deployed")
// ✔ Services deployed
Progress

Progress presents determinate work as one transient terminal line and stable semantic lines in redirected output. A Progress is concurrency-safe, single-use, and must be constructed with Console.Progress or NewProgress; the first call to Complete, Fail, or Stop wins.

animations := false
color := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	ColorEnabled:      &color,
	UnicodeEnabled:    &unicode,
}))
var progress *console.Progress = console.NewProgress(2, "Deploying services")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Deploying services
progress.Add(2)
progress.Complete("Services deployed")
// ✔ Services deployed
Progress.Add

Add changes the completed amount by delta and clamps it between zero and the total.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(2, "Deploying services")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Deploying services
progress.Add(1)
progress.Add(1)
progress.Complete("Services deployed")
// ✔ Services deployed
Progress.Complete

Complete fills and finishes the display with a success message. An empty message reuses the current progress message.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(1, "Packaging release")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Packaging release
progress.Complete("Release ready")
// ✔ Release ready
Progress.Fail

Fail finishes the display with an error message on stderr. An empty message reuses the current progress message.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(1, "Publishing release")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Publishing release
progress.Fail("Registry refused upload")
// ✖ Registry refused upload
Progress.Set

Set replaces the completed amount and clamps it between zero and the total. Reaching the total does not complete the display; Complete records the durable outcome.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(100, "Uploading release")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Uploading release
progress.Set(100)
progress.Complete("Release uploaded")
// ✔ Release uploaded
Progress.Start

Start begins the progress display and is harmless when called more than once. Live terminal displays can return ErrTransientActive when another display owns the console.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(3, "Running checks")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Running checks
progress.Stop()
Progress.Step

Step replaces the completed amount and message in one atomic progress update. The amount is clamped between zero and the total, and updates after a terminal operation are ignored.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(2, "Deploying API")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Deploying API
progress.Step(1, "Deploying worker")
progress.Complete("")
// ✔ Deploying worker
Progress.Stop

Stop removes the transient display without printing a completion message.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(1, "Checking release")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Checking release
progress.Stop()
Progress.Update

Update changes the progress message and immediately redraws a live terminal display. Updates after a terminal operation are ignored.

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(2, "Deploying API")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Deploying API
progress.Update("Deploying worker")
progress.Complete("")
// ✔ Deploying worker

Prompts

Ask

Ask prompts through the default console.

var output bytes.Buffer
interactive := true
unicode := true
console.SetDefault(console.New(console.Config{
	Stdin:              strings.NewReader("Ada\n"),
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	UnicodeEnabled:     &unicode,
}))
name, err := console.Ask("Name")
fmt.Printf("%q\n", output.String())
// "› Name: "
fmt.Println(name, err)
// Ada <nil>
AskDefault

AskDefault prompts with a default through the default console.

var output bytes.Buffer
interactive := true
unicode := true
console.SetDefault(console.New(console.Config{
	Stdin:              strings.NewReader("\n"),
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	UnicodeEnabled:     &unicode,
}))
environment, err := console.AskDefault("Environment", "production")
fmt.Printf("%q\n", output.String())
// "› Environment [production]: "
fmt.Println(environment, err)
// production <nil>
AskSecret

AskSecret prompts without echoing input through the default console.

var output bytes.Buffer
interactive := true
unicode := true
console.SetDefault(console.New(console.Config{
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	UnicodeEnabled:     &unicode,
	ReadSecret: func() (string, error) {
		return "token-value", nil
	},
}))
secret, err := console.AskSecret("API token")
fmt.Printf("%q\n", output.String())
// "› API token: \n"
fmt.Println(len(secret), err)
// 11 <nil>
Choose

Choose asks the user to select an option through the default console.

var output bytes.Buffer
interactive := true
unicode := true
console.SetDefault(console.New(console.Config{
	Stdin:              strings.NewReader("2\n"),
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	UnicodeEnabled:     &unicode,
}))
channel, err := console.Choose("Release channel", []string{"stable", "beta"}, 0)
fmt.Printf("%q\n", output.String())
// "Release channel\n1. stable\n2. beta\n› Choose [1-2, default 1]: "
fmt.Println(channel, err)
// beta <nil>
ChooseIndex

ChooseIndex asks the user to select an option index through the default console.

var output bytes.Buffer
interactive := true
unicode := true
console.SetDefault(console.New(console.Config{
	Stdin:              strings.NewReader("2\n"),
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	UnicodeEnabled:     &unicode,
}))
index, err := console.ChooseIndex("Release channel", []string{"stable", "beta"}, 0)
fmt.Printf("%q\n", output.String())
// "Release channel\n1. stable\n2. beta\n› Choose [1-2, default 1]: "
fmt.Println(index, err)
// 1 <nil>
Confirm

Confirm asks for confirmation through the default console.

var output bytes.Buffer
interactive := true
unicode := true
console.SetDefault(console.New(console.Config{
	Stdin:              strings.NewReader("yes\n"),
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	UnicodeEnabled:     &unicode,
}))
confirmed, err := console.Confirm("Deploy now", false)
fmt.Printf("%q\n", output.String())
// "› Deploy now [y/N]: "
fmt.Println(confirmed, err)
// true <nil>
ErrNonInteractive

ErrNonInteractive is returned when a prompt would read from a console that is not interactive. Set Config.InteractiveEnabled when intentionally driving prompts with an injected reader.

interactive := false
console.SetDefault(console.New(console.Config{InteractiveEnabled: &interactive}))
_, err := console.Ask("Name")
fmt.Println(errors.Is(err, console.ErrNonInteractive))
// true

Runtime

ASCIIMarks

ASCIIMarks returns symbols suitable for constrained terminals and plain logs.

marks := console.ASCIIMarks()
fmt.Println(marks.Success, marks.Warn, marks.Error)
// + ! x
Config

Config configures a Console instance.

Every field is optional. Nil functions and writers use their operating-system defaults, while nil boolean pointers select automatic behavior.

configuration := console.Config{Width: 100}
commandConsole := console.New(configuration)
fmt.Println(commandConsole.Width())
// 100
Console

Console coordinates output policy, terminal capabilities, prompts, and transient displays. A Console is safe for concurrent message writes and must be constructed with New.

var commandConsole *console.Console = console.New(console.Config{Width: 120})
fmt.Println(commandConsole.Width())
// 120
Default

Default returns the console currently used by package-level helpers.

fmt.Println(console.Default() != nil)
// true
DefaultMarks

DefaultMarks returns the Unicode symbols used by a default console.

marks := console.DefaultMarks()
fmt.Println(marks.Success, marks.Warn, marks.Error)
// ✔ ! ✖
Marks

Marks contains the symbols used for messages, lists, selections, and loaders.

marks := console.Marks{Success: "OK"}
fmt.Println(marks.Success)
// OK
New

New creates an isolated console with optional runtime overrides.

var output bytes.Buffer
color := false
unicode := true
commandConsole := console.New(console.Config{
	Stdout:         &output,
	ColorEnabled:   &color,
	UnicodeEnabled: &unicode,
})
commandConsole.Success("ready")
fmt.Print(output.String())
// ✔ ready
SetDefault

SetDefault replaces the console used by package-level helpers. It panics when console is nil because package helpers always require a usable runtime.

previous := console.Default()
defer console.SetDefault(previous)

var output bytes.Buffer
console.SetDefault(console.New(console.Config{Stdout: &output}))
console.Println("ready")
fmt.Print(output.String())
// ready

Styling

ColorBlack

ColorBlack is a black ANSI foreground color.

fmt.Printf("%q\n", console.ColorBlack)
// "\x1b[30m"
ColorBlue

ColorBlue is a blue ANSI foreground color.

fmt.Printf("%q\n", console.ColorBlue)
// "\x1b[34m"
ColorBoldGreen

ColorBoldGreen is a bold green ANSI foreground color.

fmt.Printf("%q\n", console.ColorBoldGreen)
// "\x1b[1;32m"
ColorBoldWhite

ColorBoldWhite is a bold white ANSI foreground color.

fmt.Printf("%q\n", console.ColorBoldWhite)
// "\x1b[1;97m"
ColorCyan

ColorCyan is a cyan ANSI foreground color.

fmt.Printf("%q\n", console.ColorCyan)
// "\x1b[36m"
ColorGray

ColorGray is a muted gray ANSI foreground color.

fmt.Printf("%q\n", console.ColorGray)
// "\x1b[90m"
ColorGreen

ColorGreen is a green ANSI foreground color.

fmt.Printf("%q\n", console.ColorGreen)
// "\x1b[32m"
ColorMagenta

ColorMagenta is a magenta ANSI foreground color.

fmt.Printf("%q\n", console.ColorMagenta)
// "\x1b[35m"
ColorRed

ColorRed is a red ANSI foreground color.

fmt.Printf("%q\n", console.ColorRed)
// "\x1b[31m"
ColorReset

ColorReset resets ANSI styling.

fmt.Printf("%q\n", console.ColorReset)
// "\x1b[0m"
ColorWhite

ColorWhite is a white ANSI foreground color.

fmt.Printf("%q\n", console.ColorWhite)
// "\x1b[37m"
ColorYellow

ColorYellow is a yellow ANSI foreground color.

fmt.Printf("%q\n", console.ColorYellow)
// "\x1b[33m"
Colorize

Colorize applies an ANSI color using the default console's color policy.

color := true
console.SetDefault(console.New(console.Config{ColorEnabled: &color}))
fmt.Printf("%q\n", console.Colorize(console.ColorCyan, "connected"))
// "\x1b[36mconnected\x1b[0m"
Style

Style applies ANSI styles using the default console's color policy.

color := true
console.SetDefault(console.New(console.Config{ColorEnabled: &color}))
fmt.Printf("%q\n", console.Style("ready", console.StyleBold, console.ColorGreen))
// "\x1b[1m\x1b[32mready\x1b[0m"
StyleBold

StyleBold enables bold ANSI text.

fmt.Printf("%q\n", console.StyleBold)
// "\x1b[1m"
StyleDim

StyleDim enables dim ANSI text.

fmt.Printf("%q\n", console.StyleDim)
// "\x1b[2m"
StyleUnderline

StyleUnderline enables underlined ANSI text.

fmt.Printf("%q\n", console.StyleUnderline)
// "\x1b[4m"

Tables

RenderTable

RenderTable renders a table using the default console.

fmt.Println(console.RenderTable(
	[]string{"Name", "State"},
	[][]string{{"worker", "idle"}},
))
// ┌────────┬───────┐
// │ Name   │ State │
// ├────────┼───────┤
// │ worker │ idle  │
// └────────┴───────┘
Table

Table prints a table through the default console.

console.Table(
	[]string{"Name", "State"},
	[][]string{{"api", "ready"}},
)
// ┌──────┬───────┐
// │ Name │ State │
// ├──────┼───────┤
// │ api  │ ready │
// └──────┴───────┘
TableCenterAlign

TableCenterAlign centers the headers and values in the selected zero-based columns. Negative and out-of-range columns are ignored.

fmt.Println(console.RenderTable(
	[]string{"Service", "State"},
	[][]string{{"api", "up"}},
	console.TableCenterAlign(1),
))
// ┌─────────┬───────┐
// │ Service │ State │
// ├─────────┼───────┤
// │ api     │  up   │
// └─────────┴───────┘
TableCompact

TableCompact removes the outer frame and separates columns with two spaces. A compact table with headers retains one horizontal separator for readability.

fmt.Println(console.RenderTable(
	[]string{"Name", "State"},
	[][]string{{"api", "ready"}},
	console.TableCompact(),
))
// Name  State
// ────  ─────
// api   ready
TableOption

TableOption configures one rendered table.

options := []console.TableOption{console.TableCompact()}
fmt.Println(console.RenderTable(
	[]string{"Name", "State"},
	[][]string{{"api", "ready"}},
	options...,
))
// Name  State
// ────  ─────
// api   ready
TableRightAlign

TableRightAlign right-aligns the headers and values in the selected zero-based columns. Negative and out-of-range columns are ignored.

fmt.Println(console.RenderTable(
	[]string{"Item", "Count"},
	[][]string{{"api", "12"}},
	console.TableRightAlign(1),
))
// ┌──────┬───────┐
// │ Item │ Count │
// ├──────┼───────┤
// │ api  │    12 │
// └──────┴───────┘
TableWidths

TableWidths sets content widths by zero-based column position. Values less than one leave that column automatic, and configured widths may still shrink when the complete table would exceed the console width.

fmt.Println(console.RenderTable(
	[]string{"Name", "State"},
	[][]string{{"api", "ready"}},
	console.TableWidths(6, 7),
))
// ┌────────┬─────────┐
// │ Name   │ State   │
// ├────────┼─────────┤
// │ api    │ ready   │
// └────────┴─────────┘

Terminal

ErrTransientActive

ErrTransientActive is returned when another live loader or progress display owns the transient line.

fmt.Println(console.ErrTransientActive)
// console: another transient display is already active
IsInteractive

IsInteractive reports whether the default console is interactive.

previous := console.Default()
defer console.SetDefault(previous)
interactive := true
console.SetDefault(console.New(console.Config{InteractiveEnabled: &interactive}))

fmt.Println(console.IsInteractive())
// true
SupportsColor

SupportsColor reports whether the default console emits ANSI styling.

previous := console.Default()
defer console.SetDefault(previous)
color := true
console.SetDefault(console.New(console.Config{ColorEnabled: &color}))

fmt.Println(console.SupportsColor())
// true
SupportsUnicode

SupportsUnicode reports whether the default console uses Unicode presentation characters.

previous := console.Default()
defer console.SetDefault(previous)
unicode := false
console.SetDefault(console.New(console.Config{UnicodeEnabled: &unicode}))

fmt.Println(console.SupportsUnicode())
// false
Width

Width returns the width of the default console.

previous := console.Default()
defer console.SetDefault(previous)
console.SetDefault(console.New(console.Config{Width: 100}))

fmt.Println(console.Width())
// 100

Text

ExpandTabs

ExpandTabs replaces tabs with spaces at eight-cell stops on each line. ANSI escape sequences do not affect tab positions.

fmt.Printf("%q\n", console.ExpandTabs("a\tb"))
// "a       b"
Indent

Indent prefixes every line in value with prefix. Empty input remains empty.

fmt.Printf("%q\n", console.Indent("one\ntwo", "> "))
// "> one\n> two"
PadCenter

PadCenter adds spaces around every line until it reaches width terminal cells. Odd padding places the extra space on the right. Lines already at or beyond width are unchanged. Tabs are expanded only on lines that need padding so their alignment remains stable.

fmt.Printf("%q\n", console.PadCenter("go", 6))
// "  go  "
PadLeft

PadLeft prepends spaces until every line reaches width terminal cells. Lines already at or beyond width are unchanged. Tabs are expanded only on lines that need padding because leading spaces otherwise change their terminal tab stops.

fmt.Printf("%q\n", console.PadLeft("go", 5))
// "   go"
PadRight

PadRight appends spaces until every line reaches width terminal cells. Lines already at or beyond width are unchanged.

fmt.Printf("%q\n", console.PadRight("go", 5))
// "go   "
StripANSI

StripANSI removes complete ANSI CSI, OSC, and ESC sequences from value. Incomplete escape sequences are retained so malformed input is not silently discarded.

fmt.Println(console.StripANSI(console.ColorRed + "failed" + console.ColorReset))
// failed
Truncate

Truncate shortens each line of value to width terminal cells and uses an ellipsis when content is removed. Active SGR styles and OSC 8 hyperlinks are closed before the ellipsis. Values less than one produce an empty string.

fmt.Println(console.Truncate("deployment", 7))
// deploy…
TruncateMiddle

TruncateMiddle shortens each line of value to width terminal cells by replacing its center with an ellipsis. Active SGR styles and OSC 8 hyperlinks are kept with the visible text on either side of the ellipsis. Values less than one produce an empty string.

fmt.Println(console.TruncateMiddle("abcdefghij", 7))
// abc…hij
VisibleWidth

VisibleWidth returns the largest terminal-cell width among value's lines. ANSI escapes and combining characters occupy no cells, tabs advance to an eight-cell stop, and common East Asian and emoji runes occupy two cells.

fmt.Println(console.VisibleWidth("Go界"))
// 4
Wrap

Wrap inserts newlines so each resulting line fits within width terminal cells where possible. Existing line breaks and ANSI styling are preserved; active SGR styles and OSC 8 hyperlinks are balanced at each line boundary so they cannot bleed into surrounding layout. Long unbroken words wrap at cell boundaries. Breakable whitespace at the beginning or end of a resulting line is removed. Values less than one are returned unchanged.

fmt.Printf("%q\n", console.Wrap("ship the release", 8))
// "ship the\nrelease"

Trees

Node

Node creates a tree node and preserves the supplied child order.

console.Tree(console.Node("cmd", console.Node("deploy")))
// cmd
// └── deploy
RenderTree

RenderTree renders a static tree through the default console.

fmt.Println(console.RenderTree(console.Node("services",
	console.Node("api"),
	console.Node("worker"),
)))
// services
// ├── api
// └── worker
Tree

Tree prints a static tree through the default console.

console.Tree(console.Node("project",
	console.Node("cmd", console.Node("deploy")),
	console.Node("README.md"),
))
// project
// ├── cmd
// │   └── deploy
// └── README.md
TreeNode

TreeNode contains one label and its ordered child nodes.

tree := console.TreeNode{
	Label: "project",
	Children: []console.TreeNode{
		{Label: "cmd"},
		{Label: "README.md"},
	},
}
console.Tree(tree)
// project
// ├── cmd
// └── README.md

Executable examples

These focused snippets are generated from standard Go example tests. The test suite executes each one and verifies every inline output comment.

Semantic and multiline messages

console.Action("Building application")
// · Building application
console.Success("API ready\nWorker ready")
// ✔ API ready
//   Worker ready
console.Warn("Configuration is incomplete")
// ! Configuration is incomplete
console.Error("Port already in use")
// ✖ Port already in use

Plain output and coordinated writers

console.Println("plain output")
// plain output
fmt.Fprintln(console.StdoutWriter(), "streamed output")
// streamed output
fmt.Fprintln(console.StderrWriter(), "diagnostic output")
// diagnostic output

Adaptive styles and marks

fmt.Println(console.ActionMark(), console.SuccessMark(), console.ErrorMark())
// · ✔ ✖
fmt.Println(console.Style("release ready", console.StyleBold, console.ColorGreen))
// release ready

Sections, rules, and summaries

fmt.Println(console.RenderSection("Deployment"))
// ◇ Deployment
fmt.Println(console.RenderKeyValues(
	console.KV("Environment", "production"),
	console.KV("Region", "eu-west-1"),
))
// Environment  production
// Region       eu-west-1
fmt.Println(console.RenderRule("Next"))
// ── Next ────────────────

Bulleted and numbered lists

console.List("validate configuration", "connect to database")
// • validate configuration
// • connect to database
console.NumberedList("build", "test", "publish")
// 1. build
// 2. test
// 3. publish

Trees

console.Tree(console.Node("project",
	console.Node("cmd", console.Node("deploy")),
	console.Node("internal"),
	console.Node("README.md"),
))
// project
// ├── cmd
// │   └── deploy
// ├── internal
// └── README.md

Boxes

console.Box(
	"The API and worker are healthy.",
	console.BoxTitle("Status"),
	console.BoxWidth(38),
)
// ┌─ Status ───────────────────────────┐
// │ The API and worker are healthy.    │
// └────────────────────────────────────┘

Tables

console.Table(
	[]string{"Service", "State"},
	[][]string{{"api", "ready"}, {"worker", "ready"}},
)
// ┌─────────┬───────┐
// │ Service │ State │
// ├─────────┼───────┤
// │ api     │ ready │
// │ worker  │ ready │
// └─────────┴───────┘

Compact, fixed, and aligned tables

console.Table(
	[]string{"Task", "Seconds"},
	[][]string{{"compile packages", "12"}, {"test", "3"}},
	console.TableCompact(),
	console.TableWidths(8, 7),
	console.TableRightAlign(1),
)
// Task      Seconds
// ────────  ───────
// compile        12
// packages
// test            3

ASCII borders and centered columns

console.Table(
	[]string{"Status", "Count"},
	[][]string{{"ready", "2"}, {"waiting", "12"}},
	console.TableWidths(8, 5),
	console.TableCenterAlign(0),
	console.TableRightAlign(1),
)
// +----------+-------+
// |  Status  | Count |
// +----------+-------+
// |  ready   |     2 |
// | waiting  |    12 |
// +----------+-------+

Redirect-safe loader outcomes

download := console.NewLoader("Downloading modules")
if err := download.Start(); err != nil {
	console.Error(err.Error())
	return
}
// · Downloading modules
defer download.Stop()
download.Success("Modules ready")
// ✔ Modules ready

publish := console.NewLoader("Publishing release")
if err := publish.Start(); err != nil {
	console.Error(err.Error())
	return
}
// · Publishing release
defer publish.Stop()
publish.Fail("Registry refused upload")
// ✖ Registry refused upload

Determinate progress

progress := console.NewProgress(100, "Packaging release")
if err := progress.Start(); err != nil {
	console.Error(err.Error())
	return
}
// · Packaging release
defer progress.Stop()
progress.Step(40, "Uploading release")
progress.Add(60)
progress.Complete("Release ready")
// ✔ Release ready

Questions, defaults, and confirmation

var output bytes.Buffer
interactive := true
color := false
unicode := true
console.SetDefault(console.New(console.Config{
	Stdin:              strings.NewReader("Ada\n\nyes\n"),
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	ColorEnabled:       &color,
	UnicodeEnabled:     &unicode,
}))

name, _ := console.Ask("Name")
environment, _ := console.AskDefault("Environment", "production")
confirmed, _ := console.Confirm("Deploy now", false)
fmt.Printf("%q\n", output.String())
// "› Name: › Environment [production]: › Deploy now [y/N]: "
fmt.Println(name, environment, confirmed)
// Ada production true

Choices and secret input

var output bytes.Buffer
interactive := true
color := false
unicode := true
console.SetDefault(console.New(console.Config{
	Stdin:              strings.NewReader("2"),
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	ColorEnabled:       &color,
	UnicodeEnabled:     &unicode,
	ReadSecret: func() (string, error) {
		return "token-value", nil
	},
}))

channel, _ := console.Choose("Release channel", []string{"stable", "beta"}, 0)
secret, _ := console.AskSecret("API token")
fmt.Printf("%q\n", output.String())
// "Release channel\n1. stable\n2. beta\n› Choose [1-2, default 1]: \n› API token: \n"
fmt.Println(channel, len(secret))
// beta 11

ANSI-aware text utilities

styled := "\x1b[31mGo 世界\x1b[0m"

fmt.Println(console.StripANSI(styled))
// Go 世界
fmt.Println(console.VisibleWidth(styled))
// 7
fmt.Printf("%q\n", console.PadLeft("Go", 6))
// "    Go"
fmt.Printf("%q\n", console.PadCenter("Go", 6))
// "  Go  "
fmt.Println(console.TruncateMiddle("github.com/goforj/console", 15))
// github.…console
fmt.Println(console.Wrap("deploying worker service", 10))
// deploying
// worker
// service

Recipe: a deployment lifecycle

console.Section("Deploy production")
// ◇ Deploy production
console.KeyValues(
	console.KV("Environment", "production"),
	console.KV("Region", "eu-west-1"),
)
// Environment  production
// Region       eu-west-1

progress := console.NewProgress(2, "Deploying services")
if err := progress.Start(); err != nil {
	console.Error(err.Error())
	return
}
// · Deploying services
defer progress.Stop()
progress.Step(1, "Deploying worker")
progress.Complete("Services deployed")
// ✔ Services deployed

console.Table(
	[]string{"Service", "State"},
	[][]string{{"api", "ready"}, {"worker", "ready"}},
)
// ┌─────────┬───────┐
// │ Service │ State │
// ├─────────┼───────┤
// │ api     │ ready │
// │ worker  │ ready │
// └─────────┴───────┘
console.Success("Deployment complete")
// ✔ Deployment complete

Recipe: an actionable validation report

console.Section("Configuration check")
// ◇ Configuration check
console.KeyValues(
	console.KV("Checks", 8),
	console.KV("Passed", 6),
	console.KV("Failed", 2),
)
// Checks  8
// Passed  6
// Failed  2
console.Warn("2 issues need attention")
// ! 2 issues need attention
console.List("DATABASE_URL is missing", "PORT must be between 1 and 65535")
// • DATABASE_URL is missing
// • PORT must be between 1 and 65535
console.Error("Validation failed")
// ✖ Validation failed

Recipe: machine stdout and status stderr

var machineOutput bytes.Buffer
var statusOutput bytes.Buffer
color := false
unicode := false
console.SetDefault(console.New(console.Config{
	Stdout:         &machineOutput,
	Stderr:         &statusOutput,
	ColorEnabled:   &color,
	UnicodeEnabled: &unicode,
}))

fmt.Fprintln(console.StdoutWriter(), `{"artifact":"app.tar.gz","status":"ready"}`)
fmt.Fprintln(console.StderrWriter(), "status: uploading app.tar.gz")
fmt.Printf("stdout: %q\n", machineOutput.String())
// stdout: "{\"artifact\":\"app.tar.gz\",\"status\":\"ready\"}\n"
fmt.Printf("stderr: %q\n", statusOutput.String())
// stderr: "status: uploading app.tar.gz\n"

Isolated console instances

var output bytes.Buffer
color := false
unicode := false
commandConsole := console.New(console.Config{
	Stdout:         &output,
	ColorEnabled:   &color,
	UnicodeEnabled: &unicode,
})

commandConsole.Success("Isolated output")
fmt.Print(output.String())
// + Isolated output

Development

go test ./...
go test -race ./...
go -C docs test ./...
go -C examples test ./...
go generate .
go vet ./...
go -C docs vet ./...
go -C examples vet ./...

The docs and examples are separate Go modules so release archives contain only the library. The README API index uses a generator-owned grouping manifest, while each local API target and code sample is generated from the declaration's GoDoc Example: block. Focused workflow examples come from standard Go example tests that execute and verify their inline output. Generation validates its marker pair and every example target before writing, so malformed documentation fails without partially changing the README.

Documentation

Releasing

Before tagging a release:

  • Run the root, docs, and examples tests and vet commands above, including the race suite.
  • Run go generate . and confirm the working tree has no generated or module-file diff.
  • Choose the next semantic version and review the public API and README output one final time.
  • Create an annotated tag with git tag -a vX.Y.Z -m "vX.Y.Z", then push it with git push origin vX.Y.Z.

The tag runs the same test matrix before the Go module proxy discovers the release.

License

Released under the MIT License.

Documentation

Overview

Package console provides lightweight building blocks for polished command-line output.

It includes semantic messages, ANSI-aware text utilities, composable layouts, tables, boxes, trees, prompts, loaders, and progress without imposing a full-screen event loop. Package-level helpers use Default; applications that need isolated writers or deterministic behavior can construct a Console with New.

Example (CiRecipe)

Example_ciRecipe demonstrates keeping machine output separate from human-facing CI status.

@readme ci-recipe

package main

import (
	"bytes"
	"fmt"

	"github.com/goforj/console"
)

func main() {
	var machineOutput bytes.Buffer
	var statusOutput bytes.Buffer
	color := false
	unicode := false
	// @readme:setup:start
	previous := console.Default()
	defer console.SetDefault(previous)
	// @readme:setup:end
	console.SetDefault(console.New(console.Config{
		Stdout:         &machineOutput,
		Stderr:         &statusOutput,
		ColorEnabled:   &color,
		UnicodeEnabled: &unicode,
	}))

	fmt.Fprintln(console.StdoutWriter(), `{"artifact":"app.tar.gz","status":"ready"}`)
	fmt.Fprintln(console.StderrWriter(), "status: uploading app.tar.gz")
	fmt.Printf("stdout: %q\n", machineOutput.String())
	// stdout: "{\"artifact\":\"app.tar.gz\",\"status\":\"ready\"}\n"
	fmt.Printf("stderr: %q\n", statusOutput.String())
	// stderr: "status: uploading app.tar.gz\n"

}
Output:
stdout: "{\"artifact\":\"app.tar.gz\",\"status\":\"ready\"}\n"
stderr: "status: uploading app.tar.gz\n"
Example (DeploymentRecipe)

Example_deploymentRecipe demonstrates a complete deployment lifecycle with concise package helpers.

@readme deployment-recipe

package main

import (
	"os"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	animations := false
	unicode := true
	defer useExampleDefault(console.Config{
		Stdout:            os.Stdout,
		Stderr:            os.Stdout,
		ColorEnabled:      &color,
		UnicodeEnabled:    &unicode,
		AnimationsEnabled: &animations,
	})()
	// @readme:setup:end

	console.Section("Deploy production")
	// ◇ Deploy production
	console.KeyValues(
		console.KV("Environment", "production"),
		console.KV("Region", "eu-west-1"),
	)
	// Environment  production
	// Region       eu-west-1

	progress := console.NewProgress(2, "Deploying services")
	if err := progress.Start(); err != nil {
		console.Error(err.Error())
		return
	}
	// · Deploying services
	defer progress.Stop()
	progress.Step(1, "Deploying worker")
	progress.Complete("Services deployed")
	// ✔ Services deployed

	console.Table(
		[]string{"Service", "State"},
		[][]string{{"api", "ready"}, {"worker", "ready"}},
	)
	// ┌─────────┬───────┐
	// │ Service │ State │
	// ├─────────┼───────┤
	// │ api     │ ready │
	// │ worker  │ ready │
	// └─────────┴───────┘
	console.Success("Deployment complete")
	// ✔ Deployment complete

}
Output:
◇ Deploy production
Environment  production
Region       eu-west-1
· Deploying services
✔ Services deployed
┌─────────┬───────┐
│ Service │ State │
├─────────┼───────┤
│ api     │ ready │
│ worker  │ ready │
└─────────┴───────┘
✔ Deployment complete
Example (ValidationRecipe)

Example_validationRecipe demonstrates a compact report that tells users what to fix next.

@readme validation-recipe

package main

import (
	"os"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	unicode := true
	defer useExampleDefault(console.Config{
		Stdout:         os.Stdout,
		Stderr:         os.Stdout,
		ColorEnabled:   &color,
		UnicodeEnabled: &unicode,
	})()
	// @readme:setup:end

	console.Section("Configuration check")
	// ◇ Configuration check
	console.KeyValues(
		console.KV("Checks", 8),
		console.KV("Passed", 6),
		console.KV("Failed", 2),
	)
	// Checks  8
	// Passed  6
	// Failed  2
	console.Warn("2 issues need attention")
	// ! 2 issues need attention
	console.List("DATABASE_URL is missing", "PORT must be between 1 and 65535")
	// • DATABASE_URL is missing
	// • PORT must be between 1 and 65535
	console.Error("Validation failed")
	// ✖ Validation failed

}
Output:
◇ Configuration check
Checks  8
Passed  6
Failed  2
! 2 issues need attention
• DATABASE_URL is missing
• PORT must be between 1 and 65535
✖ Validation failed

Index

Examples

Constants

View Source
const (
	// ColorReset resets ANSI styling.
	//
	// Example: inspect the reset sequence
	//
	//	fmt.Printf("%q\n", console.ColorReset)
	//	// "\x1b[0m"
	ColorReset = "\033[0m"
	// StyleBold enables bold ANSI text.
	//
	// Example: inspect the bold sequence
	//
	//	fmt.Printf("%q\n", console.StyleBold)
	//	// "\x1b[1m"
	StyleBold = "\033[1m"
	// StyleDim enables dim ANSI text.
	//
	// Example: inspect the dim sequence
	//
	//	fmt.Printf("%q\n", console.StyleDim)
	//	// "\x1b[2m"
	StyleDim = "\033[2m"
	// StyleUnderline enables underlined ANSI text.
	//
	// Example: inspect the underline sequence
	//
	//	fmt.Printf("%q\n", console.StyleUnderline)
	//	// "\x1b[4m"
	StyleUnderline = "\033[4m"
	// ColorBlack is a black ANSI foreground color.
	//
	// Example: inspect the black sequence
	//
	//	fmt.Printf("%q\n", console.ColorBlack)
	//	// "\x1b[30m"
	ColorBlack = "\033[30m"
	// ColorRed is a red ANSI foreground color.
	//
	// Example: inspect the red sequence
	//
	//	fmt.Printf("%q\n", console.ColorRed)
	//	// "\x1b[31m"
	ColorRed = "\033[31m"
	// ColorGreen is a green ANSI foreground color.
	//
	// Example: inspect the green sequence
	//
	//	fmt.Printf("%q\n", console.ColorGreen)
	//	// "\x1b[32m"
	ColorGreen = "\033[32m"
	// ColorYellow is a yellow ANSI foreground color.
	//
	// Example: inspect the yellow sequence
	//
	//	fmt.Printf("%q\n", console.ColorYellow)
	//	// "\x1b[33m"
	ColorYellow = "\033[33m"
	// ColorBlue is a blue ANSI foreground color.
	//
	// Example: inspect the blue sequence
	//
	//	fmt.Printf("%q\n", console.ColorBlue)
	//	// "\x1b[34m"
	ColorBlue = "\033[34m"
	// ColorMagenta is a magenta ANSI foreground color.
	//
	// Example: inspect the magenta sequence
	//
	//	fmt.Printf("%q\n", console.ColorMagenta)
	//	// "\x1b[35m"
	ColorMagenta = "\033[35m"
	// ColorCyan is a cyan ANSI foreground color.
	//
	// Example: inspect the cyan sequence
	//
	//	fmt.Printf("%q\n", console.ColorCyan)
	//	// "\x1b[36m"
	ColorCyan = "\033[36m"
	// ColorWhite is a white ANSI foreground color.
	//
	// Example: inspect the white sequence
	//
	//	fmt.Printf("%q\n", console.ColorWhite)
	//	// "\x1b[37m"
	ColorWhite = "\033[37m"
	// ColorGray is a muted gray ANSI foreground color.
	//
	// Example: inspect the gray sequence
	//
	//	fmt.Printf("%q\n", console.ColorGray)
	//	// "\x1b[90m"
	ColorGray = "\033[90m"
	// ColorBoldWhite is a bold white ANSI foreground color.
	//
	// Example: inspect the bold white sequence
	//
	//	fmt.Printf("%q\n", console.ColorBoldWhite)
	//	// "\x1b[1;97m"
	ColorBoldWhite = "\033[1;97m"
	// ColorBoldGreen is a bold green ANSI foreground color.
	//
	// Example: inspect the bold green sequence
	//
	//	fmt.Printf("%q\n", console.ColorBoldGreen)
	//	// "\x1b[1;32m"
	ColorBoldGreen = "\033[1;32m"
)

ANSI style and color codes are grouped here so callers can compose them with Style.

Variables

View Source
var ErrNonInteractive = errors.New("console: prompting requires an interactive console")

ErrNonInteractive is returned when a prompt would read from a console that is not interactive. Set Config.InteractiveEnabled when intentionally driving prompts with an injected reader.

Example: recognize a non-interactive prompt

interactive := false
console.SetDefault(console.New(console.Config{InteractiveEnabled: &interactive}))
_, err := console.Ask("Name")
fmt.Println(errors.Is(err, console.ErrNonInteractive))
// true
View Source
var ErrTransientActive = errors.New("console: another transient display is already active")

ErrTransientActive is returned when another live loader or progress display owns the transient line.

Example: inspect the transient ownership error

fmt.Println(console.ErrTransientActive)
// console: another transient display is already active

Functions

func Action

func Action(message string)

Action prints an action message through the default console.

Example: announce work

console.Action("building release")
// · building release
Example

ExampleAction demonstrates semantic messages and hanging indentation through package-level helpers.

@readme messages

package main

import (
	"os"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	unicode := true
	defer useExampleDefault(console.Config{
		Stdout:         os.Stdout,
		Stderr:         os.Stdout,
		ColorEnabled:   &color,
		UnicodeEnabled: &unicode,
	})()
	// @readme:setup:end

	console.Action("Building application")
	// · Building application
	console.Success("API ready\nWorker ready")
	// ✔ API ready
	//   Worker ready
	console.Warn("Configuration is incomplete")
	// ! Configuration is incomplete
	console.Error("Port already in use")
	// ✖ Port already in use

}
Output:
· Building application
✔ API ready
  Worker ready
! Configuration is incomplete
✖ Port already in use

func ActionMark

func ActionMark() string

ActionMark returns the default console's action indicator.

Example: inspect the action mark

fmt.Println(console.ActionMark())
// ·

func Actionf

func Actionf(format string, arguments ...any)

Actionf prints a formatted action message through the default console.

Example: announce formatted work

console.Actionf("building %s", "release")
// · building release

func Ask

func Ask(prompt string) (string, error)

Ask prompts through the default console.

Example:

var output bytes.Buffer
interactive := true
unicode := true
console.SetDefault(console.New(console.Config{
	Stdin:              strings.NewReader("Ada\n"),
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	UnicodeEnabled:     &unicode,
}))
name, err := console.Ask("Name")
fmt.Printf("%q\n", output.String())
// "› Name: "
fmt.Println(name, err)
// Ada <nil>
Example

ExampleAsk demonstrates the common line, default, and confirmation prompts with scripted input.

@readme prompts

package main

import (
	"bytes"
	"fmt"
	"strings"

	"github.com/goforj/console"
)

func main() {
	var output bytes.Buffer
	interactive := true
	color := false
	unicode := true
	// @readme:setup:start
	previous := console.Default()
	defer console.SetDefault(previous)
	// @readme:setup:end
	console.SetDefault(console.New(console.Config{
		Stdin:              strings.NewReader("Ada\n\nyes\n"),
		Stdout:             &output,
		InteractiveEnabled: &interactive,
		ColorEnabled:       &color,
		UnicodeEnabled:     &unicode,
	}))

	name, _ := console.Ask("Name")
	environment, _ := console.AskDefault("Environment", "production")
	confirmed, _ := console.Confirm("Deploy now", false)
	fmt.Printf("%q\n", output.String())
	// "› Name: › Environment [production]: › Deploy now [y/N]: "
	fmt.Println(name, environment, confirmed)
	// Ada production true

}
Output:
"› Name: › Environment [production]: › Deploy now [y/N]: "
Ada production true

func AskDefault

func AskDefault(prompt, defaultValue string) (string, error)

AskDefault prompts with a default through the default console.

Example:

var output bytes.Buffer
interactive := true
unicode := true
console.SetDefault(console.New(console.Config{
	Stdin:              strings.NewReader("\n"),
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	UnicodeEnabled:     &unicode,
}))
environment, err := console.AskDefault("Environment", "production")
fmt.Printf("%q\n", output.String())
// "› Environment [production]: "
fmt.Println(environment, err)
// production <nil>

func AskSecret

func AskSecret(prompt string) (string, error)

AskSecret prompts without echoing input through the default console.

Example:

var output bytes.Buffer
interactive := true
unicode := true
console.SetDefault(console.New(console.Config{
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	UnicodeEnabled:     &unicode,
	ReadSecret: func() (string, error) {
		return "token-value", nil
	},
}))
secret, err := console.AskSecret("API token")
fmt.Printf("%q\n", output.String())
// "› API token: \n"
fmt.Println(len(secret), err)
// 11 <nil>

func Box

func Box(content string, options ...BoxOption)

Box prints a box through the default console.

Example: print a boxed result

console.Box("ready", console.BoxTitle("Status"), console.BoxColor(""))
// ┌─ Status ┐
// │ ready   │
// └─────────┘
Example

ExampleBox demonstrates the useful box defaults and the two common adjustments.

@readme boxes

package main

import (
	"os"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	unicode := true
	defer useExampleDefault(console.Config{
		Stdout:         os.Stdout,
		ColorEnabled:   &color,
		UnicodeEnabled: &unicode,
	})()
	// @readme:setup:end

	console.Box(
		"The API and worker are healthy.",
		console.BoxTitle("Status"),
		console.BoxWidth(38),
	)
	// ┌─ Status ───────────────────────────┐
	// │ The API and worker are healthy.    │
	// └────────────────────────────────────┘

}
Output:
┌─ Status ───────────────────────────┐
│ The API and worker are healthy.    │
└────────────────────────────────────┘

func Choose

func Choose(prompt string, options []string, defaultIndex int) (string, error)

Choose asks the user to select an option through the default console.

Example:

var output bytes.Buffer
interactive := true
unicode := true
console.SetDefault(console.New(console.Config{
	Stdin:              strings.NewReader("2\n"),
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	UnicodeEnabled:     &unicode,
}))
channel, err := console.Choose("Release channel", []string{"stable", "beta"}, 0)
fmt.Printf("%q\n", output.String())
// "Release channel\n1. stable\n2. beta\n› Choose [1-2, default 1]: "
fmt.Println(channel, err)
// beta <nil>
Example

ExampleChoose demonstrates a numbered choice and non-echoed secret input.

@readme selection

package main

import (
	"bytes"
	"fmt"
	"strings"

	"github.com/goforj/console"
)

func main() {
	var output bytes.Buffer
	interactive := true
	color := false
	unicode := true
	// @readme:setup:start
	previous := console.Default()
	defer console.SetDefault(previous)
	// @readme:setup:end
	console.SetDefault(console.New(console.Config{
		Stdin:              strings.NewReader("2"),
		Stdout:             &output,
		InteractiveEnabled: &interactive,
		ColorEnabled:       &color,
		UnicodeEnabled:     &unicode,
		ReadSecret: func() (string, error) {
			return "token-value", nil
		},
	}))

	channel, _ := console.Choose("Release channel", []string{"stable", "beta"}, 0)
	secret, _ := console.AskSecret("API token")
	fmt.Printf("%q\n", output.String())
	// "Release channel\n1. stable\n2. beta\n› Choose [1-2, default 1]: \n› API token: \n"
	fmt.Println(channel, len(secret))
	// beta 11

}
Output:
"Release channel\n1. stable\n2. beta\n› Choose [1-2, default 1]: \n› API token: \n"
beta 11

func ChooseIndex

func ChooseIndex(prompt string, options []string, defaultIndex int) (int, error)

ChooseIndex asks the user to select an option index through the default console.

Example:

var output bytes.Buffer
interactive := true
unicode := true
console.SetDefault(console.New(console.Config{
	Stdin:              strings.NewReader("2\n"),
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	UnicodeEnabled:     &unicode,
}))
index, err := console.ChooseIndex("Release channel", []string{"stable", "beta"}, 0)
fmt.Printf("%q\n", output.String())
// "Release channel\n1. stable\n2. beta\n› Choose [1-2, default 1]: "
fmt.Println(index, err)
// 1 <nil>

func Colorize

func Colorize(color, value string) string

Colorize applies an ANSI color using the default console's color policy.

Example: color text

color := true
console.SetDefault(console.New(console.Config{ColorEnabled: &color}))
fmt.Printf("%q\n", console.Colorize(console.ColorCyan, "connected"))
// "\x1b[36mconnected\x1b[0m"

func Confirm

func Confirm(prompt string, defaultValue bool) (bool, error)

Confirm asks for confirmation through the default console.

Example:

var output bytes.Buffer
interactive := true
unicode := true
console.SetDefault(console.New(console.Config{
	Stdin:              strings.NewReader("yes\n"),
	Stdout:             &output,
	InteractiveEnabled: &interactive,
	UnicodeEnabled:     &unicode,
}))
confirmed, err := console.Confirm("Deploy now", false)
fmt.Printf("%q\n", output.String())
// "› Deploy now [y/N]: "
fmt.Println(confirmed, err)
// true <nil>

func Debug

func Debug(message string)

Debug prints a diagnostic message through the default console when enabled.

Example: print diagnostics

debug := true
console.SetDefault(console.New(console.Config{DebugEnabled: &debug}))
console.Debug("cache miss")
// ? cache miss

func DebugMark

func DebugMark() string

DebugMark returns the default console's debug indicator.

Example: inspect the debug mark

fmt.Println(console.DebugMark())
// ?

func Debugf

func Debugf(format string, arguments ...any)

Debugf prints a formatted diagnostic message through the default console when enabled.

Example: print formatted diagnostics

debug := true
console.SetDefault(console.New(console.Config{DebugEnabled: &debug}))
console.Debugf("attempt %d of %d", 1, 3)
// ? attempt 1 of 3

func Error

func Error(message string)

Error prints an error message through the default console.

Example: report an error

console.Error("deployment failed")
// ✖ deployment failed

func ErrorMark

func ErrorMark() string

ErrorMark returns the default console's error indicator.

Example: inspect the error mark

fmt.Println(console.ErrorMark())
// ✖

func Errorf

func Errorf(format string, arguments ...any)

Errorf prints a formatted error message through the default console.

Example: report a formatted error

console.Errorf("deployment failed: %s", "timeout")
// ✖ deployment failed: timeout

func ExpandTabs

func ExpandTabs(value string) string

ExpandTabs replaces tabs with spaces at eight-cell stops on each line. ANSI escape sequences do not affect tab positions.

Example: expand terminal tab stops

fmt.Printf("%q\n", console.ExpandTabs("a\tb"))
// "a       b"

func Fatal

func Fatal(message string)

Fatal prints an error through the default console and exits with status 1.

Example: report a fatal error

console.SetDefault(console.New(console.Config{
	Exit: func(code int) { fmt.Println("exit", code) },
}))
console.Fatal("invalid configuration")
// ✖ invalid configuration
// exit 1

func Fatalf

func Fatalf(format string, arguments ...any)

Fatalf prints a formatted error through the default console and exits with status 1.

Example: report a formatted fatal error

console.SetDefault(console.New(console.Config{
	Exit: func(code int) { fmt.Println("exit", code) },
}))
console.Fatalf("invalid port: %d", 0)
// ✖ invalid port: 0
// exit 1

func Indent

func Indent(value, prefix string) string

Indent prefixes every line in value with prefix. Empty input remains empty.

Example: indent multiline text

fmt.Printf("%q\n", console.Indent("one\ntwo", "> "))
// "> one\n> two"

func Info

func Info(message string)

Info prints an informational message through the default console.

Example: share information

console.Info("using cached dependencies")
// · using cached dependencies

func InfoMark

func InfoMark() string

InfoMark returns the default console's informational indicator.

Example: inspect the information mark

fmt.Println(console.InfoMark())
// ·

func Infof

func Infof(format string, arguments ...any)

Infof prints a formatted informational message through the default console.

Example: share formatted information

console.Infof("using %s dependencies", "cached")
// · using cached dependencies

func IsInteractive

func IsInteractive() bool

IsInteractive reports whether the default console is interactive.

Example:

previous := console.Default()
defer console.SetDefault(previous)
interactive := true
console.SetDefault(console.New(console.Config{InteractiveEnabled: &interactive}))

fmt.Println(console.IsInteractive())
// true

func KeyValueMap

func KeyValueMap(values map[string]any)

KeyValueMap prints a sorted key/value map through the default console.

Example: print map values in stable key order

console.KeyValueMap(map[string]any{"port": 8080, "mode": "production"})
// mode  production
// port  8080

func KeyValues

func KeyValues(entries ...KeyValue)

KeyValues prints ordered key/value entries through the default console.

Example: print an ordered deployment summary

console.KeyValues(
	console.KV("Mode", "production"),
	console.KV("Port", 8080),
)
// Mode  production
// Port  8080

func List

func List(items ...string)

List prints an unordered list through the default console.

Example: print a short checklist

console.List("build", "test", "publish")
// • build
// • test
// • publish
Example

ExampleList demonstrates the two common list presentations.

@readme lists

package main

import (
	"os"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	unicode := true
	defer useExampleDefault(console.Config{
		Stdout:         os.Stdout,
		ColorEnabled:   &color,
		UnicodeEnabled: &unicode,
	})()
	// @readme:setup:end

	console.List("validate configuration", "connect to database")
	// • validate configuration
	// • connect to database
	console.NumberedList("build", "test", "publish")
	// 1. build
	// 2. test
	// 3. publish

}
Output:
• validate configuration
• connect to database
1. build
2. test
3. publish

func NewLine

func NewLine()

NewLine writes one blank line through the default console.

Example: separate output

console.Println("before")
console.NewLine()
console.Println("after")
// before
//
// after

func NumberedList

func NumberedList(items ...string)

NumberedList prints an ordered list through the default console.

Example: print release steps

console.NumberedList("build", "test", "publish")
// 1. build
// 2. test
// 3. publish

func PadCenter

func PadCenter(value string, width int) string

PadCenter adds spaces around every line until it reaches width terminal cells. Odd padding places the extra space on the right. Lines already at or beyond width are unchanged. Tabs are expanded only on lines that need padding so their alignment remains stable.

Example: center text

fmt.Printf("%q\n", console.PadCenter("go", 6))
// "  go  "

func PadLeft

func PadLeft(value string, width int) string

PadLeft prepends spaces until every line reaches width terminal cells. Lines already at or beyond width are unchanged. Tabs are expanded only on lines that need padding because leading spaces otherwise change their terminal tab stops.

Example: left-pad text

fmt.Printf("%q\n", console.PadLeft("go", 5))
// "   go"

func PadRight

func PadRight(value string, width int) string

PadRight appends spaces until every line reaches width terminal cells. Lines already at or beyond width are unchanged.

Example: right-pad text

fmt.Printf("%q\n", console.PadRight("go", 5))
// "go   "

func Print

func Print(values ...any)

Print writes values through the default console without adding a newline.

Example: print without a newline

var output bytes.Buffer
console.SetDefault(console.New(console.Config{Stdout: &output}))
console.Print("deploying")
fmt.Printf("%q\n", output.String())
// "deploying"

func Printf

func Printf(format string, arguments ...any)

Printf writes formatted output through the default console without adding a newline.

Example: print formatted output

var output bytes.Buffer
console.SetDefault(console.New(console.Config{Stdout: &output}))
console.Printf("copied %d files", 3)
fmt.Printf("%q\n", output.String())
// "copied 3 files"

func Println

func Println(values ...any)

Println writes values through the default console followed by a newline.

Example: print a line

console.Println("deployment complete")
// deployment complete
Example

ExamplePrintln demonstrates ordinary output and writer adapters that cooperate with transient displays.

@readme output

package main

import (
	"fmt"
	"os"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	unicode := true
	defer useExampleDefault(console.Config{
		Stdout:         os.Stdout,
		Stderr:         os.Stdout,
		ColorEnabled:   &color,
		UnicodeEnabled: &unicode,
	})()
	// @readme:setup:end

	console.Println("plain output")
	// plain output
	fmt.Fprintln(console.StdoutWriter(), "streamed output")
	// streamed output
	fmt.Fprintln(console.StderrWriter(), "diagnostic output")
	// diagnostic output

}
Output:
plain output
streamed output
diagnostic output

func RenderBox

func RenderBox(content string, options ...BoxOption) string

RenderBox renders a box using the default console.

Example: compose a box without printing it directly

fmt.Println(console.RenderBox("complete", console.BoxColor("")))
// ┌──────────┐
// │ complete │
// └──────────┘

func RenderKeyValueMap

func RenderKeyValueMap(values map[string]any) string

RenderKeyValueMap renders a sorted key/value map through the default console.

Example: compose deterministic map output

fmt.Println(console.RenderKeyValueMap(map[string]any{"port": 8080, "mode": "production"}))
// mode  production
// port  8080

func RenderKeyValues

func RenderKeyValues(entries ...KeyValue) string

RenderKeyValues renders ordered key/value entries through the default console.

Example: compose an ordered summary

fmt.Println(console.RenderKeyValues(
	console.KV("Mode", "production"),
	console.KV("Port", 8080),
))
// Mode  production
// Port  8080

func RenderList

func RenderList(items ...string) string

RenderList renders an unordered list through the default console.

Example: compose an unordered list

fmt.Println(console.RenderList("build", "test"))
// • build
// • test

func RenderNumberedList

func RenderNumberedList(items ...string) string

RenderNumberedList renders an ordered list through the default console.

Example: compose ordered steps

fmt.Println(console.RenderNumberedList("build", "test"))
// 1. build
// 2. test

func RenderRule

func RenderRule(title string) string

RenderRule renders a horizontal rule through the default console.

Example: compose a phase separator

previous := console.Default()
defer console.SetDefault(previous)
console.SetDefault(console.New(console.Config{Width: 16}))
fmt.Println(console.RenderRule("Next"))
// ── Next ────────

func RenderSection

func RenderSection(title string) string

RenderSection renders a section heading through the default console.

Example: compose a section heading

fmt.Println(console.RenderSection("Deployment"))
// ◇ Deployment

func RenderTable

func RenderTable(headers []string, rows [][]string, options ...TableOption) string

RenderTable renders a table using the default console.

Example: compose a bordered table

fmt.Println(console.RenderTable(
	[]string{"Name", "State"},
	[][]string{{"worker", "idle"}},
))
// ┌────────┬───────┐
// │ Name   │ State │
// ├────────┼───────┤
// │ worker │ idle  │
// └────────┴───────┘

func RenderTree

func RenderTree(nodes ...TreeNode) string

RenderTree renders a static tree through the default console.

Example: compose a service tree

fmt.Println(console.RenderTree(console.Node("services",
	console.Node("api"),
	console.Node("worker"),
)))
// services
// ├── api
// └── worker

func Rule

func Rule(title string)

Rule prints a horizontal rule through the default console.

Example: separate two phases

previous := console.Default()
defer console.SetDefault(previous)
console.SetDefault(console.New(console.Config{Width: 16}))
console.Rule("Next")
// ── Next ────────

func Section

func Section(title string)

Section prints a section heading through the default console.

Example: print a deployment section

console.Section("Deployment")
// ◇ Deployment
Example

ExampleSection demonstrates render-only layout helpers for composing deployment summaries.

@readme summaries

package main

import (
	"fmt"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	unicode := true
	defer useExampleDefault(console.Config{
		ColorEnabled:   &color,
		UnicodeEnabled: &unicode,
		Width:          24,
	})()
	// @readme:setup:end

	fmt.Println(console.RenderSection("Deployment"))
	// ◇ Deployment
	fmt.Println(console.RenderKeyValues(
		console.KV("Environment", "production"),
		console.KV("Region", "eu-west-1"),
	))
	// Environment  production
	// Region       eu-west-1
	fmt.Println(console.RenderRule("Next"))
	// ── Next ────────────────

}
Output:
◇ Deployment
Environment  production
Region       eu-west-1
── Next ────────────────

func SetDefault

func SetDefault(console *Console)

SetDefault replaces the console used by package-level helpers. It panics when console is nil because package helpers always require a usable runtime.

Example:

previous := console.Default()
defer console.SetDefault(previous)

var output bytes.Buffer
console.SetDefault(console.New(console.Config{Stdout: &output}))
console.Println("ready")
fmt.Print(output.String())
// ready

func StderrWriter

func StderrWriter() io.Writer

StderrWriter returns a coordinated writer using a snapshot of the current default console. Later calls to SetDefault do not retarget an existing writer.

Example: pass console errors to an io.Writer API

fmt.Fprintln(console.StderrWriter(), "download failed")
// download failed

func StdoutWriter

func StdoutWriter() io.Writer

StdoutWriter returns a coordinated writer using a snapshot of the current default console. Later calls to SetDefault do not retarget an existing writer.

Example: pass console output to an io.Writer API

fmt.Fprintln(console.StdoutWriter(), "download complete")
// download complete

func StripANSI

func StripANSI(value string) string

StripANSI removes complete ANSI CSI, OSC, and ESC sequences from value. Incomplete escape sequences are retained so malformed input is not silently discarded.

Example: remove terminal styling

fmt.Println(console.StripANSI(console.ColorRed + "failed" + console.ColorReset))
// failed
Example

ExampleStripANSI demonstrates terminal-cell-aware shaping for plain and styled text.

@readme text

package main

import (
	"fmt"

	"github.com/goforj/console"
)

func main() {
	styled := "\x1b[31mGo 世界\x1b[0m"

	fmt.Println(console.StripANSI(styled))
	// Go 世界
	fmt.Println(console.VisibleWidth(styled))
	// 7
	fmt.Printf("%q\n", console.PadLeft("Go", 6))
	// "    Go"
	fmt.Printf("%q\n", console.PadCenter("Go", 6))
	// "  Go  "
	fmt.Println(console.TruncateMiddle("github.com/goforj/console", 15))
	// github.…console
	fmt.Println(console.Wrap("deploying worker service", 10))
	// deploying
	// worker
	// service

}
Output:
Go 世界
7
"    Go"
"  Go  "
github.…console
deploying
worker
service

func Style

func Style(value string, styles ...string) string

Style applies ANSI styles using the default console's color policy.

Example: compose text styles

color := true
console.SetDefault(console.New(console.Config{ColorEnabled: &color}))
fmt.Printf("%q\n", console.Style("ready", console.StyleBold, console.ColorGreen))
// "\x1b[1m\x1b[32mready\x1b[0m"
Example

ExampleStyle demonstrates marks and styles that follow the console's output policy.

@readme styling

package main

import (
	"fmt"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	unicode := true
	defer useExampleDefault(console.Config{
		ColorEnabled:   &color,
		UnicodeEnabled: &unicode,
	})()
	// @readme:setup:end

	fmt.Println(console.ActionMark(), console.SuccessMark(), console.ErrorMark())
	// · ✔ ✖
	fmt.Println(console.Style("release ready", console.StyleBold, console.ColorGreen))
	// release ready

}
Output:
· ✔ ✖
release ready

func Success

func Success(message string)

Success prints a success message through the default console.

Example: report success

console.Success("release published")
// ✔ release published

func SuccessMark

func SuccessMark() string

SuccessMark returns the default console's success indicator.

Example: inspect the success mark

fmt.Println(console.SuccessMark())
// ✔

func Successf

func Successf(format string, arguments ...any)

Successf prints a formatted success message through the default console.

Example: report formatted success

console.Successf("published %s", "v1.2.0")
// ✔ published v1.2.0

func SupportsColor

func SupportsColor() bool

SupportsColor reports whether the default console emits ANSI styling.

Example:

previous := console.Default()
defer console.SetDefault(previous)
color := true
console.SetDefault(console.New(console.Config{ColorEnabled: &color}))

fmt.Println(console.SupportsColor())
// true

func SupportsUnicode

func SupportsUnicode() bool

SupportsUnicode reports whether the default console uses Unicode presentation characters.

Example:

previous := console.Default()
defer console.SetDefault(previous)
unicode := false
console.SetDefault(console.New(console.Config{UnicodeEnabled: &unicode}))

fmt.Println(console.SupportsUnicode())
// false

func Table

func Table(headers []string, rows [][]string, options ...TableOption)

Table prints a table through the default console.

Example: print the default bordered table

console.Table(
	[]string{"Name", "State"},
	[][]string{{"api", "ready"}},
)
// ┌──────┬───────┐
// │ Name │ State │
// ├──────┼───────┤
// │ api  │ ready │
// └──────┴───────┘
Example

ExampleTable demonstrates the bordered table used by default.

@readme tables

package main

import (
	"os"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	unicode := true
	defer useExampleDefault(console.Config{
		Stdout:         os.Stdout,
		ColorEnabled:   &color,
		UnicodeEnabled: &unicode,
	})()
	// @readme:setup:end

	console.Table(
		[]string{"Service", "State"},
		[][]string{{"api", "ready"}, {"worker", "ready"}},
	)
	// ┌─────────┬───────┐
	// │ Service │ State │
	// ├─────────┼───────┤
	// │ api     │ ready │
	// │ worker  │ ready │
	// └─────────┴───────┘

}
Output:
┌─────────┬───────┐
│ Service │ State │
├─────────┼───────┤
│ api     │ ready │
│ worker  │ ready │
└─────────┴───────┘
Example (Ascii)

ExampleTable_ascii demonstrates the ASCII fallback and centered columns for constrained terminals.

@readme table-ascii

package main

import (
	"os"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	unicode := false
	defer useExampleDefault(console.Config{
		Stdout:         os.Stdout,
		ColorEnabled:   &color,
		UnicodeEnabled: &unicode,
	})()
	// @readme:setup:end

	console.Table(
		[]string{"Status", "Count"},
		[][]string{{"ready", "2"}, {"waiting", "12"}},
		console.TableWidths(8, 5),
		console.TableCenterAlign(0),
		console.TableRightAlign(1),
	)
	// +----------+-------+
	// |  Status  | Count |
	// +----------+-------+
	// |  ready   |     2 |
	// | waiting  |    12 |
	// +----------+-------+

}
Output:
+----------+-------+
|  Status  | Count |
+----------+-------+
|  ready   |     2 |
| waiting  |    12 |
+----------+-------+
Example (Options)

ExampleTable_options demonstrates the restrained options for compact, fixed, aligned, and wrapped columns.

@readme table-options

package main

import (
	"os"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	unicode := true
	defer useExampleDefault(console.Config{
		Stdout:         os.Stdout,
		ColorEnabled:   &color,
		UnicodeEnabled: &unicode,
	})()
	// @readme:setup:end

	console.Table(
		[]string{"Task", "Seconds"},
		[][]string{{"compile packages", "12"}, {"test", "3"}},
		console.TableCompact(),
		console.TableWidths(8, 7),
		console.TableRightAlign(1),
	)
	// Task      Seconds
	// ────────  ───────
	// compile        12
	// packages
	// test            3

}
Output:
Task      Seconds
────────  ───────
compile        12
packages
test            3

func Tree

func Tree(nodes ...TreeNode)

Tree prints a static tree through the default console.

Example: print a project tree

console.Tree(console.Node("project",
	console.Node("cmd", console.Node("deploy")),
	console.Node("README.md"),
))
// project
// ├── cmd
// │   └── deploy
// └── README.md
Example

ExampleTree demonstrates an ordered static hierarchy with automatic connectors.

@readme trees

package main

import (
	"os"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	unicode := true
	defer useExampleDefault(console.Config{
		Stdout:         os.Stdout,
		ColorEnabled:   &color,
		UnicodeEnabled: &unicode,
	})()
	// @readme:setup:end

	console.Tree(console.Node("project",
		console.Node("cmd", console.Node("deploy")),
		console.Node("internal"),
		console.Node("README.md"),
	))
	// project
	// ├── cmd
	// │   └── deploy
	// ├── internal
	// └── README.md

}
Output:
project
├── cmd
│   └── deploy
├── internal
└── README.md

func Truncate

func Truncate(value string, width int) string

Truncate shortens each line of value to width terminal cells and uses an ellipsis when content is removed. Active SGR styles and OSC 8 hyperlinks are closed before the ellipsis. Values less than one produce an empty string.

Example: shorten text

fmt.Println(console.Truncate("deployment", 7))
// deploy…

func TruncateMiddle

func TruncateMiddle(value string, width int) string

TruncateMiddle shortens each line of value to width terminal cells by replacing its center with an ellipsis. Active SGR styles and OSC 8 hyperlinks are kept with the visible text on either side of the ellipsis. Values less than one produce an empty string.

Example: preserve both ends

fmt.Println(console.TruncateMiddle("abcdefghij", 7))
// abc…hij

func VisibleWidth

func VisibleWidth(value string) int

VisibleWidth returns the largest terminal-cell width among value's lines. ANSI escapes and combining characters occupy no cells, tabs advance to an eight-cell stop, and common East Asian and emoji runes occupy two cells.

Example: measure terminal cells

fmt.Println(console.VisibleWidth("Go界"))
// 4

func Warn

func Warn(message string)

Warn prints a warning message through the default console.

Example: report a warning

console.Warn("configuration is deprecated")
// ! configuration is deprecated

func WarnMark

func WarnMark() string

WarnMark returns the default console's warning indicator.

Example: inspect the warning mark

fmt.Println(console.WarnMark())
// !

func Warnf

func Warnf(format string, arguments ...any)

Warnf prints a formatted warning message through the default console.

Example: report a formatted warning

console.Warnf("retrying in %d seconds", 5)
// ! retrying in 5 seconds

func Width

func Width() int

Width returns the width of the default console.

Example:

previous := console.Default()
defer console.SetDefault(previous)
console.SetDefault(console.New(console.Config{Width: 100}))

fmt.Println(console.Width())
// 100

func Wrap

func Wrap(value string, width int) string

Wrap inserts newlines so each resulting line fits within width terminal cells where possible. Existing line breaks and ANSI styling are preserved; active SGR styles and OSC 8 hyperlinks are balanced at each line boundary so they cannot bleed into surrounding layout. Long unbroken words wrap at cell boundaries. Breakable whitespace at the beginning or end of a resulting line is removed. Values less than one are returned unchanged.

Example: wrap text to a terminal width

fmt.Printf("%q\n", console.Wrap("ship the release", 8))
// "ship the\nrelease"

Types

type BoxOption

type BoxOption func(*boxOptions)

BoxOption configures one rendered box.

Example: collect box options for reuse

options := []console.BoxOption{
	console.BoxTitle("Status"),
	console.BoxColor(""),
}
fmt.Println(console.RenderBox("ready", options...))
// ┌─ Status ┐
// │ ready   │
// └─────────┘

func BoxColor

func BoxColor(color string) BoxOption

BoxColor sets the ANSI color used for borders when styling is enabled. An empty color leaves borders unstyled.

Example: color a healthy status border

fmt.Println(console.StripANSI(console.RenderBox("healthy", console.BoxColor(console.ColorGreen))))
// ┌─────────┐
// │ healthy │
// └─────────┘

func BoxPadding

func BoxPadding(padding int) BoxOption

BoxPadding sets the horizontal padding on both sides of the content. Negative values are treated as zero, and padding is capped when necessary to fit the console width.

Example: remove box padding

fmt.Println(console.RenderBox("ready", console.BoxPadding(0), console.BoxColor("")))
// ┌─────┐
// │ready│
// └─────┘

func BoxTitle

func BoxTitle(title string) BoxOption

BoxTitle adds a title to the top border.

Example: title a status box

fmt.Println(console.RenderBox("ready", console.BoxTitle("Status"), console.BoxColor("")))
// ┌─ Status ┐
// │ ready   │
// └─────────┘

func BoxWidth

func BoxWidth(width int) BoxOption

BoxWidth fixes the total visible width, including borders and padding. Values below the structural minimum expand enough to preserve a valid frame. Values less than one select an automatic width bounded by the console width. Larger values are bounded by the console width when the structural minimum permits.

Example: fix a box width

fmt.Println(console.RenderBox("ready", console.BoxWidth(16), console.BoxColor("")))
// ┌──────────────┐
// │ ready        │
// └──────────────┘

type Config

type Config struct {
	// Stdin supplies answers to prompts.
	Stdin io.Reader
	// Stdout receives ordinary and successful output.
	Stdout io.Writer
	// Stderr receives errors and fatal messages.
	Stderr io.Writer

	// ColorEnabled forces ANSI styling on or off. Nil enables environment and terminal detection.
	ColorEnabled *bool
	// DebugEnabled forces debug messages on or off. Nil reads the supported debug environment variables.
	DebugEnabled *bool
	// InteractiveEnabled overrides terminal detection for prompt-oriented callers.
	InteractiveEnabled *bool
	// UnicodeEnabled selects Unicode or ASCII presentation characters. Nil enables conservative environment detection.
	UnicodeEnabled *bool
	// AnimationsEnabled permits or disables transient loader and progress output. Even when true, stdout must be a terminal.
	AnimationsEnabled *bool

	// Width fixes the available output width. Values less than one use terminal detection and then an 80-column fallback.
	// Configured, detected, and environment widths are capped at 32,768 columns to keep layout allocations practical.
	Width int
	// LoaderInterval controls animated loader frame timing. Values less than or equal to zero use 80 milliseconds.
	LoaderInterval time.Duration
	// Marks replaces the complete semantic symbol set when non-nil.
	Marks *Marks

	// Getenv reads environment variables.
	Getenv func(string) string
	// IsTerminal reports whether a file descriptor is attached to a terminal.
	IsTerminal func(int) bool
	// GetSize returns the terminal dimensions for a file descriptor.
	GetSize func(int) (width, height int, err error)
	// Exit terminates the process for Fatal and Fatalf.
	Exit func(int)
	// ReadSecret reads one value without echoing it to the terminal.
	// Nil uses terminal password input; tests and custom terminals can inject a reader.
	ReadSecret func() (string, error)
}

Config configures a Console instance.

Every field is optional. Nil functions and writers use their operating-system defaults, while nil boolean pointers select automatic behavior.

Example: configure a fixed output width

configuration := console.Config{Width: 100}
commandConsole := console.New(configuration)
fmt.Println(commandConsole.Width())
// 100

type Console

type Console struct {
	// contains filtered or unexported fields
}

Console coordinates output policy, terminal capabilities, prompts, and transient displays. A Console is safe for concurrent message writes and must be constructed with New.

Example: declare an isolated console

var commandConsole *console.Console = console.New(console.Config{Width: 120})
fmt.Println(commandConsole.Width())
// 120

func Default

func Default() *Console

Default returns the console currently used by package-level helpers.

Example:

fmt.Println(console.Default() != nil)
// true

func New

func New(config Config) *Console

New creates an isolated console with optional runtime overrides.

Example:

var output bytes.Buffer
color := false
unicode := true
commandConsole := console.New(console.Config{
	Stdout:         &output,
	ColorEnabled:   &color,
	UnicodeEnabled: &unicode,
})
commandConsole.Success("ready")
fmt.Print(output.String())
// ✔ ready
Example

ExampleNew demonstrates an isolated console for libraries and independently configured commands.

@readme instance

package main

import (
	"bytes"
	"fmt"

	"github.com/goforj/console"
)

func main() {
	var output bytes.Buffer
	color := false
	unicode := false
	commandConsole := console.New(console.Config{
		Stdout:         &output,
		ColorEnabled:   &color,
		UnicodeEnabled: &unicode,
	})

	commandConsole.Success("Isolated output")
	fmt.Print(output.String())
	// + Isolated output

}
Output:
+ Isolated output

func (*Console) Action

func (c *Console) Action(message string)

Action prints an action message.

func (*Console) ActionMark

func (c *Console) ActionMark() string

ActionMark returns the action indicator.

func (*Console) Actionf

func (c *Console) Actionf(format string, arguments ...any)

Actionf prints a formatted action message.

func (*Console) Ask

func (c *Console) Ask(prompt string) (string, error)

Ask prompts for one trimmed line of input. An empty line is returned as an empty string; EOF without input is returned as an error.

func (*Console) AskDefault

func (c *Console) AskDefault(prompt, defaultValue string) (string, error)

AskDefault prompts for one trimmed line and returns defaultValue when the line is empty.

func (*Console) AskSecret

func (c *Console) AskSecret(prompt string) (string, error)

AskSecret prompts for one value without echoing input to the terminal. Config.ReadSecret can provide compatible behavior for tests and custom terminals.

func (*Console) Box

func (c *Console) Box(content string, options ...BoxOption)

Box prints content inside a box followed by a newline.

func (*Console) Choose

func (c *Console) Choose(prompt string, options []string, defaultIndex int) (string, error)

Choose prints numbered options and returns the selected value. defaultIndex is zero-based; use -1 to require an explicit choice.

func (*Console) ChooseIndex

func (c *Console) ChooseIndex(prompt string, options []string, defaultIndex int) (int, error)

ChooseIndex prints numbered options and returns the selected zero-based index. defaultIndex is zero-based; use -1 to require an explicit choice.

func (*Console) Colorize

func (c *Console) Colorize(color, value string) string

Colorize applies one ANSI color to value when color output is enabled.

func (*Console) Confirm

func (c *Console) Confirm(prompt string, defaultValue bool) (bool, error)

Confirm prompts until it reads yes or no, using defaultValue for an empty line. Accepted answers are y, yes, n, and no in any letter case.

func (*Console) Debug

func (c *Console) Debug(message string)

Debug prints a diagnostic message when debug output is enabled.

func (*Console) DebugMark

func (c *Console) DebugMark() string

DebugMark returns the debug indicator.

func (*Console) Debugf

func (c *Console) Debugf(format string, arguments ...any)

Debugf prints a formatted diagnostic message when debug output is enabled.

func (*Console) Error

func (c *Console) Error(message string)

Error prints an error message to stderr.

func (*Console) ErrorMark

func (c *Console) ErrorMark() string

ErrorMark returns the error indicator using the stderr color policy.

func (*Console) Errorf

func (c *Console) Errorf(format string, arguments ...any)

Errorf prints a formatted error message to stderr.

func (*Console) ExpandTabs

func (c *Console) ExpandTabs(value string) string

ExpandTabs replaces tabs through a Console instance. Its behavior matches the package-level ExpandTabs helper.

func (*Console) Fatal

func (c *Console) Fatal(message string)

Fatal prints an error message and exits with status 1.

func (*Console) Fatalf

func (c *Console) Fatalf(format string, arguments ...any)

Fatalf prints a formatted error message and exits with status 1.

func (*Console) Indent

func (c *Console) Indent(value, prefix string) string

Indent prefixes each line through a Console instance. Its behavior matches the package-level Indent helper.

func (*Console) Info

func (c *Console) Info(message string)

Info prints an informational message.

func (*Console) InfoMark

func (c *Console) InfoMark() string

InfoMark returns the informational indicator.

func (*Console) Infof

func (c *Console) Infof(format string, arguments ...any)

Infof prints a formatted informational message.

func (*Console) IsInteractive

func (c *Console) IsInteractive() bool

IsInteractive reports whether both configured input and output are terminals unless explicitly overridden.

func (*Console) KeyValueMap

func (c *Console) KeyValueMap(values map[string]any)

KeyValueMap prints a map in sorted-key order for deterministic output.

func (*Console) KeyValues

func (c *Console) KeyValues(entries ...KeyValue)

KeyValues prints ordered and visibly aligned key/value entries.

func (*Console) List

func (c *Console) List(items ...string)

List prints an unordered list and applies hanging indentation to wrapped items.

func (*Console) Loader

func (c *Console) Loader(message string) *Loader

Loader constructs a loader without starting it.

func (*Console) NewLine

func (c *Console) NewLine()

NewLine writes one blank line to ordinary output.

func (*Console) NumberedList

func (c *Console) NumberedList(items ...string)

NumberedList prints a one-based ordered list with aligned numeric prefixes.

func (*Console) PadCenter

func (c *Console) PadCenter(value string, width int) string

PadCenter pads value on both sides through a Console instance. Its behavior matches the package-level PadCenter helper.

func (*Console) PadLeft

func (c *Console) PadLeft(value string, width int) string

PadLeft pads value on the left through a Console instance. Its behavior matches the package-level PadLeft helper.

func (*Console) PadRight

func (c *Console) PadRight(value string, width int) string

PadRight pads value to a terminal-cell width through a Console instance. Its behavior matches the package-level PadRight helper.

func (*Console) Print

func (c *Console) Print(values ...any)

Print writes values to ordinary output without adding a newline.

func (*Console) Printf

func (c *Console) Printf(format string, arguments ...any)

Printf writes formatted ordinary output without adding a newline.

func (*Console) Println

func (c *Console) Println(values ...any)

Println writes values to ordinary output followed by a newline.

func (*Console) Progress

func (c *Console) Progress(total int, message string) *Progress

Progress constructs a determinate progress display without starting it. Start returns an error when total is less than one.

func (*Console) RenderBox

func (c *Console) RenderBox(content string, options ...BoxOption) string

RenderBox returns content inside a box without a trailing newline.

func (*Console) RenderKeyValueMap

func (c *Console) RenderKeyValueMap(values map[string]any) string

RenderKeyValueMap returns map entries in sorted-key order without a trailing newline. Empty maps produce an empty string.

func (*Console) RenderKeyValues

func (c *Console) RenderKeyValues(entries ...KeyValue) string

RenderKeyValues returns ordered and visibly aligned key/value entries without a trailing newline. Empty entries produce an empty string.

func (*Console) RenderList

func (c *Console) RenderList(items ...string) string

RenderList returns an unordered list with hanging indentation and no trailing newline. Empty items produce an empty string.

func (*Console) RenderNumberedList

func (c *Console) RenderNumberedList(items ...string) string

RenderNumberedList returns a one-based ordered list with hanging indentation and no trailing newline. Empty items produce an empty string.

func (*Console) RenderRule

func (c *Console) RenderRule(title string) string

RenderRule returns a horizontal rule without a trailing newline. The optional title interrupts the rule when the configured width allows it.

func (*Console) RenderSection

func (c *Console) RenderSection(title string) string

RenderSection returns a visually distinct section heading without a trailing newline.

func (*Console) RenderTable

func (c *Console) RenderTable(headers []string, rows [][]string, options ...TableOption) string

RenderTable returns a table without a trailing newline. Empty headers and rows produce an empty string.

func (*Console) RenderTree

func (c *Console) RenderTree(nodes ...TreeNode) string

RenderTree returns a static tree without a trailing newline. Root labels remain unprefixed, while descendants use connectors selected by the console's Unicode policy.

func (*Console) Rule

func (c *Console) Rule(title string)

Rule prints a horizontal rule, optionally interrupted by title.

func (*Console) Section

func (c *Console) Section(title string)

Section prints a visually distinct section heading.

func (*Console) StderrWriter

func (c *Console) StderrWriter() io.Writer

StderrWriter returns a writer coordinated with this console's prompts and transient displays. The destination is captured when the adapter is constructed, and its write results are preserved.

func (*Console) StdoutWriter

func (c *Console) StdoutWriter() io.Writer

StdoutWriter returns a writer coordinated with this console's prompts and transient displays. The destination is captured when the adapter is constructed, and its write results are preserved.

func (*Console) StripANSI

func (c *Console) StripANSI(value string) string

StripANSI removes complete ANSI sequences from value through a Console instance. Its behavior matches the package-level StripANSI helper.

func (*Console) Style

func (c *Console) Style(value string, styles ...string) string

Style applies ANSI style sequences to value when color output is enabled.

func (*Console) Success

func (c *Console) Success(message string)

Success prints a success message.

func (*Console) SuccessMark

func (c *Console) SuccessMark() string

SuccessMark returns the success indicator.

func (*Console) Successf

func (c *Console) Successf(format string, arguments ...any)

Successf prints a formatted success message.

func (*Console) SupportsColor

func (c *Console) SupportsColor() bool

SupportsColor reports whether ordinary output should contain ANSI styling.

func (*Console) SupportsUnicode

func (c *Console) SupportsUnicode() bool

SupportsUnicode reports whether the console selected Unicode presentation characters.

func (*Console) Table

func (c *Console) Table(headers []string, rows [][]string, options ...TableOption)

Table prints a table followed by a newline. The default presentation is bordered; ragged rows are padded, and cells wrap when their automatic or configured columns must shrink.

func (*Console) Tree

func (c *Console) Tree(nodes ...TreeNode)

Tree prints a static tree followed by a newline. Empty trees produce no output.

func (*Console) Truncate

func (c *Console) Truncate(value string, width int) string

Truncate shortens value through a Console instance using the public Unicode ellipsis contract. Its behavior matches the package-level Truncate helper regardless of the console's layout policy.

func (*Console) TruncateMiddle

func (c *Console) TruncateMiddle(value string, width int) string

TruncateMiddle shortens value through a Console instance using the public Unicode ellipsis contract. Its behavior matches the package-level TruncateMiddle helper regardless of the console's layout policy.

func (*Console) VisibleWidth

func (c *Console) VisibleWidth(value string) int

VisibleWidth returns value's terminal-cell width through a Console instance. Its behavior matches the package-level VisibleWidth helper.

func (*Console) Warn

func (c *Console) Warn(message string)

Warn prints a warning message.

func (*Console) WarnMark

func (c *Console) WarnMark() string

WarnMark returns the warning indicator.

func (*Console) Warnf

func (c *Console) Warnf(format string, arguments ...any)

Warnf prints a formatted warning message.

func (*Console) Width

func (c *Console) Width() int

Width returns the configured or detected terminal width, capped at 32,768 columns, and falls back to 80 columns.

func (*Console) Wrap

func (c *Console) Wrap(value string, width int) string

Wrap inserts terminal-cell-aware line breaks through a Console instance. Its behavior matches the package-level Wrap helper.

type KeyValue

type KeyValue struct {
	// Key is the label displayed in the left column.
	Key string
	// Value is formatted with fmt.Sprint in the right column.
	Value any
}

KeyValue contains one ordered label and value for KeyValues.

Example: construct an ordered deployment summary

entries := []console.KeyValue{
	{Key: "Mode", Value: "production"},
	{Key: "Port", Value: 8080},
}
console.KeyValues(entries...)
// Mode  production
// Port  8080

func KV

func KV(key string, value any) KeyValue

KV creates one ordered key/value entry.

Example: build an ordered summary entry

console.KeyValues(console.KV("Region", "eu-west-1"))
// Region  eu-west-1

type Loader

type Loader struct {
	// contains filtered or unexported fields
}

Loader presents one transient activity line on terminals and stable semantic lines in redirected output. A Loader is concurrency-safe, single-use, and must be constructed with Console.Loader or NewLoader; the first call to Stop, Success, Warn, or Fail wins.

Example: run a loader to completion

animations := false
color := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	ColorEnabled:      &color,
	UnicodeEnabled:    &unicode,
}))
var loader *console.Loader = console.NewLoader("Building application")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Building application
loader.Success("Application ready")
// ✔ Application ready

func NewLoader

func NewLoader(message string) *Loader

NewLoader constructs a loader using a snapshot of the current default console. It does not start the loader.

Example:

animations := false
color := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	ColorEnabled:      &color,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Downloading modules")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Downloading modules
loader.Success("Modules ready")
// ✔ Modules ready
Example

ExampleNewLoader demonstrates stable loader outcomes when output is redirected.

@readme loader

package main

import (
	"os"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	animations := false
	unicode := true
	defer useExampleDefault(console.Config{
		Stdout:            os.Stdout,
		Stderr:            os.Stdout,
		ColorEnabled:      &color,
		UnicodeEnabled:    &unicode,
		AnimationsEnabled: &animations,
	})()
	// @readme:setup:end

	download := console.NewLoader("Downloading modules")
	if err := download.Start(); err != nil {
		console.Error(err.Error())
		return
	}
	// · Downloading modules
	defer download.Stop()
	download.Success("Modules ready")
	// ✔ Modules ready

	publish := console.NewLoader("Publishing release")
	if err := publish.Start(); err != nil {
		console.Error(err.Error())
		return
	}
	// · Publishing release
	defer publish.Stop()
	publish.Fail("Registry refused upload")
	// ✖ Registry refused upload

}
Output:
· Downloading modules
✔ Modules ready
· Publishing release
✖ Registry refused upload

func (*Loader) Fail

func (l *Loader) Fail(message string)

Fail completes the loader with an error message on stderr. An empty message reuses the loader's current message.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Uploading release")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Uploading release
loader.Fail("Registry refused upload")
// ✖ Registry refused upload

func (*Loader) Start

func (l *Loader) Start() error

Start begins the loader and is harmless when called more than once. Animated loaders can return ErrTransientActive when another live display owns the same console.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Building application")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Building application
loader.Stop()

func (*Loader) Stop

func (l *Loader) Stop()

Stop removes the transient loader without printing a completion message.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Checking configuration")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Checking configuration
loader.Stop()

func (*Loader) Success

func (l *Loader) Success(message string)

Success completes the loader with a success message. An empty message reuses the loader's current message.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Publishing release")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Publishing release
loader.Success("Release published")
// ✔ Release published

func (*Loader) Update

func (l *Loader) Update(message string)

Update changes the loader message and immediately redraws an active animation. Updates after a terminal operation are ignored.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Downloading modules")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Downloading modules
loader.Update("Verifying modules")
loader.Success("")
// ✔ Verifying modules

func (*Loader) Warn

func (l *Loader) Warn(message string)

Warn completes the loader with a warning message. An empty message reuses the loader's current message.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
loader := console.NewLoader("Checking optional tools")
if err := loader.Start(); err != nil {
	panic(err)
}
// · Checking optional tools
loader.Warn("Optional tool not found")
// ! Optional tool not found

type Marks

type Marks struct {
	// Action identifies work that is starting or underway.
	Action string
	// Info identifies neutral information.
	Info string
	// Success identifies successful work.
	Success string
	// Warn identifies a warning.
	Warn string
	// Error identifies a failure.
	Error string
	// Debug identifies diagnostic output.
	Debug string
	// Bullet identifies an unordered list item.
	Bullet string
	// Pointer identifies a prompt or selected item.
	Pointer string
	// SpinnerFrames contains the loader animation sequence.
	SpinnerFrames []string
}

Marks contains the symbols used for messages, lists, selections, and loaders.

Example: define custom semantic marks

marks := console.Marks{Success: "OK"}
fmt.Println(marks.Success)
// OK

func ASCIIMarks

func ASCIIMarks() Marks

ASCIIMarks returns symbols suitable for constrained terminals and plain logs.

Example:

marks := console.ASCIIMarks()
fmt.Println(marks.Success, marks.Warn, marks.Error)
// + ! x

func DefaultMarks

func DefaultMarks() Marks

DefaultMarks returns the Unicode symbols used by a default console.

Example:

marks := console.DefaultMarks()
fmt.Println(marks.Success, marks.Warn, marks.Error)
// ✔ ! ✖

type Progress

type Progress struct {
	// contains filtered or unexported fields
}

Progress presents determinate work as one transient terminal line and stable semantic lines in redirected output. A Progress is concurrency-safe, single-use, and must be constructed with Console.Progress or NewProgress; the first call to Complete, Fail, or Stop wins.

Example: track determinate work to completion

animations := false
color := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	ColorEnabled:      &color,
	UnicodeEnabled:    &unicode,
}))
var progress *console.Progress = console.NewProgress(2, "Deploying services")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Deploying services
progress.Add(2)
progress.Complete("Services deployed")
// ✔ Services deployed

func NewProgress

func NewProgress(total int, message string) *Progress

NewProgress constructs a progress display using a snapshot of the current default console. It does not start the display.

Example:

animations := false
color := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	ColorEnabled:      &color,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(2, "Deploying services")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Deploying services
progress.Add(2)
progress.Complete("Services deployed")
// ✔ Services deployed
Example

ExampleNewProgress demonstrates determinate work with a durable redirected-output contract.

@readme progress

package main

import (
	"os"

	"github.com/goforj/console"
)

// useExampleDefault installs a deterministic package-level console and returns its restore function.
func useExampleDefault(config console.Config) func() {
	previous := console.Default()
	console.SetDefault(console.New(config))
	return func() {
		console.SetDefault(previous)
	}
}

func main() {
	// @readme:setup:start
	color := false
	animations := false
	unicode := true
	defer useExampleDefault(console.Config{
		Stdout:            os.Stdout,
		ColorEnabled:      &color,
		UnicodeEnabled:    &unicode,
		AnimationsEnabled: &animations,
	})()
	// @readme:setup:end

	progress := console.NewProgress(100, "Packaging release")
	if err := progress.Start(); err != nil {
		console.Error(err.Error())
		return
	}
	// · Packaging release
	defer progress.Stop()
	progress.Step(40, "Uploading release")
	progress.Add(60)
	progress.Complete("Release ready")
	// ✔ Release ready

}
Output:
· Packaging release
✔ Release ready

func (*Progress) Add

func (p *Progress) Add(delta int)

Add changes the completed amount by delta and clamps it between zero and the total.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(2, "Deploying services")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Deploying services
progress.Add(1)
progress.Add(1)
progress.Complete("Services deployed")
// ✔ Services deployed

func (*Progress) Complete

func (p *Progress) Complete(message string)

Complete fills and finishes the display with a success message. An empty message reuses the current progress message.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(1, "Packaging release")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Packaging release
progress.Complete("Release ready")
// ✔ Release ready

func (*Progress) Fail

func (p *Progress) Fail(message string)

Fail finishes the display with an error message on stderr. An empty message reuses the current progress message.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(1, "Publishing release")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Publishing release
progress.Fail("Registry refused upload")
// ✖ Registry refused upload

func (*Progress) Set

func (p *Progress) Set(current int)

Set replaces the completed amount and clamps it between zero and the total. Reaching the total does not complete the display; Complete records the durable outcome.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(100, "Uploading release")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Uploading release
progress.Set(100)
progress.Complete("Release uploaded")
// ✔ Release uploaded

func (*Progress) Start

func (p *Progress) Start() error

Start begins the progress display and is harmless when called more than once. Live terminal displays can return ErrTransientActive when another display owns the console.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(3, "Running checks")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Running checks
progress.Stop()

func (*Progress) Step

func (p *Progress) Step(current int, message string)

Step replaces the completed amount and message in one atomic progress update. The amount is clamped between zero and the total, and updates after a terminal operation are ignored.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(2, "Deploying API")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Deploying API
progress.Step(1, "Deploying worker")
progress.Complete("")
// ✔ Deploying worker

func (*Progress) Stop

func (p *Progress) Stop()

Stop removes the transient display without printing a completion message.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(1, "Checking release")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Checking release
progress.Stop()

func (*Progress) Update

func (p *Progress) Update(message string)

Update changes the progress message and immediately redraws a live terminal display. Updates after a terminal operation are ignored.

Example:

animations := false
unicode := true
console.SetDefault(console.New(console.Config{
	AnimationsEnabled: &animations,
	UnicodeEnabled:    &unicode,
}))
progress := console.NewProgress(2, "Deploying API")
if err := progress.Start(); err != nil {
	panic(err)
}
// · Deploying API
progress.Update("Deploying worker")
progress.Complete("")
// ✔ Deploying worker

type TableOption

type TableOption func(*tableOptions)

TableOption configures one rendered table.

Example: collect table options for reuse

options := []console.TableOption{console.TableCompact()}
fmt.Println(console.RenderTable(
	[]string{"Name", "State"},
	[][]string{{"api", "ready"}},
	options...,
))
// Name  State
// ────  ─────
// api   ready

func TableCenterAlign

func TableCenterAlign(columns ...int) TableOption

TableCenterAlign centers the headers and values in the selected zero-based columns. Negative and out-of-range columns are ignored.

Example: center a status column

fmt.Println(console.RenderTable(
	[]string{"Service", "State"},
	[][]string{{"api", "up"}},
	console.TableCenterAlign(1),
))
// ┌─────────┬───────┐
// │ Service │ State │
// ├─────────┼───────┤
// │ api     │  up   │
// └─────────┴───────┘

func TableCompact

func TableCompact() TableOption

TableCompact removes the outer frame and separates columns with two spaces. A compact table with headers retains one horizontal separator for readability.

Example: render a compact table

fmt.Println(console.RenderTable(
	[]string{"Name", "State"},
	[][]string{{"api", "ready"}},
	console.TableCompact(),
))
// Name  State
// ────  ─────
// api   ready

func TableRightAlign

func TableRightAlign(columns ...int) TableOption

TableRightAlign right-aligns the headers and values in the selected zero-based columns. Negative and out-of-range columns are ignored.

Example: align numeric columns

fmt.Println(console.RenderTable(
	[]string{"Item", "Count"},
	[][]string{{"api", "12"}},
	console.TableRightAlign(1),
))
// ┌──────┬───────┐
// │ Item │ Count │
// ├──────┼───────┤
// │ api  │    12 │
// └──────┴───────┘

func TableWidths

func TableWidths(widths ...int) TableOption

TableWidths sets content widths by zero-based column position. Values less than one leave that column automatic, and configured widths may still shrink when the complete table would exceed the console width.

Example: reserve predictable column widths

fmt.Println(console.RenderTable(
	[]string{"Name", "State"},
	[][]string{{"api", "ready"}},
	console.TableWidths(6, 7),
))
// ┌────────┬─────────┐
// │ Name   │ State   │
// ├────────┼─────────┤
// │ api    │ ready   │
// └────────┴─────────┘

type TreeNode

type TreeNode struct {
	// Label is displayed on the node's first physical line.
	Label string
	// Children are displayed in their supplied order beneath the node.
	Children []TreeNode
}

TreeNode contains one label and its ordered child nodes.

Example: construct a project hierarchy

tree := console.TreeNode{
	Label: "project",
	Children: []console.TreeNode{
		{Label: "cmd"},
		{Label: "README.md"},
	},
}
console.Tree(tree)
// project
// ├── cmd
// └── README.md

func Node

func Node(label string, children ...TreeNode) TreeNode

Node creates a tree node and preserves the supplied child order.

Example: build a nested command node

console.Tree(console.Node("cmd", console.Node("deploy")))
// cmd
// └── deploy

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL