pier-cli / pier

A Linux script management CLI written in Rust
MIT License
536 stars 33 forks source link

Shell completion #42

Open Plommonsorbet opened 4 years ago

Plommonsorbet commented 4 years ago

Pier is lacking shell completions at the moment for all the cli options, however since pier is using clap / structopt this does not seem relatively easy to do.

To start with perhaps we should limit it to bash / zsh just to keep it simple, however it seems like it's possible to generate powershell / fish completions via clap as well.

I'm not sure how well pier works on windows right now at least, but I'd be curious to know.

Useful links:

docs.rs about the shell generation in clap structopt example code for generating shell completions

herbertjones commented 3 years ago

I threw something together for bash, which could be used in the meantime.

__member() { local e; for e in "${@:2}"; do [[ $e = "$1" ]] && return 0; done; return 1; }

_pier()
{
    local cur prev cmd opts config_file
    declare -a config_file_args
    declare -r -a subcommands=(
        add config-init copy edit help list remove run show
    )
    declare -r -a subcommands_aliases=(
        init ls rm
    )
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    if [[ $prev == --config-file ]] ; then
        COMPREPLY=( $(compgen -f -- ${cur}) )
        return 0
    fi

    declare -i i
    for ((i = 0; i < ${#COMP_WORDS[*]}; ++i)); do
        if __member "${COMP_WORDS[$i]}" "${subcommands[@]}" "${subcommands_aliases[@]}"; then
            cmd="${COMP_WORDS[$i]}"
            break
        fi
    done
    for ((i = 2; i < ${#COMP_WORDS[*]}; ++i)); do
        if __member "${COMP_WORDS[$((i-1))]}" --config-file -c; then
            config_file="${COMP_WORDS[$i]}"
            config_file="${config_file/#\~/$HOME}"
            if [[ -e $config_file ]]; then
                config_file_args=(--config-file "${config_file}")
            fi
            break
        fi
    done

    if __member "${cmd}" ls list; then
        opts="--cmd_full --help --list_aliases --cmd_width --tag"

        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi

    if __member "${cmd}" run edit remove rm show copy; then
        opts="--help"

        if [[ $cur == -* ]] ; then
            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
            return 0
        fi

        opts="${opts} $(pier "${config_file_args[@]}" list --list_aliases)"
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi

    if [[ $cmd == add ]]; then
        if [[ $cur == -* ]] ; then
            opts="--help --alias --description --tag"
            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
            return 0
        fi

        # TODO: tag completion

        if ! __member "${prev}" --alias --description --tag; then
            COMPREPLY=( $(compgen -f -- ${cur}) )
            return 0
        fi

        return 0
    fi

    opts="--version --verbose --help --config-file"

    if [[ $cur == -* ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi

    if [[ ! $cmd ]]; then
        opts="add config-init copy edit help list remove run show $(pier "${config_file_args[@]}" list --list_aliases)"
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi
}
complete -F _pier pier
Plommonsorbet commented 3 years ago

Hey,

I tried it out an it seems to work pretty well. However I've been in the process of limiting the scope and my responsibilities in pier so I can focus more on other projects. And shell completions is not something I'm very well versed in writing, so I was thinking about scrapping this issue as it would require a lot of involvement for me to maintain.

However if you feel up to taking over the responsibility of maintaining this, then I'd be happy to add it! If this is the case, perhaps you have a good way to distribute it.

i5hi commented 3 years ago

I would love to work with someone to make this update. It would be an additional time saver to have shell completion and pier being a productivity tool, every little gain adds to the experience.

We could integrate (ShellCompletion)[https://github.com/JoshMcguigan/shell_completion]

I will be going through the codebase later today to start getting an idea of what is happening.

Plommonsorbet commented 3 years ago

Feel free to send a pull request, I'm however stepping away from any active development on this project due to burnout as I already have been for a little while now. So if you want something done then you'll have to make it happen on your own.

I'll still check in and review pull requests from time to time though. GL