From d347d89dfeef54d648ffdea054897617c0016509 Mon Sep 17 00:00:00 2001 From: salmonik Date: Sat, 6 Jun 2026 19:48:22 +0300 Subject: correctly working auto completion for db --- completions/_rsp | 67 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 30 deletions(-) (limited to 'completions/_rsp') diff --git a/completions/_rsp b/completions/_rsp index 1ddc1fe..9bf0579 100644 --- a/completions/_rsp +++ b/completions/_rsp @@ -1,55 +1,62 @@ -# Dynamic completion overrides for rsp play/queue arguments. - # Save clap-generated function so we can delegate non-dynamic cases. functions[_rsp_clap]=$functions[_rsp] _rsp() { case $words[2] in play|queue) - _rsp_complete_args - ;; - *) - _rsp_clap "$@" + if (( CURRENT > 2 )); then + _rsp_complete_args + return 0 + fi ;; esac + _rsp_clap "$@" } _rsp_complete_args() { setopt localoptions setopt nobanghist - # Reconstruct full query from all argument words after subcommand. - # This handles spaces in names (e.g. "Master of Puppets") that get - # split across multiple $words entries when backslash escaping breaks. local -a args=("${(@)words[3,$CURRENT]}") local cur="${(j: :)args}" + local cur_clean="${cur//\\/}" local -a suggestions - local n_slashes=${#cur//[^\/]/} - case $n_slashes in - 0) suggestions=(${(f)"$(rsp db-complete artists "$cur" 2>/dev/null)"}) ;; - 1) suggestions=(${(f)"$(rsp db-complete albums "$cur" 2>/dev/null)"}) ;; - *) suggestions=(${(f)"$(rsp db-complete tracks "$cur" 2>/dev/null)"}) ;; - esac - # display: what the user sees in the completion menu (raw values) - local -a display=("${suggestions[@]}") - # vals: what gets inserted (with ZSH backslash escaping + ! escape) - local -a vals=() - local slash_idx=$cur[(I)/] - local s + suggestions=("${(@f)"$(rsp db-complete "$cur" 2>/dev/null)"}") + # Filter out empty entries (e.g. from empty command output) + local -a filtered=() for s in "${suggestions[@]}"; do - local esc="${(q)s:gs/\!/\\\!/}" - if (( slash_idx )); then - local dir_part=$cur[1,$slash_idx] - local edir="${(q)dir_part:gs/\!/\\\!/}" - vals+=("${edir}${esc}") - else - vals+=("${esc}") + if [[ -n "$s" ]]; then + filtered+=("$s") fi done + suggestions=("${filtered[@]}") if (( ${#suggestions} )); then + local noslash="${cur_clean//\/}" + local n_slashes=$(( ${#cur_clean} - ${#noslash} )) + local -a display=() + local -a vals=() + for s in "${suggestions[@]}"; do + vals+=("$s") + if [[ "$cur_clean" == */ ]]; then + local stripped="$s" + local i=0 + while (( i < n_slashes )); do + stripped="${stripped#*/}" + (( i++ )) + done + display+=("$stripped") + else + display+=("$s") + fi + done + if (( ${#suggestions} > 1 )); then + compstate[insert]=menu + fi if [[ ${vals[1]} == */ ]]; then - compadd -U -S '' -d display -- "${vals[@]}" + compadd -U -S '' -M 'm:{a-z}={A-Z} l:|=*' -d display -- "${vals[@]}" else - compadd -U -d display -- "${vals[@]}" + compadd -U -M 'm:{a-z}={A-Z} l:|=*' -d display -- "${vals[@]}" fi + else + compadd -U -S '' fi } -- cgit v1.2.3