mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
fix: use ANSI colors codes instead of RGB (#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
This commit is contained in:
@ -37,17 +37,21 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
Green = Color("#04B575")
|
||||
Red = Color("#ED567A")
|
||||
Fuchsia = Color("#EE6FF8")
|
||||
Yellow = Color("#ECFD65")
|
||||
Blue = Color("#5000ff")
|
||||
// ANSI color codes
|
||||
red = Color("1")
|
||||
green = Color("2")
|
||||
yellow = Color("3")
|
||||
magenta = Color("5")
|
||||
white = Color("7")
|
||||
brightBlue = Color("12")
|
||||
brightMagenta = Color("13")
|
||||
)
|
||||
|
||||
// Color returns a color for the given string.
|
||||
func Color(s string) termenv.Color {
|
||||
colorOnce.Do(func() {
|
||||
color = termenv.NewOutput(os.Stdout).ColorProfile()
|
||||
color = termenv.NewOutput(os.Stdout).EnvColorProfile()
|
||||
|
||||
if flag.Lookup("test.v") != nil {
|
||||
// Use a consistent colorless profile in tests so that results
|
||||
// are deterministic.
|
||||
@ -123,42 +127,45 @@ func init() {
|
||||
DefaultStyles = Styles{
|
||||
Code: pretty.Style{
|
||||
ifTerm(pretty.XPad(1, 1)),
|
||||
pretty.FgColor(Red),
|
||||
pretty.BgColor(color.Color("#2c2c2c")),
|
||||
pretty.FgColor(Color("#ED567A")),
|
||||
pretty.BgColor(Color("#2C2C2C")),
|
||||
},
|
||||
DateTimeStamp: pretty.Style{
|
||||
pretty.FgColor(color.Color("#7571F9")),
|
||||
pretty.FgColor(brightBlue),
|
||||
},
|
||||
Error: pretty.Style{
|
||||
pretty.FgColor(Red),
|
||||
pretty.FgColor(red),
|
||||
},
|
||||
Field: pretty.Style{
|
||||
pretty.XPad(1, 1),
|
||||
pretty.FgColor(color.Color("#FFFFFF")),
|
||||
pretty.BgColor(color.Color("#2b2a2a")),
|
||||
pretty.FgColor(Color("#FFFFFF")),
|
||||
pretty.BgColor(Color("#2B2A2A")),
|
||||
},
|
||||
Fuchsia: pretty.Style{
|
||||
pretty.FgColor(brightMagenta),
|
||||
},
|
||||
FocusedPrompt: pretty.Style{
|
||||
pretty.FgColor(white),
|
||||
pretty.Wrap("> ", ""),
|
||||
pretty.FgColor(brightBlue),
|
||||
},
|
||||
Keyword: pretty.Style{
|
||||
pretty.FgColor(Green),
|
||||
pretty.FgColor(green),
|
||||
},
|
||||
Placeholder: pretty.Style{
|
||||
pretty.FgColor(color.Color("#4d46b3")),
|
||||
pretty.FgColor(magenta),
|
||||
},
|
||||
Prompt: pretty.Style{
|
||||
pretty.FgColor(color.Color("#5C5C5C")),
|
||||
pretty.Wrap("> ", ""),
|
||||
pretty.FgColor(white),
|
||||
pretty.Wrap(" ", ""),
|
||||
},
|
||||
Warn: pretty.Style{
|
||||
pretty.FgColor(Yellow),
|
||||
pretty.FgColor(yellow),
|
||||
},
|
||||
Wrap: pretty.Style{
|
||||
pretty.LineWrap(80),
|
||||
},
|
||||
}
|
||||
|
||||
DefaultStyles.FocusedPrompt = append(
|
||||
DefaultStyles.Prompt,
|
||||
pretty.FgColor(Blue),
|
||||
)
|
||||
}
|
||||
|
||||
// ValidateNotEmpty is a helper function to disallow empty inputs!
|
||||
|
@ -256,7 +256,7 @@ func (m selectModel) View() string {
|
||||
if m.cursor == start+i {
|
||||
style = pretty.Style{
|
||||
pretty.Wrap("> ", ""),
|
||||
pretty.FgColor(Green),
|
||||
DefaultStyles.Keyword,
|
||||
}
|
||||
}
|
||||
|
||||
@ -481,13 +481,13 @@ func (m multiSelectModel) View() string {
|
||||
o := option.option
|
||||
|
||||
if m.cursor == i {
|
||||
cursor = pretty.Sprint(pretty.FgColor(Green), "> ")
|
||||
chosen = pretty.Sprint(pretty.FgColor(Green), "[ ]")
|
||||
o = pretty.Sprint(pretty.FgColor(Green), o)
|
||||
cursor = pretty.Sprint(DefaultStyles.Keyword, "> ")
|
||||
chosen = pretty.Sprint(DefaultStyles.Keyword, "[ ]")
|
||||
o = pretty.Sprint(DefaultStyles.Keyword, o)
|
||||
}
|
||||
|
||||
if option.chosen {
|
||||
chosen = pretty.Sprint(pretty.FgColor(Green), "[x]")
|
||||
chosen = pretty.Sprint(DefaultStyles.Keyword, "[x]")
|
||||
}
|
||||
|
||||
_, _ = s.WriteString(fmt.Sprintf(
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"github.com/coder/coder/v2/cli/cliui"
|
||||
"github.com/coder/coder/v2/coderd/database/dbtime"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/pretty"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
@ -37,6 +38,44 @@ func main() {
|
||||
},
|
||||
}
|
||||
|
||||
root.Children = append(root.Children, &serpent.Command{
|
||||
Use: "colors",
|
||||
Hidden: true,
|
||||
Handler: func(inv *serpent.Invocation) error {
|
||||
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Code, "This is a code message")
|
||||
_, _ = fmt.Fprintln(inv.Stdout)
|
||||
|
||||
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.DateTimeStamp, "This is a datetimestamp message")
|
||||
_, _ = fmt.Fprintln(inv.Stdout)
|
||||
|
||||
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Error, "This is an error message")
|
||||
_, _ = fmt.Fprintln(inv.Stdout)
|
||||
|
||||
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Field, "This is a field message")
|
||||
_, _ = fmt.Fprintln(inv.Stdout)
|
||||
|
||||
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Keyword, "This is a keyword message")
|
||||
_, _ = fmt.Fprintln(inv.Stdout)
|
||||
|
||||
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Placeholder, "This is a placeholder message")
|
||||
_, _ = fmt.Fprintln(inv.Stdout)
|
||||
|
||||
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Prompt, "This is a prompt message")
|
||||
_, _ = fmt.Fprintln(inv.Stdout)
|
||||
|
||||
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.FocusedPrompt, "This is a focused prompt message")
|
||||
_, _ = fmt.Fprintln(inv.Stdout)
|
||||
|
||||
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Fuchsia, "This is a fuchsia message")
|
||||
_, _ = fmt.Fprintln(inv.Stdout)
|
||||
|
||||
pretty.Fprintf(inv.Stdout, cliui.DefaultStyles.Warn, "This is a warning message")
|
||||
_, _ = fmt.Fprintln(inv.Stdout)
|
||||
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
||||
root.Children = append(root.Children, &serpent.Command{
|
||||
Use: "prompt",
|
||||
Handler: func(inv *serpent.Invocation) error {
|
||||
|
Reference in New Issue
Block a user