Documentation
¶
Overview ¶
Package ui provides terminal user interface components and utilities.
This package contains all terminal-facing UI elements used by nssh CLI commands, including styled output, prompts, tables, and fuzzy selection.
Output Functions ¶
Styled output functions for consistent CLI appearance:
ui.Info("Processing %d hosts", count) // Blue info message
ui.Success("Connection established") // Green success message
ui.Warning("Certificate expires soon") // Yellow warning
ui.Error("Connection failed: %v", err) // Red error message
Prompts ¶
Interactive prompts for user input:
name, err := ui.Prompt("Hostname", "default-value")
password, err := ui.PasswordSecure("Password") // Returns *memguard.LockedBuffer
confirmed, err := ui.Confirm("Delete host?", false)
Fuzzy Selection ¶
Integration with fzf for fuzzy selection:
selected, err := ui.FuzzySelectString("Select host", hosts, "")
Tables ¶
Formatted table output:
t := ui.NewTable("Name", "Host", "Port")
t.AddRow("server1", "10.0.0.1", "22")
t.Print()
Styled Help ¶
Custom help formatting for Cobra commands:
ui.ApplyStyledHelp(cmd) // Single command ui.ApplyStyledHelpRecursive(cmd) // Command and all subcommands
Components ¶
Visual components for command output:
ui.Ruler("SECTION TITLE") // Horizontal rule with title
ui.CommandStart("CONNECT") // Command header
ui.CommandEnd(ui.StatusSuccess) // Command footer with status
Package ui provides terminal user interface components including styled text, panels, tables, prompts, and progress bars using lipgloss and huh.
Index ¶
- Variables
- func Abort(format string, args ...any)
- func ApplyStyledHelp(cmd *cobra.Command)
- func ApplyStyledHelpRecursive(cmd *cobra.Command)
- func BatchPreview(groups []BatchGroup, action string)
- func BatchSummaryLine(totalItems, groupCount int, itemNoun string)
- func Bold(s string) string
- func BorderedPanel(title, content string, titleAlign string, width int, padY ...bool) string
- func Box(title, content string)
- func CommandEnd(status StatusType)
- func CommandStart(title string)
- func CompatFixPreview(hostname string, fixes []string)
- func Confirm(title string, defaultValue bool) (bool, error)
- func Creation(format string, args ...any)
- func Cyan(s string) string
- func Deletion(format string, args ...any)
- func DimCyan(s string) string
- func DimGreen(s string) string
- func DimRed(s string) string
- func Error(format string, args ...any)
- func FuzzySelect(prompt string, options []FuzzySelectOption, initialQuery ...string) (int, error)
- func FuzzySelectMulti(prompt string, options []FuzzySelectOption) ([]int, error)
- func FuzzySelectString(prompt string, options []string, initialQuery ...string) (string, error)
- func FzfAvailable() bool
- func Gray(s string) string
- func Green(s string) string
- func Header(title string)
- func Indent(s string, level int) string
- func Info(format string, args ...any)
- func InfoBox(title, content string)
- func InfoCentered(format string, args ...any)
- func InfoWithMargin(margin int, format string, args ...any)
- func Input(title, placeholder string) (string, error)
- func InputHostname(title, defaultValue string) (string, error)
- func InputWithDefault(title, defaultValue string) (string, error)
- func InputWithFzf(title, defaultValue string, fzfChoices []string, fzfPrompt string) (string, error)
- func InsertionPreview(newLines, beforeHost, afterHost []string, targetFile string, ...)
- func IsExplainShown(err error) bool
- func KeyValue(key, value string) string
- func KeyValueBlock(pairs map[string]string, order []string)
- func List(items []string)
- func Magenta(s string) string
- func Noop(format string, args ...any)
- func NumberedList(items []string)
- func Password(title string) (string, error)
- func PasswordSecure(title string) (*memguard.LockedBuffer, error)
- func PasswordSecureWithConfirm(title string) (*memguard.LockedBuffer, error)
- func PasswordWithConfirm(title string) (string, error)
- func PrintKeyValue(key, value string)
- func PrintRuler(title string)
- func PrintTable(headers []TableHeader, rows [][]string) int
- func Red(s string) string
- func RemovalPreview(hostLines []string, targetFile string)
- func RenderProgress(label string, current, total int) string
- func RenderStyledHelp(cmd *cobra.Command, cfg StyledHelpConfig) string
- func Ruler(title string) string
- func Section(title string)
- func Select(title string, options []SelectOption) (string, error)
- func SelectIndex(title string, options []string, input io.Reader) (int, error)
- func SimpleTable(headers []string, rows [][]string)
- func StatusLine(ok bool, label, value string)
- func StatusLineNeutral(label, value string)
- func StatusLineNeutralText(text string)
- func StripANSI(s string) string
- func SubSection(title string, skipNewline ...bool)
- func Success(format string, args ...any)
- func SuccessBox(title, content string)
- func Truncate(s string, maxWidth int) string
- func VisualWidth(s string) int
- func Warning(format string, args ...any)
- func WarningBox(title, content string)
- func WarningCentered(format string, args ...any)
- func Yellow(s string) string
- type BatchGroup
- type BatchItem
- type BatchProgress
- type FuzzySelectOption
- type Panel
- type ProgressBar
- func (p *ProgressBar) Clear()
- func (p *ProgressBar) Print()
- func (p *ProgressBar) PrintLn()
- func (p *ProgressBar) Render() string
- func (p *ProgressBar) Update(current int)
- func (p *ProgressBar) WithWidth(width int) *ProgressBar
- func (p *ProgressBar) WithoutCount() *ProgressBar
- func (p *ProgressBar) WithoutPercent() *ProgressBar
- type SelectOption
- type StatusType
- type StyledHelpConfig
- type Table
- type TableHeader
Constants ¶
This section is empty.
Variables ¶
var ( ColorCyan = lipgloss.Color("6") // ANSI cyan ColorGreen = lipgloss.Color("78") // Soft green ColorYellow = lipgloss.Color("220") // Warning yellow ColorRed = lipgloss.Color("196") // Error red ColorGray = lipgloss.Color("245") // Muted gray ColorDim = lipgloss.Color("240") // Dimmer gray for borders ColorWhite = lipgloss.Color("255") // Bright white ColorMagenta = lipgloss.Color("213") // Soft magenta )
Color palette - muted, professional tones
var ( StyleBold = lipgloss.NewStyle().Bold(true) StyleDim = lipgloss.NewStyle().Foreground(ColorGray) StyleCyan = lipgloss.NewStyle().Foreground(ColorCyan) StyleGreen = lipgloss.NewStyle().Foreground(ColorGreen) StyleYellow = lipgloss.NewStyle().Foreground(ColorYellow) StyleRed = lipgloss.NewStyle().Foreground(ColorRed) StyleMagenta = lipgloss.NewStyle().Foreground(ColorMagenta) StyleWhite = lipgloss.NewStyle().Foreground(ColorWhite) StyleLabel = lipgloss.NewStyle().Foreground(ColorGray).Bold(true) StyleValue = lipgloss.NewStyle().Foreground(ColorCyan) StyleValueDim = lipgloss.NewStyle().Foreground(ColorGray) StyleHighlight = lipgloss.NewStyle().Foreground(ColorGreen).Bold(true) )
Text styles
var ErrInterrupted = errors.New("input interrupted")
ErrInterrupted is returned when the user cancels input with Ctrl+C or SIGTERM. Callers should check for this error and exit gracefully without printing an error message.
Functions ¶
func ApplyStyledHelp ¶
ApplyStyledHelp sets a command to use styled help rendering. It also adds an --explain flag for extended help if the command has a Long description.
func ApplyStyledHelpRecursive ¶
ApplyStyledHelpRecursive applies styled help to a command and all subcommands.
func BatchPreview ¶
func BatchPreview(groups []BatchGroup, action string)
BatchPreview displays a pretty preview of batch operations grouped by context. action is "+" for add, "-" for remove
func BatchSummaryLine ¶
BatchSummaryLine prints a summary line for batch operations. Example: " 6 hosts across 2 contexts"
func BorderedPanel ¶
BorderedPanel renders content in a bordered panel with title on the border. titleAlign: "left" (default) or "center" width: 0 = auto-fit to content padY: add empty lines inside top/bottom of box
func CommandEnd ¶
func CommandEnd(status StatusType)
CommandEnd prints a status-colored footer banner.
func CommandStart ¶
func CommandStart(title string)
CommandStart prints the header banner for a command (cyan-colored).
func CompatFixPreview ¶
CompatFixPreview displays what compatibility fixes will be applied.
func FuzzySelect ¶
func FuzzySelect(prompt string, options []FuzzySelectOption, initialQuery ...string) (int, error)
FuzzySelect presents a fuzzy finder interface and returns the selected option. Returns the index of the selected option, or -1 if canceled. Optional initialQuery pre-fills the search input. Falls back to huh's filtered select if fzf is unavailable.
func FuzzySelectMulti ¶
func FuzzySelectMulti(prompt string, options []FuzzySelectOption) ([]int, error)
FuzzySelectMulti presents a fuzzy finder for multi-selection. Returns indices of selected options, or empty slice if canceled. Falls back to huh's multi-select if fzf is unavailable.
func FuzzySelectString ¶
FuzzySelectString presents a fuzzy finder for a simple string list. Returns the selected string, or empty string if canceled. Optional initialQuery pre-fills the search input. Falls back to huh's filtered select if fzf is unavailable.
func Header ¶
func Header(title string)
Header prints a prominent header (cyan-colored, for top-level commands).
func InfoCentered ¶
InfoCentered prints a centered info message.
func InfoWithMargin ¶
InfoWithMargin prints an info message with a left margin.
func Input ¶
Input shows a text input prompt. After completion, prints the result so it persists on screen.
func InputHostname ¶
InputHostname shows a text input prompt for a hostname (FQDN, short name, or IP). After completion, prints the result so it persists on screen.
func InputWithDefault ¶
InputWithDefault shows a text input prompt with a pre-filled default value. After completion, prints the result so it persists on screen.
func InputWithFzf ¶
func InputWithFzf(title, defaultValue string, fzfChoices []string, fzfPrompt string) (string, error)
InputWithFzf shows a text input prompt with optional Tab-triggered fzf selection. User can:
- Press Enter to accept default
- Type a value and press Enter
- Press Tab to launch fzf browser (if choices provided and fzf is available)
After completion, prints the result so it persists on screen.
func InsertionPreview ¶
func InsertionPreview(newLines, beforeHost, afterHost []string, targetFile string, maxContextLines int)
InsertionPreview displays a diff-style preview of where a new host will be inserted in the SSH config file.
Parameters:
- newLines: The new host config lines to be inserted
- beforeHost: Lines of the host that will appear before (nil if inserting at start)
- afterHost: Lines of the host that will appear after (nil if inserting at end)
- targetFile: Path to the target file (for display)
- maxContextLines: Maximum lines to show per context block (0 = show all)
func IsExplainShown ¶
IsExplainShown checks if the error is from --explain being handled.
func KeyValueBlock ¶
KeyValueBlock prints multiple key-value pairs aligned.
func Password ¶
Password shows a password input prompt (masked). After completion, prints a masked indicator so it persists on screen.
func PasswordSecure ¶
func PasswordSecure(title string) (*memguard.LockedBuffer, error)
PasswordSecure prompts for password input and returns a secure buffer. The returned buffer must be destroyed by the caller after use. Returns ErrInterrupted if the user cancels with Ctrl+C or SIGTERM.
func PasswordSecureWithConfirm ¶
func PasswordSecureWithConfirm(title string) (*memguard.LockedBuffer, error)
PasswordSecureWithConfirm prompts for password input twice and verifies they match. Returns a secure buffer containing the confirmed password. The returned buffer must be destroyed by the caller after use. Returns ErrInterrupted if the user cancels with Ctrl+C or SIGTERM.
NOTE: This function does NOT validate passphrase requirements (length, etc.). For passphrase initialization, use PassphraseStore.Initialize() which validates BEFORE confirmation to provide better UX (fail fast on invalid input). This function is for general-purpose confirmed input where validation is handled by the caller or not required.
func PasswordWithConfirm ¶
PasswordWithConfirm shows two password prompts and validates they match. Returns an error if passwords don't match or are empty.
func PrintKeyValue ¶
func PrintKeyValue(key, value string)
PrintKeyValue prints a formatted key-value pair with info status prefix.
func PrintTable ¶
func PrintTable(headers []TableHeader, rows [][]string) int
PrintTable prints a table with styled headers and returns the left margin.
func RemovalPreview ¶
RemovalPreview displays a diff-style preview of a host being removed.
func RenderProgress ¶
RenderProgress is a helper to render a simple one-line progress bar. Returns the rendered string without printing.
func RenderStyledHelp ¶
func RenderStyledHelp(cmd *cobra.Command, cfg StyledHelpConfig) string
RenderStyledHelp renders a command's help in styled panel format.
func Ruler ¶
Ruler prints a horizontal line with optional centered title. Example: ──────────── HOST DETAILS ────────────
func Select ¶
func Select(title string, options []SelectOption) (string, error)
Select shows a select prompt and returns the selected value. Returns empty string if canceled.
func SelectIndex ¶
SelectIndex shows a select prompt and returns the selected index. Returns -1 if canceled.
func SimpleTable ¶
SimpleTable prints a quick table from headers and rows.
func StatusLine ¶
StatusLine prints an inline status with icon. ok=true shows green [✓], ok=false shows red [✗]
func StatusLineNeutral ¶
func StatusLineNeutral(label, value string)
StatusLineNeutral prints an inline status with neutral [-] icon (dimmed).
func StatusLineNeutralText ¶
func StatusLineNeutralText(text string)
StatusLineNeutralText prints text with neutral [-] icon (dimmed), no label.
func SubSection ¶
SubSection prints a lightweight sub-section header with a mini ruler. Example: ── Preview Pass skipNewline=true to omit the leading blank line.
func SuccessBox ¶
func SuccessBox(title, content string)
SuccessBox prints content in a green success box.
func Truncate ¶
Truncate shortens a string to maxWidth display width, adding ellipsis if needed. Handles multi-byte characters correctly using runewidth.
func VisualWidth ¶
VisualWidth returns the visual width of a string, ignoring ANSI escape codes.
func WarningBox ¶
func WarningBox(title, content string)
WarningBox prints content in a red warning box.
func WarningCentered ¶
WarningCentered prints a centered warning message.
Types ¶
type BatchGroup ¶
BatchGroup represents a group of items for batch display.
type BatchItem ¶
type BatchItem struct {
Name string
Detail string // optional additional info (e.g., hostname when different from alias)
}
BatchItem represents an item in a batch operation.
type BatchProgress ¶
type BatchProgress struct {
// contains filtered or unexported fields
}
BatchProgress tracks and displays progress of batch operations.
func NewBatchProgress ¶
func NewBatchProgress(items []string) *BatchProgress
NewBatchProgress creates a new batch progress tracker.
func (*BatchProgress) MarkError ¶
func (bp *BatchProgress) MarkError(name, message string)
MarkError marks an item as failed.
func (*BatchProgress) MarkSuccess ¶
func (bp *BatchProgress) MarkSuccess(name string)
MarkSuccess marks an item as successful.
type FuzzySelectOption ¶
type FuzzySelectOption struct {
// Label is the main display text
Label string
// Description is the secondary text (shown on the right)
Description string
// Value is the underlying value to return when selected
Value any
}
FuzzySelectOption represents an option in fuzzy selection.
func HostSelectOption ¶
func HostSelectOption(alias, hostname, user, configFile string) FuzzySelectOption
HostSelectOption creates a FuzzySelectOption for a host entry.
type Panel ¶
type Panel struct {
// contains filtered or unexported fields
}
Panel displays key-value content within rulers. Top ruler has title, bottom ruler has optional footer (like "OK").
func (*Panel) WithFooter ¶
WithFooter sets the footer text.
func (*Panel) WithWarning ¶
WithWarning makes the panel use warning colors.
type ProgressBar ¶
type ProgressBar struct {
// contains filtered or unexported fields
}
ProgressBar renders a styled progress bar that matches the UI theme. Example output:
[-] Exporting [████████████░░░░░░░░░░░░] 60/100 60%
func NewProgressBar ¶
func NewProgressBar(label string, total int) *ProgressBar
NewProgressBar creates a new progress bar with the given label.
func (*ProgressBar) Print ¶
func (p *ProgressBar) Print()
Print renders the progress bar to stdout with carriage return (for updates).
func (*ProgressBar) PrintLn ¶
func (p *ProgressBar) PrintLn()
PrintLn renders the progress bar to stdout with newline (final state).
func (*ProgressBar) Render ¶
func (p *ProgressBar) Render() string
Render returns the progress bar as a styled string.
func (*ProgressBar) Update ¶
func (p *ProgressBar) Update(current int)
Update sets the current progress value.
func (*ProgressBar) WithWidth ¶
func (p *ProgressBar) WithWidth(width int) *ProgressBar
WithWidth sets the bar width (default 30).
func (*ProgressBar) WithoutCount ¶
func (p *ProgressBar) WithoutCount() *ProgressBar
WithoutCount hides the count display.
func (*ProgressBar) WithoutPercent ¶
func (p *ProgressBar) WithoutPercent() *ProgressBar
WithoutPercent hides the percentage display.
type SelectOption ¶
SelectOption represents a choice in a select prompt.
type StatusType ¶
type StatusType int
StatusType represents the type of status message for output formatting.
const ( StatusSuccess StatusType = iota // Success status with checkmark StatusNoop // No operation performed StatusAbort // Operation aborted StatusInfo // Informational message StatusWarning // Warning message StatusError // Error message StatusDeletion // Item being deleted StatusCreation // Item being created )
Status message types for formatted output.
type StyledHelpConfig ¶
type StyledHelpConfig struct {
// ShowGlobalFlags includes global flags in output
ShowGlobalFlags bool
// Width is the panel width (0 = auto-detect terminal width)
Width int
}
StyledHelpConfig holds configuration for styled help rendering.
func DefaultHelpConfig ¶
func DefaultHelpConfig() StyledHelpConfig
DefaultHelpConfig returns the default styled help configuration.
type Table ¶
type Table struct {
// contains filtered or unexported fields
}
Table wraps table data for consistent styling.
func BuildTable ¶
func BuildTable(headers []TableHeader, rows [][]string) *Table
BuildTable creates a table without printing it.
func (*Table) AddFooterRow ¶
AddFooterRow adds a row that will be styled as a footer with a separator border.
func (*Table) LeftMargin ¶
LeftMargin returns the left margin that would be used for centering without printing.
func (*Table) Render ¶
Render prints the table to stdout (centered) and returns the left margin used for centering.
func (*Table) RenderLeft ¶
func (t *Table) RenderLeft()
RenderLeft prints the table to stdout with left alignment (no centering).
type TableHeader ¶
type TableHeader struct {
Title string
Color string // not used currently, kept for API compatibility
}
TableHeader represents a column header with optional styling.