From fece037f453006c83c45825e3649495180eb30c9 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Wed, 25 Mar 2026 13:22:16 +0800 Subject: Split Unix completion script entry into separate bash/zsh/fish versions --- scripts/deploy/completions/bash.sh | 90 +++++++++++++++--------------------- scripts/deploy/completions/fish.fish | 76 ++++++++++++++++++++++++------ scripts/deploy/completions/zsh.sh | 48 ------------------- scripts/deploy/completions/zsh.zsh | 48 +++++++++++++++++++ 4 files changed, 145 insertions(+), 117 deletions(-) delete mode 100644 scripts/deploy/completions/zsh.sh create mode 100644 scripts/deploy/completions/zsh.zsh (limited to 'scripts/deploy/completions') diff --git a/scripts/deploy/completions/bash.sh b/scripts/deploy/completions/bash.sh index e1b2a31..a9a3263 100644 --- a/scripts/deploy/completions/bash.sh +++ b/scripts/deploy/completions/bash.sh @@ -1,65 +1,47 @@ #!/usr/bin/env bash _jvn_bash_completion() { - local cur prev words cword - - local line="${COMP_LINE}" - local point="${COMP_POINT}" - - if [ "${point}" -gt "${#line}" ]; then - point="${#line}" - fi - - words=($line) - cword=0 - - local i=0 - local pos=0 - for word in "${words[@]}"; do - local word_start=$pos - local word_end=$((pos + ${#word})) - - if [ "${point}" -ge "${word_start}" ] && [ "${point}" -le "${word_end}" ]; then - cword=$i - cur="${word}" - break - fi - - pos=$((pos + ${#word} + 1)) - i=$((i + 1)) + local cur="${COMP_WORDS[COMP_CWORD]}" + local prev="" + [ $COMP_CWORD -gt 0 ] && prev="${COMP_WORDS[COMP_CWORD-1]}" + + local word_index=$((COMP_CWORD + 1)) + + local args=() + args+=(-f="${COMP_LINE//-/^}") + args+=(-C="$COMP_POINT") + args+=(-w="${cur//-/^}") + args+=(-p="${prev//-/^}") + args+=(-c="${COMP_WORDS[0]//-/^}") + args+=(-i="$word_index") + + for word in "${COMP_WORDS[@]}"; do + args+=(-a="${word//-/^}") done - if [ "${point}" -gt "${pos}" ]; then - cword=${#words[@]} - cur="" - fi - - if [ "${cword}" -gt 0 ]; then - prev="${words[$((cword-1))]}" - else - prev="" - fi - - local args=( - -f "${COMP_LINE//-/^}" - -C "$COMP_POINT" - -w "${cur//-/^}" - -p "${prev//-/^}" - -c "${words[0]}" - -i "$cword" - -a "${words[@]//-/^}" - ) - local suggestions if suggestions=$(jvn_comp "${args[@]}" 2>/dev/null); then - if [ "$suggestions" = "_file_" ]; then - compopt -o default - COMPREPLY=() - else - mapfile -t COMPREPLY < <(printf '%s\n' "$suggestions") + if [ $? -eq 0 ]; then + if [ "$suggestions" = "_file_" ]; then + compopt -o default + COMPREPLY=() + return + fi + + if [ -n "$suggestions" ]; then + local -a all_suggestions filtered + mapfile -t all_suggestions < <(printf '%s\n' "$suggestions") + + for suggestion in "${all_suggestions[@]}"; do + [ -z "$cur" ] || [[ "$suggestion" == "$cur"* ]] && filtered+=("$suggestion") + done + + [ ${#filtered[@]} -gt 0 ] && COMPREPLY=("${filtered[@]}") + return + fi fi - else - COMPREPLY=() fi + + COMPREPLY=() } complete -F _jvn_bash_completion jvn diff --git a/scripts/deploy/completions/fish.fish b/scripts/deploy/completions/fish.fish index 558b602..eb2c2df 100644 --- a/scripts/deploy/completions/fish.fish +++ b/scripts/deploy/completions/fish.fish @@ -4,6 +4,7 @@ function __jvn_fish_complete set -l buffer (commandline -b) set -l cursor (commandline -C) + # Calculate current word and word index set -l current_word "" set -l previous_word "" set -l word_index 0 @@ -11,7 +12,10 @@ function __jvn_fish_complete for i in (seq (count $cmdline)) set word $cmdline[$i] - set char_count (math $char_count + (string length "$word") + 1) + if test $i -gt 1 + set char_count (math $char_count + 1) + end + set char_count (math $char_count + (string length -- "$word")) if test $cursor -le $char_count set word_index $i @@ -23,21 +27,63 @@ function __jvn_fish_complete end end - set -l args \ - -f (string replace -a - ^ -- "$buffer") \ - -C "$cursor" \ - -w (string replace -a - ^ -- "$current_word") \ - -p (string replace -a - ^ -- "$previous_word") \ - -c "$cmdline[1]" \ - -i "$word_index" \ - -a (string replace -a - ^ -- "$cmdline") - - set -l output (jvn_comp $args 2>/dev/null) - if test "$output" = "_file_" - __fish_complete_path "$current_word" + # Handle cursor after last word + if test $word_index -eq 0 -a (count $cmdline) -gt 0 + set word_index (count $cmdline) + set current_word "" + set previous_word $cmdline[-1] + end + + # Ensure word_index is within bounds + if test $word_index -gt (count $cmdline) + set word_index (count $cmdline) + end + + # Replace hyphens with carets for jvn_comp + set -l buffer_replaced (string replace -a "-" "^" -- "$buffer") + set -l current_word_replaced (string replace -a "-" "^" -- "$current_word") + set -l previous_word_replaced (string replace -a "-" "^" -- "$previous_word") + + # Build args array + set -l args + set -a args -f "$buffer_replaced" -C "$cursor" -w "$current_word_replaced" -p "$previous_word_replaced" + + if test (count $cmdline) -gt 0 + set -a args -c "$cmdline[1]" else - printf "%s\n" $output + set -a args -c "" + end + + set -a args -i "$word_index" + + # Replace hyphens in all words + if test (count $cmdline) -gt 0 + set -l all_words_replaced + for word in $cmdline + set -a all_words_replaced (string replace -a "-" "^" -- "$word") + end + set -a args -a $all_words_replaced + else + set -a args -a "" + end + + # Call jvn_comp and handle output + set -l output + if not jvn_comp $args 2>/dev/null | read -z output + return + end + + set -l trimmed_output (string trim -- "$output") + if test "$trimmed_output" = "_file_" + __fish_complete_path "$current_word" + return 0 + else if test -n "$trimmed_output" + string split -n \n -- "$output" | while read -l line + test -n "$line" && echo "$line" + end + return 0 end + return 1 end -complete -c jvn -a '(__jvn_fish_complete)' +complete -c jvn -a '(__jvn_fish_complete)' -f diff --git a/scripts/deploy/completions/zsh.sh b/scripts/deploy/completions/zsh.sh deleted file mode 100644 index dd1ff38..0000000 --- a/scripts/deploy/completions/zsh.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env zsh -_jvn_completion() { - local -a args - local suggestions - - local buffer="$BUFFER" - local cursor="$CURSOR" - local current_word="${words[$CURRENT]}" - local previous_word="" - local command_name="${words[1]}" - local word_index="$CURRENT" - - if [[ $CURRENT -gt 1 ]]; then - previous_word="${words[$((CURRENT-1))]}" - fi - - args=( - -f "${buffer//-/^}" - -C "$cursor" - -w "${current_word//-/^}" - -p "${previous_word//-/^}" - -c "$command_name" - -i "$word_index" - -a "${(@)words//-/^}" - ) - - suggestions=$(jvn_comp "${args[@]}" 2>/dev/null) - - if [[ $? -eq 0 ]] && [[ -n "$suggestions" ]]; then - local -a completions - completions=(${(f)suggestions}) - - if [[ "${completions[1]}" == "_file_" ]]; then - shift completions - _files - elif (( $+functions[_describe] )); then - _describe 'jvn commands' completions - else - compadd -a completions - fi - fi -} - -compdef _jvn_completion jvn - -if [[ $? -ne 0 ]]; then - compctl -K _jvn_completion jvn -fi diff --git a/scripts/deploy/completions/zsh.zsh b/scripts/deploy/completions/zsh.zsh new file mode 100644 index 0000000..dd1ff38 --- /dev/null +++ b/scripts/deploy/completions/zsh.zsh @@ -0,0 +1,48 @@ +#!/usr/bin/env zsh +_jvn_completion() { + local -a args + local suggestions + + local buffer="$BUFFER" + local cursor="$CURSOR" + local current_word="${words[$CURRENT]}" + local previous_word="" + local command_name="${words[1]}" + local word_index="$CURRENT" + + if [[ $CURRENT -gt 1 ]]; then + previous_word="${words[$((CURRENT-1))]}" + fi + + args=( + -f "${buffer//-/^}" + -C "$cursor" + -w "${current_word//-/^}" + -p "${previous_word//-/^}" + -c "$command_name" + -i "$word_index" + -a "${(@)words//-/^}" + ) + + suggestions=$(jvn_comp "${args[@]}" 2>/dev/null) + + if [[ $? -eq 0 ]] && [[ -n "$suggestions" ]]; then + local -a completions + completions=(${(f)suggestions}) + + if [[ "${completions[1]}" == "_file_" ]]; then + shift completions + _files + elif (( $+functions[_describe] )); then + _describe 'jvn commands' completions + else + compadd -a completions + fi + fi +} + +compdef _jvn_completion jvn + +if [[ $? -ne 0 ]]; then + compctl -K _jvn_completion jvn +fi -- cgit