diff --git a/src/main/antlr/Vimscript.g4 b/src/main/antlr/Vimscript.g4 index fe1efb73a..9eae5a705 100644 --- a/src/main/antlr/Vimscript.g4 +++ b/src/main/antlr/Vimscript.g4 @@ -63,13 +63,13 @@ finallyBlock: (WS | COLON)* FINALLY WS* ((inline_comment NEW_LINE) | ( ; functionDefinition: - (WS | COLON)* FUNCTION (replace = EXCLAMATION)? WS+ (SID | SNR)? (anyCaseNameWithDigitsAndUnderscores NUM)* (functionScope COLON)? (functionName | (literalDictionaryKey (DOT literalDictionaryKey)+)) WS* L_PAREN WS* argumentsDeclaration R_PAREN WS* (functionFlag WS*)* ((inline_comment NEW_LINE) | (NEW_LINE | BAR)+) + (WS | COLON)* FUNCTION (replace = EXCLAMATION)? WS+ (SID | SNR)? (anyCaseNameWithDigitsAndUnderscores NUM)* (functionScope COLON)? (functionName | (literalDictionaryKey (DOT literalDictionaryKey)+)) WS* L_PAREN WS* argumentsDeclaration WS* R_PAREN WS* (functionFlag WS*)* ((inline_comment NEW_LINE) | (NEW_LINE | BAR)+) blockMember* (WS | COLON)* ENDFUNCTION WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR)) ; functionFlag: RANGE | ABORT | DICT | CLOSURE; -argumentsDeclaration: (ETC | (variableName (WS* COMMA WS* variableName)* defaultValue* (WS* COMMA WS* ETC WS*)? WS*))?; -defaultValue: WS* COMMA WS* variableName WS* ASSIGN WS* expr; +argumentsDeclaration: (ETC | defaultValue (WS* COMMA WS* defaultValue)* (WS* COMMA WS* ETC WS*)? | (variableName (WS* COMMA WS* variableName)* (WS* COMMA WS* defaultValue)* (WS* COMMA WS* ETC WS*)?))?; +defaultValue: variableName WS* ASSIGN WS* expr; autoCmd: (WS | COLON)* AUTOCMD commandArgument = ~(NEW_LINE)*? NEW_LINE; diff --git a/test/org/jetbrains/plugins/ideavim/ex/implementation/statements/FunctionDeclarationTest.kt b/test/org/jetbrains/plugins/ideavim/ex/implementation/statements/FunctionDeclarationTest.kt index 0ddf1f7bc..791d1a814 100644 --- a/test/org/jetbrains/plugins/ideavim/ex/implementation/statements/FunctionDeclarationTest.kt +++ b/test/org/jetbrains/plugins/ideavim/ex/implementation/statements/FunctionDeclarationTest.kt @@ -541,6 +541,46 @@ class FunctionDeclarationTest : VimTestCase() { typeText(commandToKeys("delf! F1")) } + fun `test only optional arguments`() { + configureByText("\n") + typeText( + commandToKeys( + "" + + "function GetOptionalArgs(...) |" + + " return a:000 | " + + "endfunction" + ) + ) + typeText(commandToKeys("echo GetOptionalArgs()")) + assertExOutput("[]\n") + typeText( + commandToKeys( + "echo GetOptionalArgs(42, 'optional arg')" + ) + ) + assertExOutput("[42, 'optional arg']\n") + + typeText(commandToKeys("delfunction! GetOptionalArgs")) + } + + fun `test only default arguments`() { + configureByText("\n") + typeText( + commandToKeys( + "" + + "function GetDefaultArgs(a = 10, b = 20) |" + + " return [a:a, a:b] | " + + "endfunction" + ) + ) + typeText(commandToKeys("echo GetDefaultArgs()")) + assertExOutput("[10, 20]\n") + typeText(commandToKeys("echo GetDefaultArgs(42, 'optional arg')")) + assertExOutput("[42, 'optional arg']\n") + + typeText(commandToKeys("delfunction! GetDefaultArgs")) + } + fun `test optional arguments`() { configureByText("\n") typeText(