Rich Enhanced Shell History - Contextual shell history for zsh and bash
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
resh/pkg/strat/dynamic-record-distance.go

85 lines
2.4 KiB

package strat
import (
"math"
"sort"
"strconv"
"github.com/curusarn/resh/pkg/records"
)
type DynamicRecordDistance struct {
history []records.EnrichedRecord
DistParams records.DistParams
pwdHistogram map[string]int
realPwdHistogram map[string]int
gitOriginHistogram map[string]int
MaxDepth int
Label string
}
type strDynDistEntry struct {
cmdLine string
distance float64
}
func (s *DynamicRecordDistance) Init() {
s.history = nil
s.pwdHistogram = map[string]int{}
s.realPwdHistogram = map[string]int{}
s.gitOriginHistogram = map[string]int{}
}
func (s *DynamicRecordDistance) GetTitleAndDescription() (string, string) {
return "dynamic record distance (depth:" + strconv.Itoa(s.MaxDepth) + ";" + s.Label + ")", "Use TF-IDF record distance to recommend commands"
}
func (s *DynamicRecordDistance) idf(count int) float64 {
return math.Log(float64(len(s.history)) / float64(count))
}
func (s *DynamicRecordDistance) GetCandidates(strippedRecord records.EnrichedRecord) []string {
if len(s.history) == 0 {
return nil
}
var mapItems []strDynDistEntry
for i, record := range s.history {
if s.MaxDepth != 0 && i > s.MaxDepth {
break
}
distParams := records.DistParams{
Pwd: s.DistParams.Pwd * s.idf(s.pwdHistogram[strippedRecord.PwdAfter]),
RealPwd: s.DistParams.RealPwd * s.idf(s.realPwdHistogram[strippedRecord.RealPwdAfter]),
Git: s.DistParams.Git * s.idf(s.gitOriginHistogram[strippedRecord.GitOriginRemote]),
Time: s.DistParams.Time,
SessionID: s.DistParams.SessionID,
}
distance := record.DistanceTo(strippedRecord, distParams)
mapItems = append(mapItems, strDynDistEntry{record.CmdLine, distance})
}
sort.SliceStable(mapItems, func(i int, j int) bool { return mapItems[i].distance < mapItems[j].distance })
var hist []string
histSet := map[string]bool{}
for _, item := range mapItems {
if histSet[item.cmdLine] {
continue
}
histSet[item.cmdLine] = true
hist = append(hist, item.cmdLine)
}
return hist
}
func (s *DynamicRecordDistance) AddHistoryRecord(record *records.EnrichedRecord) error {
// append record to front
s.history = append([]records.EnrichedRecord{*record}, s.history...)
s.pwdHistogram[record.Pwd]++
s.realPwdHistogram[record.RealPwd]++
s.gitOriginHistogram[record.GitOriginRemote]++
return nil
}
func (s *DynamicRecordDistance) ResetHistory() error {
s.Init()
return nil
}