import std/[nre, sequtils] const CSI = "\x1b[" const RESET_FORMATTING* = "\x1b[0m" const ANSI_ESCAPE_CODE_ENDINGS*: seq[char] = toSeq('A'..'Z') & toSeq('a'..'z') let FORMATTING_REGEX* = re("\x1b\\[([0-9;]*)([a-zA-Z])") type CursorType* = enum ctBlockBlink = 1, ctBlock, ctUnderlineBlink, ctUnderline, ctBarBlink, ctBar EraseMode* = enum emToEnd, emToStart, emAll TerminalColors* = enum cBlack, cRed, cGreen, cYellow, cBlue, cMagenta, cCyan, cWhite proc stripFormatting*(text: string): string = text.replace(FORMATTING_REGEX, "") proc stripAnsi*(text: string): string = stripFormatting(text) func ansiAwareSubstring*(s: string, start, length: int): string = result = "" var curAnsiEscCode = "" var i = 0 var visibleLen = 0 while i < len(s) and visibleLen < length: if len(s) > i + len(CSI) and # We need to notice ANSI escape codes... s[i..