diff --git a/src/click/shell_completion.py b/src/click/shell_completion.py index 8f1564c49..4a543f6a6 100644 --- a/src/click/shell_completion.py +++ b/src/click/shell_completion.py @@ -418,7 +418,12 @@ def get_completion_args(self) -> tuple[list[str], str]: def format_completion(self, item: CompletionItem) -> str: if item.help: - return f"{item.type},{item.value}\t{item.help}" + help_ = " ".join( + part.strip() for part in item.help.splitlines() if part.strip() + ) + + if help_: + return f"{item.type},{item.value}\t{help_}" return f"{item.type},{item.value}" diff --git a/tests/test_shell_completion.py b/tests/test_shell_completion.py index 20cff238f..8ac2a4ab2 100644 --- a/tests/test_shell_completion.py +++ b/tests/test_shell_completion.py @@ -370,6 +370,33 @@ def test_full_complete(runner, shell, env, expect): assert result.output == expect +def test_fish_complete_multiline_help(runner): + cli = Command( + "cli", + params=[ + Option( + ["--at"], + help="Attachment with explicit mimetype,\n--at image.jpg image/jpeg", + ) + ], + ) + + result = runner.invoke( + cli, + env={ + "_CLI_COMPLETE": "fish_complete", + "COMP_WORDS": "cli --", + "COMP_CWORD": "--", + }, + ) + + assert ( + result.output + == "plain,--at\tAttachment with explicit mimetype, --at image.jpg image/jpeg\n" + "plain,--help\tShow this message and exit.\n" + ) + + @pytest.mark.parametrize( ("env", "expect"), [