feat: add history filter handler

this adds a history handler which will be called
on all history and returns a boolean
to signify whether to include the command
in the history menu or not

it is passed 2 arguments: the user query and
command
history-searcher
TorchedSammy 2022-07-17 18:25:54 -04:00
parent 7434d270e4
commit 40c2933a95
Signed by: sammyette
GPG Key ID: 904FC49417B44DCD
1 changed files with 46 additions and 5 deletions

51
rl.go
View File

@ -31,15 +31,56 @@ func newLineReader(prompt string, noHist bool) *lineReader {
rl.SetHistoryCtrlR("History", &luaHistory{}) rl.SetHistoryCtrlR("History", &luaHistory{})
rl.HistoryAutoWrite = false rl.HistoryAutoWrite = false
} }
oldSearcher := rl.HistorySearcher oldSearcher := rl.HistorySearcher
rl.HistorySearcher = func(filter string) []string { rl.HistorySearcher = func(query string, suggestions []string) []string {
searcherHandler := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("searcher")) return oldSearcher(query, suggestions)
if searcherHandler == rt.NilValue { searcherBool := hshMod.Get(rt.StringValue("opts")).AsTable().Get(rt.StringValue("searcher"))
return oldSearcher(filter) if b, _ := searcherBool.TryBool(); !b {
} }
ret, err := rt.Call1(l.MainThread(), searcherHandler, rt.StringValue(filter)) searcherHandler := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("searcher"))
entries := []string{} entries := []string{}
if searcherHandler == rt.NilValue {
// if no searcher, just do a simple filter function
filter := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("filter"))
if filter == rt.NilValue {
return oldSearcher(query, suggestions)
}
histAll := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("all"))
cmds, err := rt.Call1(l.MainThread(), histAll)
if err != nil || cmds.Type() != rt.TableType {
return entries
}
util.ForEach(cmds.AsTable(), func(k rt.Value, cmd rt.Value) {
if k.Type() != rt.IntType && cmd.Type() != rt.StringType {
return
}
ret, err := rt.Call1(l.MainThread(), filter, rt.StringValue(query), cmd)
if err != nil {
return // TODO: true to stop for each (implement in util)
}
if ret.Type() != rt.BoolType {
return // just skip normally
}
if ret.AsBool() {
entries = append(entries, cmd.AsString())
}
})
return entries
}
luaSuggs := rt.NewTable()
for i, sug := range suggestions {
luaSuggs.Set(rt.IntValue(int64(i + 1)), rt.StringValue(sug))
}
ret, err := rt.Call1(l.MainThread(), searcherHandler, rt.StringValue(query), luaSuggs)
if err == nil && ret.Type() == rt.TableType { if err == nil && ret.Type() == rt.TableType {
util.ForEach(ret.AsTable(), func(k rt.Value, v rt.Value) { util.ForEach(ret.AsTable(), func(k rt.Value, v rt.Value) {
if k.Type() == rt.IntType && v.Type() == rt.StringType { if k.Type() == rt.IntType && v.Type() == rt.StringType {