Skip to content

Commit 4c53021

Browse files
authored
term: add writeln_color() (#24463)
1 parent 558c034 commit 4c53021

2 files changed

Lines changed: 97 additions & 2 deletions

File tree

‎vlib/term/colors.v‎

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// that can be found in the LICENSE file.
44
module term
55

6+
import strings
7+
68
// format_esc produces an ANSI escape code, for selecting the graphics rendition of the following
79
// text. Each of the attributes that can be passed in `code`, separated by `;`, will be in effect,
810
// until the terminal encounters another SGR ANSI escape code. For more details about the different
@@ -275,3 +277,77 @@ pub fn bright_bg_white(msg string) string {
275277
pub fn highlight_command(command string) string {
276278
return bright_white(bg_cyan(' ${command} '))
277279
}
280+
281+
pub enum TextStyle {
282+
bold = 1
283+
dim = 2
284+
italic = 3
285+
underline = 4
286+
blink = 5
287+
reverse = 7
288+
}
289+
290+
pub enum FgColor {
291+
black = 30
292+
red = 31
293+
green = 32
294+
yellow = 33
295+
blue = 34
296+
magenta = 35
297+
cyan = 36
298+
white = 37
299+
}
300+
301+
pub enum BgColor {
302+
black = 40
303+
red = 41
304+
green = 42
305+
yellow = 43
306+
blue = 44
307+
magenta = 45
308+
cyan = 46
309+
white = 47
310+
}
311+
312+
@[params]
313+
pub struct ColorConfig {
314+
pub mut:
315+
styles []TextStyle
316+
fg ?FgColor
317+
bg ?BgColor
318+
custom string
319+
}
320+
321+
// write_color appends the ANSI colorful string `s` to the buffer.
322+
pub fn write_color(mut b strings.Builder, s string, config ColorConfig) {
323+
mut codes := []string{cap: 3}
324+
325+
for style in config.styles {
326+
codes << int(style).str()
327+
}
328+
329+
if fg := config.fg {
330+
codes << int(fg).str()
331+
}
332+
333+
if bg := config.bg {
334+
codes << int(bg).str()
335+
}
336+
337+
if config.custom != '' {
338+
codes << config.custom
339+
}
340+
341+
if codes.len > 0 {
342+
code_str := codes.join(';')
343+
b.write_string('\x1b[${code_str}m${s}\x1b[0m')
344+
} else {
345+
b.write_string(s)
346+
}
347+
}
348+
349+
// writeln_color appends the ANSI colorful string `s`, and then a newline character.
350+
pub fn writeln_color(mut b strings.Builder, s string, color ColorConfig) {
351+
write_color(mut b, s, color)
352+
b.writeln('')
353+
}

‎vlib/term/term_test.v‎

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import term
3+
import strings
34

45
fn test_get_terminal_size() {
56
cols, _ := term.get_terminal_size()
@@ -113,14 +114,32 @@ fn test_set_tab_title() {
113114
}
114115

115116
fn test_strip_ansi() {
116-
strings := [
117+
string_list := [
117118
'abc',
118119
term.bold('abc'),
119120
term.yellow('abc'),
120121
term.bold(term.red('abc')),
121122
term.strikethrough(term.inverse(term.dim(term.bold(term.bright_bg_blue('abc'))))),
122123
]
123-
for s in strings {
124+
for s in string_list {
124125
assert term.strip_ansi(s) == 'abc'
125126
}
126127
}
128+
129+
fn test_write_color() {
130+
mut sb := strings.new_builder(100)
131+
term.writeln_color(mut sb, 'hello')
132+
term.writeln_color(mut sb, 'hello', fg: .red)
133+
term.writeln_color(mut sb, 'hello', bg: .cyan)
134+
term.writeln_color(mut sb, 'hello', styles: [.bold, .italic, .underline], fg: .red, bg: .cyan)
135+
term.writeln_color(mut sb, 'hello', custom: '38;5;214')
136+
137+
output := sb.str()
138+
println(output)
139+
140+
assert output.contains('\x1b[0m')
141+
assert output.contains('\x1b[31m')
142+
assert output.contains('\x1b[46m')
143+
assert output.contains('\x1b[1;3;4;31;46m')
144+
assert output.contains('\x1b[38;5;214m')
145+
}

0 commit comments

Comments
 (0)