Add brace expansion

This commit is contained in:
Sami Samhuri 2026-02-02 21:15:48 -08:00
parent a1410cb5da
commit a323ea89fe
No known key found for this signature in database
2 changed files with 26 additions and 5 deletions

View file

@ -18,11 +18,19 @@ module Shell
protected_line = protect_escaped_dollars(line)
substituted_line = expand_command_substitution(protected_line)
shellsplit(substituted_line)
.map do |word|
expand_variables(word)
.flat_map do |word|
expanded = expand_variables(word)
.tr(ESCAPED_DOLLAR, "$")
.tr(ESCAPED_BACKTICK, "`")
# TODO: expand globs
expand_braces(expanded)
end
.flat_map do |word|
if word =~ /[*?\[]/
glob_words = expand_globs(word)
glob_words.empty? ? [word] : glob_words
else
[word]
end
end
end
@ -268,6 +276,20 @@ module Shell
stdout.tr("\n", " ")
end
def expand_braces(word)
# Simple, non-nested brace expansion: pre{a,b}post -> preapost, prebpost
match = word.match(/(.*?)\{([^{}]*)\}(.*)/)
return [word] unless match
prefix = match[1]
body = match[2]
suffix = match[3]
return [word] unless body.include?(",")
parts = body.split(",", -1)
parts.flat_map { |part| expand_braces(prefix + part + suffix) }
end
def escaped_replacement(char)
case char
when "$"

View file

@ -63,7 +63,6 @@ class ShellTest < Minitest::Test
end
def test_expands_brace_expansion
skip "brace expansion not implemented"
assert_equal "a b", `#{A1_PATH} -c 'echo {a,b}'`.chomp
end
@ -99,7 +98,7 @@ class ShellTest < Minitest::Test
end
def test_does_not_expand_escaped_command_substitution_dollar_paren_in_double_quotes
assert_equal "$(echo hi)", %x(#{A1_PATH} -c 'echo "\\$(echo hi)"').chomp
assert_equal "$(echo hi)", `#{A1_PATH} -c 'echo "\\$(echo hi)"'`.chomp
end
def test_does_not_expand_escaped_command_substitution_backticks_in_double_quotes