fmt.v

2.1 KB · raw

1//! Presentation primitives shared by the two places Koh prints: the command2//! line and the full-screen history view.3//!4//! Colour lives here so both surfaces use one palette, and `NO_COLOR` /5//! `KOH_NO_COLOR` turn it off for both at once.67module fmt89import os10import time1112pub const glyph_ok = '✦'13pub const glyph_fail = '✗'1415pub fn colour_enabled() bool {16	if os.getenv('NO_COLOR') != '' || os.getenv('KOH_NO_COLOR') != '' {17		return false18	}19	return os.is_atty(1) != 020}2122fn paint(text string, code string) string {23	if !colour_enabled() {24		return text25	}26	return '\x1b[${code}m${text}\x1b[0m'27}2829pub fn bold(text string) string {30	return paint(text, '1')31}3233pub fn reverse(text string) string {34	return paint(text, '7')35}3637pub fn amber(text string) string {38	return paint(text, '38;5;214')39}4041pub fn red(text string) string {42	return paint(text, '38;5;203')43}4445pub fn green(text string) string {46	return paint(text, '38;5;114')47}4849pub fn dim(text string) string {50	return paint(text, '38;5;245')51}5253// strip_ansi removes the colour codes, for measuring how wide a line really is.54pub fn strip_ansi(text string) string {55	mut out := ''56	mut skipping := false57	for c in text.runes() {58		if c == `\x1b` {59			skipping = true60			continue61		}62		if skipping {63			if (c >= `a` && c <= `z`) || (c >= `A` && c <= `Z`) {64				skipping = false65			}66			continue67		}68		out += c.str()69	}70	return out71}7273pub fn visible_width(text string) int {74	return strip_ansi(text).runes().len75}7677pub fn stamp(unix_seconds i64) string {78	return time.unix(unix_seconds).local().format()79}8081pub fn date_of(unix_seconds i64) string {82	return time.unix(unix_seconds).local().ymmdd()83}8485pub fn clock_of(unix_seconds i64) string {86	return time.unix(unix_seconds).local().hhmmss()87}8889pub fn human_bytes(bytes i64) string {90	mut value := f64(bytes)91	mut unit := 'B'92	for suffix in ['KiB', 'MiB', 'GiB'] {93		if value < 1024 {94			break95		}96		value /= 102497		unit = suffix98	}99	if unit == 'B' {100		return '${bytes} B'101	}102	return '${value:.1f} ${unit}'103}104105// plural renders "1 file" / "3 files".106pub fn plural(count int, noun string) string {107	if count == 1 {108		return '1 ${noun}'109	}110	return '${count} ${noun}s'111}