Skip to content

Conversation

the-13th-letter
Copy link
Contributor

@the-13th-letter the-13th-letter commented Jan 17, 2025

The Zsh completion script uses different primitives to load completion items into Zsh depending on whether a completion item has a description or not.

  • For items with descriptions, the Zsh _describe function is used, which expects item plus description pairs as values, separated by a colon. In turn, any colon within the item must be escaped.
  • For items without descriptions, the Zsh compadd builtin is used, which expects literal items, without escaping. Actually escaping colons in the item will corrupt the item.

click's built-in Zsh completion class does not escape colons in the item. So it only handles the second case correctly, not the first; see e.g. #2703. This PR fixes this by choosing a suitable serialization, for each item separately, according to the abovementioned escaping requirements.

Since at its core this is an issue of two systems not agreeing on the format for exchanging data, and since we principally control both systems, we could fix this on either side. However, because the Zsh completion script is typically already installed in the user's shell, which is both harder to detect within click and harder to change or influence, we opt to change the click side instead, even if it the serialization needs to be more irregular.

Resolves #2703


  • Add tests that demonstrate the correct behavior of the change. Tests should fail without the change.
  • Add or update relevant docs, in the docs folder and in code.
    • “docs“ presumably not applicable in this case?
  • Add an entry in CHANGES.rst summarizing the change and linking to the issue.
  • Add .. versionchanged:: entries in any relevant code docs.
    • Not applicable in this case?

@Rowlando13
Copy link
Collaborator

Thanks for taking the time to submit this PR. We will review this.

@the-13th-letter the-13th-letter force-pushed the fix-zsh-completion-colon-escaping branch from 866b128 to 11a1428 Compare March 20, 2025 17:46
@the-13th-letter the-13th-letter changed the base branch from release-8.2.0 to main March 20, 2025 17:46
@the-13th-letter
Copy link
Contributor Author

Rebased onto and retargeted to main, since release-8.2.0 looks pretty dead to me. I used this opportunity to also add some TLDR-style inline commentary to the patch, and fix some other commentary typos.

@Rowlando13 Rowlando13 added this to the 8.2.1 milestone May 10, 2025
@davidism davidism modified the milestones: 8.2.1, 8.2.2 May 14, 2025
@AndreasBackx
Copy link
Collaborator

Apologies for the delay. This looks pretty good, but it's a bit hard to review. We'd ideally need some way to create tests for autocomplete. Does anyone know how we could possibly trigger autocomplete? If so, we might be able to use scrut to create a test for it.

I think it should be fine with just a note in the changes and if that's done, we can merge this afaik.

Copy link
Collaborator

@AndreasBackx AndreasBackx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See previous comment, a nitpick and otherwise just CHANGES that needs an addition.

Comment on lines 375 to 389
""""""
# See issue #1812 and issue #2703 for further context. (TL;DR:
# colons sometimes need special handling.)
#
# Items *with* help are registered with zsh's `_describe`, which
# splits off the help/description after the first colon. So
# escape all colons in item.value so that they arrive intact.
#
# Items *without* help are registered with zsh's `compadd`,
# which does no colon handling. So do *not* escape colons in
# item.value, lest the completions themselves ultimately get
# mangled.
#
# Finally, there is no functional difference between using an
# empty help and using "_" as help.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean this up a tad perhaps? It'd be nice to have this explained in-line if possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commentary rewritten in the current iteration of this PR.

Copy link
Collaborator

@AndreasBackx AndreasBackx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meant to click request changes, woopsie!

@the-13th-letter the-13th-letter force-pushed the fix-zsh-completion-colon-escaping branch from 11a1428 to 6111c55 Compare May 18, 2025 16:08
@the-13th-letter
Copy link
Contributor Author

Rebased onto stable as of today, and attempted to clean up the inline commentary as requested.

Apologies for the delay. This looks pretty good, but it's a bit hard to review. We'd ideally need some way to create tests for autocomplete. Does anyone know how we could possibly trigger autocomplete? If so, we might be able to use scrut to create a test for it.

Can't help you there, sorry. To test my submission, I did write a small < 50-line click application that completed filenames manually, sometimes adding help texts, sometimes even with colons, and then interactively tab-completed arguments in a zsh session, in a directory with specially-prepared filenames. This isn't very generalizable to other test uses, and the triggering of tab completion was still manual.

@davidism davidism changed the base branch from main to stable May 18, 2025 16:46
@Rowlando13 Rowlando13 deleted the branch pallets:stable July 16, 2025 06:23
@Rowlando13 Rowlando13 closed this Jul 16, 2025
@Rowlando13 Rowlando13 reopened this Jul 16, 2025
@Rowlando13 Rowlando13 modified the milestones: 8.2.2, 8.2.3 Jul 16, 2025
@AndreasBackx AndreasBackx force-pushed the fix-zsh-completion-colon-escaping branch from 791aad9 to 22718de Compare July 21, 2025 19:25
@AndreasBackx
Copy link
Collaborator

I've rebased this on stable. Then I've removed the ZSH template check, I'm not sure why we're checking the output of the ZSH completion here. We only really care about the output, don't we? Let me know in case I missed something. Otherwise this seems good to land if CI is good.

@AndreasBackx AndreasBackx merged commit a1235aa into pallets:stable Jul 21, 2025
10 checks passed
@Rowlando13 Rowlando13 modified the milestones: 8.2.3, 8.2.2 Jul 22, 2025
@kdeldycke kdeldycke added the bug label Jul 22, 2025
@kdeldycke kdeldycke added the f:completion feature: shell completion label Jul 22, 2025
Rowlando13 pushed a commit to Rowlando13/click that referenced this pull request Jul 30, 2025
Resolves pallets#2846.

Co-authored-by: Andreas Backx <andreas@backx.org>
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 6, 2025
@the-13th-letter the-13th-letter deleted the fix-zsh-completion-colon-escaping branch August 28, 2025 20:03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug f:completion feature: shell completion
Projects
None yet
Development

Successfully merging this pull request may close these issues.

zsh completion still misbehaving in the presence of :
5 participants