refactor: move color logic to module

This commit is contained in:
Jan De Dobbeleer 2022-01-26 13:09:21 +01:00 committed by Jan De Dobbeleer
parent 906ece2af9
commit c86b7b62bc
50 changed files with 452 additions and 413 deletions

View file

@ -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)
}

View file

@ -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<all>(?:\\[(?P<name>.+)\\])(?:\\((?P<url>.*)\\)))", 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<context><(?P<format>[buis])>(?P<text>[^<]+)</[buis]>)", 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
}

View file

@ -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 <s>is</s> 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)
}

View file

@ -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}

View file

@ -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)
}
}
}

View file

@ -1,4 +1,4 @@
package main
package color
import (
"fmt"

View file

@ -1,4 +1,4 @@
package main
package color
import (
"testing"

View file

@ -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()
}

View file

@ -1,4 +1,4 @@
package main
package color
import (
"fmt"
@ -10,23 +10,24 @@ const (
colorRegex = `<(?P<foreground>[^,>]+)?,?(?P<background>[^>]+)?>(?P<content>[^<]*)<\/>`
)
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()
}

View file

@ -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)
}
}

View file

@ -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 {

View file

@ -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 {

View file

@ -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,

View file

@ -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 ""
}

View file

@ -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)
}
}
}

View file

@ -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
}

View file

@ -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,

View file

@ -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{

View file

@ -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<color>#[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

View file

@ -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)
}

View file

@ -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
}

View file

@ -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

View file

@ -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

View file

@ -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
}

View file

@ -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 {

View file

@ -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 {

View file

@ -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 != ""

View file

@ -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

View file

@ -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 )?(?P<type>branch|commit|tag) '(?P<theirs>.*)'`, 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 {

View file

@ -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")

View file

@ -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 {

View file

@ -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

View file

@ -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
}

View file

@ -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 {

View file

@ -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")
}
}

View file

@ -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) {

View file

@ -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

View file

@ -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
}

View file

@ -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"])
}
}

View file

@ -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 {

View file

@ -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"}

View file

@ -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) {

View file

@ -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 ")
}
}

View file

@ -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

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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

View file

@ -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)

View file

@ -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