oh-my-posh/src/segment_executiontime.go
2021-11-26 11:11:07 +01:00

209 lines
5.6 KiB
Go

package main
import (
"fmt"
"strconv"
lang "golang.org/x/text/language"
"golang.org/x/text/message"
)
type executiontime struct {
props properties
env environmentInfo
FormattedMs string
Ms int64
}
// DurationStyle how to display the time
type DurationStyle string
const (
// ThresholdProperty represents minimum duration (milliseconds) required to enable this segment
ThresholdProperty Property = "threshold"
// Austin milliseconds short
Austin DurationStyle = "austin"
// Roundrock milliseconds long
Roundrock DurationStyle = "roundrock"
// Dallas milliseconds full
Dallas DurationStyle = "dallas"
// Galveston hour
Galveston DurationStyle = "galveston"
// Houston hour and milliseconds
Houston DurationStyle = "houston"
// Amarillo seconds
Amarillo DurationStyle = "amarillo"
// Round will round the output of the format
Round DurationStyle = "round"
second = 1000
minute = 60000
hour = 3600000
day = 86400000
secondsPerMinute = 60
minutesPerHour = 60
hoursPerDay = 24
)
func (t *executiontime) enabled() bool {
alwaysEnabled := t.props.getBool(AlwaysEnabled, false)
executionTimeMs := t.env.executionTime()
thresholdMs := t.props.getFloat64(ThresholdProperty, float64(500))
if !alwaysEnabled && executionTimeMs < thresholdMs {
return false
}
style := DurationStyle(t.props.getString(Style, string(Austin)))
t.Ms = int64(executionTimeMs)
t.FormattedMs = t.formatDuration(style)
return t.FormattedMs != ""
}
func (t *executiontime) string() string {
return t.FormattedMs
}
func (t *executiontime) init(props properties, env environmentInfo) {
t.props = props
t.env = env
}
func (t *executiontime) formatDuration(style DurationStyle) string {
switch style {
case Austin:
return t.formatDurationAustin()
case Roundrock:
return t.formatDurationRoundrock()
case Dallas:
return t.formatDurationDallas()
case Galveston:
return t.formatDurationGalveston()
case Houston:
return t.formatDurationHouston()
case Amarillo:
return t.formatDurationAmarillo()
case Round:
return t.formatDurationRound()
default:
return fmt.Sprintf("Style: %s is not available", style)
}
}
func (t *executiontime) formatDurationAustin() string {
if t.Ms < second {
return fmt.Sprintf("%dms", t.Ms%second)
}
seconds := float64(t.Ms%minute) / second
result := strconv.FormatFloat(seconds, 'f', -1, 64) + "s"
if t.Ms >= minute {
result = fmt.Sprintf("%dm %s", t.Ms/minute%secondsPerMinute, result)
}
if t.Ms >= hour {
result = fmt.Sprintf("%dh %s", t.Ms/hour%hoursPerDay, result)
}
if t.Ms >= day {
result = fmt.Sprintf("%dd %s", t.Ms/day, result)
}
return result
}
func (t *executiontime) formatDurationRoundrock() string {
result := fmt.Sprintf("%dms", t.Ms%second)
if t.Ms >= second {
result = fmt.Sprintf("%ds %s", t.Ms/second%secondsPerMinute, result)
}
if t.Ms >= minute {
result = fmt.Sprintf("%dm %s", t.Ms/minute%minutesPerHour, result)
}
if t.Ms >= hour {
result = fmt.Sprintf("%dh %s", t.Ms/hour%hoursPerDay, result)
}
if t.Ms >= day {
result = fmt.Sprintf("%dd %s", t.Ms/day, result)
}
return result
}
func (t *executiontime) formatDurationDallas() string {
seconds := float64(t.Ms%minute) / second
result := strconv.FormatFloat(seconds, 'f', -1, 64)
if t.Ms >= minute {
result = fmt.Sprintf("%d:%s", t.Ms/minute%minutesPerHour, result)
}
if t.Ms >= hour {
result = fmt.Sprintf("%d:%s", t.Ms/hour%hoursPerDay, result)
}
if t.Ms >= day {
result = fmt.Sprintf("%d:%s", t.Ms/day, result)
}
return result
}
func (t *executiontime) formatDurationGalveston() string {
result := fmt.Sprintf("%02d:%02d:%02d", t.Ms/hour, t.Ms/minute%minutesPerHour, t.Ms%minute/second)
return result
}
func (t *executiontime) formatDurationHouston() string {
milliseconds := ".0"
if t.Ms%second > 0 {
// format milliseconds as a string with truncated trailing zeros
milliseconds = strconv.FormatFloat(float64(t.Ms%second)/second, 'f', -1, 64)
// at this point milliseconds looks like "0.5". remove the leading "0"
milliseconds = milliseconds[1:]
}
result := fmt.Sprintf("%02d:%02d:%02d%s", t.Ms/hour, t.Ms/minute%minutesPerHour, t.Ms%minute/second, milliseconds)
return result
}
func (t *executiontime) formatDurationAmarillo() string {
// wholeNumber represents the value to the left of the decimal point (seconds)
wholeNumber := t.Ms / second
// decimalNumber represents the value to the right of the decimal point (milliseconds)
decimalNumber := float64(t.Ms%second) / second
// format wholeNumber as a string with thousands separators
printer := message.NewPrinter(lang.English)
result := printer.Sprintf("%d", wholeNumber)
if decimalNumber > 0 {
// format decimalNumber as a string with truncated trailing zeros
decimalResult := strconv.FormatFloat(decimalNumber, 'f', -1, 64)
// at this point decimalResult looks like "0.5"
// remove the leading "0" and append
result += decimalResult[1:]
}
result += "s"
return result
}
func (t *executiontime) formatDurationRound() string {
toRoundString := func(one, two int64, oneText, twoText string) string {
if two == 0 {
return fmt.Sprintf("%d%s", one, oneText)
}
return fmt.Sprintf("%d%s %d%s", one, oneText, two, twoText)
}
hours := t.Ms / hour % hoursPerDay
if t.Ms >= day {
return toRoundString(t.Ms/day, hours, "d", "h")
}
minutes := t.Ms / minute % secondsPerMinute
if t.Ms >= hour {
return toRoundString(hours, minutes, "h", "m")
}
seconds := (t.Ms % minute) / second
if t.Ms >= minute {
return toRoundString(minutes, seconds, "m", "s")
}
if t.Ms >= second {
return fmt.Sprintf("%ds", seconds)
}
return fmt.Sprintf("%dms", t.Ms%second)
}