From 90bcb09b3e2875afe42269f5377105e272301875 Mon Sep 17 00:00:00 2001 From: sawka Date: Thu, 10 Nov 2022 18:51:20 -0800 Subject: [PATCH] hook up new command completion --- pkg/cmdrunner/cmdrunner.go | 87 +++++++++++++++++++++++--------------- pkg/comp/comp.go | 26 +++++++++--- pkg/comp/simplecomp.go | 7 ++- pkg/sstore/updatebus.go | 4 +- 4 files changed, 82 insertions(+), 42 deletions(-) diff --git a/pkg/cmdrunner/cmdrunner.go b/pkg/cmdrunner/cmdrunner.go index 71d9aef4..17edd0b4 100644 --- a/pkg/cmdrunner/cmdrunner.go +++ b/pkg/cmdrunner/cmdrunner.go @@ -1077,23 +1077,14 @@ func makeInfoFromComps(compType string, comps []string, hasMore bool) sstore.Upd return update } -func makeInsertUpdateFromComps(pos int64, prefix string, comps []string, hasMore bool) sstore.UpdatePacket { - if hasMore { - return nil - } - lcp := utilfn.LongestPrefix(prefix, comps) - if lcp == prefix || len(lcp) < len(prefix) || !strings.HasPrefix(lcp, prefix) { - return nil - } - insertChars := lcp[len(prefix):] - clu := &sstore.CmdLineType{InsertChars: insertChars, InsertPos: pos} - return sstore.ModelUpdate{CmdLine: clu} -} - func simpleCompMeta(ctx context.Context, prefix string, compCtx comp.CompContext, args []interface{}) (*comp.CompReturn, error) { - compsCmd, _ := comp.DoSimpleComp(ctx, "command", prefix, compCtx, nil) - compsMeta, _ := simpleCompCommandMeta(ctx, prefix, compCtx, nil) - return comp.CombineCompReturn(compsCmd, compsMeta), nil + if strings.HasPrefix(prefix, "/") { + compsCmd, _ := comp.DoSimpleComp(ctx, comp.CGTypeCommand, prefix, compCtx, nil) + compsMeta, _ := simpleCompCommandMeta(ctx, prefix, compCtx, nil) + return comp.CombineCompReturn(comp.CGTypeCommandMeta, compsCmd, compsMeta), nil + } else { + return comp.DoSimpleComp(ctx, comp.CGTypeCommand, prefix, compCtx, nil) + } } func simpleCompCommandMeta(ctx context.Context, prefix string, compCtx comp.CompContext, args []interface{}) (*comp.CompReturn, error) { @@ -1158,7 +1149,13 @@ func doCompGen(ctx context.Context, pk *scpacket.FeCommandPacketType, prefix str return comps, hasMore, nil } +// func DoCompGen(ctx context.Context, sp StrWithPos, compCtx CompContext) (*CompReturn, *StrWithPos, error) + func CompGenCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) { + ids, err := resolveUiIds(ctx, pk, 0) // best-effort + if err != nil { + return nil, fmt.Errorf("/compgen error: %w", err) + } cmdLine := firstArg(pk) pos := len(cmdLine) if pk.Kwargs["comppos"] != "" { @@ -1175,28 +1172,52 @@ func CompGenCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (ssto pos = len(cmdLine) } showComps := resolveBool(pk.Kwargs["compshow"], false) - prefix := cmdLine[:pos] - parts := strings.Split(prefix, " ") - compType := "file" - if len(parts) > 0 && len(parts) < 2 && strings.HasPrefix(parts[0], "/") { - compType = "metacommand" - } else if len(parts) == 2 && (parts[0] == "cd" || parts[0] == "/cd") { - compType = "directory" - } else if len(parts) <= 1 { - compType = "command" + cmdSP := comp.StrWithPos{Str: cmdLine, Pos: pos} + compCtx := comp.CompContext{} + if ids.Remote != nil { + rptr := ids.Remote.RemotePtr + compCtx.RemotePtr = &rptr + compCtx.State = ids.Remote.RemoteState } - lastPart := "" - if len(parts) > 0 { - lastPart = parts[len(parts)-1] - } - comps, hasMore, err := doCompGen(ctx, pk, lastPart, compType, showComps) + compCtx.ForDisplay = showComps + crtn, newSP, err := comp.DoCompGen(ctx, cmdSP, compCtx) if err != nil { return nil, err } - if showComps { - return makeInfoFromComps(compType, comps, hasMore), nil + if crtn == nil { + return nil, fmt.Errorf("no return value from DoCompGen") } - return makeInsertUpdateFromComps(int64(pos), lastPart, comps, hasMore), nil + if showComps || newSP == nil { + compStrs := crtn.GetCompDisplayStrs() + return makeInfoFromComps(crtn.CompType, compStrs, crtn.HasMore), nil + } + update := sstore.ModelUpdate{ + CmdLine: &sstore.CmdLineType{CmdLine: newSP.Str, CursorPos: newSP.Pos}, + } + return update, nil + + // prefix := cmdLine[:pos] + // parts := strings.Split(prefix, " ") + // compType := "file" + // if len(parts) > 0 && len(parts) < 2 && strings.HasPrefix(parts[0], "/") { + // compType = "metacommand" + // } else if len(parts) == 2 && (parts[0] == "cd" || parts[0] == "/cd") { + // compType = "directory" + // } else if len(parts) <= 1 { + // compType = "command" + // } + // lastPart := "" + // if len(parts) > 0 { + // lastPart = parts[len(parts)-1] + // } + // comps, hasMore, err := doCompGen(ctx, pk, lastPart, compType, showComps) + // if err != nil { + // return nil, err + // } + // if showComps { + // return makeInfoFromComps(compType, comps, hasMore), nil + // } + // return makeInsertUpdateFromComps(int64(pos), lastPart, comps, hasMore), nil } func CommentCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) { diff --git a/pkg/comp/comp.go b/pkg/comp/comp.go index 7714c474..b446450d 100644 --- a/pkg/comp/comp.go +++ b/pkg/comp/comp.go @@ -43,7 +43,7 @@ const ( ) type CompContext struct { - RemotePtr sstore.RemotePtrType + RemotePtr *sstore.RemotePtrType State *packet.ShellState ForDisplay bool } @@ -76,8 +76,9 @@ type CompEntry struct { } type CompReturn struct { - Entries []CompEntry - HasMore bool + CompType string + Entries []CompEntry + HasMore bool } func compQuoteDQString(s string, close bool) string { @@ -204,7 +205,7 @@ func (p *CompPoint) FullyExtend(crtn *CompReturn) StrWithPos { if crtn == nil || crtn.HasMore { return StrWithPos{Str: p.getOrigStr(), Pos: p.getOrigPos()} } - compStrs := crtn.getCompStrs() + compStrs := crtn.GetCompStrs() compPrefix := p.getCompPrefix() lcp := utilfn.LongestPrefix(compPrefix, compStrs) if lcp == compPrefix || len(lcp) < len(compPrefix) || !strings.HasPrefix(lcp, compPrefix) { @@ -420,7 +421,7 @@ func SortCompReturnEntries(c *CompReturn) { }) } -func CombineCompReturn(c1 *CompReturn, c2 *CompReturn) *CompReturn { +func CombineCompReturn(compType string, c1 *CompReturn, c2 *CompReturn) *CompReturn { if c1 == nil { return c2 } @@ -428,6 +429,7 @@ func CombineCompReturn(c1 *CompReturn, c2 *CompReturn) *CompReturn { return c1 } var rtn CompReturn + rtn.CompType = compType rtn.HasMore = c1.HasMore || c2.HasMore rtn.Entries = append([]CompEntry{}, c1.Entries...) rtn.Entries = append(rtn.Entries, c2.Entries...) @@ -435,7 +437,7 @@ func CombineCompReturn(c1 *CompReturn, c2 *CompReturn) *CompReturn { return &rtn } -func (c *CompReturn) getCompStrs() []string { +func (c *CompReturn) GetCompStrs() []string { rtn := make([]string, len(c.Entries)) for idx, entry := range c.Entries { rtn[idx] = entry.Word @@ -443,6 +445,18 @@ func (c *CompReturn) getCompStrs() []string { return rtn } +func (c *CompReturn) GetCompDisplayStrs() []string { + rtn := make([]string, len(c.Entries)) + for idx, entry := range c.Entries { + if entry.IsMetaCmd { + rtn[idx] = "^" + entry.Word + } else { + rtn[idx] = entry.Word + } + } + return rtn +} + func (p CompPoint) getOrigPos() int { pword := p.Words[p.CompWord] return len(p.Prefix) + pword.Offset + len(pword.Prefix) + p.CompWordPos diff --git a/pkg/comp/simplecomp.go b/pkg/comp/simplecomp.go index bdc0c5c4..f3b93d07 100644 --- a/pkg/comp/simplecomp.go +++ b/pkg/comp/simplecomp.go @@ -41,7 +41,12 @@ func DoSimpleComp(ctx context.Context, compType string, prefix string, compCtx C if compFn == nil { return nil, fmt.Errorf("no simple comp fn for %q", compType) } - return compFn(ctx, prefix, compCtx, args) + crtn, err := compFn(ctx, prefix, compCtx, args) + if err != nil { + return nil, err + } + crtn.CompType = compType + return crtn, nil } func compsToCompReturn(comps []string, hasMore bool) *CompReturn { diff --git a/pkg/sstore/updatebus.go b/pkg/sstore/updatebus.go index a224ab40..30206451 100644 --- a/pkg/sstore/updatebus.go +++ b/pkg/sstore/updatebus.go @@ -113,8 +113,8 @@ type HistoryInfoType struct { } type CmdLineType struct { - InsertChars string `json:"insertchars"` - InsertPos int64 `json:"insertpos"` + CmdLine string `json:"cmdline"` + CursorPos int `json:"cursorpos"` } type UpdateChannel struct {