Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kamel 1.5.1 CLI generates broken zsh completions #2622

Closed
DylanSale opened this issue Sep 8, 2021 · 1 comment
Closed

Kamel 1.5.1 CLI generates broken zsh completions #2622

DylanSale opened this issue Sep 8, 2021 · 1 comment
Milestone

Comments

@DylanSale
Copy link

DylanSale commented Sep 8, 2021

I did brew install kamel (on MacOS 11.5.2):

==> Downloading https://ghcr.io/v2/homebrew/core/kamel/manifests/1.5.1
Already downloaded: /Users/dylan/Library/Caches/Homebrew/downloads/9342e8dbc1d75c099d6e3bcada1150e31f2a0176c62de74b73bfbcc30727b413--kamel-1.5.1.bottle_manifest.json
==> Downloading https://ghcr.io/v2/homebrew/core/kamel/blobs/sha256:247f124ed56b
Already downloaded: /Users/dylan/Library/Caches/Homebrew/downloads/2221fae4f84c4f4d2c4cfcfe5c49137c79e561229b6247f774b630c8bea07a54--kamel--1.5.1.big_sur.bottle.tar.gz
==> Reinstalling kamel
==> Pouring kamel--1.5.1.big_sur.bottle.tar.gz
==> Caveats
zsh completions have been installed to:
  /usr/local/share/zsh/site-functions
==> Summary
🍺  /usr/local/Cellar/kamel/1.5.1: 9 files, 67.3MB

then when I type kamel <TAB> it outputs: kamel Error:\ unknown\ command\ \"__complete\"\ for\ \"kamel\"

Here is the debug log file:

========= starting completion logic ==========
CURRENT: 2, words[*]: kamel __complete
Truncated words[*]: kamel __complete,
lastParam: __complete, lastChar: e
About to call: eval kamel __complete __complete
completion output: Error: unknown command "__complete" for "kamel"
last line: Error: unknown command "__complete" for "kamel"
No directive found.  Setting do default
directive: 0
completions: Error: unknown command "__complete" for "kamel"
flagPrefix:
Adding completion: Error\: unknown command "__complete" for "kamel"

This is my generated _kamel completion file:

> cat /usr/local/share/zsh/site-functions/_kamel                                                                                                                                                                                                                                                   
#compdef _kamel kamel

# zsh completion for kamel                                -*- shell-script -*-

__kamel_debug()
{
    local file="$BASH_COMP_DEBUG_FILE"
    if [[ -n ${file} ]]; then
        echo "$*" >> "${file}"
    fi
}

