summary refs log tree commit diff
path: root/vendor/github.com/chzyer/readline/complete_segment.go
diff options
context:
space:
mode:
authorEmile <git@emile.space>2024-10-25 15:55:50 +0200
committerEmile <git@emile.space>2024-10-25 15:55:50 +0200
commitc90f36e3dd179d2de96f4f5fe38d8dc9a9de6dfe (patch)
tree89e9afb41c5bf76f48cfb09305a2d3db8d302b06 /vendor/github.com/chzyer/readline/complete_segment.go
parent98bbb0f559a8883bc47bae80607dbe326a448e61 (diff)
vendor HEAD main
Diffstat (limited to 'vendor/github.com/chzyer/readline/complete_segment.go')
-rw-r--r--vendor/github.com/chzyer/readline/complete_segment.go82
1 files changed, 82 insertions, 0 deletions
diff --git a/vendor/github.com/chzyer/readline/complete_segment.go b/vendor/github.com/chzyer/readline/complete_segment.go
new file mode 100644
index 0000000..5ceadd8
--- /dev/null
+++ b/vendor/github.com/chzyer/readline/complete_segment.go
@@ -0,0 +1,82 @@
+package readline
+
+type SegmentCompleter interface {
+	// a
+	// |- a1
+	// |--- a11
+	// |- a2
+	// b
+	// input:
+	//   DoTree([], 0) [a, b]
+	//   DoTree([a], 1) [a]
+	//   DoTree([a, ], 0) [a1, a2]
+	//   DoTree([a, a], 1) [a1, a2]
+	//   DoTree([a, a1], 2) [a1]
+	//   DoTree([a, a1, ], 0) [a11]
+	//   DoTree([a, a1, a], 1) [a11]
+	DoSegment([][]rune, int) [][]rune
+}
+
+type dumpSegmentCompleter struct {
+	f func([][]rune, int) [][]rune
+}
+
+func (d *dumpSegmentCompleter) DoSegment(segment [][]rune, n int) [][]rune {
+	return d.f(segment, n)
+}
+
+func SegmentFunc(f func([][]rune, int) [][]rune) AutoCompleter {
+	return &SegmentComplete{&dumpSegmentCompleter{f}}
+}
+
+func SegmentAutoComplete(completer SegmentCompleter) *SegmentComplete {
+	return &SegmentComplete{
+		SegmentCompleter: completer,
+	}
+}
+
+type SegmentComplete struct {
+	SegmentCompleter
+}
+
+func RetSegment(segments [][]rune, cands [][]rune, idx int) ([][]rune, int) {
+	ret := make([][]rune, 0, len(cands))
+	lastSegment := segments[len(segments)-1]
+	for _, cand := range cands {
+		if !runes.HasPrefix(cand, lastSegment) {
+			continue
+		}
+		ret = append(ret, cand[len(lastSegment):])
+	}
+	return ret, idx
+}
+
+func SplitSegment(line []rune, pos int) ([][]rune, int) {
+	segs := [][]rune{}
+	lastIdx := -1
+	line = line[:pos]
+	pos = 0
+	for idx, l := range line {
+		if l == ' ' {
+			pos = 0
+			segs = append(segs, line[lastIdx+1:idx])
+			lastIdx = idx
+		} else {
+			pos++
+		}
+	}
+	segs = append(segs, line[lastIdx+1:])
+	return segs, pos
+}
+
+func (c *SegmentComplete) Do(line []rune, pos int) (newLine [][]rune, offset int) {
+
+	segment, idx := SplitSegment(line, pos)
+
+	cands := c.DoSegment(segment, idx)
+	newLine, offset = RetSegment(segment, cands, idx)
+	for idx := range newLine {
+		newLine[idx] = append(newLine[idx], ' ')
+	}
+	return newLine, offset
+}