https://git.spwbk.site/swatson/go-pest/raw/master/pest.go
___________________________________
package main

import (
       "fmt"
       "github.com/go-git/go-git/v5"
       "github.com/gookit/color"
       "github.com/pelletier/go-toml/v2"
       "os"
       "os/user"
       "strings"
)

// go-pest -- A reimplementation of cl-pest in Go, for the sake of learning a bit of Go
// See: https://git.spwbk.site/swatson/cl-pest/src/master/pest.lisp

type PestConfig struct {
       Git    GitConfig    `toml:"git"`
       Prompt PromptConfig `toml:"prompt"`
}

type GitConfig struct {
       DisplayHead   bool   `toml:"display_head"`
       DisplayBranch bool   `toml:"display_branch"`
       GitPrefix     string `toml:"git_prefix"`
       Colors        Colors `toml:"colors"`
}

type PromptConfig struct {
       DisplayUser     bool   `toml:"display_user"`
       UserSuffix      string `toml:"user_suffix"`
       DisplayHostname bool   `toml:"display_hostname"`
       HostnameSuffix  string `toml:"hostname_suffix"`
       DisplayPwd      bool   `toml:"display_pwd"`
       PwdSuffix       string `toml:"pwd_suffix"`
       PromptChar      string `toml:"prompt_char"`
       Colors          Colors `toml:"colors"`
}

type Colors struct {
       Fg []int `toml:"fg"`
       Bg []int `toml:"bg"`
}

const tomlData = `
[git]
display_head = false
display_branch = false
git_prefix = ""
[git.colors]
fg = [0, 120, 50]
bg = [0, 0, 0]

[prompt]
display_user = false
user_suffix = ""
display_hostname = false
hostname_suffix = ""
display_pwd = true
pwd_suffix = ""
prompt_char = " λ "
[prompt.colors]
fg = [255, 255, 255]
bg = [0, 0, 0]
`

func parseTomlFromString(tomlString string) (PestConfig, error) {
       var config PestConfig
       err := toml.Unmarshal([]byte(tomlString), &config)
       return config, err
}

func parseTomlFromFile(filePath string) (PestConfig, error) {
       var cfg PestConfig
       fileContent, err := os.ReadFile(filePath)
       switch err {
       case nil:
               {
                       err = toml.Unmarshal(fileContent, &cfg)
                       return cfg, err
               }
       default:
               {
                       // We had some kind of error, use the builtin config
                       cfg, err = parseTomlFromString(tomlData)
                       return cfg, err
               }
       }
}

func gitGetHead(filePath string) (string, string) {
       gitObj, err := git.PlainOpen(filePath)
       if err != nil {
               // Likely not a git dir, return empty
               return "", ""
       }

       headRef, err := gitObj.Head()
       if err != nil {
               panic(err)
       }

       sha := headRef.Hash().String()[:6]
       branch := headRef.Name().Short()
       return sha, branch
}

func getHostname() string {
       hostname, err := os.Hostname()
       if err != nil {
               panic(err)
       }
       return hostname
}

func getUser() string {
       username, err := user.Current()
       if err != nil {
               panic(err)
       }
       return username.Username
}

func getPwd() string {
       pwd, err := os.Getwd()
       if err != nil {
               panic(err)
       }
       return pwd
}

type RGBColorInput struct {
       r uint8
       g uint8
       b uint8
}

// make_style -- given a set of RGBColorInputs return a color.RGBColor pair
func make_style(fg, bg RGBColorInput) color.Style {
       fg_s := color.RGB(fg.r, fg.g, fg.b)
       bg_s := color.RGB(bg.r, bg.g, bg.b, true)
       style := color.New(fg_s.Color(), bg_s.Color())
       return style
}

func assemble_prompt(config *PestConfig) {
       var prompt_builder strings.Builder
       var git_prompt_builder strings.Builder

       if config.Git.DisplayHead || config.Git.DisplayBranch {
               sha, branch := gitGetHead(getPwd())
               if config.Git.DisplayHead && config.Git.DisplayBranch {
                       git_prompt := sha + "|" + branch
                       git_prompt_builder.WriteString(config.Git.GitPrefix)
                       git_prompt_builder.WriteString(git_prompt)
               } else if config.Git.DisplayHead {
                       git_prompt_builder.WriteString(config.Git.GitPrefix)
                       git_prompt_builder.WriteString(sha)
               } else if config.Git.DisplayBranch {
                       git_prompt_builder.WriteString(config.Git.GitPrefix)
                       git_prompt_builder.WriteString(branch)
               }
               git_prompt_builder.WriteString(" ")
       }

       git_prompt_color := make_style(
               RGBColorInput{
                       uint8(config.Git.Colors.Fg[0]),
                       uint8(config.Git.Colors.Fg[1]),
                       uint8(config.Git.Colors.Fg[2]),
               },
               RGBColorInput{
                       uint8(config.Git.Colors.Bg[0]),
                       uint8(config.Git.Colors.Bg[1]),
                       uint8(config.Git.Colors.Bg[2]),
               })

       if config.Prompt.DisplayUser {
               prompt_builder.WriteString(getUser())
               prompt_builder.WriteString(config.Prompt.UserSuffix)
       }

       if config.Prompt.DisplayHostname {
               prompt_builder.WriteString(getHostname())
               prompt_builder.WriteString(config.Prompt.HostnameSuffix)
       }

       if config.Prompt.DisplayPwd {
               prompt_builder.WriteString(getPwd())
               prompt_builder.WriteString(config.Prompt.PwdSuffix)
       }

       prompt_builder.WriteString(config.Prompt.PromptChar)

       prompt_color := make_style(
               RGBColorInput{
                       uint8(config.Prompt.Colors.Fg[0]),
                       uint8(config.Prompt.Colors.Fg[1]),
                       uint8(config.Prompt.Colors.Fg[2]), // This will of course panic if this number is > 255
               },
               RGBColorInput{
                       uint8(config.Prompt.Colors.Bg[0]),
                       uint8(config.Prompt.Colors.Bg[1]),
                       uint8(config.Prompt.Colors.Bg[2]),
               })

       git_prompt_color.Printf(git_prompt_builder.String())
       prompt_color.Printf(prompt_builder.String())

}

func main() {

       parsed_config, err := parseTomlFromFile("/home/swatson/Repos/go-pest/pest.cfg")
       if err != nil {
               fmt.Println("Couldn't parse TOML const!")
       }

       assemble_prompt(&parsed_config)

}