From bd35e3b87163ad9516b0955b16143aff766e2e57 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Thu, 21 Apr 2022 14:01:59 -0400 Subject: [PATCH] refactor: use foreach function to loop over lua tables --- api.go | 87 ++----------------------------------------- complete.go | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++ rl.go | 70 +++++++++++++--------------------- util/util.go | 14 +++++++ 4 files changed, 147 insertions(+), 127 deletions(-) diff --git a/api.go b/api.go index c32bf5d..5a72ddf 100644 --- a/api.go +++ b/api.go @@ -148,75 +148,6 @@ func getenv(key, fallback string) string { return value } -func luaFileComplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { - query, ctx, fds, err := getCompleteParams(t, c) - if err != nil { - return nil, err - } - - completions, _ := fileComplete(query, ctx, fds) - luaComps := rt.NewTable() - - for i, comp := range completions { - luaComps.Set(rt.IntValue(int64(i + 1)), rt.StringValue(comp)) - } - - return c.PushingNext1(t.Runtime, rt.TableValue(luaComps)), nil -} - -func luaBinaryComplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { - query, ctx, fds, err := getCompleteParams(t, c) - if err != nil { - return nil, err - } - - completions, _ := binaryComplete(query, ctx, fds) - luaComps := rt.NewTable() - - for i, comp := range completions { - luaComps.Set(rt.IntValue(int64(i + 1)), rt.StringValue(comp)) - } - - return c.PushingNext1(t.Runtime, rt.TableValue(luaComps)), nil -} - -func getCompleteParams(t *rt.Thread, c *rt.GoCont) (string, string, []string, error) { - if err := c.CheckNArgs(3); err != nil { - return "", "", []string{}, err - } - query, err := c.StringArg(0) - if err != nil { - return "", "", []string{}, err - } - ctx, err := c.StringArg(1) - if err != nil { - return "", "", []string{}, err - } - fields, err := c.TableArg(2) - if err != nil { - return "", "", []string{}, err - } - - var fds []string - nextVal := rt.NilValue - for { - next, val, ok := fields.Next(nextVal) - if next == rt.NilValue { - break - } - nextVal = next - - valStr, ok := val.TryString() - if !ok { - continue - } - - fds = append(fds, valStr) - } - - return query, ctx, fds, err -} - func setVimMode(mode string) { util.SetField(l, hshMod, "vimMode", rt.StringValue(mode), "Current Vim mode of Hilbish (nil if not in Vim mode)") hooks.Em.Emit("hilbish.vimMode", mode) @@ -395,21 +326,11 @@ func hlappendPath(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { // check if dir is a table or a string if arg.Type() == rt.TableType { - nextVal := rt.NilValue - for { - next, val, ok := arg.AsTable().Next(nextVal) - if next == rt.NilValue { - break + util.ForEach(arg.AsTable(), func(k rt.Value, v rt.Value) { + if v.Type() == rt.StringType { + appendPath(v.AsString()) } - nextVal = next - - valStr, ok := val.TryString() - if !ok { - continue - } - - appendPath(valStr) - } + }) } else if arg.Type() == rt.StringType { appendPath(arg.AsString()) } else { diff --git a/complete.go b/complete.go index 04f9095..68f5d67 100644 --- a/complete.go +++ b/complete.go @@ -1,9 +1,14 @@ package main import ( + "errors" "path/filepath" "strings" "os" + + "hilbish/util" + + rt "github.com/arnodel/golua/runtime" ) func fileComplete(query, ctx string, fields []string) ([]string, string) { @@ -111,3 +116,101 @@ func escapeFilename(fname string) string { r := strings.NewReplacer(args...) return r.Replace(fname) } + +func callLuaCompleter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { + if err := c.CheckNArgs(4); err != nil { + return nil, err + } + completer, err := c.StringArg(0) + if err != nil { + return nil, err + } + query, err := c.StringArg(1) + if err != nil { + return nil, err + } + ctx, err := c.StringArg(2) + if err != nil { + return nil, err + } + fields, err := c.TableArg(3) + if err != nil { + return nil, err + } + + var completecb *rt.Closure + var ok bool + if completecb, ok = luaCompletions[completer]; !ok { + return nil, errors.New("completer " + completer + " does not exist") + } + + // we must keep the holy 80 cols + completerReturn, err := rt.Call1(l.MainThread(), + rt.FunctionValue(completecb), rt.StringValue(query), + rt.StringValue(ctx), rt.TableValue(fields)) + + if err != nil { + return nil, err + } + + return c.PushingNext1(t.Runtime, completerReturn), nil +} + +func luaFileComplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { + query, ctx, fds, err := getCompleteParams(t, c) + if err != nil { + return nil, err + } + + completions, _ := fileComplete(query, ctx, fds) + luaComps := rt.NewTable() + + for i, comp := range completions { + luaComps.Set(rt.IntValue(int64(i + 1)), rt.StringValue(comp)) + } + + return c.PushingNext1(t.Runtime, rt.TableValue(luaComps)), nil +} + +func luaBinaryComplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { + query, ctx, fds, err := getCompleteParams(t, c) + if err != nil { + return nil, err + } + + completions, _ := binaryComplete(query, ctx, fds) + luaComps := rt.NewTable() + + for i, comp := range completions { + luaComps.Set(rt.IntValue(int64(i + 1)), rt.StringValue(comp)) + } + + return c.PushingNext1(t.Runtime, rt.TableValue(luaComps)), nil +} + +func getCompleteParams(t *rt.Thread, c *rt.GoCont) (string, string, []string, error) { + if err := c.CheckNArgs(3); err != nil { + return "", "", []string{}, err + } + query, err := c.StringArg(0) + if err != nil { + return "", "", []string{}, err + } + ctx, err := c.StringArg(1) + if err != nil { + return "", "", []string{}, err + } + fields, err := c.TableArg(2) + if err != nil { + return "", "", []string{}, err + } + + var fds []string + util.ForEach(fields, func(k rt.Value, v rt.Value) { + if v.Type() == rt.StringType { + fds = append(fds, v.AsString()) + } + }) + + return query, ctx, fds, err +} diff --git a/rl.go b/rl.go index 8093273..cd1f4eb 100644 --- a/rl.go +++ b/rl.go @@ -34,8 +34,7 @@ func newLineReader(prompt string, noHist bool) *lineReader { case readline.VimKeys: modeStr = "normal" case readline.VimInsert: modeStr = "insert" case readline.VimDelete: modeStr = "delete" - case readline.VimReplaceOnce: - case readline.VimReplaceMany: modeStr = "replace" + case readline.VimReplaceOnce, readline.VimReplaceMany: modeStr = "replace" } setVimMode(modeStr) } @@ -153,71 +152,54 @@ func newLineReader(prompt string, noHist bool) *lineReader { to work on subcommands and subcompletions */ if cmpTbl, ok := luacompleteTable.TryTable(); ok { - nextVal := rt.NilValue - for { - next, val, ok := cmpTbl.Next(nextVal) - if next == rt.NilValue { - break - } - nextVal = next - - _, ok = next.TryInt() - valTbl, okk := val.TryTable() - if !ok || !okk { - // TODO: error? - break + util.ForEach(cmpTbl, func(key rt.Value, val rt.Value) { + if key.Type() != rt.IntType && val.Type() != rt.TableType { + return } + valTbl := val.AsTable() luaCompType := valTbl.Get(rt.StringValue("type")) luaCompItems := valTbl.Get(rt.StringValue("items")) - compType, ok := luaCompType.TryString() - compItems, okk := luaCompItems.TryTable() - if !ok || !okk { - // TODO: error - break + if luaCompType.Type() != rt.StringType && luaCompItems.Type() != rt.TableType { + return } - var items []string + items := []string{} itemDescriptions := make(map[string]string) - nxVal := rt.NilValue - for { - nx, vl, _ := compItems.Next(nxVal) - if nx == rt.NilValue { - break - } - nxVal = nx - if tstr := nx.Type(); tstr == rt.StringType { + util.ForEach(luaCompItems.AsTable(), func(lkey rt.Value, lval rt.Value) { + if keytyp := lkey.Type(); keytyp == rt.StringType { // ['--flag'] = {'description', '--flag-alias'} - nxStr, ok := nx.TryString() - vlTbl, okk := vl.TryTable() - if !ok || !okk { + itemName, ok := lkey.TryString() + vlTbl, okk := lval.TryTable() + if !ok && !okk { // TODO: error - continue + return } - items = append(items, nxStr) + + items = append(items, itemName) itemDescription, ok := vlTbl.Get(rt.IntValue(1)).TryString() if !ok { // TODO: error - continue + return } - itemDescriptions[nxStr] = itemDescription - } else if tstr == rt.IntType { - vlStr, okk := vl.TryString() - if !okk { + itemDescriptions[itemName] = itemDescription + } else if keytyp == rt.IntType { + vlStr, ok := lval.TryString() + if !ok { // TODO: error - continue + return } items = append(items, vlStr) } else { // TODO: error - continue + return } - } + }) var dispType readline.TabDisplayType - switch compType { + switch luaCompType.AsString() { case "grid": dispType = readline.TabDisplayGrid case "list": dispType = readline.TabDisplayList // need special cases, will implement later @@ -231,7 +213,7 @@ func newLineReader(prompt string, noHist bool) *lineReader { TrimSlash: false, NoSpace: true, }) - } + }) } } diff --git a/util/util.go b/util/util.go index b8c267a..c1688e0 100644 --- a/util/util.go +++ b/util/util.go @@ -118,3 +118,17 @@ func HandleStrCallback(t *rt.Thread, c *rt.GoCont) (string, *rt.Closure, error) return name, cb, err } + +// ForEach loops through a Lua table. +func ForEach(tbl *rt.Table, cb func(key rt.Value, val rt.Value)) { + nextVal := rt.NilValue + for { + key, val, _ := tbl.Next(nextVal) + if key == rt.NilValue { + break + } + nextVal = key + + cb(key, val) + } +}