2019-03-13 04:14:30 -07:00
|
|
|
package main
|
|
|
|
|
2020-11-14 23:47:00 -08:00
|
|
|
import (
|
|
|
|
"errors"
|
2020-12-06 10:34:42 -08:00
|
|
|
"fmt"
|
2022-01-26 01:23:18 -08:00
|
|
|
"oh-my-posh/environment"
|
2022-01-26 04:53:35 -08:00
|
|
|
"oh-my-posh/properties"
|
2021-11-11 23:40:08 -08:00
|
|
|
"runtime/debug"
|
2021-04-18 10:16:06 -07:00
|
|
|
"time"
|
2020-11-14 23:47:00 -08:00
|
|
|
)
|
2020-09-17 07:51:29 -07:00
|
|
|
|
2020-11-12 00:43:32 -08:00
|
|
|
// Segment represent a single segment and it's configuration
|
2019-03-13 04:14:30 -07:00
|
|
|
type Segment struct {
|
2022-01-26 04:53:35 -08:00
|
|
|
Type SegmentType `config:"type"`
|
|
|
|
Tips []string `config:"tips"`
|
|
|
|
Style SegmentStyle `config:"style"`
|
|
|
|
PowerlineSymbol string `config:"powerline_symbol"`
|
|
|
|
InvertPowerline bool `config:"invert_powerline"`
|
|
|
|
Foreground string `config:"foreground"`
|
|
|
|
ForegroundTemplates []string `config:"foreground_templates"`
|
|
|
|
Background string `config:"background"`
|
|
|
|
BackgroundTemplates []string `config:"background_templates"`
|
|
|
|
LeadingDiamond string `config:"leading_diamond"`
|
|
|
|
TrailingDiamond string `config:"trailing_diamond"`
|
|
|
|
Properties properties.Map `config:"properties"`
|
2021-02-13 07:27:31 -08:00
|
|
|
writer SegmentWriter
|
|
|
|
stringValue string
|
|
|
|
active bool
|
2022-01-26 01:23:18 -08:00
|
|
|
env environment.Environment
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
|
|
|
|
2021-04-18 10:16:06 -07:00
|
|
|
// SegmentTiming holds the timing context for a segment
|
|
|
|
type SegmentTiming struct {
|
|
|
|
name string
|
|
|
|
nameLength int
|
|
|
|
enabled bool
|
|
|
|
stringValue string
|
|
|
|
enabledDuration time.Duration
|
|
|
|
stringDuration time.Duration
|
|
|
|
}
|
|
|
|
|
2020-11-12 00:43:32 -08:00
|
|
|
// SegmentWriter is the interface used to define what and if to write to the prompt
|
2019-03-13 04:14:30 -07:00
|
|
|
type SegmentWriter interface {
|
2022-01-26 05:26:56 -08:00
|
|
|
Enabled() bool
|
|
|
|
Template() string
|
|
|
|
Init(props properties.Properties, env environment.Environment)
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
|
|
|
|
2020-11-12 00:43:32 -08:00
|
|
|
// SegmentStyle the syle of segment, for more information, see the constants
|
2019-03-13 04:14:30 -07:00
|
|
|
type SegmentStyle string
|
|
|
|
|
2020-11-12 00:43:32 -08:00
|
|
|
// SegmentType the type of segment, for more information, see the constants
|
2019-03-13 04:14:30 -07:00
|
|
|
type SegmentType string
|
|
|
|
|
|
|
|
const (
|
2022-01-26 05:10:18 -08:00
|
|
|
// SESSION represents the user info segment
|
|
|
|
SESSION SegmentType = "session"
|
|
|
|
// PATH represents the current path segment
|
|
|
|
PATH SegmentType = "path"
|
|
|
|
// GIT represents the git status and information
|
|
|
|
GIT SegmentType = "git"
|
|
|
|
// PLASTIC represents the plastic scm status and information
|
|
|
|
PLASTIC SegmentType = "plastic"
|
|
|
|
// EXIT writes the last exit code
|
|
|
|
EXIT SegmentType = "exit"
|
|
|
|
// PYTHON writes the virtual env name
|
|
|
|
PYTHON SegmentType = "python"
|
|
|
|
// ROOT writes root symbol
|
|
|
|
ROOT SegmentType = "root"
|
|
|
|
// TIME writes the current timestamp
|
|
|
|
TIME SegmentType = "time"
|
|
|
|
// TEXT writes a text
|
|
|
|
TEXT SegmentType = "text"
|
|
|
|
// CMD writes the output of a shell command
|
|
|
|
CMD SegmentType = "command"
|
|
|
|
// BATTERY writes the battery percentage
|
|
|
|
BATTERY SegmentType = "battery"
|
|
|
|
// SPOTIFY writes the SPOTIFY status for Mac
|
|
|
|
SPOTIFY SegmentType = "spotify"
|
|
|
|
// SHELL writes which shell we're currently in
|
|
|
|
SHELL SegmentType = "shell"
|
|
|
|
// NODE writes which node version is currently active
|
|
|
|
NODE SegmentType = "node"
|
|
|
|
// OS write os specific icon
|
|
|
|
OS SegmentType = "os"
|
|
|
|
// AZ writes the Azure subscription info we're currently in
|
|
|
|
AZ SegmentType = "az"
|
|
|
|
// KUBECTL writes the Kubernetes context we're currently in
|
|
|
|
KUBECTL SegmentType = "kubectl"
|
|
|
|
// DOTNET writes which dotnet version is currently active
|
|
|
|
DOTNET SegmentType = "dotnet"
|
|
|
|
// TERRAFORM writes the terraform workspace we're currently in
|
|
|
|
TERRAFORM SegmentType = "terraform"
|
|
|
|
// GOLANG writes which go version is currently active
|
|
|
|
GOLANG SegmentType = "go"
|
|
|
|
// JULIA writes which julia version is currently active
|
|
|
|
JULIA SegmentType = "julia"
|
2020-11-12 00:43:32 -08:00
|
|
|
// Powerline writes it Powerline style
|
2019-03-13 04:14:30 -07:00
|
|
|
Powerline SegmentStyle = "powerline"
|
2020-11-12 00:43:32 -08:00
|
|
|
// Plain writes it without ornaments
|
2019-03-13 04:14:30 -07:00
|
|
|
Plain SegmentStyle = "plain"
|
2020-11-12 00:43:32 -08:00
|
|
|
// Diamond writes the prompt shaped with a leading and trailing symbol
|
2019-03-13 04:14:30 -07:00
|
|
|
Diamond SegmentStyle = "diamond"
|
2020-11-19 19:12:20 -08:00
|
|
|
// YTM writes YouTube Music information and status
|
|
|
|
YTM SegmentType = "ytm"
|
2022-01-26 05:10:18 -08:00
|
|
|
// EXECUTIONTIME writes the execution time of the last run command
|
|
|
|
EXECUTIONTIME SegmentType = "executiontime"
|
|
|
|
// RUBY writes which ruby version is currently active
|
|
|
|
RUBY SegmentType = "ruby"
|
|
|
|
// AWS writes the active aws context
|
|
|
|
AWS SegmentType = "aws"
|
|
|
|
// JAVA writes the active java version
|
|
|
|
JAVA SegmentType = "java"
|
|
|
|
// POSHGIT writes the posh git prompt
|
|
|
|
POSHGIT SegmentType = "poshgit"
|
|
|
|
// AZFUNC writes current AZ func version
|
|
|
|
AZFUNC SegmentType = "azfunc"
|
|
|
|
// CRYSTAL writes the active crystal version
|
|
|
|
CRYSTAL SegmentType = "crystal"
|
|
|
|
// DART writes the active dart version
|
|
|
|
DART SegmentType = "dart"
|
|
|
|
// NBGV writes the nbgv version information
|
|
|
|
NBGV SegmentType = "nbgv"
|
|
|
|
// RUST writes the cargo version information if cargo.toml is present
|
|
|
|
RUST SegmentType = "rust"
|
2021-08-17 23:21:55 -07:00
|
|
|
// OWM writes the weather coming from openweatherdata
|
|
|
|
OWM SegmentType = "owm"
|
2022-01-26 05:10:18 -08:00
|
|
|
// SYSTEMINFO writes system information (memory, cpu, load)
|
|
|
|
SYSTEMINFO SegmentType = "sysinfo"
|
|
|
|
// ANGULAR writes which angular cli version us currently active
|
|
|
|
ANGULAR SegmentType = "angular"
|
2021-10-27 01:52:56 -07:00
|
|
|
// PHP writes which php version is currently active
|
|
|
|
PHP SegmentType = "php"
|
2022-01-26 05:10:18 -08:00
|
|
|
// NIGHTSCOUT is an open source diabetes system
|
|
|
|
NIGHTSCOUT SegmentType = "nightscout"
|
|
|
|
// STRAVA is a sports activity tracker
|
|
|
|
STRAVA SegmentType = "strava"
|
|
|
|
// WAKATIME writes tracked time spend in dev editors
|
|
|
|
WAKATIME SegmentType = "wakatime"
|
|
|
|
// WIFI writes details about the current WIFI connection
|
|
|
|
WIFI SegmentType = "wifi"
|
|
|
|
// WINREG queries the Windows registry.
|
|
|
|
WINREG SegmentType = "winreg"
|
2021-12-14 23:49:32 -08:00
|
|
|
// Brewfather segment
|
2022-01-26 05:10:18 -08:00
|
|
|
BREWFATHER SegmentType = "brewfather"
|
|
|
|
// IPIFY segment
|
|
|
|
IPIFY SegmentType = "ipify"
|
2019-03-13 04:14:30 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
func (segment *Segment) string() string {
|
2022-01-23 12:37:51 -08:00
|
|
|
template := &textTemplate{
|
2022-01-26 05:26:56 -08:00
|
|
|
Template: segment.writer.Template(),
|
2022-01-23 12:37:51 -08:00
|
|
|
Context: segment.writer,
|
|
|
|
Env: segment.env,
|
|
|
|
}
|
|
|
|
text, err := template.render()
|
|
|
|
if err != nil {
|
|
|
|
return err.Error()
|
|
|
|
}
|
|
|
|
return text
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func (segment *Segment) enabled() bool {
|
2022-01-26 05:26:56 -08:00
|
|
|
segment.active = segment.writer.Enabled()
|
2020-10-12 23:57:46 -07:00
|
|
|
return segment.active
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
|
|
|
|
2022-01-26 04:53:35 -08:00
|
|
|
func (segment *Segment) getValue(property properties.Property, defaultValue string) string {
|
2020-10-02 07:58:25 -07:00
|
|
|
if value, ok := segment.Properties[property]; ok {
|
2022-01-26 04:53:35 -08:00
|
|
|
return properties.ParseString(value, defaultValue)
|
2020-10-02 07:58:25 -07:00
|
|
|
}
|
|
|
|
return defaultValue
|
|
|
|
}
|
|
|
|
|
2021-10-20 08:01:19 -07:00
|
|
|
func (segment *Segment) shouldIncludeFolder() bool {
|
|
|
|
cwdIncluded := segment.cwdIncluded()
|
|
|
|
cwdExcluded := segment.cwdExcluded()
|
2021-02-27 20:05:51 -08:00
|
|
|
return (cwdIncluded && !cwdExcluded)
|
|
|
|
}
|
|
|
|
|
2021-10-20 08:01:19 -07:00
|
|
|
func (segment *Segment) cwdIncluded() bool {
|
2022-01-26 04:53:35 -08:00
|
|
|
value, ok := segment.Properties[properties.IncludeFolders]
|
2021-02-27 20:05:51 -08:00
|
|
|
if !ok {
|
|
|
|
// IncludeFolders isn't specified, everything is included
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2022-01-26 04:53:35 -08:00
|
|
|
list := properties.ParseStringArray(value)
|
2021-02-27 20:05:51 -08:00
|
|
|
|
|
|
|
if len(list) == 0 {
|
|
|
|
// IncludeFolders is an empty array, everything is included
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2022-01-26 01:23:18 -08:00
|
|
|
return environment.DirMatchesOneOf(segment.env, segment.env.Pwd(), list)
|
2021-02-27 20:05:51 -08:00
|
|
|
}
|
|
|
|
|
2021-10-20 08:01:19 -07:00
|
|
|
func (segment *Segment) cwdExcluded() bool {
|
2022-01-26 04:53:35 -08:00
|
|
|
value, ok := segment.Properties[properties.ExcludeFolders]
|
2021-02-27 20:05:51 -08:00
|
|
|
if !ok {
|
2022-01-26 04:53:35 -08:00
|
|
|
value = segment.Properties[properties.IgnoreFolders]
|
2021-02-27 20:05:51 -08:00
|
|
|
}
|
2022-01-26 04:53:35 -08:00
|
|
|
list := properties.ParseStringArray(value)
|
2022-01-26 01:23:18 -08:00
|
|
|
return environment.DirMatchesOneOf(segment.env, segment.env.Pwd(), list)
|
2020-10-02 07:58:25 -07:00
|
|
|
}
|
|
|
|
|
2021-02-13 07:27:31 -08:00
|
|
|
func (segment *Segment) getColor(templates []string, defaultColor string) string {
|
|
|
|
if len(templates) == 0 {
|
|
|
|
return defaultColor
|
|
|
|
}
|
|
|
|
txtTemplate := &textTemplate{
|
|
|
|
Context: segment.writer,
|
2021-05-26 12:12:58 -07:00
|
|
|
Env: segment.env,
|
2021-02-13 07:27:31 -08:00
|
|
|
}
|
|
|
|
for _, template := range templates {
|
|
|
|
txtTemplate.Template = template
|
2021-04-11 06:24:03 -07:00
|
|
|
value, err := txtTemplate.render()
|
|
|
|
if err != nil || value == "" {
|
2021-02-13 07:27:31 -08:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
return defaultColor
|
|
|
|
}
|
|
|
|
|
2021-06-05 07:14:44 -07:00
|
|
|
func (segment *Segment) shouldInvokeWithTip(tip string) bool {
|
|
|
|
for _, t := range segment.Tips {
|
|
|
|
if t == tip {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2021-02-13 07:27:31 -08:00
|
|
|
func (segment *Segment) foreground() string {
|
2022-01-23 11:24:02 -08:00
|
|
|
return segment.getColor(segment.ForegroundTemplates, segment.Foreground)
|
2021-02-13 07:27:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (segment *Segment) background() string {
|
2022-01-23 11:24:02 -08:00
|
|
|
return segment.getColor(segment.BackgroundTemplates, segment.Background)
|
2021-02-13 07:27:31 -08:00
|
|
|
}
|
|
|
|
|
2022-01-26 01:23:18 -08:00
|
|
|
func (segment *Segment) mapSegmentWithWriter(env environment.Environment) error {
|
2021-05-26 12:12:58 -07:00
|
|
|
segment.env = env
|
2019-03-13 04:14:30 -07:00
|
|
|
functions := map[SegmentType]SegmentWriter{
|
2022-01-26 05:10:18 -08:00
|
|
|
OWM: &Owm{},
|
|
|
|
SESSION: &Session{},
|
|
|
|
PATH: &Path{},
|
|
|
|
GIT: &Git{},
|
|
|
|
PLASTIC: &Plastic{},
|
|
|
|
EXIT: &Exit{},
|
|
|
|
PYTHON: &Python{},
|
|
|
|
ROOT: &Root{},
|
|
|
|
TEXT: &Text{},
|
|
|
|
TIME: &Time{},
|
|
|
|
CMD: &Cmd{},
|
|
|
|
BATTERY: &Battery{},
|
|
|
|
SPOTIFY: &Spotify{},
|
|
|
|
SHELL: &Shell{},
|
|
|
|
NODE: &Node{},
|
|
|
|
OS: &Os{},
|
|
|
|
AZ: &Az{},
|
|
|
|
KUBECTL: &Kubectl{},
|
|
|
|
DOTNET: &Dotnet{},
|
|
|
|
TERRAFORM: &Terraform{},
|
|
|
|
GOLANG: &Golang{},
|
|
|
|
JULIA: &Julia{},
|
|
|
|
YTM: &Ytm{},
|
|
|
|
EXECUTIONTIME: &Executiontime{},
|
|
|
|
RUBY: &Ruby{},
|
|
|
|
AWS: &Aws{},
|
|
|
|
JAVA: &Java{},
|
|
|
|
POSHGIT: &PoshGit{},
|
|
|
|
AZFUNC: &AzFunc{},
|
|
|
|
CRYSTAL: &Crystal{},
|
|
|
|
DART: &Dart{},
|
|
|
|
NBGV: &Nbgv{},
|
|
|
|
RUST: &Rust{},
|
|
|
|
SYSTEMINFO: &SystemInfo{},
|
|
|
|
ANGULAR: &Angular{},
|
|
|
|
PHP: &Php{},
|
|
|
|
NIGHTSCOUT: &Nightscout{},
|
|
|
|
STRAVA: &Strava{},
|
|
|
|
WAKATIME: &Wakatime{},
|
|
|
|
WIFI: &Wifi{},
|
|
|
|
WINREG: &WindowsRegistry{},
|
|
|
|
BREWFATHER: &Brewfather{},
|
|
|
|
IPIFY: &IPify{},
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
2021-12-03 03:17:26 -08:00
|
|
|
if segment.Properties == nil {
|
2022-01-26 04:53:35 -08:00
|
|
|
segment.Properties = make(properties.Map)
|
2021-12-03 03:17:26 -08:00
|
|
|
}
|
2019-03-13 04:14:30 -07:00
|
|
|
if writer, ok := functions[segment.Type]; ok {
|
2022-01-26 05:26:56 -08:00
|
|
|
writer.Init(segment.Properties, env)
|
2019-03-13 04:14:30 -07:00
|
|
|
segment.writer = writer
|
2020-10-12 23:57:46 -07:00
|
|
|
return nil
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
2020-11-12 00:43:32 -08:00
|
|
|
return errors.New("unable to map writer")
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
2020-11-14 23:47:00 -08:00
|
|
|
|
2022-01-26 01:23:18 -08:00
|
|
|
func (segment *Segment) setStringValue(env environment.Environment) {
|
2020-12-30 13:01:39 -08:00
|
|
|
defer func() {
|
|
|
|
err := recover()
|
|
|
|
if err == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// display a message explaining omp failed(with the err)
|
2021-11-11 23:40:08 -08:00
|
|
|
message := fmt.Sprintf("\noh-my-posh fatal error rendering %s segment:%s\n\n%s\n", segment.Type, err, debug.Stack())
|
2020-12-30 13:01:39 -08:00
|
|
|
fmt.Println(message)
|
|
|
|
segment.stringValue = "error"
|
|
|
|
segment.active = true
|
|
|
|
}()
|
2020-11-14 23:47:00 -08:00
|
|
|
err := segment.mapSegmentWithWriter(env)
|
2021-10-20 08:01:19 -07:00
|
|
|
if err != nil || !segment.shouldIncludeFolder() {
|
2020-11-14 23:47:00 -08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
if segment.enabled() {
|
|
|
|
segment.stringValue = segment.string()
|
|
|
|
}
|
|
|
|
}
|