_kamel()
{
    local shellCompDirectiveError=1
    local shellCompDirectiveNoSpace=2
    local shellCompDirectiveNoFileComp=4
    local shellCompDirectiveFilterFileExt=8
    local shellCompDirectiveFilterDirs=16

    local lastParam lastChar flagPrefix requestComp out directive compCount comp lastComp
    local -a completions

    __kamel_debug "\n========= starting completion logic =========="
    __kamel_debug "CURRENT: ${CURRENT}, words[*]: ${words[*]}"

    # The user could have moved the cursor backwards on the command-line.
    # We need to trigger completion from the $CURRENT location, so we need
    # to truncate the command-line ($words) up to the $CURRENT location.
    # (We cannot use $CURSOR as its value does not work when a command is an alias.)
    words=("${=words[1,CURRENT]}")
    __kamel_debug "Truncated words[*]: ${words[*]},"

    lastParam=${words[-1]}
    lastChar=${lastParam[-1]}
    __kamel_debug "lastParam: ${lastParam}, lastChar: ${lastChar}"

    # For zsh, when completing a flag with an = (e.g., kamel -n=<TAB>)
    # completions must be prefixed with the flag
    setopt local_options BASH_REMATCH
    if [[ "${lastParam}" =~ '-.*=' ]]; then
        # We are dealing with a flag with an =
        flagPrefix="-P ${BASH_REMATCH}"
    fi

    # Prepare the command to obtain completions
    requestComp="${words[1]} __complete ${words[2,-1]}"
    if [ "${lastChar}" = "" ]; then
        # If the last parameter is complete (there is a space following it)
        # We add an extra empty parameter so we can indicate this to the go completion code.
        __kamel_debug "Adding extra empty parameter"
        requestComp="${requestComp} \"\""
    fi

    __kamel_debug "About to call: eval ${requestComp}"

    # Use eval to handle any environment variables and such
    out=$(eval ${requestComp} 2>/dev/null)
    __kamel_debug "completion output: ${out}"

    # Extract the directive integer following a : from the last line
    local lastLine
    while IFS='\n' read -r line; do
        lastLine=${line}
    done < <(printf "%s\n" "${out[@]}")
    __kamel_debug "last line: ${lastLine}"

    if [ "${lastLine[1]}" = : ]; then
        directive=${lastLine[2,-1]}
        # Remove the directive including the : and the newline
        local suffix
        (( suffix=${#lastLine}+2))
        out=${out[1,-$suffix]}
    else
        # There is no directive specified.  Leave $out as is.
        __kamel_debug "No directive found.  Setting do default"
        directive=0
    fi

    __kamel_debug "directive: ${directive}"
    __kamel_debug "completions: ${out}"
    __kamel_debug "flagPrefix: ${flagPrefix}"

    if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then
        __kamel_debug "Completion received error. Ignoring completions."
        return
    fi

    compCount=0
    while IFS='\n' read -r comp; do
        if [ -n "$comp" ]; then
            # If requested, completions are returned with a description.
            # The description is preceded by a TAB character.
            # For zsh's _describe, we need to use a : instead of a TAB.
            # We first need to escape any : as part of the completion itself.
            comp=${comp//:/\\:}

            local tab=$(printf '\t')
            comp=${comp//$tab/:}

            ((compCount++))
            __kamel_debug "Adding completion: ${comp}"
            completions+=${comp}
            lastComp=$comp
        fi
    done < <(printf "%s\n" "${out[@]}")

    if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
        # File extension filtering
        local filteringCmd
        filteringCmd='_files'
        for filter in ${completions[@]}; do
            if [ ${filter[1]} != '*' ]; then
                # zsh requires a glob pattern to do file filtering
                filter="\*.$filter"
            fi
            filteringCmd+=" -g $filter"
        done
        filteringCmd+=" ${flagPrefix}"

        __kamel_debug "File filtering command: $filteringCmd"
        _arguments '*:filename:'"$filteringCmd"
    elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then
        # File completion for directories only
        local subDir
        subdir="${completions[1]}"
        if [ -n "$subdir" ]; then
            __kamel_debug "Listing directories in $subdir"
            pushd "${subdir}" >/dev/null 2>&1
        else
            __kamel_debug "Listing directories in ."
        fi

        _arguments '*:dirname:_files -/'" ${flagPrefix}"
        if [ -n "$subdir" ]; then
            popd >/dev/null 2>&1
        fi
    elif [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ] && [ ${compCount} -eq 1 ]; then
        __kamel_debug "Activating nospace."
        # We can use compadd here as there is no description when
        # there is only one completion.
        compadd -S '' "${lastComp}"
    elif [ ${compCount} -eq 0 ]; then
        if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then
            __kamel_debug "deactivating file completion"
        else
            # Perform file completion
            __kamel_debug "activating file completion"
            _arguments '*:filename:_files'" ${flagPrefix}"
        fi
    else
        _describe "completions" completions $(echo $flagPrefix)
    fi
}

# don't run the completion function when being source-ed or eval-ed
if [ "$funcstack[1]" = "_kamel" ]; then
	_kamel
fi
@nicolaferraro nicolaferraro added this to the 1.6.1 milestone Sep 8, 2021
@nicolaferraro nicolaferraro modified the milestones: 1.6.1, 1.7.0 Oct 23, 2021
@nicolaferraro nicolaferraro modified the milestones: 1.7.0, 1.8.0 Nov 15, 2021
@oscerd oscerd modified the milestones: 1.8.0, 1.9.0 Jan 19, 2022
@github-actions
Copy link
Contributor

This issue has been automatically marked as stale due to 90 days of inactivity.
It will be closed if no further activity occurs within 15 days.
If you think that’s incorrect or the issue should never stale, please simply write any comment.
Thanks for your contributions!

@oscerd oscerd modified the milestones: 1.9.0, 1.9.1 Apr 26, 2022
@oscerd oscerd modified the milestones: 1.9.1, 1.9.2 May 13, 2022
@oscerd oscerd modified the milestones: 1.9.2, 2.0.0 May 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants