comp checkpoint

This commit is contained in:
sawka 2022-11-10 15:28:39 -08:00
parent 055dc7c8ac
commit 2ab8795643
3 changed files with 98 additions and 37 deletions

View File

@ -1081,7 +1081,7 @@ func makeInsertUpdateFromComps(pos int64, prefix string, comps []string, hasMore
if hasMore { if hasMore {
return nil return nil
} }
lcp := longestPrefix(prefix, comps) lcp := utilfn.LongestPrefix(prefix, comps)
if lcp == prefix || len(lcp) < len(prefix) || !strings.HasPrefix(lcp, prefix) { if lcp == prefix || len(lcp) < len(prefix) || !strings.HasPrefix(lcp, prefix) {
return nil return nil
} }
@ -1090,35 +1090,6 @@ func makeInsertUpdateFromComps(pos int64, prefix string, comps []string, hasMore
return sstore.ModelUpdate{CmdLine: clu} return sstore.ModelUpdate{CmdLine: clu}
} }
func longestPrefix(root string, comps []string) string {
if len(comps) == 0 {
return root
}
if len(comps) == 1 {
comp := comps[0]
if len(comp) >= len(root) && strings.HasPrefix(comp, root) {
if strings.HasSuffix(comp, "/") {
return comps[0]
}
return comps[0] + " "
}
}
lcp := comps[0]
for i := 1; i < len(comps); i++ {
s := comps[i]
for j := 0; j < len(lcp); j++ {
if j >= len(s) || lcp[j] != s[j] {
lcp = lcp[0:j]
break
}
}
}
if len(lcp) < len(root) || !strings.HasPrefix(lcp, root) {
return root
}
return lcp
}
func simpleCompMeta(ctx context.Context, prefix string, compCtx comp.CompContext, args []interface{}) (*comp.CompReturn, error) { func simpleCompMeta(ctx context.Context, prefix string, compCtx comp.CompContext, args []interface{}) (*comp.CompReturn, error) {
compsCmd, _ := comp.DoSimpleComp(ctx, "command", prefix, compCtx, nil) compsCmd, _ := comp.DoSimpleComp(ctx, "command", prefix, compCtx, nil)
compsMeta, _ := simpleCompCommandMeta(ctx, prefix, compCtx, nil) compsMeta, _ := simpleCompCommandMeta(ctx, prefix, compCtx, nil)

View File

@ -43,9 +43,9 @@ type CompContext struct {
ForDisplay bool ForDisplay bool
} }
type SimpleCompPoint struct { type StrWithPos struct {
Word string Str string
Pos int Pos int
} }
type fullCompPrefix struct { type fullCompPrefix struct {
@ -130,7 +130,10 @@ func compQuoteString(s string, quoteType string, close bool) string {
return rtn return rtn
} }
if quoteType == QuoteTypeSQ { if quoteType == QuoteTypeSQ {
rtn := utilfn.ShellQuote(s, true, MaxCompQuoteLen) rtn := utilfn.ShellQuote(s, false, MaxCompQuoteLen)
if len(rtn) > 0 && rtn[0] != '\'' {
rtn = "'" + rtn + "'"
}
if !close { if !close {
rtn = rtn[0 : len(rtn)-1] rtn = rtn[0 : len(rtn)-1]
} }
@ -185,18 +188,46 @@ func (p *CompPoint) getCompPrefix() string {
return shexec.SimpleExpandPartialWord(shexec.SimpleExpandContext{}, partialWordStr, false) return shexec.SimpleExpandPartialWord(shexec.SimpleExpandContext{}, partialWordStr, false)
} }
func (p *CompPoint) extendWord(newWord string, newWordComplete bool) (string, int) { func (p *CompPoint) extendWord(newWord string, newWordComplete bool) StrWithPos {
pword := p.Words[p.CompWord] pword := p.Words[p.CompWord]
wordStr := p.wordAsStr(pword) wordStr := p.wordAsStr(pword)
quotePref := getQuoteTypePref(wordStr) quotePref := getQuoteTypePref(wordStr)
needsClose := newWordComplete && (len(wordStr) == p.CompWordPos) needsClose := newWordComplete && (len(wordStr) == p.CompWordPos)
wordSuffix := wordStr[p.CompWordPos:] wordSuffix := wordStr[p.CompWordPos:]
newQuotedStr := compQuoteString(newWord, quotePref, needsClose) newQuotedStr := compQuoteString(newWord, quotePref, needsClose)
if needsClose && wordSuffix == "" { if needsClose && wordSuffix == "" && !strings.HasSuffix(newWord, "/") {
newQuotedStr = newQuotedStr + " " newQuotedStr = newQuotedStr + " "
} }
newPos := len(newQuotedStr) newPos := len(newQuotedStr)
return newQuotedStr + wordSuffix, newPos return StrWithPos{Str: newQuotedStr + wordSuffix, Pos: newPos}
}
func (p *CompPoint) FullyExtend(crtn *CompReturn) StrWithPos {
if crtn == nil || crtn.HasMore {
return StrWithPos{Str: p.getOrigStr(), Pos: p.getOrigPos()}
}
compStrs := crtn.getCompStrs()
compPrefix := p.getCompPrefix()
lcp := utilfn.LongestPrefix(compPrefix, compStrs)
if lcp == compPrefix || len(lcp) < len(compPrefix) || !strings.HasPrefix(lcp, compPrefix) {
return StrWithPos{Str: p.getOrigStr(), Pos: p.getOrigPos()}
}
newStr := p.extendWord(lcp, utilfn.ContainsStr(compStrs, lcp))
var buf bytes.Buffer
buf.WriteString(p.Prefix)
for idx, w := range p.Words {
if idx == p.CompWord {
buf.WriteString(w.Prefix)
buf.WriteString(newStr.Str)
} else {
buf.WriteString(w.Prefix)
buf.WriteString(p.wordAsStr(w))
}
}
buf.WriteString(p.Suffix)
compWord := p.Words[p.CompWord]
newPos := len(p.Prefix) + compWord.Offset + len(compWord.Prefix) + newStr.Pos
return StrWithPos{Str: buf.String(), Pos: newPos}
} }
func (p *CompPoint) dump() { func (p *CompPoint) dump() {
@ -223,6 +254,10 @@ func (p *CompPoint) dump() {
var SimpleCompGenFns map[string]SimpleCompGenFnType var SimpleCompGenFns map[string]SimpleCompGenFnType
func (sp StrWithPos) String() string {
return strWithCursor(sp.Str, sp.Pos)
}
func strWithCursor(str string, pos int) string { func strWithCursor(str string, pos int) string {
if pos < 0 { if pos < 0 {
return "[*]_" + str return "[*]_" + str
@ -384,3 +419,20 @@ func CombineCompReturn(c1 *CompReturn, c2 *CompReturn) *CompReturn {
SortCompReturnEntries(&rtn) SortCompReturnEntries(&rtn)
return &rtn return &rtn
} }
func (c *CompReturn) getCompStrs() []string {
rtn := make([]string, len(c.Entries))
for idx, entry := range c.Entries {
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
}
func (p CompPoint) getOrigStr() string {
return p.Prefix + p.StmtStr + p.Suffix
}

View File

@ -74,3 +74,41 @@ func ShellQuote(val string, forceQuote bool, maxLen int) string {
return rtn return rtn
} }
} }
func LongestPrefix(root string, strs []string) string {
if len(strs) == 0 {
return root
}
if len(strs) == 1 {
comp := strs[0]
if len(comp) >= len(root) && strings.HasPrefix(comp, root) {
if strings.HasSuffix(comp, "/") {
return strs[0]
}
return strs[0]
}
}
lcp := strs[0]
for i := 1; i < len(strs); i++ {
s := strs[i]
for j := 0; j < len(lcp); j++ {
if j >= len(s) || lcp[j] != s[j] {
lcp = lcp[0:j]
break
}
}
}
if len(lcp) < len(root) || !strings.HasPrefix(lcp, root) {
return root
}
return lcp
}
func ContainsStr(strs []string, test string) bool {
for _, s := range strs {
if s == test {
return true
}
}
return false
}