Skip to content

Commit 14d3e30

Browse files
fix: use ANSI colors codes instead of RGB (coder#14665)
* chore: add command for showing colors * fix: use ANSI color codes instead of RGB * feat: add '--no-color' flag * fix: revert colors * chore: change colors * fix: update golden files * fix: replace blue with brightBlue * fix: drop '> ' for unfocused prompts * fix: run 'make fmt' * chore: allow disabling color with env flags * fix: apply fixes from feedback * fix: run 'make gen' * fix: refactor janky code * fix: re-add public function * fix: re-add init for non-color tests * fix: move styles to 'init' that can be * fix: stop overwriting entire DefaultStyles * fix: make code and field obey --no-color * fix: rip out '--no-color' due to race condition We still support `NO_COLOR` env variable through termenv's `EnvColorProfile`. The reason for the race condition is that `DefaultStyles` is a global that we shouldn't mutate after `init` is called, but we have to mutate it after `init` has ran to have serpent collect the cli flags and env vars for us. * fix: apply nit * fix: simplify code && hide command * fix: newline shouldn't be themed * fix: appease the linter
1 parent 6ff9a05 commit 14d3e30

File tree

3 files changed

+73
-27
lines changed

3 files changed

+73
-27
lines changed

cli/cliui/cliui.go

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,21 @@ var (
3737
)
3838

3939
var (
40-
Green = Color("#04B575")
41-
Red = Color("#ED567A")
42-
Fuchsia = Color("#EE6FF8")
43-
Yellow = Color("#ECFD65")
44-
Blue = Color("#5000ff")
40+
// ANSI color codes
41+
red = Color("1")
42+
green = Color("2")
43+
yellow = Color("3")
44+
magenta = Color("5")
45+
white = Color("7")
46+
brightBlue = Color("12")
47+
brightMagenta = Color("13")
4548
)
4649

4750
// Color returns a color for the given string.
4851
func Color(s string) termenv.Color {
4952
colorOnce.Do(func() {
50-
color = termenv.NewOutput(os.Stdout).ColorProfile()
53+
color = termenv.NewOutput(os.Stdout).EnvColorProfile()
54+
5155
if flag.Lookup("test.v") != nil {
5256
// Use a consistent colorless profile in tests so that results
5357
// are deterministic.
@@ -123,42 +127,45 @@ func init() {
123127
DefaultStyles = Styles{
124128
Code: pretty.Style{
125129
ifTerm(pretty.XPad(1, 1)),
126-
pretty.FgColor(Red),
127-
pretty.BgColor(color.Color("#2c2c2c")),
130+
pretty.FgColor(Color("#ED567A")),
131+
pretty.BgColor(Color("#2C2C2C")),
128132
},
129133
DateTimeStamp: pretty.Style{
130-
pretty.FgColor(color.Color("#7571F9")),
134+
pretty.FgColor(brightBlue),
131135
},
132136
Error: pretty.Style{
133-
pretty.FgColor(Red),
137+
pretty.FgColor(red),
134138
},
135139
Field: pretty.Style{
136140
pretty.XPad(1, 1),
137-
pretty.FgColor(color.Color("#FFFFFF")),
138-
pretty.BgColor(color.Color("#2b2a2a")),
141+
pretty.FgColor(Color("#FFFFFF")),
142+
pretty.BgColor(Color("#2B2A2A")),
143+
},
144+
Fuchsia: pretty.Style{
145+
pretty.FgColor(brightMagenta),
146+
},
147+
FocusedPrompt: pretty.Style{
148+
pretty.FgColor(white),
149+
pretty.Wrap("> ", ""),
150+
pretty.FgColor(brightBlue),
139151
},
140152
Keyword: pretty.Style{
141-
pretty.FgColor(Green),
153+
pretty.FgColor(green),
142154
},
143155
Placeholder: pretty.Style{
144-
pretty.FgColor(color.Color("#4d46b3")),
156+
pretty.FgColor(magenta),
145157
},
146158
Prompt: pretty.Style{
147-
pretty.FgColor(color.Color("#5C5C5C")),
148-
pretty.Wrap("> ", ""),
159+
pretty.FgColor(white),
160+
pretty.Wrap(" ", ""),
149161
},
150162
Warn: pretty.Style{
151-
pretty.FgColor(Yellow),
163+
pretty.FgColor(yellow),
152164
},
153165
Wrap: pretty.Style{
154166
pretty.LineWrap(80),
155167
},
156168
}
157-
158-
DefaultStyles.FocusedPrompt = append(
159-
DefaultStyles.Prompt,
160-
pretty.FgColor(Blue),
161-
)
162169
}
163170

164171
// ValidateNotEmpty is a helper function to disallow empty inputs!

cli/cliui/select.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ func (m selectModel) View() string {
256256
if m.cursor == start+i {
257257
style = pretty.Style{
258258
pretty.Wrap("> ", ""),
259-
pretty.FgColor(Green),
259+
DefaultStyles.Keyword,
260260
}
261261
}
262262

@@ -481,13 +481,13 @@ func (m multiSelectModel) View() string {
481481
o := option.option
482482

483483
if m.cursor == i {
484-
cursor = pretty.Sprint(pretty.FgColor(Green), "> ")
485-
chosen = pretty.Sprint(pretty.FgColor(Green), "[ ]")
486-
o = pretty.Sprint(pretty.FgColor(Green), o)
484+
cursor = pretty.Sprint(DefaultStyles.Keyword, "> ")
485+
chosen = pretty.Sprint(DefaultStyles.Keyword, "[ ]")
486+
o = pretty.Sprint(DefaultStyles.Keyword, o)
487487
}
488488

489489
if option.chosen {
490-
chosen = pretty.Sprint(pretty.FgColor(Green), "[x]")
490+
chosen = pretty.Sprint(DefaultStyles.Keyword, "[x]")
491491
}
492492

493493
_, _ = s.WriteString(fmt.Sprintf(

cmd/cliui/main.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/coder/coder/v2/cli/cliui"
1919
"github.com/coder/coder/v2/coderd/database/dbtime"
2020
"github.com/coder/coder/v2/codersdk"
21+
"github.com/coder/pretty"
2122
"github.com/coder/serpent"
2223
)
2324

@@ -37,6 +38,44 @@ func main() {
3738
},
3839
}
3940

41+
root.Children = append(root.Children, &serpent.Command{
42+
Use: "colors",
43+
Hidden: true,
44+
Handler: func(inv *serpent.Invocation) error {
45+
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Code, "This is a code message")
46+
_, _ = fmt.Fprintln(inv.Stdout)
47+
48+
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.DateTimeStamp, "This is a datetimestamp message")
49+
_, _ = fmt.Fprintln(inv.Stdout)
50+
51+
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Error, "This is an error message")
52+
_, _ = fmt.Fprintln(inv.Stdout)
53+
54+
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Field, "This is a field message")
55+
_, _ = fmt.Fprintln(inv.Stdout)
56+
57+
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Keyword, "This is a keyword message")
58+
_, _ = fmt.Fprintln(inv.Stdout)
59+
60+
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Placeholder, "This is a placeholder message")
61+
_, _ = fmt.Fprintln(inv.Stdout)
62+
63+
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Prompt, "This is a prompt message")
64+
_, _ = fmt.Fprintln(inv.Stdout)
65+
66+
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.FocusedPrompt, "This is a focused prompt message")
67+
_, _ = fmt.Fprintln(inv.Stdout)
68+
69+
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Fuchsia, "This is a fuchsia message")
70+
_, _ = fmt.Fprintln(inv.Stdout)
71+
72+
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Warn, "This is a warning message")
73+
_, _ = fmt.Fprintln(inv.Stdout)
74+
75+
return nil
76+
},
77+
})
78+
4079
root.Children = append(root.Children, &serpent.Command{
4180
Use: "prompt",
4281
Handler: func(inv *serpent.Invocation) error {

0 commit comments

Comments
 (0)