-
Notifications
You must be signed in to change notification settings - Fork 63
/
colors.go
118 lines (100 loc) · 2.32 KB
/
colors.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 Docker Compose CLI authors
// Copyright 2022 Unikraft GmbH. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// Package rainbowprint provides primitives for colorized output
// on ANSI-compliant console.
package rainbowprint
import (
"fmt"
"strconv"
"sync"
"kraftkit.sh/iostreams"
)
var names = []string{
"grey",
"red",
"green",
"yellow",
"blue",
"magenta",
"cyan",
"white",
}
const (
// Never use ANSI codes
Never = "never"
// Always use ANSI codes
Always = "always"
// Auto detect terminal is a tty and can use ANSI codes
Auto = "auto"
)
// SetANSIMode configure formatter for colored output on ANSI-compliant console
func SetANSIMode(streams *iostreams.IOStreams, ansi string) {
if !useAnsi(streams, ansi) {
NextColor = func() ColorFunc {
return monochrome
}
}
}
func useAnsi(streams *iostreams.IOStreams, ansi string) bool {
switch ansi {
case Always:
return true
case Auto:
return streams.ColorEnabled()
}
return false
}
// ColorFunc use ANSI codes to render colored text on console
type ColorFunc func(s string) string
var monochrome = func(s string) string {
return s
}
func ansiColor(code, s string) string {
return fmt.Sprintf("%s%s%s", ansi(code), s, ansi("0"))
}
func ansi(code string) string {
return fmt.Sprintf("\033[%sm", code)
}
func makeColorFunc(code string) ColorFunc {
return func(s string) string {
return ansiColor(code, s)
}
}
var (
NextColor = rainbowColor
rainbow []ColorFunc
currentIndex = 0
mutex sync.Mutex
)
func initializeRainbow() {
colors := map[string]ColorFunc{}
for i, name := range names {
colors[name] = makeColorFunc(strconv.Itoa(30 + i))
colors["intense_"+name] = makeColorFunc(strconv.Itoa(30+i) + ";1")
}
rainbow = []ColorFunc{
colors["cyan"],
colors["yellow"],
colors["green"],
colors["magenta"],
colors["blue"],
colors["intense_cyan"],
colors["intense_yellow"],
colors["intense_green"],
colors["intense_magenta"],
colors["intense_blue"],
}
}
func rainbowColor() ColorFunc {
if len(rainbow) == 0 {
initializeRainbow()
}
mutex.Lock()
defer mutex.Unlock()
result := rainbow[currentIndex]
currentIndex = (currentIndex + 1) % len(rainbow)
return result
}