term: add term.strip_ansi/1 (based on ansi2txt) and term.header_left/1
parent
25ca1dd276
commit
c8a9052a5f
|
@ -63,6 +63,66 @@ pub fn colorize(cfn fn (string) string, s string) string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct AnsiScanner {
|
||||||
|
mut:
|
||||||
|
pos int
|
||||||
|
input string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut ss AnsiScanner) next() int {
|
||||||
|
if ss.pos < ss.input.len {
|
||||||
|
opos := ss.pos
|
||||||
|
ss.pos++
|
||||||
|
return ss.input[opos]
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// strip_ansi removes any ANSI sequences in the `text`
|
||||||
|
pub fn strip_ansi(text string) string {
|
||||||
|
// This is a port of https://github.com/kilobyte/colorized-logs/blob/master/ansi2txt.c
|
||||||
|
// \e, [, 1, m, a, b, c, \e, [, 2, 2, m => abc
|
||||||
|
mut input := AnsiScanner{
|
||||||
|
input: text
|
||||||
|
}
|
||||||
|
mut output := []byte{cap: text.len}
|
||||||
|
mut ch := 0
|
||||||
|
for ch != -1 {
|
||||||
|
ch = input.next()
|
||||||
|
if ch == 27 {
|
||||||
|
ch = input.next()
|
||||||
|
if ch == `[` {
|
||||||
|
for {
|
||||||
|
ch = input.next()
|
||||||
|
if ch in [`;`, `?`] || (ch >= `0` && ch <= `9`) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else if ch == `]` {
|
||||||
|
ch = input.next()
|
||||||
|
if ch >= `0` && ch <= `9` {
|
||||||
|
for {
|
||||||
|
ch = input.next()
|
||||||
|
if ch == -1 || ch == 7 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if ch == 27 {
|
||||||
|
ch = input.next()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ch == `%` {
|
||||||
|
ch = input.next()
|
||||||
|
}
|
||||||
|
} else if ch != -1 {
|
||||||
|
output << byte(ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.bytestr()
|
||||||
|
}
|
||||||
|
|
||||||
// h_divider returns a horizontal divider line with a dynamic width,
|
// h_divider returns a horizontal divider line with a dynamic width,
|
||||||
// that depends on the current terminal settings.
|
// that depends on the current terminal settings.
|
||||||
// If an empty string is passed in, print enough spaces to make a new line
|
// If an empty string is passed in, print enough spaces to make a new line
|
||||||
|
@ -77,6 +137,20 @@ pub fn h_divider(divider string) string {
|
||||||
return result[0..cols]
|
return result[0..cols]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// header_left returns a horizontal divider line with a title text on the left.
|
||||||
|
// e.g: term.header_left('TITLE', '=')
|
||||||
|
// ==== TITLE =========================
|
||||||
|
pub fn header_left(text string, divider string) string {
|
||||||
|
plain_text := strip_ansi(text)
|
||||||
|
xcols, _ := get_terminal_size()
|
||||||
|
cols := imax(1, xcols)
|
||||||
|
relement := if divider.len > 0 { divider } else { ' ' }
|
||||||
|
hstart := relement.repeat(4)[0..4]
|
||||||
|
remaining_cols := (cols - (hstart.len + 1 + plain_text.len + 1))
|
||||||
|
hend := relement.repeat((remaining_cols + 1) / relement.len)[0..remaining_cols]
|
||||||
|
return '$hstart $text $hend'
|
||||||
|
}
|
||||||
|
|
||||||
// header returns a horizontal divider line with a centered text in the middle.
|
// header returns a horizontal divider line with a centered text in the middle.
|
||||||
// e.g: term.header('TEXT', '=')
|
// e.g: term.header('TEXT', '=')
|
||||||
// =============== TEXT ===============
|
// =============== TEXT ===============
|
||||||
|
|
|
@ -100,3 +100,16 @@ fn test_set_terminal_title() {
|
||||||
title_change := term.set_terminal_title('v is awesome!')
|
title_change := term.set_terminal_title('v is awesome!')
|
||||||
assert title_change == true
|
assert title_change == true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_strip_ansi() {
|
||||||
|
strings := [
|
||||||
|
'abc',
|
||||||
|
term.bold('abc'),
|
||||||
|
term.yellow('abc'),
|
||||||
|
term.bold(term.red('abc')),
|
||||||
|
term.strikethrough(term.inverse(term.dim(term.bold(term.bright_bg_blue('abc'))))),
|
||||||
|
]
|
||||||
|
for s in strings {
|
||||||
|
assert term.strip_ansi(s) == 'abc'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue