diff --git a/brush-core/src/builtins/brushinfo.rs b/brush-core/src/builtins/brushinfo.rs index 9db907c0..a8175152 100644 --- a/brush-core/src/builtins/brushinfo.rs +++ b/brush-core/src/builtins/brushinfo.rs @@ -15,7 +15,6 @@ pub(crate) struct BrushInfoCommand { enum CommandGroup { #[clap(subcommand)] Process(ProcessCommand), - #[clap(subcommand)] Complete(CompleteCommand), } diff --git a/brush-parser/src/parser.rs b/brush-parser/src/parser.rs index 98a62eb9..9d083d51 100644 --- a/brush-parser/src/parser.rs +++ b/brush-parser/src/parser.rs @@ -534,7 +534,10 @@ peg::parser! { c:compound_command() r:redirect_list()? { ast::FunctionBody(c, r) } rule fname() -> &'input str = - name() + // Special-case: don't allow it to end with an equals sign, to avoid the challenge of + // misinterpreting certain declaration assignments as function definitions. + // TODO: Find a way to make this still work without requiring this targeted exception. + w:[Token::Word(word, _) if !word.ends_with('=')] { w.to_str() } rule brace_group() -> ast::BraceGroupCommand = specific_word("{") c:compound_list() specific_word("}") { ast::BraceGroupCommand(c) } diff --git a/brush-shell/tests/cases/arrays.yaml b/brush-shell/tests/cases/arrays.yaml index f4c8e864..c8398102 100644 --- a/brush-shell/tests/cases/arrays.yaml +++ b/brush-shell/tests/cases/arrays.yaml @@ -284,3 +284,16 @@ cases: ourarray+=("${otherarray[@]/a/x}") declare -p otherarray declare -p ourarray + + - name: "Array declaration in a function" + stdin: | + outer() { + inner=() + if test true; then + echo true + else + echo false + fi + } + + outer diff --git a/brush-shell/tests/cases/functions.yaml b/brush-shell/tests/cases/functions.yaml index 88d03612..ffdea285 100644 --- a/brush-shell/tests/cases/functions.yaml +++ b/brush-shell/tests/cases/functions.yaml @@ -163,3 +163,36 @@ cases: myfunc myvar="overridden" myfunc myfunc + + - name: "Function definition without braces" + stdin: | + myfunc() + if true; then + echo true + else + echo false + fi + + myfunc + + - name: "Nested function definition" + stdin: | + outer() { + echo "Entered outer" + + inner() { + echo "In inner" + } + + echo "Invoking inner" + + inner + + echo "Returning from outer" + } + + echo "Calling outer from toplevel" + outer + + echo "Calling inner from toplevel" + inner