git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 1/1] completion: load completion file for external subcommand

From
SZEDER Gábor <szeder.dev@gmail.com>
Date
Apr 18, 2018, 19:51 UTC
Message-ID
<CAM0VKj=pDVxfJtUZx7c6uCmPxwQFPBOQYdd7NH=YnVG86iK0Pw@mail.gmail.com>
In-Reply-To
<20180410202758.5877-2-mail@floga.de>
On Tue, Apr 10, 2018 at 10:28 PM, Florian Gamböck <mail@floga.de> wrote:
Show 8 quoted lines
> Adding external subcommands to Git is as easy as to put an executable
> file git-foo into PATH. Packaging such subcommands for a Linux
> distribution can be achieved by unpacking the executable into /usr/bin
> of the user's system. Adding system-wide completion scripts for new
> subcommands, however, can be a bit tricky.
>
> Since bash-completion started to use dynamical loading of completion
> scripts since v1.90 (preview of v2.0),
I believe the main bash-completion repository can be found at:
  https://github.com/scop/bash-completion.git

This repository still contains the branch 'dynamic-loading'; for the record it points to 3b029892f6f9db3b7210a7f66d636be3e5ec5fa2.

Two commits on that branch are worth mentioning:
  20c05b43 (Load completions in separate files dynamically, get rid of
            have()., 2011-10-12)
  5baebf81 (Add _xfunc for loading and calling functions on demand,
            use it in apt-get, cvsps, rsync, and sshfs., 2011-10-13)
Show 30 quoted lines
> it is no longer sufficient to
> drop a completion script of a subcommand into the standard completions
> path, /usr/share/bash-completion/completions, since this script will not
> be loaded if called as a git subcommand.
>
> For example, look at https://bugs.gentoo.org/544722. To give a short
> summary: The popular git-flow subcommand provides a completion script,
> which gets installed as /usr/share/bash-completion/completions/git-flow.
>
> If you now type into a Bash shell:
>
>     git flow <TAB>
>
> You will not get any completions, because bash-completion only loads
> completions for git and git has no idea that git-flow is defined in
> another file. You have to load this script manually or trigger the
> dynamic loader with:
>
>     git-flow <TAB> # Please notice the dash instead of whitespace
>
> This will not complete anything either, because it only defines a Bash
> function, without generating completions. But now the correct completion
> script has been loaded and the first command can use the completions.
>
> So, the goal is now to teach the git completion script to consider the
> possibility of external completion scripts for subcommands, but of
> course without breaking current workflows.
>
> I think the easiest method is to use a function that is defined by
> bash-completion v2.0+, namely __load_completion.

This is wrong, __load_completion() was introduced in cad3abfc (__load_completion: New function, use in _completion_loader and _xfunc, 2015-07-15), and the first release tag containg it is '2.2' from 2016-03-03.

The release tags '1.90' and '2.0' are from 2011-11-03 and 2012-06-17, respectively. This leaves a couple of years long hole where completions were already loaded dynamically but there was no __load_completion() function.

Would it be possible to use _xfunc() instead to plug that hole? It seems the be tricky, because that function not only sources but also _calls_ the completion function.

Show 43 quoted lines
> It will take care of
> loading the correct script if present. Afterwards, the git completion
> script behaves as usual.
>
> This way we can leverage bash-completion's dynamic loading for git
> subcommands and make it easier for developers to distribute custom
> completion scripts.
>
> Signed-off-by: Florian Gamböck <mail@floga.de>
> ---
>  contrib/completion/git-completion.bash | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
> index b09c8a236..09a820990 100644
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -3096,12 +3096,22 @@ __git_main ()
>         fi
>
>         local completion_func="_git_${command//-/_}"
> +       if ! declare -f $completion_func >/dev/null 2>/dev/null &&
> +               declare -f __load_completion >/dev/null 2>/dev/null
> +       then
> +               __load_completion "git-$command"
> +       fi
>         declare -f $completion_func >/dev/null 2>/dev/null && $completion_func && return
>
>         local expansion=$(__git_aliased_command "$command")
>         if [ -n "$expansion" ]; then
>                 words[1]=$expansion
>                 completion_func="_git_${expansion//-/_}"
> +               if ! declare -f $completion_func >/dev/null 2>/dev/null &&
> +                       declare -f __load_completion >/dev/null 2>/dev/null
> +               then
> +                       __load_completion "git-$expansion"
> +               fi
>                 declare -f $completion_func >/dev/null 2>/dev/null && $completion_func
>         fi
>  }
> --
> 2.16.1
>
Previous: Florian GamböckNext: Florian Gamböck
Message 3 of 10 in “completion: dynamic completion loading”
  1. 0/1 completion: dynamic completion loadingFlorian Gamböck, Apr 10, 2018
  2. 1/1 completion: load completion file for external subcommandFlorian Gamböck, Apr 10, 2018
  3. SZEDER GáborApr 18, 2018
  4. Florian GamböckApr 19, 2018
  5. SZEDER GáborApr 23, 2018
  6. Florian GamböckApr 23, 2018
  7. SZEDER GáborApr 25, 2018
  8. Florian GamböckApr 29, 2018
  9. SZEDER GáborApr 29, 2018
  10. Florian GamböckApr 29, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.