//! Presentation primitives shared by the two places Koh prints: the command //! line and the full-screen history view. //! //! Colour lives here so both surfaces use one palette, and `NO_COLOR` / //! `KOH_NO_COLOR` turn it off for both at once. module fmt import os import time pub const glyph_ok = '✦' pub const glyph_fail = '✗' pub fn colour_enabled() bool { if os.getenv('NO_COLOR') != '' || os.getenv('KOH_NO_COLOR') != '' { return false } return os.is_atty(1) != 0 } fn paint(text string, code string) string { if !colour_enabled() { return text } return '\x1b[${code}m${text}\x1b[0m' } pub fn bold(text string) string { return paint(text, '1') } pub fn reverse(text string) string { return paint(text, '7') } pub fn amber(text string) string { return paint(text, '38;5;214') } pub fn red(text string) string { return paint(text, '38;5;203') } pub fn green(text string) string { return paint(text, '38;5;114') } pub fn dim(text string) string { return paint(text, '38;5;245') } // strip_ansi removes the colour codes, for measuring how wide a line really is. pub fn strip_ansi(text string) string { mut out := '' mut skipping := false for c in text.runes() { if c == `\x1b` { skipping = true continue } if skipping { if (c >= `a` && c <= `z`) || (c >= `A` && c <= `Z`) { skipping = false } continue } out += c.str() } return out } pub fn visible_width(text string) int { return strip_ansi(text).runes().len } pub fn stamp(unix_seconds i64) string { return time.unix(unix_seconds).local().format() } pub fn date_of(unix_seconds i64) string { return time.unix(unix_seconds).local().ymmdd() } pub fn clock_of(unix_seconds i64) string { return time.unix(unix_seconds).local().hhmmss() } pub fn human_bytes(bytes i64) string { mut value := f64(bytes) mut unit := 'B' for suffix in ['KiB', 'MiB', 'GiB'] { if value < 1024 { break } value /= 1024 unit = suffix } if unit == 'B' { return '${bytes} B' } return '${value:.1f} ${unit}' } // plural renders "1 file" / "3 files". pub fn plural(count int, noun string) string { if count == 1 { return '1 ${noun}' } return '${count} ${noun}s' }