add ShlexSplit() as an alternative to shlex.Split()

This commit is contained in:
koba1t
2025-07-12 07:24:16 +09:00
parent 042a2cf177
commit b6128950c9
2 changed files with 68 additions and 22 deletions

View File

@@ -5,15 +5,55 @@ package execplugin
import (
"fmt"
shlex "github.com/carapace-sh/carapace-shlex"
"strings"
"unicode"
)
// ShlexSplit splits a string into a slice of strings using shell-style rules for quoting and commenting
// Similar to Python's shlex.split with comments enabled
func ShlexSplit(s string) ([]string, error) {
// return shlexSplit(s)
tokens, err := shlex.Split(s)
if err != nil {
return nil, fmt.Errorf("shlex split error: %w", err)
}
return tokens.Strings(), nil
return shlexSplit(s)
}
func shlexSplit(s string) ([]string, error) {
result := []string{}
var current strings.Builder
var quote rune
var escaped bool
for _, r := range s {
switch {
case escaped:
current.WriteRune(r)
escaped = false
case r == '\\' && quote != '\'':
escaped = true
case (r == '\'' || r == '"') && quote == 0:
quote = r
case r == quote:
quote = 0
case r == '#' && quote == 0:
// Comment starts, ignore the rest of the line
if current.Len() > 0 {
result = append(result, current.String())
}
return result, nil
case quote == 0 && unicode.IsSpace(r):
if current.Len() > 0 {
result = append(result, current.String())
current.Reset()
}
default:
current.WriteRune(r)
}
}
if quote != 0 {
return nil, fmt.Errorf("unclosed quote in string")
}
if current.Len() > 0 {
result = append(result, current.String())
}
return result, nil
}