python-fire icon indicating copy to clipboard operation
python-fire copied to clipboard

Fix completion for Fire(fn)

Open wchliao opened this issue 4 years ago • 0 comments

This is a bug that should have been fixed long time ago. (#14) However, it seems that the bug appeared again.

The issue is that completion for Fire(fn) is missing. Take the following program as an example.

import fire

def hello(name):
  return 'Hello {name}!'.format(name=name)

if __name__ == '__main__':
  fire.Fire(hello)

When we type example.py the command should automatically complete --name, but the completion script generated by current Fire fails to do so. The generated script is as follow.

# bash completion support for example.py
# DO NOT EDIT.
# This script is autogenerated by fire/completion.py.

_complete-examplepy()
{
  local cur prev opts lastcommand
  COMPREPLY=()
  prev="${COMP_WORDS[COMP_CWORD-1]}"
  cur="${COMP_WORDS[COMP_CWORD]}"
  lastcommand=$(get_lastcommand)

  opts=""
  GLOBAL_OPTIONS="--name"


  case "${lastcommand}" in
  
  esac

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

get_lastcommand()
{
  local lastcommand i

  lastcommand=
  for ((i=0; i < ${#COMP_WORDS[@]}; ++i)); do
    if [[ ${COMP_WORDS[i]} != -* ]] && [[ -n ${COMP_WORDS[i]} ]] && [[
      ${COMP_WORDS[i]} != $cur ]]; then
      lastcommand=${COMP_WORDS[i]}
    fi
  done

  echo $lastcommand
}

filter_options()
{
  local opts
  opts=""
  for opt in "$@"
  do
    if ! option_already_entered $opt; then
      opts="$opts $opt"
    fi
  done

  echo $opts
}

option_already_entered()
{
  local opt
  for opt in ${COMP_WORDS[@]:0:COMP_CWORD}
  do
    if [ $1 == $opt ]; then
      return 0
    fi
  done
  return 1
}

is_prev_global()
{
  local opt
  for opt in $GLOBAL_OPTIONS
  do
    if [ $opt == $prev ]; then
      return 0
    fi
  done
  return 1
}

complete -F _complete-examplepy example.py


After the change, now completion for Fine(fn) works. The generated script is as follow.

# bash completion support for example.py
# DO NOT EDIT.
# This script is autogenerated by fire/completion.py.

_complete-examplepy()
{
  local cur prev opts lastcommand
  COMPREPLY=()
  prev="${COMP_WORDS[COMP_CWORD-1]}"
  cur="${COMP_WORDS[COMP_CWORD]}"
  lastcommand=$(get_lastcommand)

  opts=""
  GLOBAL_OPTIONS="--name"


  case "${lastcommand}" in
  
    example.py)
      
      opts=" ${GLOBAL_OPTIONS}" 
      opts=$(filter_options $opts)
    ;;
  esac

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

get_lastcommand()
{
  local lastcommand i

  lastcommand=
  for ((i=0; i < ${#COMP_WORDS[@]}; ++i)); do
    if [[ ${COMP_WORDS[i]} != -* ]] && [[ -n ${COMP_WORDS[i]} ]] && [[
      ${COMP_WORDS[i]} != $cur ]]; then
      lastcommand=${COMP_WORDS[i]}
    fi
  done

  echo $lastcommand
}

filter_options()
{
  local opts
  opts=""
  for opt in "$@"
  do
    if ! option_already_entered $opt; then
      opts="$opts $opt"
    fi
  done

  echo $opts
}

option_already_entered()
{
  local opt
  for opt in ${COMP_WORDS[@]:0:COMP_CWORD}
  do
    if [ $1 == $opt ]; then
      return 0
    fi
  done
  return 1
}

is_prev_global()
{
  local opt
  for opt in $GLOBAL_OPTIONS
  do
    if [ $opt == $prev ]; then
      return 0
    fi
  done
  return 1
}

complete -F _complete-examplepy example.py


wchliao avatar Apr 26 '21 05:04 wchliao