Only count it as a naked invocation at the end of the "file"

This is a weird confusion between the "end" and "terminate" token
types.

"end" is the end of the "line" - a newline or ";".

"terminate" is the end of the "file" - like pressing newline
interactively or having the file end.

So this would count things like `if` and `switch` as a "help"
invocation even if followed by a newline, e.g.

```fish
if; echo foo
```

and

```fish
switch
case foo
```

The result of that was that a naked "if" in a script file isn't an
error, but doesn't start a block either, so if you complete the block
it would count the "end" as superfluous, which sends you on a bit of a
hunt to figure out where the block start is missing.
This commit is contained in:
Fabian Boehm
2025-05-01 14:51:30 +02:00
parent bf0a30b9a8
commit f7bde1354d
2 changed files with 4 additions and 5 deletions

View File

@@ -3580,8 +3580,7 @@ fn new_decorated_statement(slf: &mut Populator<'_>) -> StatementVariant {
let naked_invocation_invokes_help =
![ParseKeyword::Begin, ParseKeyword::End].contains(&self.peek_token(0).keyword);
if naked_invocation_invokes_help
&& [ParseTokenType::end, ParseTokenType::terminate]
.contains(&self.peek_token(1).typ)
&& [ParseTokenType::terminate].contains(&self.peek_token(1).typ)
{
return new_decorated_statement(self);
}

View File

@@ -66,9 +66,9 @@ switch
echo banana
end
'
#CHECKERR: fish: 'case' builtin not inside of switch block
#CHECKERR: case a
#CHECKERR: ^~~^
# CHECKERR: fish: Expected a string, but found end of the statement
# CHECKERR: switch
# CHECKERR: ^
set smurf green