diff --git a/src/block.go b/src/block.go index 815a9d47..127ec4d0 100644 --- a/src/block.go +++ b/src/block.go @@ -1,6 +1,7 @@ package main import ( + "oh-my-posh/color" "oh-my-posh/environment" "sync" "time" @@ -35,27 +36,27 @@ type Block struct { Newline bool `config:"newline"` env environment.Environment - writer promptWriter - ansi *ansiUtils + writer color.Writer + ansi *color.Ansi activeSegment *Segment previousActiveSegment *Segment activeBackground string activeForeground string } -func (b *Block) init(env environment.Environment, writer promptWriter, ansi *ansiUtils) { +func (b *Block) init(env environment.Environment, writer color.Writer, ansi *color.Ansi) { b.env = env b.writer = writer b.ansi = ansi } func (b *Block) initPlain(env environment.Environment, config *Config) { - b.ansi = &ansiUtils{} - b.ansi.init(plain) - b.writer = &AnsiWriter{ - ansi: b.ansi, - terminalBackground: getConsoleBackgroundColor(env, config.TerminalBackground), - ansiColors: MakeColors(env, config), + b.ansi = &color.Ansi{} + b.ansi.Init(plain) + b.writer = &color.AnsiWriter{ + Ansi: b.ansi, + TerminalBackground: getConsoleBackgroundColor(env, config.TerminalBackground), + AnsiColors: config.MakeColors(env), } b.env = env } @@ -64,7 +65,7 @@ func (b *Block) setActiveSegment(segment *Segment) { b.activeSegment = segment b.activeBackground = segment.background() b.activeForeground = segment.foreground() - b.writer.setColors(b.activeBackground, b.activeForeground) + b.writer.SetColors(b.activeBackground, b.activeForeground) } func (b *Block) enabled() bool { @@ -92,7 +93,7 @@ func (b *Block) setStringValues() { } func (b *Block) renderSegments() string { - defer b.writer.reset() + defer b.writer.Reset() for _, segment := range b.Segments { if !segment.active { continue @@ -100,8 +101,8 @@ func (b *Block) renderSegments() string { b.renderSegment(segment) } b.writePowerline(true) - b.writer.clearParentColors() - return b.writer.string() + b.writer.ClearParentColors() + return b.writer.String() } func (b *Block) renderSegment(segment *Segment) { @@ -111,19 +112,19 @@ func (b *Block) renderSegment(segment *Segment) { case Plain, Powerline: b.renderText(segment.stringValue) case Diamond: - b.writer.write(Transparent, b.activeBackground, b.activeSegment.LeadingDiamond) + b.writer.Write(color.Transparent, b.activeBackground, b.activeSegment.LeadingDiamond) b.renderText(segment.stringValue) - b.writer.write(Transparent, b.activeBackground, b.activeSegment.TrailingDiamond) + b.writer.Write(color.Transparent, b.activeBackground, b.activeSegment.TrailingDiamond) } b.previousActiveSegment = b.activeSegment - b.writer.setParentColors(b.activeBackground, b.activeForeground) + b.writer.SetParentColors(b.activeBackground, b.activeForeground) } func (b *Block) renderText(text string) { defaultValue := " " - b.writer.write(b.activeBackground, b.activeForeground, b.activeSegment.getValue(Prefix, defaultValue)) - b.writer.write(b.activeBackground, b.activeForeground, text) - b.writer.write(b.activeBackground, b.activeForeground, b.activeSegment.getValue(Postfix, defaultValue)) + b.writer.Write(b.activeBackground, b.activeForeground, b.activeSegment.getValue(Prefix, defaultValue)) + b.writer.Write(b.activeBackground, b.activeForeground, text) + b.writer.Write(b.activeBackground, b.activeForeground, b.activeSegment.getValue(Postfix, defaultValue)) } func (b *Block) writePowerline(final bool) { @@ -142,21 +143,21 @@ func (b *Block) writePowerline(final bool) { } background := b.activeSegment.background() if final || b.activeSegment.Style != Powerline { - background = Transparent + background = color.Transparent } if b.activeSegment.Style == Diamond && len(b.activeSegment.LeadingDiamond) == 0 { background = b.activeSegment.background() } if b.activeSegment.InvertPowerline { - b.writer.write(b.getPowerlineColor(), background, symbol) + b.writer.Write(b.getPowerlineColor(), background, symbol) return } - b.writer.write(background, b.getPowerlineColor(), symbol) + b.writer.Write(background, b.getPowerlineColor(), symbol) } func (b *Block) getPowerlineColor() string { if b.previousActiveSegment == nil { - return Transparent + return color.Transparent } if b.previousActiveSegment.Style == Diamond && len(b.previousActiveSegment.TrailingDiamond) == 0 { return b.previousActiveSegment.background() @@ -165,7 +166,7 @@ func (b *Block) getPowerlineColor() string { return b.previousActiveSegment.background() } if b.previousActiveSegment.Style != Powerline { - return Transparent + return color.Transparent } return b.previousActiveSegment.background() } @@ -195,8 +196,8 @@ func (b *Block) debug() (int, []*SegmentTiming) { segmentTiming.stringDuration = time.Since(start) b.renderSegment(segment) b.writePowerline(true) - segmentTiming.stringValue = b.writer.string() - b.writer.reset() + segmentTiming.stringValue = b.writer.String() + b.writer.Reset() } segmentTimings = append(segmentTimings, &segmentTiming) } diff --git a/src/ansi.go b/src/color/ansi.go similarity index 84% rename from src/ansi.go rename to src/color/ansi.go index a0bd6a2f..f45fb75e 100644 --- a/src/ansi.go +++ b/src/color/ansi.go @@ -1,4 +1,4 @@ -package main +package color import ( "fmt" @@ -8,9 +8,17 @@ import ( const ( ansiRegex = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))" + + zsh = "zsh" + bash = "bash" + pwsh = "pwsh" + + str = "STR" + url = "URL" ) -type ansiUtils struct { +type Ansi struct { + title string shell string linechange string left string @@ -20,7 +28,6 @@ type ansiUtils struct { clearLine string saveCursorPosition string restoreCursorPosition string - title string colorSingle string colorFull string colorTransparent string @@ -32,7 +39,7 @@ type ansiUtils struct { italic string underline string strikethrough string - bashFormat string + format string shellReservedKeywords []shellKeyWordReplacement } @@ -41,11 +48,11 @@ type shellKeyWordReplacement struct { replacement string } -func (a *ansiUtils) init(shell string) { +func (a *Ansi) Init(shell string) { a.shell = shell - a.bashFormat = "\\[%s\\]" switch shell { case zsh: + a.format = "%%{%s%%}" a.linechange = "%%{\x1b[%d%s%%}" a.right = "%%{\x1b[%dC%%}" a.left = "%%{\x1b[%dD%%}" @@ -69,6 +76,7 @@ func (a *ansiUtils) init(shell string) { // escape double quotes and variable expansion a.shellReservedKeywords = append(a.shellReservedKeywords, shellKeyWordReplacement{"\\", "\\\\"}, shellKeyWordReplacement{"%", "%%"}) case bash: + a.format = "\\[%s\\]" a.linechange = "\\[\x1b[%d%s\\]" a.right = "\\[\x1b[%dC\\]" a.left = "\\[\x1b[%dD\\]" @@ -93,6 +101,7 @@ func (a *ansiUtils) init(shell string) { // https://tldp.org/HOWTO/Bash-Prompt-HOWTO/bash-prompt-escape-sequences.html a.shellReservedKeywords = append(a.shellReservedKeywords, shellKeyWordReplacement{"\\", "\\\\"}) default: + a.format = "%s" a.linechange = "\x1b[%d%s" a.right = "\x1b[%dC" a.left = "\x1b[%dD" @@ -118,7 +127,7 @@ func (a *ansiUtils) init(shell string) { a.shellReservedKeywords = append(a.shellReservedKeywords, shellKeyWordReplacement{"`", "'"}) } -func (a *ansiUtils) lenWithoutANSI(text string) int { +func (a *Ansi) LenWithoutANSI(text string) int { if len(text) == 0 { return 0 } @@ -139,7 +148,7 @@ func (a *ansiUtils) lenWithoutANSI(text string) int { return len(runeText) } -func (a *ansiUtils) generateHyperlink(text string) string { +func (a *Ansi) generateHyperlink(text string) string { // hyperlink matching results := regex.FindNamedRegexMatch("(?P(?:\\[(?P.+)\\])(?:\\((?P.*)\\)))", text) if len(results) != 3 { @@ -151,7 +160,7 @@ func (a *ansiUtils) generateHyperlink(text string) string { return strings.Replace(text, results["all"], hyperlink, 1) } -func (a *ansiUtils) formatText(text string) string { +func (a *Ansi) formatText(text string) string { results := regex.FindAllNamedRegexMatch("(?P<(?P[buis])>(?P[^<]+))", text) for _, result := range results { var formatted string @@ -170,16 +179,16 @@ func (a *ansiUtils) formatText(text string) string { return text } -func (a *ansiUtils) carriageForward() string { +func (a *Ansi) CarriageForward() string { return fmt.Sprintf(a.right, 1000) } -func (a *ansiUtils) getCursorForRightWrite(text string, offset int) string { - strippedLen := a.lenWithoutANSI(text) + -offset +func (a *Ansi) GetCursorForRightWrite(text string, offset int) string { + strippedLen := a.LenWithoutANSI(text) + -offset return fmt.Sprintf(a.left, strippedLen) } -func (a *ansiUtils) changeLine(numberOfLines int) string { +func (a *Ansi) ChangeLine(numberOfLines int) string { position := "B" if numberOfLines < 0 { position = "F" @@ -188,21 +197,41 @@ func (a *ansiUtils) changeLine(numberOfLines int) string { return fmt.Sprintf(a.linechange, numberOfLines, position) } -func (a *ansiUtils) consolePwd(pwd string) string { +func (a *Ansi) ConsolePwd(pwd string) string { if strings.HasSuffix(pwd, ":") { pwd += "\\" } return fmt.Sprintf(a.osc99, pwd) } -func (a *ansiUtils) clearAfter() string { +func (a *Ansi) ClearAfter() string { return a.clearLine + a.clearBelow } -func (a *ansiUtils) escapeText(text string) string { +func (a *Ansi) EscapeText(text string) string { // what to escape/replace is different per shell for _, s := range a.shellReservedKeywords { text = strings.ReplaceAll(text, s.text, s.replacement) } return text } + +func (a *Ansi) Title(title string) string { + return fmt.Sprintf(a.title, title) +} + +func (a *Ansi) ColorReset() string { + return a.creset +} + +func (a *Ansi) FormatText(text string) string { + return fmt.Sprintf(a.format, text) +} + +func (a *Ansi) SaveCursorPosition() string { + return a.saveCursorPosition +} + +func (a *Ansi) RestoreCursorPosition() string { + return a.restoreCursorPosition +} diff --git a/src/ansi_test.go b/src/color/ansi_test.go similarity index 92% rename from src/ansi_test.go rename to src/color/ansi_test.go index 7655e946..40ec6412 100644 --- a/src/ansi_test.go +++ b/src/color/ansi_test.go @@ -1,4 +1,4 @@ -package main +package color import ( "testing" @@ -17,9 +17,9 @@ func TestLenWithoutAnsi(t *testing.T) { {Text: "\\[\x1b[44m\\]hello\\[\x1b[0m\\]", ShellName: bash, Expected: 5}, } for _, tc := range cases { - a := ansiUtils{} - a.init(tc.ShellName) - strippedLength := a.lenWithoutANSI(tc.Text) + a := Ansi{} + a.Init(tc.ShellName) + strippedLength := a.LenWithoutANSI(tc.Text) assert.Equal(t, 5, strippedLength) } } @@ -35,8 +35,8 @@ func TestGenerateHyperlinkNoUrl(t *testing.T) { {Text: "sample text with no url", ShellName: bash, Expected: "sample text with no url"}, } for _, tc := range cases { - a := ansiUtils{} - a.init(tc.ShellName) + a := Ansi{} + a.Init(tc.ShellName) hyperlinkText := a.generateHyperlink(tc.Text) assert.Equal(t, tc.Expected, hyperlinkText) } @@ -53,8 +53,8 @@ func TestGenerateHyperlinkWithUrl(t *testing.T) { {Text: "[google](http://www.google.be)", ShellName: bash, Expected: "\\[\x1b]8;;http://www.google.be\x1b\\\\\\]google\\[\x1b]8;;\x1b\\\\\\]"}, } for _, tc := range cases { - a := ansiUtils{} - a.init(tc.ShellName) + a := Ansi{} + a.Init(tc.ShellName) hyperlinkText := a.generateHyperlink(tc.Text) assert.Equal(t, tc.Expected, hyperlinkText) } @@ -71,8 +71,8 @@ func TestGenerateHyperlinkWithUrlNoName(t *testing.T) { {Text: "[](http://www.google.be)", ShellName: bash, Expected: "[](http://www.google.be)"}, } for _, tc := range cases { - a := ansiUtils{} - a.init(tc.ShellName) + a := Ansi{} + a.Init(tc.ShellName) hyperlinkText := a.generateHyperlink(tc.Text) assert.Equal(t, tc.Expected, hyperlinkText) } @@ -91,8 +91,8 @@ func TestFormatText(t *testing.T) { {Case: "strikethrough", Text: "This is white", Expected: "This \x1b[9mis\x1b[29m white"}, } for _, tc := range cases { - a := ansiUtils{} - a.init("") + a := Ansi{} + a.Init("") formattedText := a.formatText(tc.Text) assert.Equal(t, tc.Expected, formattedText, tc.Case) } diff --git a/src/colors.go b/src/color/colors.go similarity index 89% rename from src/colors.go rename to src/color/colors.go index 4b151a1a..c2c9b204 100644 --- a/src/colors.go +++ b/src/color/colors.go @@ -1,20 +1,12 @@ -package main +package color import ( "fmt" - "oh-my-posh/environment" "github.com/gookit/color" ) -// MakeColors creates instance of AnsiColors to use in AnsiWriter according to -// environment and configuration. -func MakeColors(env environment.Environment, cfg *Config) AnsiColors { - cacheDisabled := env.Getenv("OMP_CACHE_DISABLED") == "1" - return makeColors(cfg.Palette, !cacheDisabled) -} - -func makeColors(palette Palette, cacheEnabled bool) (colors AnsiColors) { +func MakeColors(palette Palette, cacheEnabled bool) (colors AnsiColors) { colors = &DefaultColors{} if palette != nil { colors = &PaletteColors{ansiColors: colors, palette: palette} diff --git a/src/colors_test.go b/src/color/colors_test.go similarity index 82% rename from src/colors_test.go rename to src/color/colors_test.go index 628082de..061e3c3e 100644 --- a/src/colors_test.go +++ b/src/color/colors_test.go @@ -1,4 +1,4 @@ -package main +package color import ( "testing" @@ -30,29 +30,19 @@ func TestGetAnsiFromColorString(t *testing.T) { } func TestMakeColors(t *testing.T) { - colors := makeColors(nil, false) + colors := MakeColors(nil, false) assert.IsType(t, &DefaultColors{}, colors) - colors = makeColors(nil, true) + colors = MakeColors(nil, true) assert.IsType(t, &CachedColors{}, colors) assert.IsType(t, &DefaultColors{}, colors.(*CachedColors).ansiColors) - colors = makeColors(testPalette, false) + colors = MakeColors(testPalette, false) assert.IsType(t, &PaletteColors{}, colors) assert.IsType(t, &DefaultColors{}, colors.(*PaletteColors).ansiColors) - colors = makeColors(testPalette, true) + colors = MakeColors(testPalette, true) assert.IsType(t, &CachedColors{}, colors) assert.IsType(t, &PaletteColors{}, colors.(*CachedColors).ansiColors) assert.IsType(t, &DefaultColors{}, colors.(*CachedColors).ansiColors.(*PaletteColors).ansiColors) } - -func BenchmarkEngineRenderPalette(b *testing.B) { - var err error - for i := 0; i < b.N; i++ { - err = engineRender("jandedobbeleer-palette.omp.json") - if err != nil { - b.Fatal(err) - } - } -} diff --git a/src/palette.go b/src/color/palette.go similarity index 99% rename from src/palette.go rename to src/color/palette.go index d476819b..103864d5 100644 --- a/src/palette.go +++ b/src/color/palette.go @@ -1,4 +1,4 @@ -package main +package color import ( "fmt" diff --git a/src/palette_test.go b/src/color/palette_test.go similarity index 99% rename from src/palette_test.go rename to src/color/palette_test.go index 95b61bc5..5a0b31e6 100644 --- a/src/palette_test.go +++ b/src/color/palette_test.go @@ -1,4 +1,4 @@ -package main +package color import ( "testing" diff --git a/src/writer_plain.go b/src/color/plain_writer.go similarity index 70% rename from src/writer_plain.go rename to src/color/plain_writer.go index 37f89c4c..1694ba5e 100644 --- a/src/writer_plain.go +++ b/src/color/plain_writer.go @@ -1,4 +1,4 @@ -package main +package color import ( "oh-my-posh/regex" @@ -10,11 +10,11 @@ type PlainWriter struct { builder strings.Builder } -func (a *PlainWriter) setColors(background, foreground string) {} -func (a *PlainWriter) setParentColors(background, foreground string) {} -func (a *PlainWriter) clearParentColors() {} +func (a *PlainWriter) SetColors(background, foreground string) {} +func (a *PlainWriter) SetParentColors(background, foreground string) {} +func (a *PlainWriter) ClearParentColors() {} -func (a *PlainWriter) write(background, foreground, text string) { +func (a *PlainWriter) Write(background, foreground, text string) { if len(text) == 0 { return } @@ -33,10 +33,10 @@ func (a *PlainWriter) write(background, foreground, text string) { a.builder.WriteString(text) } -func (a *PlainWriter) string() string { +func (a *PlainWriter) String() string { return a.builder.String() } -func (a *PlainWriter) reset() { +func (a *PlainWriter) Reset() { a.builder.Reset() } diff --git a/src/writer_ansi.go b/src/color/writer.go similarity index 82% rename from src/writer_ansi.go rename to src/color/writer.go index cc18eb20..032de184 100644 --- a/src/writer_ansi.go +++ b/src/color/writer.go @@ -1,4 +1,4 @@ -package main +package color import ( "fmt" @@ -10,23 +10,24 @@ const ( colorRegex = `<(?P[^,>]+)?,?(?P[^>]+)?>(?P[^<]*)<\/>` ) -type promptWriter interface { - write(background, foreground, text string) - string() string - reset() - setColors(background, foreground string) - setParentColors(background, foreground string) - clearParentColors() +type Writer interface { + Write(background, foreground, text string) + String() string + Reset() + SetColors(background, foreground string) + SetParentColors(background, foreground string) + ClearParentColors() } -// AnsiWriter writes colorized strings +// AnsiWriter writes colorized ANSI strings type AnsiWriter struct { - builder strings.Builder - ansi *ansiUtils - terminalBackground string + Ansi *Ansi + TerminalBackground string Colors *Color ParentColors []*Color - ansiColors AnsiColors + AnsiColors AnsiColors + + builder strings.Builder } type Color struct { @@ -73,14 +74,14 @@ const ( Foreground = "foreground" ) -func (a *AnsiWriter) setColors(background, foreground string) { +func (a *AnsiWriter) SetColors(background, foreground string) { a.Colors = &Color{ Background: background, Foreground: foreground, } } -func (a *AnsiWriter) setParentColors(background, foreground string) { +func (a *AnsiWriter) SetParentColors(background, foreground string) { if a.ParentColors == nil { a.ParentColors = make([]*Color, 0) } @@ -90,12 +91,12 @@ func (a *AnsiWriter) setParentColors(background, foreground string) { }}, a.ParentColors...) } -func (a *AnsiWriter) clearParentColors() { +func (a *AnsiWriter) ClearParentColors() { a.ParentColors = nil } func (a *AnsiWriter) getAnsiFromColorString(colorString string, isBackground bool) AnsiColor { - return a.ansiColors.AnsiColorFromString(colorString, isBackground) + return a.AnsiColors.AnsiColorFromString(colorString, isBackground) } func (a *AnsiWriter) writeColoredText(background, foreground AnsiColor, text string) { @@ -107,22 +108,22 @@ func (a *AnsiWriter) writeColoredText(background, foreground AnsiColor, text str if foreground.IsEmpty() { foreground = a.getAnsiFromColorString("white", false) } - if foreground.IsTransparent() && !background.IsEmpty() && len(a.terminalBackground) != 0 { - fgAnsiColor := a.getAnsiFromColorString(a.terminalBackground, false) - coloredText := fmt.Sprintf(a.ansi.colorFull, background, fgAnsiColor, text) + if foreground.IsTransparent() && !background.IsEmpty() && len(a.TerminalBackground) != 0 { + fgAnsiColor := a.getAnsiFromColorString(a.TerminalBackground, false) + coloredText := fmt.Sprintf(a.Ansi.colorFull, background, fgAnsiColor, text) a.builder.WriteString(coloredText) return } if foreground.IsTransparent() && !background.IsEmpty() { - coloredText := fmt.Sprintf(a.ansi.colorTransparent, background, text) + coloredText := fmt.Sprintf(a.Ansi.colorTransparent, background, text) a.builder.WriteString(coloredText) return } else if background.IsEmpty() || background.IsTransparent() { - coloredText := fmt.Sprintf(a.ansi.colorSingle, foreground, text) + coloredText := fmt.Sprintf(a.Ansi.colorSingle, foreground, text) a.builder.WriteString(coloredText) return } - coloredText := fmt.Sprintf(a.ansi.colorFull, background, foreground, text) + coloredText := fmt.Sprintf(a.Ansi.colorFull, background, foreground, text) a.builder.WriteString(coloredText) } @@ -131,15 +132,15 @@ func (a *AnsiWriter) writeAndRemoveText(background, foreground AnsiColor, text, return strings.Replace(parentText, textToRemove, "", 1) } -func (a *AnsiWriter) write(background, foreground, text string) { +func (a *AnsiWriter) Write(background, foreground, text string) { if len(text) == 0 { return } bgAnsi, fgAnsi := a.asAnsiColors(background, foreground) - text = a.ansi.escapeText(text) - text = a.ansi.formatText(text) - text = a.ansi.generateHyperlink(text) + text = a.Ansi.EscapeText(text) + text = a.Ansi.formatText(text) + text = a.Ansi.generateHyperlink(text) // first we match for any potentially valid colors enclosed in <> // i.e., find color overrides @@ -225,10 +226,10 @@ func (a *AnsiWriter) expandKeyword(keyword string) string { return keyword } -func (a *AnsiWriter) string() string { +func (a *AnsiWriter) String() string { return a.builder.String() } -func (a *AnsiWriter) reset() { +func (a *AnsiWriter) Reset() { a.builder.Reset() } diff --git a/src/writer_ansi_test.go b/src/color/writer_test.go similarity index 96% rename from src/writer_ansi_test.go rename to src/color/writer_test.go index 5721225f..9b797ce6 100644 --- a/src/writer_ansi_test.go +++ b/src/color/writer_test.go @@ -1,4 +1,4 @@ -package main +package color import ( "testing" @@ -171,17 +171,17 @@ func TestWriteANSIColors(t *testing.T) { } for _, tc := range cases { - ansi := &ansiUtils{} - ansi.init("pwsh") + ansi := &Ansi{} + ansi.Init("pwsh") renderer := &AnsiWriter{ - ansi: ansi, + Ansi: ansi, ParentColors: []*Color{tc.Parent}, Colors: tc.Colors, - terminalBackground: tc.TerminalBackground, - ansiColors: &DefaultColors{}, + TerminalBackground: tc.TerminalBackground, + AnsiColors: &DefaultColors{}, } - renderer.write(tc.Colors.Background, tc.Colors.Foreground, tc.Input) - got := renderer.string() + renderer.Write(tc.Colors.Background, tc.Colors.Foreground, tc.Input) + got := renderer.String() assert.Equal(t, tc.Expected, got, tc.Case) } } diff --git a/src/config.go b/src/config.go index 4321d8ce..c6ebe8df 100644 --- a/src/config.go +++ b/src/config.go @@ -7,6 +7,7 @@ import ( json2 "encoding/json" "errors" "fmt" + "oh-my-posh/color" "oh-my-posh/environment" "os" "strconv" @@ -30,7 +31,14 @@ type Config struct { Blocks []*Block `config:"blocks"` Tooltips []*Segment `config:"tooltips"` TransientPrompt *TransientPrompt `config:"transient_prompt"` - Palette Palette `config:"palette"` + Palette color.Palette `config:"palette"` +} + +// MakeColors creates instance of AnsiColors to use in AnsiWriter according to +// environment and configuration. +func (cfg *Config) MakeColors(env environment.Environment) color.AnsiColors { + cacheDisabled := env.Getenv("OMP_CACHE_DISABLED") == "1" + return color.MakeColors(cfg.Palette, !cacheDisabled) } type TransientPrompt struct { diff --git a/src/console_title.go b/src/console_title.go index febeb2e7..eb9ea5be 100644 --- a/src/console_title.go +++ b/src/console_title.go @@ -1,7 +1,7 @@ package main import ( - "fmt" + "oh-my-posh/color" "oh-my-posh/environment" "strings" ) @@ -9,7 +9,7 @@ import ( type consoleTitle struct { env environment.Environment config *Config - ansi *ansiUtils + ansi *color.Ansi } // ConsoleTitleStyle defines how to show the title in the console window @@ -36,8 +36,8 @@ func (t *consoleTitle) getConsoleTitle() string { default: title = environment.Base(t.env, t.getPwd()) } - title = t.ansi.escapeText(title) - return fmt.Sprintf(t.ansi.title, title) + title = t.ansi.EscapeText(title) + return t.ansi.Title(title) } func (t *consoleTitle) getTemplateText() string { diff --git a/src/console_title_test.go b/src/console_title_test.go index 3752be1e..436781d8 100644 --- a/src/console_title_test.go +++ b/src/console_title_test.go @@ -1,6 +1,7 @@ package main import ( + "oh-my-posh/color" "oh-my-posh/environment" "oh-my-posh/mock" "testing" @@ -69,8 +70,8 @@ func TestGetConsoleTitle(t *testing.T) { PWD: tc.Cwd, Folder: "vagrant", }) - ansi := &ansiUtils{} - ansi.init(tc.ShellName) + ansi := &color.Ansi{} + ansi.Init(tc.ShellName) ct := &consoleTitle{ env: env, config: config, @@ -127,8 +128,8 @@ func TestGetConsoleTitleIfGethostnameReturnsError(t *testing.T) { Root: tc.Root, HostName: "", }) - ansi := &ansiUtils{} - ansi.init(tc.ShellName) + ansi := &color.Ansi{} + ansi.Init(tc.ShellName) ct := &consoleTitle{ env: env, config: config, diff --git a/src/engine.go b/src/engine.go index 9f5de466..a6c41b75 100644 --- a/src/engine.go +++ b/src/engine.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "oh-my-posh/color" "oh-my-posh/environment" "strings" "time" @@ -10,8 +11,8 @@ import ( type engine struct { config *Config env environment.Environment - writer promptWriter - ansi *ansiUtils + writer color.Writer + ansi *color.Ansi consoleTitle *consoleTitle plain bool @@ -40,7 +41,7 @@ func (e *engine) canWriteRPrompt() bool { if err != nil || consoleWidth == 0 { return true } - promptWidth := e.ansi.lenWithoutANSI(prompt) + promptWidth := e.ansi.LenWithoutANSI(prompt) availableSpace := consoleWidth - promptWidth // spanning multiple lines if availableSpace < 0 { @@ -48,7 +49,7 @@ func (e *engine) canWriteRPrompt() bool { availableSpace = consoleWidth - overflow } promptBreathingRoom := 30 - canWrite := (availableSpace - e.ansi.lenWithoutANSI(e.rprompt)) >= promptBreathingRoom + canWrite := (availableSpace - e.ansi.LenWithoutANSI(e.rprompt)) >= promptBreathingRoom return canWrite } @@ -59,7 +60,7 @@ func (e *engine) render() string { if e.config.ConsoleTitle { e.writeANSI(e.consoleTitle.getConsoleTitle()) } - e.writeANSI(e.ansi.creset) + e.writeANSI(e.ansi.ColorReset()) if e.config.FinalSpace { e.write(" ") } @@ -68,7 +69,7 @@ func (e *engine) render() string { return e.print() } cwd := e.env.Pwd() - e.writeANSI(e.ansi.consolePwd(cwd)) + e.writeANSI(e.ansi.ConsolePwd(cwd)) return e.print() } @@ -95,13 +96,13 @@ func (e *engine) renderBlock(block *Block) { e.write("\n") case Prompt: if block.VerticalOffset != 0 { - e.writeANSI(e.ansi.changeLine(block.VerticalOffset)) + e.writeANSI(e.ansi.ChangeLine(block.VerticalOffset)) } switch block.Alignment { case Right: - e.writeANSI(e.ansi.carriageForward()) + e.writeANSI(e.ansi.CarriageForward()) blockText := block.renderSegments() - e.writeANSI(e.ansi.getCursorForRightWrite(blockText, block.HorizontalOffset)) + e.writeANSI(e.ansi.GetCursorForRightWrite(blockText, block.HorizontalOffset)) e.write(blockText) case Left: e.write(block.renderSegments()) @@ -109,7 +110,7 @@ func (e *engine) renderBlock(block *Block) { case RPrompt: blockText := block.renderSegments() if e.env.Shell() == bash { - blockText = fmt.Sprintf(e.ansi.bashFormat, blockText) + blockText = e.ansi.FormatText(blockText) } e.rprompt = blockText } @@ -117,8 +118,8 @@ func (e *engine) renderBlock(block *Block) { // If this doesn't happen, the portion after the prompt gets colored in the background // color of the line above the new input line. Clearing the line fixes this, // but can hopefully one day be removed when this is resolved natively. - if e.ansi.shell == pwsh || e.ansi.shell == powershell5 { - e.writeANSI(e.ansi.clearAfter()) + if e.env.Shell() == pwsh || e.env.Shell() == powershell5 { + e.writeANSI(e.ansi.ClearAfter()) } } @@ -182,11 +183,11 @@ func (e *engine) print() string { if e.rprompt == "" || !e.canWriteRPrompt() || e.plain { break } - e.write(e.ansi.saveCursorPosition) - e.write(e.ansi.carriageForward()) - e.write(e.ansi.getCursorForRightWrite(e.rprompt, 0)) + e.write(e.ansi.SaveCursorPosition()) + e.write(e.ansi.CarriageForward()) + e.write(e.ansi.GetCursorForRightWrite(e.rprompt, 0)) e.write(e.rprompt) - e.write(e.ansi.restoreCursorPosition) + e.write(e.ansi.RestoreCursorPosition()) } return e.string() } @@ -222,9 +223,9 @@ func (e *engine) renderTooltip(tip string) string { case pwsh, powershell5: block.initPlain(e.env, e.config) tooltipText := block.renderSegments() - e.write(e.ansi.clearAfter()) - e.write(e.ansi.carriageForward()) - e.write(e.ansi.getCursorForRightWrite(tooltipText, 0)) + e.write(e.ansi.ClearAfter()) + e.write(e.ansi.CarriageForward()) + e.write(e.ansi.GetCursorForRightWrite(tooltipText, 0)) e.write(tooltipText) return e.string() } @@ -247,16 +248,16 @@ func (e *engine) renderTransientPrompt() string { if err != nil { prompt = err.Error() } - e.writer.setColors(e.config.TransientPrompt.Background, e.config.TransientPrompt.Foreground) - e.writer.write(e.config.TransientPrompt.Background, e.config.TransientPrompt.Foreground, prompt) + e.writer.SetColors(e.config.TransientPrompt.Background, e.config.TransientPrompt.Foreground) + e.writer.Write(e.config.TransientPrompt.Background, e.config.TransientPrompt.Foreground, prompt) switch e.env.Shell() { case zsh: // escape double quotes contained in the prompt - prompt := fmt.Sprintf("PS1=\"%s\"", strings.ReplaceAll(e.writer.string(), "\"", "\"\"")) + prompt := fmt.Sprintf("PS1=\"%s\"", strings.ReplaceAll(e.writer.String(), "\"", "\"\"")) prompt += "\nRPROMPT=\"\"" return prompt case pwsh, powershell5, winCMD: - return e.writer.string() + return e.writer.String() } return "" } diff --git a/src/engine_test.go b/src/engine_test.go index 0de63483..0dbce6bf 100644 --- a/src/engine_test.go +++ b/src/engine_test.go @@ -2,6 +2,7 @@ package main import ( "errors" + "oh-my-posh/color" "oh-my-posh/environment" "oh-my-posh/mock" "os" @@ -33,8 +34,8 @@ func TestCanWriteRPrompt(t *testing.T) { for _, tc := range cases { env := new(mock.MockedEnvironment) env.On("TerminalWidth").Return(tc.TerminalWidth, tc.TerminalWidthError) - ansi := &ansiUtils{} - ansi.init(plain) + ansi := &color.Ansi{} + ansi.Init(plain) engine := &engine{ env: env, ansi: ansi, @@ -94,13 +95,13 @@ func engineRender(configPath string) error { cfg := GetConfig(env) defer testClearDefaultConfig() - ansi := &ansiUtils{} - ansi.init(env.Shell()) - writerColors := MakeColors(env, cfg) - writer := &AnsiWriter{ - ansi: ansi, - terminalBackground: getConsoleBackgroundColor(env, cfg.TerminalBackground), - ansiColors: writerColors, + ansi := &color.Ansi{} + ansi.Init(env.Shell()) + writerColors := cfg.MakeColors(env) + writer := &color.AnsiWriter{ + Ansi: ansi, + TerminalBackground: getConsoleBackgroundColor(env, cfg.TerminalBackground), + AnsiColors: writerColors, } title := &consoleTitle{ env: env, @@ -120,3 +121,13 @@ func engineRender(configPath string) error { return nil } + +func BenchmarkEngineRenderPalette(b *testing.B) { + var err error + for i := 0; i < b.N; i++ { + err = engineRender("jandedobbeleer-palette.omp.json") + if err != nil { + b.Fatal(err) + } + } +} diff --git a/src/image.go b/src/image.go index 461505be..678b9b4e 100644 --- a/src/image.go +++ b/src/image.go @@ -26,6 +26,7 @@ import ( _ "embed" "fmt" "math" + "oh-my-posh/color" "oh-my-posh/regex" "strconv" "strings" @@ -98,7 +99,7 @@ func NewRGBColor(ansiColor string) *RGB { type ImageRenderer struct { ansiString string author string - ansi *ansiUtils + ansi *color.Ansi bgColor string factor float64 @@ -244,7 +245,7 @@ func (ir *ImageRenderer) runeAdditionalWidth(r rune) int { func (ir *ImageRenderer) calculateWidth() int { longest := 0 for _, line := range strings.Split(ir.ansiString, "\n") { - length := ir.ansi.lenWithoutANSI(line) + length := ir.ansi.LenWithoutANSI(line) for _, char := range line { length += ir.runeAdditionalWidth(char) } @@ -435,9 +436,9 @@ func (ir *ImageRenderer) shouldPrint() bool { return false case invertedColorSingle: ir.foregroundColor = ir.defaultBackgroundColor - color, _ := strconv.Atoi(match[bg]) - color += 10 - ir.setBase16Color(fmt.Sprint(color)) + bgColor, _ := strconv.Atoi(match[bg]) + bgColor += 10 + ir.setBase16Color(fmt.Sprint(bgColor)) return false case fullColor: ir.foregroundColor = NewRGBColor(match[fg]) @@ -469,48 +470,48 @@ func (ir *ImageRenderer) shouldPrint() bool { } func (ir *ImageRenderer) setBase16Color(colorStr string) { - color := ir.defaultForegroundColor + tempColor := ir.defaultForegroundColor colorInt, err := strconv.Atoi(colorStr) if err != nil { - ir.foregroundColor = color + ir.foregroundColor = tempColor } switch colorInt { case 30, 40: // Black - color = &RGB{1, 1, 1} + tempColor = &RGB{1, 1, 1} case 31, 41: // Red - color = &RGB{222, 56, 43} + tempColor = &RGB{222, 56, 43} case 32, 42: // Green - color = &RGB{57, 181, 74} + tempColor = &RGB{57, 181, 74} case 33, 43: // Yellow - color = &RGB{255, 199, 6} + tempColor = &RGB{255, 199, 6} case 34, 44: // Blue - color = &RGB{0, 111, 184} + tempColor = &RGB{0, 111, 184} case 35, 45: // Magenta - color = &RGB{118, 38, 113} + tempColor = &RGB{118, 38, 113} case 36, 46: // Cyan - color = &RGB{44, 181, 233} + tempColor = &RGB{44, 181, 233} case 37, 47: // White - color = &RGB{204, 204, 204} + tempColor = &RGB{204, 204, 204} case 90, 100: // Bright Black (Gray) - color = &RGB{128, 128, 128} + tempColor = &RGB{128, 128, 128} case 91, 101: // Bright Red - color = &RGB{255, 0, 0} + tempColor = &RGB{255, 0, 0} case 92, 102: // Bright Green - color = &RGB{0, 255, 0} + tempColor = &RGB{0, 255, 0} case 93, 103: // Bright Yellow - color = &RGB{255, 255, 0} + tempColor = &RGB{255, 255, 0} case 94, 104: // Bright Blue - color = &RGB{0, 0, 255} + tempColor = &RGB{0, 0, 255} case 95, 105: // Bright Magenta - color = &RGB{255, 0, 255} + tempColor = &RGB{255, 0, 255} case 96, 106: // Bright Cyan - color = &RGB{101, 194, 205} + tempColor = &RGB{101, 194, 205} case 97, 107: // Bright White - color = &RGB{255, 255, 255} + tempColor = &RGB{255, 255, 255} } if colorInt < 40 || (colorInt >= 90 && colorInt < 100) { - ir.foregroundColor = color + ir.foregroundColor = tempColor return } - ir.backgroundColor = color + ir.backgroundColor = tempColor } diff --git a/src/image_test.go b/src/image_test.go index 73ccaf50..4aca08bb 100644 --- a/src/image_test.go +++ b/src/image_test.go @@ -2,6 +2,7 @@ package main import ( "io/ioutil" + "oh-my-posh/color" "os" "testing" @@ -15,8 +16,8 @@ func runImageTest(content string) error { return err } defer os.Remove(file.Name()) - ansi := &ansiUtils{} - ansi.init(plain) + ansi := &color.Ansi{} + ansi.Init(plain) image := &ImageRenderer{ ansiString: content, ansi: ansi, diff --git a/src/main.go b/src/main.go index 6e1a402d..428976f2 100644 --- a/src/main.go +++ b/src/main.go @@ -4,6 +4,7 @@ import ( _ "embed" "flag" "fmt" + "oh-my-posh/color" "oh-my-posh/environment" "oh-my-posh/regex" "os" @@ -32,7 +33,8 @@ var zshInit string var cmdInit string const ( - noExe = "echo \"Unable to find Oh My Posh executable\"" + noExe = "echo \"Unable to find Oh My Posh executable\"" + zsh = "zsh" bash = "bash" pwsh = "pwsh" @@ -184,17 +186,17 @@ func main() { return } cfg := GetConfig(env) - ansi := &ansiUtils{} - ansi.init(env.Shell()) - var writer promptWriter + ansi := &color.Ansi{} + ansi.Init(env.Shell()) + var writer color.Writer if *args.Plain { - writer = &PlainWriter{} + writer = &color.PlainWriter{} } else { - writerColors := MakeColors(env, cfg) - writer = &AnsiWriter{ - ansi: ansi, - terminalBackground: getConsoleBackgroundColor(env, cfg.TerminalBackground), - ansiColors: writerColors, + writerColors := cfg.MakeColors(env) + writer = &color.AnsiWriter{ + Ansi: ansi, + TerminalBackground: getConsoleBackgroundColor(env, cfg.TerminalBackground), + AnsiColors: writerColors, } } title := &consoleTitle{ diff --git a/src/properties.go b/src/properties.go index bb259ecc..e1c30777 100644 --- a/src/properties.go +++ b/src/properties.go @@ -2,9 +2,20 @@ package main import ( "fmt" + "oh-my-posh/color" "oh-my-posh/regex" ) +type Properties interface { + GetColor(property Property, defaultColor string) string + GetBool(property Property, defaultValue bool) bool + GetString(property Property, defaultValue string) string + GetFloat64(property Property, defaultValue float64) float64 + GetInt(property Property, defaultValue int) int + GetKeyValueMap(property Property, defaultValue map[string]string) map[string]string + GetStringArray(property Property, defaultValue []string) []string +} + // Property defines one property of a segment for context type Property string @@ -42,7 +53,7 @@ const ( type properties map[Property]interface{} -func (p properties) getString(property Property, defaultValue string) string { +func (p properties) GetString(property Property, defaultValue string) string { val, found := p[property] if !found { return defaultValue @@ -58,13 +69,13 @@ func parseString(value interface{}, defaultValue string) string { return stringValue } -func (p properties) getColor(property Property, defaultValue string) string { +func (p properties) GetColor(property Property, defaultValue string) string { val, found := p[property] if !found { return defaultValue } colorString := parseString(val, defaultValue) - if IsAnsiColorName(colorString) { + if color.IsAnsiColorName(colorString) { return colorString } values := regex.FindNamedRegexMatch(`(?P#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|p:.*)`, colorString) @@ -74,7 +85,7 @@ func (p properties) getColor(property Property, defaultValue string) string { return defaultValue } -func (p properties) getBool(property Property, defaultValue bool) bool { +func (p properties) GetBool(property Property, defaultValue bool) bool { val, found := p[property] if !found { return defaultValue @@ -86,7 +97,7 @@ func (p properties) getBool(property Property, defaultValue bool) bool { return boolValue } -func (p properties) getFloat64(property Property, defaultValue float64) float64 { +func (p properties) GetFloat64(property Property, defaultValue float64) float64 { val, found := p[property] if !found { return defaultValue @@ -105,7 +116,7 @@ func (p properties) getFloat64(property Property, defaultValue float64) float64 return float64(intValue) } -func (p properties) getInt(property Property, defaultValue int) int { +func (p properties) GetInt(property Property, defaultValue int) int { val, found := p[property] if !found { return defaultValue @@ -124,7 +135,7 @@ func (p properties) getInt(property Property, defaultValue int) int { return int(intValue) } -func (p properties) getKeyValueMap(property Property, defaultValue map[string]string) map[string]string { +func (p properties) GetKeyValueMap(property Property, defaultValue map[string]string) map[string]string { val, found := p[property] if !found { return defaultValue @@ -135,7 +146,7 @@ func (p properties) getKeyValueMap(property Property, defaultValue map[string]st return keyValues } -func (p properties) getStringArray(property Property, defaultValue []string) []string { +func (p properties) GetStringArray(property Property, defaultValue []string) []string { val, found := p[property] if !found { return defaultValue diff --git a/src/properties_test.go b/src/properties_test.go index 1acf6067..86a5e104 100644 --- a/src/properties_test.go +++ b/src/properties_test.go @@ -15,100 +15,100 @@ const ( func TestGetString(t *testing.T) { var properties properties = properties{Foo: expected} - value := properties.getString(Foo, "err") + value := properties.GetString(Foo, "err") assert.Equal(t, expected, value) } func TestGetStringNoEntry(t *testing.T) { var properties properties = properties{} - value := properties.getString(Foo, expected) + value := properties.GetString(Foo, expected) assert.Equal(t, expected, value) } func TestGetStringNoTextEntry(t *testing.T) { var properties properties = properties{Foo: true} - value := properties.getString(Foo, expected) + value := properties.GetString(Foo, expected) assert.Equal(t, expected, value) } func TestGetHexColor(t *testing.T) { expected := expectedColor var properties properties = properties{Foo: expected} - value := properties.getColor(Foo, "#789123") + value := properties.GetColor(Foo, "#789123") assert.Equal(t, expected, value) } func TestGetColor(t *testing.T) { expected := "yellow" var properties properties = properties{Foo: expected} - value := properties.getColor(Foo, "#789123") + value := properties.GetColor(Foo, "#789123") assert.Equal(t, expected, value) } func TestDefaultColorWithInvalidColorCode(t *testing.T) { expected := expectedColor var properties properties = properties{Foo: "invalid"} - value := properties.getColor(Foo, expected) + value := properties.GetColor(Foo, expected) assert.Equal(t, expected, value) } func TestDefaultColorWithUnavailableProperty(t *testing.T) { expected := expectedColor var properties properties = properties{} - value := properties.getColor(Foo, expected) + value := properties.GetColor(Foo, expected) assert.Equal(t, expected, value) } func TestGetPaletteColor(t *testing.T) { expected := "p:red" var properties properties = properties{Foo: expected} - value := properties.getColor(Foo, "white") + value := properties.GetColor(Foo, "white") assert.Equal(t, expected, value) } func TestGetBool(t *testing.T) { expected := true var properties properties = properties{Foo: expected} - value := properties.getBool(Foo, false) + value := properties.GetBool(Foo, false) assert.True(t, value) } func TestGetBoolPropertyNotInMap(t *testing.T) { var properties properties = properties{} - value := properties.getBool(Foo, false) + value := properties.GetBool(Foo, false) assert.False(t, value) } func TestGetBoolInvalidProperty(t *testing.T) { var properties properties = properties{Foo: "borked"} - value := properties.getBool(Foo, false) + value := properties.GetBool(Foo, false) assert.False(t, value) } func TestGetFloat64(t *testing.T) { expected := float64(1337) var properties properties = properties{Foo: expected} - value := properties.getFloat64(Foo, 9001) + value := properties.GetFloat64(Foo, 9001) assert.Equal(t, expected, value) } func TestGetFloat64PropertyNotInMap(t *testing.T) { expected := float64(1337) var properties properties = properties{} - value := properties.getFloat64(Foo, expected) + value := properties.GetFloat64(Foo, expected) assert.Equal(t, expected, value) } func TestGetFloat64InvalidStringProperty(t *testing.T) { expected := float64(1337) - var properties properties = properties{ThresholdProperty: "invalid"} - value := properties.getFloat64(ThresholdProperty, expected) + var properties properties = properties{Foo: "invalid"} + value := properties.GetFloat64(Foo, expected) assert.Equal(t, expected, value) } func TestGetFloat64InvalidBoolProperty(t *testing.T) { expected := float64(1337) - var properties properties = properties{ThresholdProperty: true} - value := properties.getFloat64(ThresholdProperty, expected) + var properties properties = properties{Foo: true} + value := properties.GetFloat64(Foo, expected) assert.Equal(t, expected, value) } diff --git a/src/scm.go b/src/scm.go index c5959de7..febca473 100644 --- a/src/scm.go +++ b/src/scm.go @@ -55,8 +55,8 @@ func (s *scm) init(props Properties, env environment.Environment) { } func (s *scm) truncateBranch(branch string) string { - fullBranchPath := s.props.getBool(FullBranchPath, true) - maxLength := s.props.getInt(BranchMaxLength, 0) + fullBranchPath := s.props.GetBool(FullBranchPath, true) + maxLength := s.props.GetInt(BranchMaxLength, 0) if !fullBranchPath && strings.Contains(branch, "/") { index := strings.LastIndex(branch, "/") branch = branch[index+1:] @@ -64,12 +64,12 @@ func (s *scm) truncateBranch(branch string) string { if maxLength == 0 || len(branch) <= maxLength { return branch } - symbol := s.props.getString(TruncateSymbol, "") + symbol := s.props.GetString(TruncateSymbol, "") return branch[0:maxLength] + symbol } func (s *scm) shouldIgnoreRootRepository(rootDir string) bool { - excludedFolders := s.props.getStringArray(ExcludeFolders, []string{}) + excludedFolders := s.props.GetStringArray(ExcludeFolders, []string{}) if len(excludedFolders) == 0 { return false } diff --git a/src/segment.go b/src/segment.go index d7bd61fd..555ed625 100644 --- a/src/segment.go +++ b/src/segment.go @@ -38,16 +38,6 @@ type SegmentTiming struct { stringDuration time.Duration } -type Properties interface { - getColor(property Property, defaultColor string) string - getBool(property Property, defaultValue bool) bool - getString(property Property, defaultValue string) string - getFloat64(property Property, defaultValue float64) float64 - getInt(property Property, defaultValue int) int - getKeyValueMap(property Property, defaultValue map[string]string) map[string]string - getStringArray(property Property, defaultValue []string) []string -} - // SegmentWriter is the interface used to define what and if to write to the prompt type SegmentWriter interface { enabled() bool diff --git a/src/segment_aws.go b/src/segment_aws.go index 1d155677..3b99b492 100644 --- a/src/segment_aws.go +++ b/src/segment_aws.go @@ -37,7 +37,7 @@ func (a *aws) enabled() bool { } return "" } - displayDefaultUser := a.props.getBool(DisplayDefault, true) + displayDefaultUser := a.props.GetBool(DisplayDefault, true) a.Profile = getEnvFirstMatch("AWS_VAULT", "AWS_PROFILE") if !displayDefaultUser && a.Profile == defaultUser { return false diff --git a/src/segment_battery.go b/src/segment_battery.go index cb6a3611..4243aaff 100644 --- a/src/segment_battery.go +++ b/src/segment_battery.go @@ -52,11 +52,11 @@ func (b *batt) enabled() bool { switch b.Battery.State { case battery.Discharging, battery.NotCharging: - b.Icon = b.props.getString(DischargingIcon, "") + b.Icon = b.props.GetString(DischargingIcon, "") case battery.Charging: - b.Icon = b.props.getString(ChargingIcon, "") + b.Icon = b.props.GetString(ChargingIcon, "") case battery.Full: - b.Icon = b.props.getString(ChargedIcon, "") + b.Icon = b.props.GetString(ChargedIcon, "") case battery.Empty, battery.Unknown: return true } @@ -70,7 +70,7 @@ func (b *batt) enabledWhileError(err error) bool { if _, ok := err.(*environment.NoBatteryError); ok { return false } - displayError := b.props.getBool(DisplayError, false) + displayError := b.props.GetBool(DisplayError, false) if !displayError { return false } diff --git a/src/segment_brewfather.go b/src/segment_brewfather.go index 7116c3f4..e8e65bd0 100644 --- a/src/segment_brewfather.go +++ b/src/segment_brewfather.go @@ -140,12 +140,12 @@ func (bf *brewfather) enabled() bool { } // URL property set to weblink to the full batch page - batchID := bf.props.getString(BFBatchID, "") + batchID := bf.props.GetString(BFBatchID, "") if len(batchID) > 0 { bf.URL = fmt.Sprintf("https://web.brewfather.app/tabs/batches/batch/%s", batchID) } - bf.DayIcon = bf.props.getString(BFDayIcon, "d") + bf.DayIcon = bf.props.GetString(BFDayIcon, "d") return true } @@ -154,49 +154,49 @@ func (bf *brewfather) getTrendIcon(trend float64) string { // Not a fan of this logic - wondering if Go lets us do something cleaner... if trend >= 0 { if trend > 4 { - return bf.props.getString(BFDoubleUpIcon, "↑↑") + return bf.props.GetString(BFDoubleUpIcon, "↑↑") } if trend > 2 { - return bf.props.getString(BFSingleUpIcon, "↑") + return bf.props.GetString(BFSingleUpIcon, "↑") } if trend > 0.5 { - return bf.props.getString(BFFortyFiveUpIcon, "↗") + return bf.props.GetString(BFFortyFiveUpIcon, "↗") } - return bf.props.getString(BFFlatIcon, "→") + return bf.props.GetString(BFFlatIcon, "→") } if trend < -4 { - return bf.props.getString(BFDoubleDownIcon, "↓↓") + return bf.props.GetString(BFDoubleDownIcon, "↓↓") } if trend < -2 { - return bf.props.getString(BFSingleDownIcon, "↓") + return bf.props.GetString(BFSingleDownIcon, "↓") } if trend < -0.5 { - return bf.props.getString(BFFortyFiveDownIcon, "↘") + return bf.props.GetString(BFFortyFiveDownIcon, "↘") } - return bf.props.getString(BFFlatIcon, "→") + return bf.props.GetString(BFFlatIcon, "→") } func (bf *brewfather) getBatchStatusIcon(batchStatus string) string { switch batchStatus { case BFStatusPlanning: - return bf.props.getString(BFPlanningStatusIcon, "\uF8EA") + return bf.props.GetString(BFPlanningStatusIcon, "\uF8EA") case BFStatusBrewing: - return bf.props.getString(BFBrewingStatusIcon, "\uF7DE") + return bf.props.GetString(BFBrewingStatusIcon, "\uF7DE") case BFStatusFermenting: - return bf.props.getString(BFFermentingStatusIcon, "\uF499") + return bf.props.GetString(BFFermentingStatusIcon, "\uF499") case BFStatusConditioning: - return bf.props.getString(BFConditioningStatusIcon, "\uE372") + return bf.props.GetString(BFConditioningStatusIcon, "\uE372") case BFStatusCompleted: - return bf.props.getString(BFCompletedStatusIcon, "\uF7A5") + return bf.props.GetString(BFCompletedStatusIcon, "\uF7A5") case BFStatusArchived: - return bf.props.getString(BFArchivedStatusIcon, "\uF187") + return bf.props.GetString(BFArchivedStatusIcon, "\uF187") default: return "" } @@ -227,17 +227,17 @@ func (bf *brewfather) getResult() (*Batch, error) { return nil } - userID := bf.props.getString(BFUserID, "") + userID := bf.props.GetString(BFUserID, "") if len(userID) == 0 { return nil, errors.New("missing Brewfather user id (user_id)") } - apiKey := bf.props.getString(BFAPIKey, "") + apiKey := bf.props.GetString(BFAPIKey, "") if len(apiKey) == 0 { return nil, errors.New("missing Brewfather api key (api_key)") } - batchID := bf.props.getString(BFBatchID, "") + batchID := bf.props.GetString(BFBatchID, "") if len(batchID) == 0 { return nil, errors.New("missing Brewfather batch id (batch_id)") } @@ -248,8 +248,8 @@ func (bf *brewfather) getResult() (*Batch, error) { batchURL := fmt.Sprintf("https://api.brewfather.app/v1/batches/%s", batchID) batchReadingsURL := fmt.Sprintf("https://api.brewfather.app/v1/batches/%s/readings", batchID) - httpTimeout := bf.props.getInt(HTTPTimeout, DefaultHTTPTimeout) - cacheTimeout := bf.props.getInt(BFCacheTimeout, 5) + httpTimeout := bf.props.GetInt(HTTPTimeout, DefaultHTTPTimeout) + cacheTimeout := bf.props.GetInt(BFCacheTimeout, 5) if cacheTimeout > 0 { if data, err := getFromCache(batchURL); err == nil { diff --git a/src/segment_command.go b/src/segment_command.go index c31760bf..271cca15 100644 --- a/src/segment_command.go +++ b/src/segment_command.go @@ -24,11 +24,11 @@ func (c *command) template() string { } func (c *command) enabled() bool { - shell := c.props.getString(ExecutableShell, "bash") + shell := c.props.GetString(ExecutableShell, "bash") if !c.env.HasCommand(shell) { return false } - command := c.props.getString(Command, "echo no command specified") + command := c.props.GetString(Command, "echo no command specified") if strings.Contains(command, "||") { commands := strings.Split(command, "||") for _, cmd := range commands { diff --git a/src/segment_executiontime.go b/src/segment_executiontime.go index 61a55f68..5d8e7d7b 100644 --- a/src/segment_executiontime.go +++ b/src/segment_executiontime.go @@ -48,13 +48,13 @@ const ( ) func (t *executiontime) enabled() bool { - alwaysEnabled := t.props.getBool(AlwaysEnabled, false) + alwaysEnabled := t.props.GetBool(AlwaysEnabled, false) executionTimeMs := t.env.ExecutionTime() - thresholdMs := t.props.getFloat64(ThresholdProperty, float64(500)) + thresholdMs := t.props.GetFloat64(ThresholdProperty, float64(500)) if !alwaysEnabled && executionTimeMs < thresholdMs { return false } - style := DurationStyle(t.props.getString(Style, string(Austin))) + style := DurationStyle(t.props.GetString(Style, string(Austin))) t.Ms = int64(executionTimeMs) t.FormattedMs = t.formatDuration(style) return t.FormattedMs != "" diff --git a/src/segment_exit.go b/src/segment_exit.go index b1234940..4a46d9d6 100644 --- a/src/segment_exit.go +++ b/src/segment_exit.go @@ -18,7 +18,7 @@ func (e *exit) template() string { func (e *exit) enabled() bool { e.Text = e.getMeaningFromExitCode(e.env.ErrorCode()) - if e.props.getBool(AlwaysEnabled, false) { + if e.props.GetBool(AlwaysEnabled, false) { return true } return e.env.ErrorCode() != 0 diff --git a/src/segment_git.go b/src/segment_git.go index 9fa0e01b..265f1ec5 100644 --- a/src/segment_git.go +++ b/src/segment_git.go @@ -114,7 +114,7 @@ func (g *git) enabled() bool { if !g.shouldDisplay() { return false } - displayStatus := g.props.getBool(FetchStatus, false) + displayStatus := g.props.GetBool(FetchStatus, false) if displayStatus { g.setGitStatus() g.setGitHEADContext() @@ -124,13 +124,13 @@ func (g *git) enabled() bool { g.Working = &GitStatus{} g.Staging = &GitStatus{} } - if g.Upstream != "" && g.props.getBool(FetchUpstreamIcon, false) { + if g.Upstream != "" && g.props.GetBool(FetchUpstreamIcon, false) { g.UpstreamIcon = g.getUpstreamIcon() } - if g.props.getBool(FetchStashCount, false) { + if g.props.GetBool(FetchStashCount, false) { g.StashCount = g.getStashContext() } - if g.props.getBool(FetchWorktreeCount, false) { + if g.props.GetBool(FetchWorktreeCount, false) { g.WorktreeCount = g.getWorktreeContext() } return true @@ -196,19 +196,19 @@ func (g *git) shouldDisplay() bool { func (g *git) setBranchStatus() { getBranchStatus := func() string { if g.Ahead > 0 && g.Behind > 0 { - return fmt.Sprintf(" %s%d %s%d", g.props.getString(BranchAheadIcon, "\u2191"), g.Ahead, g.props.getString(BranchBehindIcon, "\u2193"), g.Behind) + return fmt.Sprintf(" %s%d %s%d", g.props.GetString(BranchAheadIcon, "\u2191"), g.Ahead, g.props.GetString(BranchBehindIcon, "\u2193"), g.Behind) } if g.Ahead > 0 { - return fmt.Sprintf(" %s%d", g.props.getString(BranchAheadIcon, "\u2191"), g.Ahead) + return fmt.Sprintf(" %s%d", g.props.GetString(BranchAheadIcon, "\u2191"), g.Ahead) } if g.Behind > 0 { - return fmt.Sprintf(" %s%d", g.props.getString(BranchBehindIcon, "\u2193"), g.Behind) + return fmt.Sprintf(" %s%d", g.props.GetString(BranchBehindIcon, "\u2193"), g.Behind) } if g.Behind == 0 && g.Ahead == 0 && g.Upstream != "" { - return fmt.Sprintf(" %s", g.props.getString(BranchIdenticalIcon, "\u2261")) + return fmt.Sprintf(" %s", g.props.GetString(BranchIdenticalIcon, "\u2261")) } if g.Upstream == "" { - return fmt.Sprintf(" %s", g.props.getString(BranchGoneIcon, "\u2262")) + return fmt.Sprintf(" %s", g.props.GetString(BranchGoneIcon, "\u2262")) } return "" } @@ -219,18 +219,18 @@ func (g *git) getUpstreamIcon() string { upstream := regex.ReplaceAllString("/.*", g.Upstream, "") g.UpstreamURL = g.getOriginURL(upstream) if strings.Contains(g.UpstreamURL, "github") { - return g.props.getString(GithubIcon, "\uF408 ") + return g.props.GetString(GithubIcon, "\uF408 ") } if strings.Contains(g.UpstreamURL, "gitlab") { - return g.props.getString(GitlabIcon, "\uF296 ") + return g.props.GetString(GitlabIcon, "\uF296 ") } if strings.Contains(g.UpstreamURL, "bitbucket") { - return g.props.getString(BitbucketIcon, "\uF171 ") + return g.props.GetString(BitbucketIcon, "\uF171 ") } if strings.Contains(g.UpstreamURL, "dev.azure.com") || strings.Contains(g.UpstreamURL, "visualstudio.com") { - return g.props.getString(AzureDevOpsIcon, "\uFD03 ") + return g.props.GetString(AzureDevOpsIcon, "\uFD03 ") } - return g.props.getString(GitIcon, "\uE5FB ") + return g.props.GetString(GitIcon, "\uE5FB ") } func (g *git) setGitStatus() { @@ -305,7 +305,7 @@ func (g *git) getGitCommandOutput(args ...string) string { } func (g *git) setGitHEADContext() { - branchIcon := g.props.getString(BranchIcon, "\uE0A0") + branchIcon := g.props.GetString(BranchIcon, "\uE0A0") if g.Ref == DETACHED { g.setPrettyHEADName() } else { @@ -338,7 +338,7 @@ func (g *git) setGitHEADContext() { onto = g.formatHEAD(onto) step := g.FileContents(g.gitWorkingFolder, "rebase-merge/msgnum") total := g.FileContents(g.gitWorkingFolder, "rebase-merge/end") - icon := g.props.getString(RebaseIcon, "\uE728 ") + icon := g.props.GetString(RebaseIcon, "\uE728 ") g.HEAD = fmt.Sprintf("%s%s onto %s%s (%s/%s) at %s", icon, origin, branchIcon, onto, step, total, g.HEAD) return } @@ -346,14 +346,14 @@ func (g *git) setGitHEADContext() { origin := getPrettyNameOrigin("rebase-apply/head-name") step := g.FileContents(g.gitWorkingFolder, "rebase-apply/next") total := g.FileContents(g.gitWorkingFolder, "rebase-apply/last") - icon := g.props.getString(RebaseIcon, "\uE728 ") + icon := g.props.GetString(RebaseIcon, "\uE728 ") g.HEAD = fmt.Sprintf("%s%s (%s/%s) at %s", icon, origin, step, total, g.HEAD) return } // merge - commitIcon := g.props.getString(CommitIcon, "\uF417") + commitIcon := g.props.GetString(CommitIcon, "\uF417") if g.hasGitFile("MERGE_MSG") { - icon := g.props.getString(MergeIcon, "\uE727 ") + icon := g.props.GetString(MergeIcon, "\uE727 ") mergeContext := g.FileContents(g.gitWorkingFolder, "MERGE_MSG") matches := regex.FindNamedRegexMatch(`Merge (remote-tracking )?(?Pbranch|commit|tag) '(?P.*)'`, mergeContext) // head := g.getGitRefFileSymbolicName("ORIG_HEAD") @@ -361,7 +361,7 @@ func (g *git) setGitHEADContext() { var headIcon, theirs string switch matches["type"] { case "tag": - headIcon = g.props.getString(TagIcon, "\uF412") + headIcon = g.props.GetString(TagIcon, "\uF412") theirs = matches["theirs"] case "commit": headIcon = commitIcon @@ -381,13 +381,13 @@ func (g *git) setGitHEADContext() { // the todo file. if g.hasGitFile("CHERRY_PICK_HEAD") { sha := g.FileContents(g.gitWorkingFolder, "CHERRY_PICK_HEAD") - cherry := g.props.getString(CherryPickIcon, "\uE29B ") + cherry := g.props.GetString(CherryPickIcon, "\uE29B ") g.HEAD = fmt.Sprintf("%s%s%s onto %s", cherry, commitIcon, g.formatSHA(sha), formatDetached()) return } if g.hasGitFile("REVERT_HEAD") { sha := g.FileContents(g.gitWorkingFolder, "REVERT_HEAD") - revert := g.props.getString(RevertIcon, "\uF0E2 ") + revert := g.props.GetString(RevertIcon, "\uF0E2 ") g.HEAD = fmt.Sprintf("%s%s%s onto %s", revert, commitIcon, g.formatSHA(sha), formatDetached()) return } @@ -399,11 +399,11 @@ func (g *git) setGitHEADContext() { sha := matches["sha"] switch action { case "p", "pick": - cherry := g.props.getString(CherryPickIcon, "\uE29B ") + cherry := g.props.GetString(CherryPickIcon, "\uE29B ") g.HEAD = fmt.Sprintf("%s%s%s onto %s", cherry, commitIcon, g.formatSHA(sha), formatDetached()) return case "revert": - revert := g.props.getString(RevertIcon, "\uF0E2 ") + revert := g.props.GetString(RevertIcon, "\uF0E2 ") g.HEAD = fmt.Sprintf("%s%s%s onto %s", revert, commitIcon, g.formatSHA(sha), formatDetached()) return } @@ -413,11 +413,11 @@ func (g *git) setGitHEADContext() { } func (g *git) formatHEAD(head string) string { - maxLength := g.props.getInt(BranchMaxLength, 0) + maxLength := g.props.GetInt(BranchMaxLength, 0) if maxLength == 0 || len(head) < maxLength { return head } - symbol := g.props.getString(TruncateSymbol, "") + symbol := g.props.GetString(TruncateSymbol, "") return head[0:maxLength] + symbol } @@ -443,7 +443,7 @@ func (g *git) setPrettyHEADName() { HEADRef := g.FileContents(g.gitWorkingFolder, "HEAD") if strings.HasPrefix(HEADRef, BRANCHPREFIX) { branchName := strings.TrimPrefix(HEADRef, BRANCHPREFIX) - g.HEAD = fmt.Sprintf("%s%s", g.props.getString(BranchIcon, "\uE0A0"), g.formatHEAD(branchName)) + g.HEAD = fmt.Sprintf("%s%s", g.props.GetString(BranchIcon, "\uE0A0"), g.formatHEAD(branchName)) return } // no branch, points to commit @@ -454,15 +454,15 @@ func (g *git) setPrettyHEADName() { // check for tag tagName := g.getGitCommandOutput("describe", "--tags", "--exact-match") if len(tagName) > 0 { - g.HEAD = fmt.Sprintf("%s%s", g.props.getString(TagIcon, "\uF412"), tagName) + g.HEAD = fmt.Sprintf("%s%s", g.props.GetString(TagIcon, "\uF412"), tagName) return } // fallback to commit if len(g.Hash) == 0 { - g.HEAD = g.props.getString(NoCommitsIcon, "\uF594 ") + g.HEAD = g.props.GetString(NoCommitsIcon, "\uF594 ") return } - g.HEAD = fmt.Sprintf("%s%s", g.props.getString(CommitIcon, "\uF417"), g.Hash) + g.HEAD = fmt.Sprintf("%s%s", g.props.GetString(CommitIcon, "\uF417"), g.Hash) } func (g *git) getStashContext() int { diff --git a/src/segment_golang.go b/src/segment_golang.go index 26c9f236..28d5b872 100644 --- a/src/segment_golang.go +++ b/src/segment_golang.go @@ -39,7 +39,7 @@ func (g *golang) init(props Properties, env environment.Environment) { } func (g *golang) getVersion() (string, error) { - if !g.props.getBool(ParseModFile, false) { + if !g.props.GetBool(ParseModFile, false) { return "", nil } gomod, err := g.language.env.HasParentFilePath("go.mod") diff --git a/src/segment_ipify.go b/src/segment_ipify.go index c0dfb35a..fb336eb1 100644 --- a/src/segment_ipify.go +++ b/src/segment_ipify.go @@ -27,9 +27,9 @@ func (i *ipify) enabled() bool { } func (i *ipify) getResult() (string, error) { - cacheTimeout := i.props.getInt(CacheTimeout, DefaultCacheTimeout) + cacheTimeout := i.props.GetInt(CacheTimeout, DefaultCacheTimeout) - url := i.props.getString(IpifyURL, "https://api.ipify.org") + url := i.props.GetString(IpifyURL, "https://api.ipify.org") if cacheTimeout > 0 { // check if data stored in cache @@ -40,7 +40,7 @@ func (i *ipify) getResult() (string, error) { } } - httpTimeout := i.props.getInt(HTTPTimeout, DefaultHTTPTimeout) + httpTimeout := i.props.GetInt(HTTPTimeout, DefaultHTTPTimeout) body, err := i.env.HTTPRequest(url, httpTimeout) if err != nil { diff --git a/src/segment_kubectl.go b/src/segment_kubectl.go index c04a16c7..a7cb56b0 100644 --- a/src/segment_kubectl.go +++ b/src/segment_kubectl.go @@ -43,7 +43,7 @@ func (k *kubectl) init(props Properties, env environment.Environment) { } func (k *kubectl) enabled() bool { - parseKubeConfig := k.props.getBool(ParseKubeConfig, false) + parseKubeConfig := k.props.GetBool(ParseKubeConfig, false) if parseKubeConfig { return k.doParseKubeConfig() } @@ -92,7 +92,7 @@ func (k *kubectl) doParseKubeConfig() bool { return true } - displayError := k.props.getBool(DisplayError, false) + displayError := k.props.GetBool(DisplayError, false) if !displayError { return false } @@ -106,7 +106,7 @@ func (k *kubectl) doCallKubectl() bool { return false } result, err := k.env.RunCommand(cmd, "config", "view", "--output", "yaml", "--minify") - displayError := k.props.getBool(DisplayError, false) + displayError := k.props.GetBool(DisplayError, false) if err != nil && displayError { k.setError("KUBECTL ERR") return true diff --git a/src/segment_language.go b/src/segment_language.go index af41f83e..3bc45493 100644 --- a/src/segment_language.go +++ b/src/segment_language.go @@ -91,18 +91,18 @@ const ( func (l *language) enabled() bool { // override default extensions if needed - l.extensions = l.props.getStringArray(LanguageExtensions, l.extensions) + l.extensions = l.props.GetStringArray(LanguageExtensions, l.extensions) inHomeDir := func() bool { return l.env.Pwd() == l.env.Home() } var enabled bool - homeEnabled := l.props.getBool(HomeEnabled, l.homeEnabled) + homeEnabled := l.props.GetBool(HomeEnabled, l.homeEnabled) if inHomeDir() && !homeEnabled { enabled = false } else { // set default mode when not set if len(l.displayMode) == 0 { - l.displayMode = l.props.getString(DisplayMode, DisplayModeFiles) + l.displayMode = l.props.GetString(DisplayMode, DisplayModeFiles) } l.loadLanguageContext() switch l.displayMode { @@ -118,7 +118,7 @@ func (l *language) enabled() bool { enabled = l.hasLanguageFiles() || l.inLanguageContext() } } - if !enabled || !l.props.getBool(FetchVersion, true) { + if !enabled || !l.props.GetBool(FetchVersion, true) { return enabled } err := l.setVersion() @@ -173,7 +173,7 @@ func (l *language) setVersion() error { l.buildVersionURL() return nil } - return errors.New(l.props.getString(MissingCommandText, "")) + return errors.New(l.props.GetString(MissingCommandText, "")) } func (l *language) loadLanguageContext() { @@ -191,7 +191,7 @@ func (l *language) inLanguageContext() bool { } func (l *language) buildVersionURL() { - versionURLTemplate := l.props.getString(VersionURLTemplate, l.versionURLTemplate) + versionURLTemplate := l.props.GetString(VersionURLTemplate, l.versionURLTemplate) if len(versionURLTemplate) == 0 { return } diff --git a/src/segment_nightscout.go b/src/segment_nightscout.go index 457509ce..a31b1a73 100644 --- a/src/segment_nightscout.go +++ b/src/segment_nightscout.go @@ -64,19 +64,19 @@ func (ns *nightscout) enabled() bool { func (ns *nightscout) getTrendIcon() string { switch ns.Direction { case "DoubleUp": - return ns.props.getString(DoubleUpIcon, "↑↑") + return ns.props.GetString(DoubleUpIcon, "↑↑") case "SingleUp": - return ns.props.getString(SingleUpIcon, "↑") + return ns.props.GetString(SingleUpIcon, "↑") case "FortyFiveUp": - return ns.props.getString(FortyFiveUpIcon, "↗") + return ns.props.GetString(FortyFiveUpIcon, "↗") case "Flat": - return ns.props.getString(FlatIcon, "→") + return ns.props.GetString(FlatIcon, "→") case "FortyFiveDown": - return ns.props.getString(FortyFiveDownIcon, "↘") + return ns.props.GetString(FortyFiveDownIcon, "↘") case "SingleDown": - return ns.props.getString(SingleDownIcon, "↓") + return ns.props.GetString(SingleDownIcon, "↓") case "DoubleDown": - return ns.props.getString(DoubleDownIcon, "↓↓") + return ns.props.GetString(DoubleDownIcon, "↓↓") default: return "" } @@ -105,10 +105,10 @@ func (ns *nightscout) getResult() (*NightscoutData, error) { return nil, errors.New("no data in cache") } - url := ns.props.getString(URL, "") - httpTimeout := ns.props.getInt(HTTPTimeout, DefaultHTTPTimeout) + url := ns.props.GetString(URL, "") + httpTimeout := ns.props.GetInt(HTTPTimeout, DefaultHTTPTimeout) // natural and understood NS timeout is 5, anything else is unusual - cacheTimeout := ns.props.getInt(NSCacheTimeout, 5) + cacheTimeout := ns.props.GetInt(NSCacheTimeout, 5) if cacheTimeout > 0 { if data, err := getCacheValue(url); err == nil { diff --git a/src/segment_node.go b/src/segment_node.go index 46e6710c..fceb33f8 100644 --- a/src/segment_node.go +++ b/src/segment_node.go @@ -48,15 +48,15 @@ func (n *node) enabled() bool { } func (n *node) loadContext() { - if !n.language.props.getBool(FetchPackageManager, false) { + if !n.language.props.GetBool(FetchPackageManager, false) { return } if n.language.env.HasFiles("yarn.lock") { - n.PackageManagerIcon = n.language.props.getString(YarnIcon, " \uF61A") + n.PackageManagerIcon = n.language.props.GetString(YarnIcon, " \uF61A") return } if n.language.env.HasFiles("package-lock.json") || n.language.env.HasFiles("package.json") { - n.PackageManagerIcon = n.language.props.getString(NPMIcon, " \uE71E") + n.PackageManagerIcon = n.language.props.GetString(NPMIcon, " \uE71E") } } diff --git a/src/segment_os.go b/src/segment_os.go index 39902c0d..cb5a86ba 100644 --- a/src/segment_os.go +++ b/src/segment_os.go @@ -66,12 +66,12 @@ func (oi *osInfo) enabled() bool { goos := oi.env.GOOS() switch goos { case environment.WindowsPlatform: - oi.Icon = oi.props.getString(Windows, "\uE62A") + oi.Icon = oi.props.GetString(Windows, "\uE62A") case environment.DarwinPlatform: - oi.Icon = oi.props.getString(MacOS, "\uF179") + oi.Icon = oi.props.GetString(MacOS, "\uF179") case environment.LinuxPlatform: platform := oi.env.Platform() - displayDistroName := oi.props.getBool(DisplayDistroName, false) + displayDistroName := oi.props.GetBool(DisplayDistroName, false) if displayDistroName { oi.Icon = platform break @@ -86,45 +86,45 @@ func (oi *osInfo) enabled() bool { func (oi *osInfo) getDistroIcon(distro string) string { switch distro { case "alpine": - return oi.props.getString(Alpine, "\uF300") + return oi.props.GetString(Alpine, "\uF300") case "aosc": - return oi.props.getString(Aosc, "\uF301") + return oi.props.GetString(Aosc, "\uF301") case "arch": - return oi.props.getString(Arch, "\uF303") + return oi.props.GetString(Arch, "\uF303") case "centos": - return oi.props.getString(Centos, "\uF304") + return oi.props.GetString(Centos, "\uF304") case "coreos": - return oi.props.getString(Coreos, "\uF305") + return oi.props.GetString(Coreos, "\uF305") case "debian": - return oi.props.getString(Debian, "\uF306") + return oi.props.GetString(Debian, "\uF306") case "devuan": - return oi.props.getString(Devuan, "\uF307") + return oi.props.GetString(Devuan, "\uF307") case "raspbian": - return oi.props.getString(Raspbian, "\uF315") + return oi.props.GetString(Raspbian, "\uF315") case "elementary": - return oi.props.getString(Elementary, "\uF309") + return oi.props.GetString(Elementary, "\uF309") case "fedora": - return oi.props.getString(Fedora, "\uF30a") + return oi.props.GetString(Fedora, "\uF30a") case "gentoo": - return oi.props.getString(Gentoo, "\uF30d") + return oi.props.GetString(Gentoo, "\uF30d") case "mageia": - return oi.props.getString(Mageia, "\uF310") + return oi.props.GetString(Mageia, "\uF310") case "manjaro": - return oi.props.getString(Manjaro, "\uF312") + return oi.props.GetString(Manjaro, "\uF312") case "mint": - return oi.props.getString(Mint, "\uF30e") + return oi.props.GetString(Mint, "\uF30e") case "nixos": - return oi.props.getString(Nixos, "\uF313") + return oi.props.GetString(Nixos, "\uF313") case "opensuse": - return oi.props.getString(Opensuse, "\uF314") + return oi.props.GetString(Opensuse, "\uF314") case "sabayon": - return oi.props.getString(Sabayon, "\uF317") + return oi.props.GetString(Sabayon, "\uF317") case "slackware": - return oi.props.getString(Slackware, "\uF319") + return oi.props.GetString(Slackware, "\uF319") case "ubuntu": - return oi.props.getString(Ubuntu, "\uF31b") + return oi.props.GetString(Ubuntu, "\uF31b") } - return oi.props.getString(Linux, "\uF17C") + return oi.props.GetString(Linux, "\uF17C") } func (oi *osInfo) init(props Properties, env environment.Environment) { diff --git a/src/segment_owm.go b/src/segment_owm.go index 2f0bb032..da11404c 100644 --- a/src/segment_owm.go +++ b/src/segment_owm.go @@ -57,7 +57,7 @@ func (d *owm) template() string { } func (d *owm) getResult() (*owmDataResponse, error) { - cacheTimeout := d.props.getInt(CacheTimeout, DefaultCacheTimeout) + cacheTimeout := d.props.GetInt(CacheTimeout, DefaultCacheTimeout) response := new(owmDataResponse) if cacheTimeout > 0 { // check if data stored in cache @@ -73,10 +73,10 @@ func (d *owm) getResult() (*owmDataResponse, error) { } } - apikey := d.props.getString(APIKey, ".") - location := d.props.getString(Location, "De Bilt,NL") - units := d.props.getString(Units, "standard") - httpTimeout := d.props.getInt(HTTPTimeout, DefaultHTTPTimeout) + apikey := d.props.GetString(APIKey, ".") + location := d.props.GetString(Location, "De Bilt,NL") + units := d.props.GetString(Units, "standard") + httpTimeout := d.props.GetInt(HTTPTimeout, DefaultHTTPTimeout) d.URL = fmt.Sprintf("http://api.openweathermap.org/data/2.5/weather?q=%s&units=%s&appid=%s", location, units, apikey) body, err := d.env.HTTPRequest(d.URL, httpTimeout) @@ -97,7 +97,7 @@ func (d *owm) getResult() (*owmDataResponse, error) { } func (d *owm) setStatus() error { - units := d.props.getString(Units, "standard") + units := d.props.GetString(Units, "standard") q, err := d.getResult() if err != nil { return err diff --git a/src/segment_path.go b/src/segment_path.go index fc02c3f0..cd1757a8 100644 --- a/src/segment_path.go +++ b/src/segment_path.go @@ -61,7 +61,7 @@ func (pt *path) template() string { func (pt *path) enabled() bool { pt.pwd = pt.env.Pwd() - switch style := pt.props.getString(Style, Agnoster); style { + switch style := pt.props.GetString(Style, Agnoster); style { case Agnoster: pt.Path = pt.getAgnosterPath() case AgnosterFull: @@ -111,7 +111,7 @@ func (pt *path) getMixedPath() string { var buffer strings.Builder pwd := pt.getPwd() splitted := strings.Split(pwd, pt.env.PathSeperator()) - threshold := int(pt.props.getFloat64(MixedThreshold, 4)) + threshold := int(pt.props.GetFloat64(MixedThreshold, 4)) for i, part := range splitted { if part == "" { continue @@ -119,9 +119,9 @@ func (pt *path) getMixedPath() string { folder := part if len(part) > threshold && i != 0 && i != len(splitted)-1 { - folder = pt.props.getString(FolderIcon, "..") + folder = pt.props.GetString(FolderIcon, "..") } - separator := pt.props.getString(FolderSeparatorIcon, pt.env.PathSeperator()) + separator := pt.props.GetString(FolderSeparatorIcon, pt.env.PathSeperator()) if i == 0 { separator = "" } @@ -136,8 +136,8 @@ func (pt *path) getAgnosterPath() string { pwd := pt.getPwd() buffer.WriteString(pt.rootLocation()) pathDepth := pt.pathDepth(pwd) - folderIcon := pt.props.getString(FolderIcon, "..") - separator := pt.props.getString(FolderSeparatorIcon, pt.env.PathSeperator()) + folderIcon := pt.props.GetString(FolderIcon, "..") + separator := pt.props.GetString(FolderSeparatorIcon, pt.env.PathSeperator()) for i := 1; i < pathDepth; i++ { buffer.WriteString(fmt.Sprintf("%s%s", separator, folderIcon)) } @@ -152,8 +152,8 @@ func (pt *path) getAgnosterLeftPath() string { separator := pt.env.PathSeperator() pwd = strings.Trim(pwd, separator) splitted := strings.Split(pwd, separator) - folderIcon := pt.props.getString(FolderIcon, "..") - separator = pt.props.getString(FolderSeparatorIcon, separator) + folderIcon := pt.props.GetString(FolderIcon, "..") + separator = pt.props.GetString(FolderSeparatorIcon, separator) switch len(splitted) { case 0: return "" @@ -174,7 +174,7 @@ func (pt *path) getLetterPath() string { var buffer strings.Builder pwd := pt.getPwd() splitted := strings.Split(pwd, pt.env.PathSeperator()) - separator := pt.props.getString(FolderSeparatorIcon, pt.env.PathSeperator()) + separator := pt.props.GetString(FolderSeparatorIcon, pt.env.PathSeperator()) for i := 0; i < len(splitted)-1; i++ { folder := splitted[i] if len(folder) == 0 { @@ -213,7 +213,7 @@ func (pt *path) getAgnosterFullPath() string { func (pt *path) getAgnosterShortPath() string { pwd := pt.getPwd() pathDepth := pt.pathDepth(pwd) - maxDepth := pt.props.getInt(MaxDepth, 1) + maxDepth := pt.props.GetInt(MaxDepth, 1) if maxDepth < 1 { maxDepth = 1 } @@ -221,8 +221,8 @@ func (pt *path) getAgnosterShortPath() string { return pt.getAgnosterFullPath() } pathSeparator := pt.env.PathSeperator() - folderSeparator := pt.props.getString(FolderSeparatorIcon, pathSeparator) - folderIcon := pt.props.getString(FolderIcon, "..") + folderSeparator := pt.props.GetString(FolderSeparatorIcon, pathSeparator) + folderIcon := pt.props.GetString(FolderIcon, "..") root := pt.rootLocation() splitted := strings.Split(pwd, pathSeparator) fullPathDepth := len(splitted) @@ -274,15 +274,15 @@ func (pt *path) replaceMappedLocations(pwd string) string { } mappedLocations := map[string]string{} - if pt.props.getBool(MappedLocationsEnabled, true) { - mappedLocations["HKCU:"] = pt.props.getString(WindowsRegistryIcon, "\uF013") - mappedLocations["HKLM:"] = pt.props.getString(WindowsRegistryIcon, "\uF013") - mappedLocations[pt.normalize(pt.env.Home())] = pt.props.getString(HomeIcon, "~") + if pt.props.GetBool(MappedLocationsEnabled, true) { + mappedLocations["HKCU:"] = pt.props.GetString(WindowsRegistryIcon, "\uF013") + mappedLocations["HKLM:"] = pt.props.GetString(WindowsRegistryIcon, "\uF013") + mappedLocations[pt.normalize(pt.env.Home())] = pt.props.GetString(HomeIcon, "~") } // merge custom locations with mapped locations // mapped locations can override predefined locations - keyValues := pt.props.getKeyValueMap(MappedLocations, make(map[string]string)) + keyValues := pt.props.GetKeyValueMap(MappedLocations, make(map[string]string)) for key, val := range keyValues { mappedLocations[pt.normalize(key)] = val } @@ -313,7 +313,7 @@ func (pt *path) replaceFolderSeparators(pwd string) string { if pwd == defaultSeparator { return pwd } - folderSeparator := pt.props.getString(FolderSeparatorIcon, defaultSeparator) + folderSeparator := pt.props.GetString(FolderSeparatorIcon, defaultSeparator) if folderSeparator == defaultSeparator { return pwd } diff --git a/src/segment_path_test.go b/src/segment_path_test.go index 3d22ba06..64ef7243 100644 --- a/src/segment_path_test.go +++ b/src/segment_path_test.go @@ -649,7 +649,7 @@ func TestParseMappedLocations(t *testing.T) { var segment Segment err = config.BindStruct("", &segment) assert.NoError(t, err) - mappedLocations := segment.Properties.getKeyValueMap(MappedLocations, make(map[string]string)) + mappedLocations := segment.Properties.GetKeyValueMap(MappedLocations, make(map[string]string)) assert.Equal(t, "two", mappedLocations["folder2"]) } } diff --git a/src/segment_plastic.go b/src/segment_plastic.go index 8deaf602..5df4b799 100644 --- a/src/segment_plastic.go +++ b/src/segment_plastic.go @@ -60,7 +60,7 @@ func (p *plastic) enabled() bool { return false } p.plasticWorkspaceFolder = wkdir.ParentFolder - displayStatus := p.props.getBool(FetchStatus, false) + displayStatus := p.props.GetBool(FetchStatus, false) p.setSelector() if displayStatus { p.setPlasticStatus() @@ -135,13 +135,13 @@ func (p *plastic) setSelector() { // changeset ref = p.parseChangesetSelector(selector) if len(ref) > 0 { - p.Selector = fmt.Sprintf("%s%s", p.props.getString(CommitIcon, "\uF417"), ref) + p.Selector = fmt.Sprintf("%s%s", p.props.GetString(CommitIcon, "\uF417"), ref) return } // fallback to label ref = p.parseLabelSelector(selector) if len(ref) > 0 { - p.Selector = fmt.Sprintf("%s%s", p.props.getString(TagIcon, "\uF412"), ref) + p.Selector = fmt.Sprintf("%s%s", p.props.GetString(TagIcon, "\uF412"), ref) return } // fallback to branch/smartbranch @@ -149,7 +149,7 @@ func (p *plastic) setSelector() { if len(ref) > 0 { ref = p.truncateBranch(ref) } - p.Selector = fmt.Sprintf("%s%s", p.props.getString(BranchIcon, "\uE0A0"), ref) + p.Selector = fmt.Sprintf("%s%s", p.props.GetString(BranchIcon, "\uE0A0"), ref) } func (p *plastic) parseChangesetSelector(selector string) string { diff --git a/src/segment_python.go b/src/segment_python.go index 38fc2647..c2ea0d09 100644 --- a/src/segment_python.go +++ b/src/segment_python.go @@ -37,8 +37,8 @@ func (p *python) init(props Properties, env environment.Environment) { }, }, versionURLTemplate: "[%s](https://www.python.org/downloads/release/python-%s%s%s/)", - displayMode: props.getString(DisplayMode, DisplayModeEnvironment), - homeEnabled: props.getBool(HomeEnabled, true), + displayMode: props.GetString(DisplayMode, DisplayModeEnvironment), + homeEnabled: props.GetBool(HomeEnabled, true), } } @@ -47,7 +47,7 @@ func (p *python) enabled() bool { } func (p *python) loadContext() { - if !p.language.props.getBool(FetchVirtualEnv, true) { + if !p.language.props.GetBool(FetchVirtualEnv, true) { return } venvVars := []string{ @@ -75,7 +75,7 @@ func (p *python) canUseVenvName(name string) bool { if name == "" || name == "." { return false } - if p.language.props.getBool(DisplayDefault, true) { + if p.language.props.GetBool(DisplayDefault, true) { return true } invalidNames := [2]string{"system", "base"} diff --git a/src/segment_shell.go b/src/segment_shell.go index e1d4f979..30b03c15 100644 --- a/src/segment_shell.go +++ b/src/segment_shell.go @@ -22,7 +22,7 @@ func (s *shell) template() string { } func (s *shell) enabled() bool { - mappedNames := s.props.getKeyValueMap(MappedShellNames, make(map[string]string)) + mappedNames := s.props.GetKeyValueMap(MappedShellNames, make(map[string]string)) s.Name = s.env.Shell() for key, val := range mappedNames { if strings.EqualFold(s.Name, key) { diff --git a/src/segment_spotify.go b/src/segment_spotify.go index 3c1600f0..720d4e60 100644 --- a/src/segment_spotify.go +++ b/src/segment_spotify.go @@ -37,11 +37,11 @@ func (s *spotify) resolveIcon() { switch s.Status { case stopped: // in this case, no artist or track info - s.Icon = s.props.getString(StoppedIcon, "\uF04D ") + s.Icon = s.props.GetString(StoppedIcon, "\uF04D ") case paused: - s.Icon = s.props.getString(PausedIcon, "\uF8E3 ") + s.Icon = s.props.GetString(PausedIcon, "\uF8E3 ") case playing: - s.Icon = s.props.getString(PlayingIcon, "\uE602 ") + s.Icon = s.props.GetString(PlayingIcon, "\uE602 ") } } diff --git a/src/segment_strava.go b/src/segment_strava.go index dc149521..f0111c53 100644 --- a/src/segment_strava.go +++ b/src/segment_strava.go @@ -108,19 +108,19 @@ func (s *strava) getActivityIcon() string { case "VirtualRide": fallthrough case "Ride": - return s.props.getString(RideIcon, "\uf5a2") + return s.props.GetString(RideIcon, "\uf5a2") case "Run": - return s.props.getString(RunIcon, "\ufc0c") + return s.props.GetString(RunIcon, "\ufc0c") case "NordicSki": case "AlpineSki": case "BackcountrySki": - return s.props.getString(SkiingIcon, "\ue213") + return s.props.GetString(SkiingIcon, "\ue213") case "WorkOut": - return s.props.getString(WorkOutIcon, "\ue213") + return s.props.GetString(WorkOutIcon, "\ue213") default: - return s.props.getString(UnknownActivityIcon, "\ue213") + return s.props.GetString(UnknownActivityIcon, "\ue213") } - return s.props.getString(UnknownActivityIcon, "\ue213") + return s.props.GetString(UnknownActivityIcon, "\ue213") } func (s *strava) getAccessToken() (string, error) { @@ -135,7 +135,7 @@ func (s *strava) getAccessToken() (string, error) { } } // use initial refresh token from property - refreshToken := s.props.getString(RefreshToken, "") + refreshToken := s.props.GetString(RefreshToken, "") if len(refreshToken) == 0 { return "", &AuthError{ message: InvalidRefreshToken, @@ -147,7 +147,7 @@ func (s *strava) getAccessToken() (string, error) { } func (s *strava) refreshToken(refreshToken string) (string, error) { - httpTimeout := s.props.getInt(HTTPTimeout, DefaultHTTPTimeout) + httpTimeout := s.props.GetInt(HTTPTimeout, DefaultHTTPTimeout) url := fmt.Sprintf("https://ohmyposh.dev/api/refresh?segment=strava&token=%s", refreshToken) body, err := s.env.HTTPRequest(url, httpTimeout) if err != nil { @@ -194,10 +194,10 @@ func (s *strava) getResult() (*StravaData, error) { // We only want the last activity url := "https://www.strava.com/api/v3/athlete/activities?page=1&per_page=1" - httpTimeout := s.props.getInt(HTTPTimeout, DefaultHTTPTimeout) + httpTimeout := s.props.GetInt(HTTPTimeout, DefaultHTTPTimeout) // No need to check more the every 30 min - cacheTimeout := s.props.getInt(CacheTimeout, 30) + cacheTimeout := s.props.GetInt(CacheTimeout, 30) if cacheTimeout > 0 { if data, err := getCacheValue(url); err == nil { return data, nil diff --git a/src/segment_sysinfo.go b/src/segment_sysinfo.go index cb169e7e..af9284e5 100644 --- a/src/segment_sysinfo.go +++ b/src/segment_sysinfo.go @@ -47,7 +47,7 @@ func (s *sysinfo) enabled() bool { func (s *sysinfo) init(props Properties, env environment.Environment) { s.props = props s.env = env - s.Precision = s.props.getInt(Precision, 2) + s.Precision = s.props.GetInt(Precision, 2) // mem memStat, err := mem.VirtualMemory() if err == nil { diff --git a/src/segment_time.go b/src/segment_time.go index 329ce89f..a2308261 100644 --- a/src/segment_time.go +++ b/src/segment_time.go @@ -18,7 +18,7 @@ const ( ) func (t *tempus) template() string { - return "{{ .CurrentDate | date \"" + t.props.getString(TimeFormat, "15:04:05") + "\" }}" + return "{{ .CurrentDate | date \"" + t.props.GetString(TimeFormat, "15:04:05") + "\" }}" } func (t *tempus) enabled() bool { diff --git a/src/segment_wakatime.go b/src/segment_wakatime.go index 7e552380..55dbe4b8 100644 --- a/src/segment_wakatime.go +++ b/src/segment_wakatime.go @@ -33,8 +33,8 @@ func (w *wakatime) enabled() bool { } func (w *wakatime) setAPIData() error { - url := w.props.getString(URL, "") - cacheTimeout := w.props.getInt(CacheTimeout, DefaultCacheTimeout) + url := w.props.GetString(URL, "") + cacheTimeout := w.props.GetInt(CacheTimeout, DefaultCacheTimeout) if cacheTimeout > 0 { // check if data stored in cache if val, found := w.env.Cache().Get(url); found { @@ -46,7 +46,7 @@ func (w *wakatime) setAPIData() error { } } - httpTimeout := w.props.getInt(HTTPTimeout, DefaultHTTPTimeout) + httpTimeout := w.props.GetInt(HTTPTimeout, DefaultHTTPTimeout) body, err := w.env.HTTPRequest(url, httpTimeout) if err != nil { diff --git a/src/segment_wifi.go b/src/segment_wifi.go index 8207a43c..913957e7 100644 --- a/src/segment_wifi.go +++ b/src/segment_wifi.go @@ -25,7 +25,7 @@ func (w *wifi) enabled() bool { return false } wifiInfo, err := w.env.WifiNetwork() - displayError := w.props.getBool(DisplayError, false) + displayError := w.props.GetBool(DisplayError, false) if err != nil && displayError { w.Error = err.Error() return true diff --git a/src/segment_winreg.go b/src/segment_winreg.go index 3c4cd735..87a5ffaf 100644 --- a/src/segment_winreg.go +++ b/src/segment_winreg.go @@ -34,8 +34,8 @@ func (wr *winreg) enabled() bool { return false } - registryPath := wr.props.getString(RegistryPath, "") - fallback := wr.props.getString(Fallback, "") + registryPath := wr.props.GetString(RegistryPath, "") + fallback := wr.props.GetString(Fallback, "") var regValue *environment.WindowsRegistryValue regValue, _ = wr.env.WindowsRegistryKeyValue(registryPath) diff --git a/src/segment_ytm.go b/src/segment_ytm.go index ea592656..e0c1521a 100644 --- a/src/segment_ytm.go +++ b/src/segment_ytm.go @@ -65,8 +65,8 @@ type track struct { func (y *ytm) setStatus() error { // https://github.com/ytmdesktop/ytmdesktop/wiki/Remote-Control-API - url := y.props.getString(APIURL, "http://127.0.0.1:9863") - httpTimeout := y.props.getInt(APIURL, DefaultHTTPTimeout) + url := y.props.GetString(APIURL, "http://127.0.0.1:9863") + httpTimeout := y.props.GetInt(APIURL, DefaultHTTPTimeout) body, err := y.env.HTTPRequest(url+"/query", httpTimeout) if err != nil { return err @@ -77,13 +77,13 @@ func (y *ytm) setStatus() error { return err } y.Status = playing - y.Icon = y.props.getString(PlayingIcon, "\uE602 ") + y.Icon = y.props.GetString(PlayingIcon, "\uE602 ") if !q.player.HasSong { y.Status = stopped - y.Icon = y.props.getString(StoppedIcon, "\uF04D ") + y.Icon = y.props.GetString(StoppedIcon, "\uF04D ") } else if q.player.IsPaused { y.Status = paused - y.Icon = y.props.getString(PausedIcon, "\uF8E3 ") + y.Icon = y.props.GetString(PausedIcon, "\uF8E3 ") } y.Artist = q.track.Author y.Track = q.track.Title