WIP: Waifufetch by JGH0 working in windows-bash
This commit is contained in:
@@ -60,12 +60,7 @@ func historyFile() string {
|
||||
func interactive() error {
|
||||
sh := shell.New()
|
||||
|
||||
// Build completer
|
||||
completer := readline.NewPrefixCompleter(
|
||||
readline.PcItemDynamic(func(line string) []string {
|
||||
return dynamicComplete(sh, line)
|
||||
}),
|
||||
)
|
||||
completer := &shellCompleter{sh: sh}
|
||||
|
||||
rl, err := readline.NewEx(&readline.Config{
|
||||
HistoryFile: historyFile(),
|
||||
@@ -183,6 +178,56 @@ func buildPrompt(sh *shell.Shell) string {
|
||||
return pwd + suffix
|
||||
}
|
||||
|
||||
// shellCompleter implements readline.AutoCompleter.
|
||||
// readline's built-in PrefixCompleter matches candidates against the full
|
||||
// line, so "C:\workspace" never matches "cd C:\w". This implementation
|
||||
// extracts the last token and returns only the suffix to append.
|
||||
type shellCompleter struct{ sh *shell.Shell }
|
||||
|
||||
func (c *shellCompleter) Do(line []rune, pos int) (newLine [][]rune, offset int) {
|
||||
lineStr := string(line[:pos])
|
||||
last := lastToken(lineStr)
|
||||
for _, comp := range dynamicComplete(c.sh, lineStr) {
|
||||
if !strings.HasPrefix(comp, last) {
|
||||
continue
|
||||
}
|
||||
suffix := []rune(comp[len(last):])
|
||||
// Add a trailing space for non-directory completions.
|
||||
if len(suffix) > 0 && suffix[len(suffix)-1] != '/' && suffix[len(suffix)-1] != '\\' {
|
||||
suffix = append(suffix, ' ')
|
||||
}
|
||||
newLine = append(newLine, suffix)
|
||||
}
|
||||
return newLine, len([]rune(last))
|
||||
}
|
||||
|
||||
// lastToken returns the last whitespace-delimited token from s,
|
||||
// respecting single and double quotes.
|
||||
func lastToken(s string) string {
|
||||
if strings.HasSuffix(s, " ") || strings.HasSuffix(s, "\t") {
|
||||
return ""
|
||||
}
|
||||
inSingle, inDouble := false, false
|
||||
start := 0
|
||||
for i := 0; i < len(s); i++ {
|
||||
switch s[i] {
|
||||
case '\'':
|
||||
if !inDouble {
|
||||
inSingle = !inSingle
|
||||
}
|
||||
case '"':
|
||||
if !inSingle {
|
||||
inDouble = !inDouble
|
||||
}
|
||||
case ' ', '\t':
|
||||
if !inSingle && !inDouble {
|
||||
start = i + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return s[start:]
|
||||
}
|
||||
|
||||
// dynamicComplete provides tab completion for commands and paths.
|
||||
func dynamicComplete(sh *shell.Shell, line string) []string {
|
||||
line = strings.TrimLeft(line, " \t")
|
||||
@@ -241,7 +286,7 @@ func dynamicComplete(sh *shell.Shell, line string) []string {
|
||||
if strings.HasPrefix(name, base) {
|
||||
p := filepath.Join(dir, name)
|
||||
if e.IsDir() {
|
||||
p += "/"
|
||||
p += string(filepath.Separator)
|
||||
}
|
||||
completions = append(completions, p)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user