WIP: Waifufetch by JGH0 working in windows-bash

This commit is contained in:
Cametendo
2026-05-28 21:00:34 +02:00
parent 114cbf43bd
commit 7b3a101946
8 changed files with 1354 additions and 105 deletions

View File

@@ -70,7 +70,10 @@ func splitPipe(input string) []string {
current.WriteByte(c)
case c == '|' && !inSingle && !inDouble && parenDepth == 0:
if i+1 < len(input) && input[i+1] == '|' {
current.WriteByte(c) // part of ||, pass through
// || operator — pass both chars through
current.WriteByte(c)
current.WriteByte(input[i+1])
i++
} else {
parts = append(parts, strings.TrimSpace(current.String()))
current.Reset()
@@ -87,6 +90,63 @@ func splitPipe(input string) []string {
return parts
}
// parseArrayAssign detects NAME=(...) or NAME+=(...) at start of input.
func (s *Shell) parseArrayAssign(input string) (name string, appendMode bool, elements []string, ok bool) {
input = strings.TrimSpace(input)
// Read identifier
i := 0
for i < len(input) && isVarChar(input[i]) {
i++
}
if i == 0 {
return
}
name = input[:i]
if !isValidIdentifier(name) {
return
}
// Optional +
if i < len(input) && input[i] == '+' {
appendMode = true
i++
}
// Require =
if i >= len(input) || input[i] != '=' {
return
}
i++
// Require (
if i >= len(input) || input[i] != '(' {
return
}
i++
// Find matching )
depth := 1
j := i
inSingle := false
inDouble := false
for j < len(input) && depth > 0 {
c := input[j]
switch {
case c == '\'' && !inDouble:
inSingle = !inSingle
case c == '"' && !inSingle:
inDouble = !inDouble
case c == '(' && !inSingle && !inDouble:
depth++
case c == ')' && !inSingle && !inDouble:
depth--
}
if depth > 0 {
j++
}
}
content := input[i:j]
elements = s.tokenize(content)
ok = true
return
}
// executeCommand executes a single command (no pipes, no &&/||).
func (s *Shell) executeCommand(input string) error {
input = strings.TrimSpace(input)
@@ -94,12 +154,22 @@ func (s *Shell) executeCommand(input string) error {
return nil
}
// Detect array assignment NAME=(...) or NAME+=(...)
if name, appendMode, elems, ok := s.parseArrayAssign(input); ok {
if appendMode {
s.appendArray(name, elems)
} else {
s.setArray(name, elems)
}
return nil
}
tokens := s.tokenize(input)
if len(tokens) == 0 {
return nil
}
cmdArgs, redirects := extractRedirects(tokens)
cmdArgs, redirects := s.extractRedirects(tokens)
if len(cmdArgs) == 0 {
// Pure redirection, e.g. "> file" creates/truncates file
return s.withRedirects(redirects, func() error { return nil })
@@ -132,7 +202,7 @@ func (s *Shell) executeCommand(input string) error {
})
}
func extractRedirects(tokens []string) ([]string, []redirect) {
func (s *Shell) extractRedirects(tokens []string) ([]string, []redirect) {
var args []string
var redirects []redirect
@@ -194,11 +264,24 @@ func extractRedirects(tokens []string) ([]string, []redirect) {
case strings.HasPrefix(tok, ">") && len(tok) > 1:
redirects = append(redirects, redirect{1, ">", tok[1:]})
i++
// < (stdin)
// < (stdin) — also handle process substitution <(...)
case tok == "<":
if i+1 < len(tokens) {
redirects = append(redirects, redirect{0, "<", tokens[i+1]})
i += 2
next := tokens[i+1]
// Process substitution: < <(cmd)
if strings.HasPrefix(next, "<(") && strings.HasSuffix(next, ")") {
cmd := next[2 : len(next)-1]
tmpf, err := os.CreateTemp("", "procsub*")
if err == nil {
s.withIO(nil, tmpf, nil, func() error { return s.Execute(cmd) })
tmpf.Close()
redirects = append(redirects, redirect{0, "<", tmpf.Name()})
}
i += 2
} else {
redirects = append(redirects, redirect{0, "<", next})
i += 2
}
} else {
i++
}
@@ -296,7 +379,7 @@ func (s *Shell) executeCommandBg(input string) error {
if len(tokens) == 0 {
return nil
}
cmdArgs, _ := extractRedirects(tokens)
cmdArgs, _ := s.extractRedirects(tokens)
if len(cmdArgs) == 0 {
return nil
}