diff --git a/src/terminal.ts b/src/terminal.ts index 769649c..df203b3 100644 --- a/src/terminal.ts +++ b/src/terminal.ts @@ -1,7 +1,35 @@ -export const BOLD = "\x1b[1m"; -export const GREEN = "\x1b[32m"; -export const YELLOW = "\x1b[33m"; -export const CYAN = "\x1b[36m"; -export const RED = "\x1b[31m"; -export const DIM = "\x1b[2m"; -export const RESET = "\x1b[0m"; +// Terminal styling utilities. +// Respects NO_COLOR convention, --no-color flag, and TTY detection. + +import { isStdoutTTY } from "./tty"; + +let _enabled: boolean | null = null; + +export function setColorEnabled(enabled: boolean): void { + _enabled = enabled; +} + +export function isColorEnabled(): boolean { + if (_enabled !== null) return _enabled; + + // Respect NO_COLOR: https://no-color.org/ + if (process.env.NO_COLOR !== undefined && process.env.NO_COLOR !== "") { + return false; + } + if (!isStdoutTTY()) return false; + if (process.env.FORCE_COLOR && process.env.FORCE_COLOR !== "0") return true; + + return true; +} + +function s(code: string): string { + return isColorEnabled() ? code : ""; +} + +export const BOLD = () => s("\x1b[1m"); +export const DIM = () => s("\x1b[2m"); +export const GREEN = () => s("\x1b[32m"); +export const YELLOW = () => s("\x1b[33m"); +export const CYAN = () => s("\x1b[36m"); +export const RED = () => s("\x1b[31m"); +export const RESET = () => s("\x1b[0m");