Fabric icon indicating copy to clipboard operation
Fabric copied to clipboard

[Feature request]: tab completion for patterns

Open hugobloem opened this issue 1 year ago • 6 comments
trafficstars

What do you need?

It is quite difficult to remember the exact spelling of the patterns, especially when getting started with pattern. It could be nice to add tab completion to the fabric cli so we can more easily use patterns instead of being halfway through a query and realising you need to run fabric -l to find the exact spelling of a pattern.

hugobloem avatar Jun 27 '24 08:06 hugobloem

At least on my setup all patterns are added as aliases. So if you don't run fabric -p extract_wisdom but instead just try to type extract_ and then tab image

You wont be able to add extra settings such as stream, but you can at least tab to find your pattern, then just step back you cursor and add fabric -sp in front if you want to stream the result for example

ndit-dev avatar Jul 01 '24 18:07 ndit-dev

I'm a Bash user, so I'm not sure if this needs tweaking for zsh, but you could add this to your ~/.bash_completion or the like:

__complete_fabric() {
  local prev="${COMP_WORDS[COMP_CWORD-1]}"
  local  cur="${COMP_WORDS[COMP_CWORD]}"

  local opts
  case "$prev" in
    -p|--pattern)
      opts=($(fabric --listpatterns | sort))
      opts=(-W "${opts[*]}")
      ;;
    -m|--model)
      opts=($(fabric --listmodels | \
        sed -En 's/^[[:blank:]]+\[[0-9]+\][[:blank:]]+(.+)$/\1/p' | sort))
      opts=(-W "${opts[*]}")
      ;;
    -C|--context)
      opts=$(fabric --listcontexts)
      opts=($([[ "$words" != *"No Contexts"* ]] && sort <<< "$words"))
      opts=(-W "${opts[*]}")
      ;;
    --session)
      opts=$(fabric --listsessions)
      opts=($([[ "$words" != *"No Sessions"* ]] && sort <<< "$words"))
      opts=(-W "${opts[*]}")
      ;;
    -o|--output)
      opts=(-A directory -A file)
      ;;
    *)
      opts=($(fabric --help | \
        sed -En 's/^[[:blank:]]+((-[a-zA-Z],)?[[:blank:]]--[a-z][-_a-zA-Z]+=?[[:blank:]]).*$/\1/p' | \
        sed -E  's/[,=]//g;s/[[:blank:]]/\n/g;/^$/d;s/^(-[^-])/-\1/' | sort -f | sed -E 's/^-(-.)$/\1/'))
      opts=(-W "${opts[*]}")
      ;;
  esac
  COMPREPLY=($(compgen "${opts[@]}" -- "$cur"))
}
complete -F __complete_fabric fabric

FYI: above works for me in macOS Bash 5.2

erhhung avatar Oct 08 '24 21:10 erhhung

btw, I've created sa small wrapper in go for fabric that lets you choose pattern in a fzf-finder instead of manually typing it. https://github.com/ndit-dev/FabricPrompt

Would be nice with something similar and more polished built in. But in the meantime i hacked this together.

Mentioned it here before #771

ndit-dev avatar Oct 10 '24 13:10 ndit-dev

@erhhung

Nicely done. Thanks.

snafu4 avatar Oct 11 '24 15:10 snafu4

Thanks for sharing @erhhung

Here's a working completion for ZSH. I put this in ~/.zsh/completions/_fabric and have fpath=(~/.zsh/completions $fpath) in my ~/.zshrc

#compdef fabric

_fabric() {
    local curcontext="$curcontext" state line
    typeset -A opt_args

    _arguments -C \
        '(-p --pattern)'{-p,--pattern}'[Pattern]: :->patterns' \
        '(-m --model)'{-m,--model}'[Model]: :->models' \
        '(-C --context)'{-C,--context}'[Context]: :->contexts' \
        '(--session)--session[Session]: :->sessions' \
        '(-o --output)'{-o,--output}'[Output]: :->output' \
        '*: :->args'

    case $state in
        patterns)
            local -a patterns
            patterns=( ${(f)"$(fabric --listpatterns)"} )
            _describe 'patterns' patterns
            ;;
        models)
            local -a models
            models=( ${(f)"$(fabric --listmodels | sed -En 's/^[[:blank:]]+\[[0-9]+\][[:blank:]]+(.+)$/\1/p')"} )
            _describe 'models' models
            ;;
        contexts)
            local -a contexts
            contexts=( ${(f)"$(fabric --listcontexts)"} )
            [[ "$contexts" != *"No Contexts"* ]] && _describe 'contexts' contexts
            ;;
        sessions)
            local -a sessions
            sessions=( ${(f)"$(fabric --listsessions)"} )
            [[ "$sessions" != *"No Sessions"* ]] && _describe 'sessions' sessions
            ;;
        output)
            _files -/
            ;;
        args)
            local -a opts
            opts=( ${(f)"$(fabric --help | sed -En 's/^[[:blank:]]+((-[a-zA-Z],)?[[:blank:]]--[a-z][-_a-zA-Z]+=?[[:blank:]]).*$/\1/p' | \
                   sed -E 's/[,=]//g;s/[[:blank:]]/\n/g;/^$/d;s/^(-[^-])/-\1/' | sort -f | sed -E 's/^-(-.)$/\1/')"} )
            _describe 'options' opts
            ;;
    esac
}

compdef _fabric fabric

natemccurdy avatar Jan 06 '25 21:01 natemccurdy

On my side, here's what I use :

_fabric_completions() {
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    if [[ ${prev} == -p || ${prev} == --pattern ]]; then
        local patterns_dir="$HOME/.config/fabric/patterns"
        local dirs=($(ls -d ${patterns_dir}/*/ 2>/dev/null))

        if [[ ${#dirs[@]} -ne 0 ]]; then
            COMPREPLY=( $(compgen -W "$(printf "%s\n" "${dirs[@]}" | xargs -n1 basename)" -- ${cur}) )
        fi
        return 0
    fi
}

complete -F _fabric_completions fabric

then source $HOME/.config/fabric/fabric_completion.sh in my bashrc

Working on a script that also shows the short description of the patterns based on pattern_explanations.md, but nothing clean to show for now.

ThomasVuillaume avatar Feb 17 '25 07:02 ThomasVuillaume

I extended @KenMacD's recent fish completion script and added new updated scripts for zsh, fish and bash in the referenced PR. Comments welcome. Cheers!

Fabric can now tab-complete patterns (and model names) via TAB in all three major shells (zsh, bash, fish).

https://github.com/user-attachments/assets/e25a1e35-898b-4580-95f2-1fb60fdb1582

ksylvan avatar Apr 25 '25 03:04 ksylvan

@hugobloem @eugeis I think we can close this issue

ksylvan avatar Apr 25 '25 14:04 ksylvan