package prep // essentially .bash_history, but in a protobuf and for any shell // An elegant weapon... for a more civilized age. // stores files ./cache/argv/.pb import ( "fmt" "os" "path/filepath" "time" "go.wit.com/lib/config" durationpb "google.golang.org/protobuf/types/known/durationpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" ) // makes a bash autocomplete file for your command func (pb *Auto) getHistoryPB() error { cacheDir, err := os.UserCacheDir() if err != nil { return err } basedir := filepath.Join(cacheDir, "argv") os.MkdirAll(basedir, os.ModePerm) fullname := filepath.Join(basedir, pb.Argname+".pb") all := NewAutos() var last *Auto data, err := os.ReadFile(fullname) if err == nil { err = all.Unmarshal(data) if err == nil { for found := range all.IterAll() { dur := time.Since(found.Ctime.AsTime()) pb.Duration = durationpb.New(dur) // found.PrintDebug() cmd := fmt.Sprintf("cmd='%s'", found.Cmd) arglast := fmt.Sprintf("last='%s'", found.Last) partial := fmt.Sprintf("p='%s'", found.Partial) age := fmt.Sprintf("age='%-6.6s'", config.FormatDuration(dur)) pb.Debugf("AUTO HISTORY: %s %-18.18s %-18.18s %-12.12s argv='%v' goargs='%v'", age, cmd, arglast, partial, found.Argv, found.Goargs) last = found } } } if all.Len() > 15 { pb.Debugf("DEBUG: trim() history is over 100 len=%d vs new=%d", all.Len(), all.Len()-90) all.Autos = all.Autos[all.Len()-10:] // newall.Autos = all.Autos[0:10] // for _, found := range all.Autos[0:10] { // newall.Append(found) // } } // need this for the first time the user runs autocomplete if last == nil { last = new(Auto) } now := time.Now() pb.Ctime = timestamppb.New(now) duration := time.Since(last.Ctime.AsTime()) all.Append(pb) data, err = all.Marshal() if err != nil { return err } f, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) defer f.Close() if err != nil { return err } _, err = f.Write(data) pb.Debugf("WRITE DEBUG: write PB='%s' len(pb)=%d len(data)=%d dur=%v err=%v", fullname, all.Len(), len(data), duration, err) return err }