ITADN

Support per-shell custom completion functions

#6404Openheaths 创建于 2026-06-06
C-enhancementA-completionS-triage
H
heathscommented
### Please complete the following tasks - [x] I have searched the [discussions](https://github.com/clap-rs/clap/discussions) - [x] I have searched the [open](https://github.com/clap-rs/clap/issues) and [rejected](https://github.com/clap-rs/clap/issues?q=is%3Aissue+label%3AS-wont-fix+is%3Aclosed) issues ### Clap Version 3.2.2 ### Describe your use case I use custom layouts frequently with [zellij](https://github.com/zellij-org/zellij) and wanted to enumerate files in its layouts directory if an obvious relative file path wasn't specified. Looking at the docs for `ValueHint`, I don't see a way to do this. I made the following changes to the generated one from homebrew: ```diff 0a1,34 > _zellij_complete_layouts() { > local current layouts_dir layout > local -a layouts > > current="${1}" > > if [[ "${current}" == */* || "${current}" == .* || "${current}" == ~* || "${current}" == *.kdl* ]] ; then > compopt -o filenames +o default +o bashdefault 2>/dev/null > COMPREPLY=($(compgen -f -- "${current}")) > return 0 > fi > > compopt +o default +o bashdefault 2>/dev/null > > layouts_dir="${XDG_CONFIG_HOME:-${HOME}/.config}/zellij/layouts" > if [[ -d "${layouts_dir}" ]] ; then > local old_nullglob > old_nullglob="$(shopt -p nullglob)" > shopt -s nullglob > for layout in "${layouts_dir}"/*.kdl > do > layout="${layout##*/}" > layouts+=("${layout%.kdl}") > done > eval "${old_nullglob}" > fi > > COMPREPLY=() > for layout in "${layouts[@]}" > do > [[ "${layout}" == "${current}"* ]] && COMPREPLY+=("${layout}") > done > } > 331c365 < COMPREPLY=($(compgen -f "${cur}")) --- > _zellij_complete_layouts "${cur}" 335c369 < COMPREPLY=($(compgen -f "${cur}")) --- > _zellij_complete_layouts "${cur}" 343c377 < COMPREPLY=($(compgen -f "${cur}")) --- > _zellij_complete_layouts "${cur}" 1177c1211 < COMPREPLY=($(compgen -f "${cur}")) --- > _zellij_complete_layouts "${cur}" 1181c1215 < COMPREPLY=($(compgen -f "${cur}")) --- > _zellij_complete_layouts "${cur}" 1243c1277 < if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then --- > if [[ ${cur} == -* ]] ; then 1246a1281,1284 > if [[ ${COMP_CWORD} -eq 3 ]] ; then > _zellij_complete_layouts "${cur}" > return 0 > fi 1829c1867 < COMPREPLY=($(compgen -f "${cur}")) --- > _zellij_complete_layouts "${cur}" 1833c1871 < COMPREPLY=($(compgen -f "${cur}")) --- > _zellij_complete_layouts "${cur}" 2187c2225 < COMPREPLY=($(compgen -f "${cur}")) --- > _zellij_complete_layouts "${cur}" 2583c2621 < COMPREPLY=($(compgen -f "${cur}")) --- > _zellij_complete_layouts "${cur}" ``` Seems to work like I want, though may not be perfect - unrelated issue, though. ### Describe the solution you'd like I appreciate these can't easily be generated, though maybe there are some common patterns someone could specify with additional `ValueHint` variants, but the main idea I was thinking was a `ValueHint` that lets you supply a custom expression. It would be up to author to define those, like dumping extra functions per-shell like https://github.com/zellij-org/zellij/blob/e9173cba163506491becbeacad162315d6e8f726/zellij-utils/src/setup.rs#L559-L572 So maybe something like a `ValueHint::Expression(Cow<'static, str>)`. That said, I'm not very experienced with completions to know if a single expression could be good enough for all of them. If not, maybe this hypothetical `Expression` variant needs to take a struct with members for each supported shell's expression that works for the shell. That's really the only questionable part, it seems, since apps can inject function definitions per-shell fairly easily as linked above in Zellij. ### Alternatives, if applicable If there are 1 or a few common patterns like this - enumerating files in a particular directory - maybe those common shell-specific functions could be still be generated e.g., given a relative path under `$XDG_CONFIG_HOME` (which, as appropriate for each shell, could default to `$HOME/.config`), functions to enumerate some pattern could be generated e.g., ```rust ValueHint::BasenamesUnderConfigDir("zellij/layouts", "*.kdl") ``` ### Additional Context _No response_
1 条评论