bashly: Bash completions do not work

I just discovered this tool, looks super cool!

I am trying to reproduce the completions example: https://github.com/DannyBen/bashly/tree/master/examples/completions but it does not seem to work.

Steps I took:

  • in an empty directory, create bashly.yml
  • paste the configuration from the example into that file
  • Run the following commands, as per the example:
$ bashly init
$ bashly add comp function
$ bashly generate
  • Run ./cli. I get the output
cli - Sample application

Usage:
  cli [command]
  cli [command] --help | -h
  cli --version | -v

Commands:
  download   Download a file
  upload     Upload a file

Note that, unlike the example, I do not have a completions command

  • ./cli completions just prints the same usage information, so I can’t eval that to enable completions.

bashly generated the following files:

$ tree
├── cli
└── src
    ├── bashly.yml
    ├── download_command.sh
    ├── initialize.sh
    ├── lib
    │   └── send_completions.sh
    └── upload_command.sh

2 directories, 6 files

My environment:

I am using bashly through docker, as described in the installation instructions.

$ bashly --version
0.6.4
$ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
$ docker image inspect dannyben/bashly
[
    {
        "Id": "sha256:82d3128ff8617e75c2e58638920f046453dd07759846b209c8bd43b0dd5f7845",
        "RepoTags": [
            "dannyben/bashly:latest"
        ],
        "RepoDigests": [
            "dannyben/bashly@sha256:bf1a326659205b5974657e76d57179ee890abf85f0fda1e960630003effb7aea"
        ],
        "Parent": "",
        "Comment": "buildkit.dockerfile.v0",
        "Created": "2021-08-27T15:24:07.059809147Z",
...

Am I doing something wrong or is this a bug?

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 19 (11 by maintainers)

Most upvoted comments

Well - the new implementation doesn’t change anything in that regard does it?

Yeah exactly, it was just an FYI because I noticed it while researching. Thanks for being so quick, as usual!

How about this? Will this work in all cases to your knowledge?

This is trying Jack’s idea:

  1. Use COMP_LINE without its first word when matching
  2. Match patterns changed to not include the command name
#!/usr/bin/env bash

# This bash completions script was generated by
# completely (https://github.com/dannyben/completely)
# Modifying it manually is not recommended
# shellcheck disable=SC2207
_mygit_completions() {
  local cur=${COMP_WORDS[COMP_CWORD]}
  local comp_line="${COMP_WORDS[*]:1}"

  case "$comp_line" in
    'status'*) COMPREPLY=($(compgen -W "forSTATUS1 forSTATUS2" -- "$cur")) ;;
    'commit'*) COMPREPLY=($(compgen -W "forCOMMIT1 forCOMMIT2" -- "$cur")) ;;
    *) COMPREPLY=($(compgen -W "status commit" -- "$cur")) ;;
  esac
}

complete -F _mygit_completions mygit

This can be tested by saving and sourcing it, and then:

$ mygit s<tab>        #=> mygit status
$ mygit c<tab>        #=> mygit commit
$ mygit commit <tab>  #=> mygit commit forCOMMIT1
$ ...

From what I can tell, this works with or without a leading path string (either ./ or even /longer/path/mygit)

Just to chime in, I also ran into this a while ago and ended up using option 1, but in my case the script is supposed to always be called from its own directory, so using a different relative path is not a case I needed to cover.

That being said, what about switching from checking that $COMP_LINE starts with <script_name> <command> to checking that ${COMP_WORDS[1]} (i.e. the second word in $COMP_LINE) matches <command>?

Using complete -F _cli_completions cli is already telling bash that this function should be used for cli, even when referring to the script from a relative/absolute path, so by the time the function is called we’re sure we’re being called for cli: there’s no need to check for that again.