prompt

My shell prompt
git clone https://hhvn.uk/prompt
git clone git://hhvn.uk/prompt
Log | Files | Refs

main.go (2167B)


      1 package main
      2 
      3 import (
      4 	"io"
      5 	"os"
      6 	"os/exec"
      7 	"strings"
      8 	"log"
      9 	"errors"
     10 	"runtime"
     11 
     12 	"hhvn.uk/prompt/config"
     13 	"hhvn.uk/prompt/tput"
     14 )
     15 
     16 var (
     17 	col = config.Colours
     18 	cnf = config.Settings
     19 )
     20 
     21 var fn = []Fn{
     22 	FnExitStatus,
     23 	nil,
     24 	FnUsername,
     25 	nil,
     26 	FnBranch,
     27 	FnDiff,
     28 	FnUnpushed,
     29 	nil,
     30 	FnDir,
     31 	FnDollar,
     32 } 
     33 
     34 // Cmd runs a command and returns a slice of the lines produced by it.
     35 //
     36 // If the command writes to stderr, the output is returned as an error.
     37 func Cmd(name string, arg ...string) ([]string, error) {
     38 	cmd := exec.Command(name, arg...)
     39 	
     40 	errp, err := cmd.StderrPipe()
     41 	if err != nil {
     42 		return nil, err
     43 	}
     44 
     45 	outp, err := cmd.StdoutPipe()
     46 	if err != nil {
     47 		return nil, err
     48 	}
     49 
     50 	if err := cmd.Start(); err != nil {
     51 		return nil, err
     52 	}
     53 	defer cmd.Wait()
     54 
     55 	b, err := io.ReadAll(errp)
     56 	if err != nil {
     57 		return nil, err
     58 	}
     59 	if len(b) != 0 {
     60 		return nil, errors.New(string(b))
     61 	}
     62 
     63 	out, err := io.ReadAll(outp)
     64 	if err != nil {
     65 		return nil, err
     66 	}
     67 
     68 	nnl := strings.TrimSuffix(string(out), "\n")
     69 
     70 	return strings.Split(nnl, "\n"), nil
     71 }
     72 
     73 func Err(e error) {
     74 	if e != nil {
     75 		pc, _, _, _ := runtime.Caller(1)
     76 		log.Printf("%s(): %s", runtime.FuncForPC(pc).Name(), e)
     77 	}
     78 }
     79 
     80 func Ignore(err error, ign ...error) error {
     81 	for i := range ign {
     82 		if errors.Is(err, ign[i]) {
     83 			return nil
     84 		}
     85 	}
     86 
     87 	return err
     88 }
     89 
     90 func ConsumeChan(ch chan string) string {
     91 	var str []string
     92 
     93 	for s := range ch {
     94 		str = append(str, s)
     95 	}
     96 
     97 	// TODO: find a better home for this
     98 	str = append(str, tput.Clear())
     99 
    100 	return strings.Join(str, "")
    101 }
    102 
    103 func Out(s string) {
    104 	os.Stdout.WriteString(s)
    105 }
    106 
    107 func main(){
    108 	if err := tput.CheckErr(); err != nil {
    109 		log.Fatal(err)
    110 	}
    111 
    112 	ch := make([]chan string, len(fn))
    113 	for i := range ch {
    114 		if fn[i] != nil {
    115 			ch[i] = make(chan string)
    116 		}
    117 	}
    118 	
    119 	for i := range fn {
    120 		if fn[i] != nil {
    121 			go fn[i](ch[i])
    122 		}
    123 	}
    124 
    125 	s := make([]string, len(fn))
    126 	for i := range ch {
    127 		if fn[i] != nil {
    128 			s[i] = ConsumeChan(ch[i])
    129 		}
    130 	}
    131 
    132 	spacer := false
    133 	for i := range s {
    134 		if fn[i] == nil {
    135 			spacer = true
    136 			continue
    137 		}
    138 
    139 		if tput.Strip(s[i]) == "" {
    140 			continue
    141 		}
    142 
    143 		if spacer == true {
    144 			Out(" ")
    145 			spacer = false
    146 		}
    147 
    148 		Out(s[i])
    149 	}
    150 
    151 	Out(" ")
    152 }