|
1 | 1 | # bash completion for venv -*- shell-script -*- |
2 | 2 |
|
3 | 3 | _venv() { |
4 | | - local cur_word prev_word subcommands fill_list |
| 4 | + local cur_word prev_word _subcommands subcommands help_options |
5 | 5 | cur_word="${COMP_WORDS[COMP_CWORD]}" |
6 | 6 | prev_word="${COMP_WORDS[COMP_CWORD-1]}" |
7 | | - subcommands="create activate install lock clear sync deactivate -V --version" |
8 | | - command_options="-h --help" |
9 | 7 |
|
10 | | - if [ "${prev_word}" == "venv" ]; then |
11 | | - fill_list="${subcommands} ${command_options}" |
12 | | - else |
13 | | - fill_list="${command_options}" |
| 8 | + _subcommands="activate clear create deactivate install lock sync" |
| 9 | + subcommands=( $(compgen -W "${_subcommands}" -- "${cur_word}") ) |
| 10 | + help_options=( $(compgen -W "-h --help" -- "${cur_word}") ) |
| 11 | + |
| 12 | + # Generate completions for subcommand options |
| 13 | + compopt -o nosort |
| 14 | + case "${prev_word}" in |
| 15 | + "venv") |
| 16 | + # If only 'venv' has been entered, generate list of subcommands and options |
| 17 | + COMPREPLY+=( ${subcommands[*]} ) |
| 18 | + COMPREPLY+=( ${help_options[*]} ) |
| 19 | + |
| 20 | + local version_options |
| 21 | + version_options=( $(compgen -W "-V --version" -- "${cur_word}") ) |
| 22 | + COMPREPLY+=( ${version_options[*]} ) |
| 23 | + ;; |
| 24 | + "create") |
| 25 | + # Generate list of all available python3 versions |
| 26 | + |
| 27 | + # The command below does the following, by line: |
| 28 | + # * List all python commands, e.g. "python3", "python3.10-config", ... |
| 29 | + # * Select only "python3.X" or "python3.XX" |
| 30 | + # * Remove the "python", leaving the version number |
| 31 | + # * Select unique entries, sorted by numerical value |
| 32 | + local python_versions |
| 33 | + python_versions=( $( \ |
| 34 | + compgen -c "python${cur_word}" \ |
| 35 | + | grep -P '^python3.\d+$' \ |
| 36 | + | sed 's|python||' \ |
| 37 | + | sort -n --unique \ |
| 38 | + ) ) |
| 39 | + COMPREPLY+=( ${python_versions[*]} ) |
| 40 | + COMPREPLY+=( ${help_options[*]} ) |
| 41 | + ;; |
| 42 | + "install"|"lock") |
| 43 | + # Generate completions for requirement and lock file paths |
| 44 | + COMPREPLY+=( $(compgen -f -X '!(*.txt|*.lock)' -- "${cur_word}" | sort) ) |
| 45 | + COMPREPLY+=( ${help_options[*]} ) |
| 46 | + compopt -o plusdirs +o nosort # Add directories after generated completions |
| 47 | + ;; |
| 48 | + "sync") |
| 49 | + # Generate completions for lock file paths |
| 50 | + COMPREPLY+=( $(compgen -f -X '!*.lock' -- "${cur_word}" | sort) ) |
| 51 | + COMPREPLY+=( ${help_options[*]} ) |
| 52 | + compopt -o plusdirs +o nosort # Add directories after generated completions |
| 53 | + ;; |
| 54 | + "activate"|"deactivate"|"clear") |
| 55 | + # Only generate help options |
| 56 | + COMPREPLY+=( ${help_options[*]} ) |
| 57 | + ;; |
| 58 | + "-V"|"--version") |
| 59 | + # Nothing to generate |
| 60 | + ;; |
| 61 | + *) |
| 62 | + # Nothing to generate |
| 63 | + ;; |
| 64 | + esac |
| 65 | + |
| 66 | + # Special case for 'venv lock requirements.txt <TAB>', where only *.lock files should be suggested |
| 67 | + if [ "${COMP_WORDS[COMP_CWORD-2]}" == "lock" ] && [[ "${prev_word}" =~ ^.*\.txt$ ]]; then |
| 68 | + COMPREPLY+=( $(compgen -f -X '!*.lock' -- "${cur_word}" | sort) ) |
| 69 | + compopt -o plusdirs +o nosort # Add directories after generated completions |
14 | 70 | fi |
15 | | - COMPREPLY=($(compgen -W "${fill_list}" -- "${cur_word}")) |
16 | 71 | } |
17 | 72 |
|
18 | 73 | complete -F _venv venv |
|
0 commit comments