Skip to content

Better completions for repos, issues, PRs, etc. in commands #360

Description

@eugene-babichenko

Editing to clarify for people who come upon this issue that:

  • Shell completion of commands is already supported in gh
  • This issue is about shell completion for particular GitHub objects (for example, easily cycling through possible PRs to checkout or view)

Original issue content:

It would be great to have completions for different shell environments. Not only for commands, but, for example, cycling through open pull request when checking out a PR branch or something like that.

Activity

  1. whi-tw commented on Feb 12, 2020

    @whi-tw
    Contributor

    You can generate command completion as-is:

    gh completion -s fish
    gh completion -s zsh
    gh completion -s bash

    This is standard behaviour when using (recent) spf13/cobra! (This may not actually be true. gh seems to follow the standard form that cobra itself uses, but appears to have been implemented specifically.)

  2. nesl247 commented on Feb 12, 2020

    @nesl247

    It would be much better if these were installed as part of the homebrew installation, same for other systems.

    Also, I did try it with fish and it did not work. Apparently the version of gh available in the tap is not updated as I'm only on 0.5.2.

    Update: Now that 0.5.4 is available in homebrew it worked.

  3. cbrnr commented on Feb 13, 2020

    @cbrnr

    This should already work with Homebrew. When installing I get the following notification:

    ==> Caveats
    Bash completion has been installed to:
      /usr/local/etc/bash_completion.d
    
    zsh completions have been installed to:
      /usr/local/share/zsh/site-functions
    
  4. eugene-babichenko commented on Feb 13, 2020

    @eugene-babichenko
    Author

    @whi-tw

    This is standard behaviour when using (recent) spf13/cobra

    I know about them, but those completions work only for subcommands and flags names. What I want is something like git completions, where you can, for example, select files to add to commit from completions. Or select the branch to checkout in the same way. Something more intelligent overall.

  5. whi-tw commented on Feb 13, 2020

    @whi-tw
    Contributor

    @eugene-babichenko

    I know about them, but those completions work only for subcommands and flags names.

    Sure, I misunderstood what you meant by 'Not only for commands' at first: that you were unaware that command completion already existed. I've tried to edit my reply to acknowledge that. Hopefully the discussion helps people when looking for 'standard' completion, and that I haven't diluted the discussion about the other context-aware completions - I agree, git style completions for PRs / branches etc would be really useful!

  6. changed the title [-]Completions for bash, zsh, etc[/-] [+]Better completions for bash, zsh, etc[/+] on Feb 20, 2020
  7. cmur2 commented on Feb 28, 2020

    @cmur2

    Would it be possible to show the availability of the gh completion subcommand in gh help? I tend to forget the specific syntax and have to search for this issue again then.

  8. AjayKMehta commented on Mar 3, 2020

    @AjayKMehta

    Is there any plan to add support for Powershell to gh completion?

  9. mislav commented on Mar 5, 2020

    @mislav
    Contributor
  10. changed the title [-]Better completions for bash, zsh, etc[/-] [+]Better completions for repos, issues, PRs, etc. in commands[/+] on Apr 20, 2020
  11. rsteube commented on Sep 9, 2020

    @rsteube
    Contributor
  12. mislav commented on Sep 14, 2020

    @mislav
    Contributor

    @rsteube That is pretty cool!

  13. added
    coreThis issue is not accepting PRs from outside contributors
    on Oct 7, 2020
  14. rsteube commented on Oct 29, 2020

    @rsteube
    Contributor

    asciicast

    added completions for the new commands - still some minor issues but otherwise works pretty well so far

  15. 6 remaining items

  16. joelostblom commented on Jan 16, 2021

    @joelostblom

    Just watched the videos. AMAZING! 🤯 Thank you so much for developing this functionality for the gh cli @rsteube !

  17. rsteube commented on May 9, 2021

    @rsteube
    Contributor

    asciicast

  18. rsteube commented on May 27, 2021

    @rsteube
    Contributor

    So anyone following this: i moved the completion to carapace-bin.
    Not much difference other than that the completion is provided by a separate binary.
    This simply means that whenever you invoke completion for gh with <TAB> it is executed with the current command line instead of gh (you can try this out by calling it directly carapace gh elvish _ gh issue view '').

    Cache is written to {os.TempDir()}/carapace (e.g. /tmp/carapace).
    Did a couple of tests and so far seems to work alright, but there might be some minor issues with different environments.

    So if you want to try it out either grab the release and source the completion for gh:

    # bash (~/.bashrc)
    source <(carapace gh bash)
    
    # elvish (~/.elvish/rc.elv)
    eval (carapace gh elvish|slurp)
    
    # fish (~/.config/fish/config.fish)
    mkdir -p ~/.config/fish/completions
    carapace --list | awk '{print $1}' | xargs -I{} touch ~/.config/fish/completions/{}.fish # disable auto-loaded completions (https://github.com/rsteube/carapace-bin/issues/185)
    carapace gh fish | source
    
    # oil (~/.config/oil/oshrc)
    source <(carapace gh oil)
    
    # powershell (~/.config/powershell/Microsoft.PowerShell_profile.ps1)
    Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
    carapace gh powershell | Out-String | Invoke-Expression
    
    # xonsh (~/.config/xonsh/rc.xsh)
    COMPLETIONS_CONFIRM=True
    exec($(carapace gh xonsh))
    
    # zsh (~/.zshrc)
    source <(carapace gh zsh)

    Or build just the completer for gh:

    cd completers/gh_completer
    go install --ldflags="-s -w"
    
    
    
    # bash (~/.bashrc)
    source <(gh_completer _carapace bash)
    
    # elvish (~/.elvish/rc.elv)
    eval (gh_completer _carapace elvish|slurp)
    
    # fish (~/.config/fish/config.fish)
    mkdir -p ~/.config/fish/completions
    touch ~/.config/fish/completions/gh.fish # disable auto-loaded completions (https://github.com/rsteube/carapace-bin/issues/185)
    gh_completer _carapace | source
    
    # oil (~/.config/oil/oshrc)
    source <(gh_completer _carapace oil)
    
    # powershell (~/.config/powershell/Microsoft.PowerShell_profile.ps1)
    Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
    gh_completer _carapace powershell | Out-String | Invoke-Expression
    
    # xonsh (~/.config/xonsh/rc.xsh)
    COMPLETIONS_CONFIRM=True
    exec($(gh_completer _carapace xonsh))
    
    # zsh (~/.zshrc)
    source <(gh_completer _carapace zsh)
  19. JonParton commented on Aug 13, 2021

    @JonParton

    just a note @rsteube; I couldn't get the above to work with fish autocompletions using the method of registering suggested:

    # fish (~/.config/fish/config.fish)
    gh_completer _carapace | source

    instead, I had to put the output in a completion's config file:

    # fish
    gh_completer _carapace > ~/.config/fish/completions/gh.fish

    Hope that might help others if they hit the same problem!

    Working fantastically once I got over that hiccup though! 👍🏼👍🏼 Thanks so much for putting all the work into this and it's a shame it won't be part of core! (Although I understand the reluctance from the maintainers!).

  20. rsteube commented on Aug 13, 2021

    @rsteube
    Contributor

    Oh yes @JonParton , that might be because of fish-shell/fish-shell#6716 as system completions (so the one installed by the package) are still being autoloaded even if one is already registered (so it overwrites it at first <TAB>).
    An empty user completion would prevent it as well but your solution is better anyway as it omits the delay of invoking gh_completer at shell startup:

    touch ~/.config/fish/completions/gh.fish
  21. cmoog commented on Aug 24, 2021

    @cmoog

    So isn't this achievable by adding the following to each appropriate command spec

    ValidArgsFunction: func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective)

    For example, the valid args function for gh issue close would return each open issue number.

    Args: cobra.ExactArgs(1),

  22. rsteube commented on Aug 24, 2021

    @rsteube
    Contributor
  23. mislav commented on Aug 24, 2021

    @mislav
    Contributor

    @cmoog This is achievable using Cobra like you've outlined, yes. We've started to add some completions to core gh already, e.g.

    cli/cmd/gh/main.go

    Lines 168 to 169 in e297345

    // provide completions for aliases and extensions
    rootCmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
    _ = cmd.RegisterFlagCompletionFunc("gitignore", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {

    However, we are going light on this approach because we don't want too many API-powered completions before we build a good foundation for performing those with proper caching in place. Otherwise the experience of using them is going to be slow and potentially frustrating.

  24. rsteube commented on Oct 27, 2021

    @rsteube
    Contributor

    Anyone here already got access to codespaces and can check if this works?

    gh codespace ssh --codespace [name] -- ls -1 -p /

    It should output files/folder from the codespace vm (replace [name]).

  25. rsteube commented on Feb 14, 2022

    @rsteube
    Contributor

    @mislav just been working on completer reusage and the same thing should work for you to provide completions for the extensions (at least the go based ones).

    Basically you just have to add a subcommand for each extension with flag parsing disabled (probably already being done) like here.
    Then in the ValidArgsFunction invoke the __complete subcommand of the extension with args and toComplete as arguments similar to this (you can ignore the directive handling as this is not needed for you).

    It outputs:

    value
    value\twithDescription
    :4
    # empty line

    So just return lines[:len(lines)-2] and :4 parsed as integer (ShellCompDirecive) and it might already work.

  26. chmouel commented on Nov 22, 2022

    @chmouel

    Here is a POC using Cobra builtin ValidArgs on zsh (should work as well on bash and any shells cobra completions support) :

    recording-20221122-15.23.06.mov

    implementation is not ideal (it use gh binary to generate the pr list and title when it could just use graphql directly) but good enough for what we want to do..

    let me know what do you think and i can clean this up and submit it...

    diff --git a/pkg/cmd/pr/view/view.go b/pkg/cmd/pr/view/view.go
    index 10300a23..c896b589 100644
    --- a/pkg/cmd/pr/view/view.go
    +++ b/pkg/cmd/pr/view/view.go
    @@ -2,6 +2,7 @@ package view
     
     import (
     	"fmt"
    +	"os/exec"
     	"sort"
     	"strconv"
     	"strings"
    @@ -51,6 +52,18 @@ func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Comman
     			With '--web', open the pull request in a web browser instead.
     		`),
     		Args: cobra.MaximumNArgs(1),
    +		ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
    +			if len(args) != 0 {
    +				return nil, cobra.ShellCompDirectiveNoFileComp
    +			}
    +			c := exec.Command("gh", "pr", "list", "--jq", ".[] | ((.number|tostring)+\"\\t\"+.title)",
    +				"--json", "number,title")
    +			out, err := c.Output()
    +			if err != nil {
    +				return nil, cobra.ShellCompDirectiveNoFileComp
    +			}
    +			return strings.Split(string(out), "\n"), cobra.ShellCompDirectiveNoFileComp
    +		},
     		RunE: func(cmd *cobra.Command, args []string) error {
     			opts.Finder = shared.NewFinder(f)
  27. chmouel commented on Nov 22, 2022

    @chmouel

    I thought it would be neat to wrap around the gh binary for generating the completion cobra expect....

    here is a shell script adding completion (only for pr and issue the rest is an exercise for the rider) to gh by wrapping around it.

    Just save this script in your $PATH before the path of where the real gh binary is and just tab on the issue and pr to get the a completion of the pr and title (as per my video in the above comment) :

    #!/usr/bin/env bash
    # Copyright 2022 Chmouel Boudjnah <[email protected]>
    # will look better on zsh if you set : 
    # zstyle ':completion:*:*:gh:*' menu yes select
    # to have a nice interactive menu to select the prnumber
    set -eufo pipefail
    shopt -s extglob
     
    [[ -n ${BASH_COMP_DEBUG_FILE:-""} ]] && echo "$@" >> $BASH_COMP_DEBUG_FILE
     
    ghbins=($(command which -a gh))
    ghbin=${ghbins[1]}
    [[ -z ${ghbin} ]] && { echo "cannot find real gh bin in path"; exit 1 ;}
     
    get_obj_title() {
        local obj=$1
        exec ${ghbin} $obj list -q '.[] | ((.number|tostring)+"\t"+.title)' --json "number,title"
    }
     
    case $@ in
        *__complete\ pr\ +(checks|close|comment|ready|review|status|view|diff|edit|merge|view|checkout)*) get_obj_title pr;;
        *__complete\ issue\ +(comment|view|delete|develop|edit|list|pin|status)*) get_obj_title issue;;
       *) exec ${ghbin} "$@";;
    esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementa request to improve CLIpitchpitched internally for prioritisation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions