Skip to content

Multi-line help text is not handled correctly in fish #3043

@kidonng

Description

@kidonng

Multi-line help text (e.g. help="\b\nAttachment with explicit mimetype,\n--at image.jpg image/jpeg") causes error when doing shell completion in fish.

How to replicate

From simonw/llm:

@click.option(
    "attachment_types",
    "--at",
    "--attachment-type",
    type=(str, str),
    multiple=True,
    callback=attachment_types_callback,
    help="\b\nAttachment with explicit mimetype,\n--at image.jpg image/jpeg",
)

Type llm --, then press Tab to complete, observe the following error output:

$ llm --
string split: --at image.jpg image/jpeg: unknown option

/opt/homebrew/share/fish/vendor_completions.d/llm.fish (line 1):
string split "," $completion
^
in command substitution
	called on line 5 of file /opt/homebrew/share/fish/vendor_completions.d/llm.fish
in function '_llm_completion'
in command substitution

(Type 'help string' for related documentation)
test: Missing argument at index 3
= dir
      ^
/opt/homebrew/share/fish/vendor_completions.d/llm.fish (line 7):
        if test $metadata[1] = "dir";
           ^
in function '_llm_completion'
in command substitution
test: Missing argument at index 3
= file
       ^
/opt/homebrew/share/fish/vendor_completions.d/llm.fish (line 9):
        else if test $metadata[1] = "file";
                ^
in function '_llm_completion'
in command substitution
test: Missing argument at index 3
= plain
        ^
/opt/homebrew/share/fish/vendor_completions.d/llm.fish (line 11):
        else if test $metadata[1] = "plain";
                ^
in function '_llm_completion'
in command substitution
string split: --at image.jpg image/jpeg: unknown option

/opt/homebrew/share/fish/vendor_completions.d/llm.fish (line 1):
string split "," $completion
^
in command substitution
	called on line 5 of file /opt/homebrew/share/fish/vendor_completions.d/llm.fish
in function '_llm_completion'
in command substitution

(Type 'help string' for related documentation)
test: Missing argument at index 3
= dir
      ^
/opt/homebrew/share/fish/vendor_completions.d/llm.fish (line 7):
        if test $metadata[1] = "dir";
           ^
in function '_llm_completion'
in command substitution
test: Missing argument at index 3
= file
       ^
/opt/homebrew/share/fish/vendor_completions.d/llm.fish (line 9):
        else if test $metadata[1] = "file";
                ^
in function '_llm_completion'
in command substitution
test: Missing argument at index 3
= plain
        ^
/opt/homebrew/share/fish/vendor_completions.d/llm.fish (line 11):
        else if test $metadata[1] = "plain";
                ^
in function '_llm_completion'
in command substitution

Analysis

Obtaining raw completion from click:

$ env _LLM_COMPLETE=fish_complete COMP_WORDS='llm --' COMP_CWORD='--' llm
plain,--system	System prompt to use
plain,--model	Model to use
plain,--database	Path to log database
plain,--query	Use first model matching these strings
plain,--attachment	Attachment path or URL or -
plain,--at
Attachment with explicit mimetype,
--at image.jpg image/jpeg
plain,--attachment-type
Attachment with explicit mimetype,
--at image.jpg image/jpeg
plain,--tool	Name of a tool to make available to the model
plain,--functions	Python code block or file path defining functions to register as tools
plain,--td	Show full details of tool executions
plain,--tools-debug	Show full details of tool executions
plain,--ta	Manually approve every tool execution
plain,--tools-approve	Manually approve every tool execution
plain,--cl	How many chained tool responses to allow, default 5, set 0 for unlimited
plain,--chain-limit	How many chained tool responses to allow, default 5, set 0 for unlimited
plain,--option	key/value options for the model
plain,--schema	JSON schema, filepath or ID
plain,--schema-multi	JSON schema to use for multiple results
plain,--fragment	Fragment (alias, URL, hash or file path) to add to the prompt
plain,--sf	Fragment to add to system prompt
plain,--system-fragment	Fragment to add to system prompt
plain,--template	Template to use
plain,--param	Parameters for template
plain,--no-stream	Do not stream output
plain,--no-log	Don't log to database
plain,--log	Log prompt and response to the database
plain,--continue	Continue the most recent conversation.
plain,--cid	Continue the conversation with the given ID.
plain,--conversation	Continue the conversation with the given ID.
plain,--key	API key to use
plain,--save	Save prompt with this template name
plain,--async	Run prompt asynchronously
plain,--usage	Show token usage
plain,--extract	Extract first fenced code block
plain,--xl	Extract last fenced code block
plain,--extract-last	Extract last fenced code block
plain,--help	Show this message and exit.

Observe that option with multi-line help text is not escaped/handled:

plain,--at
Attachment with explicit mimetype,
--at image.jpg image/jpeg
plain,--attachment-type
Attachment with explicit mimetype,
--at image.jpg image/jpeg

Which causes unexpected arguments passed to string split, causing the error:

set -l metadata (string split "," $completion);

Environment

  • Python version: 3.13.7
  • Click version: 8.2.1
  • Fish version: 4.0.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions