Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

completion support coverage #23

Open
2 of 7 tasks
amtoine opened this issue May 8, 2023 · 1 comment
Open
2 of 7 tasks

completion support coverage #23

amtoine opened this issue May 8, 2023 · 1 comment
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@amtoine
Copy link
Owner

amtoine commented May 8, 2023

in the long run, i'd like to have more external and custom completions inside both gm and sugar 👍

in gm

  • custom completion on all the exported commands, e.g. host + user + project completion, possibly by pulling GitHub (? 😮)

in sugar

external completions

  • the gh CLI command of GitHub in sugar completions gh: based on gh version 2.28.0 (2023-04-25)?
  • the usual git command
    • draw the full list of commands and options
    • write them all, even empty, for completeness
    • write custom completion for them
    • split the externals into modules, e.g. core, cherry, remote, worktree, ..., to allow importing only usefull commands more easily

custom completions

  • sugar git
  • sugar gist (removed)
  • sugar gh
  • sugar dotfiles (removed)
@amtoine amtoine added enhancement New feature or request help wanted Extra attention is needed labels May 8, 2023
@amtoine amtoine pinned this issue May 8, 2023
@amtoine
Copy link
Owner Author

amtoine commented May 18, 2023

i've started with the git external completions with the following WIP script 😮

def extract-subcommand-options [] {
    let command = $in

    let output = (
        do -i { nu -c $"git ($command) -h" }
        | complete
        | reject exit_code  # merge stdout and stderr, e.g. `am` to stderr and `checkout` to stdout
        | transpose key value
        | get value
        | str join
        | lines --skip-empty
        | str trim
        | str replace '^-' "%%-"  # merge the multiline options
        | str join "  "
        | split row "%%"
    )

    {
        usage: ($output | find --invert --regex '^-' | str replace '^usage: ' '' | split row "or:" | str trim)
        options: (
            $output
            | find --regex '^-'  # pick the options only
            | str replace "  " " %% "  # separate the flag and its description
            | split column "%%" option description
            | str trim
        )
    }
}

export def git-commands [] {
    git help -a
    | lines
    | split list ""
    | skip 1
    | each {|section| {
        section: ($section | get 0)
        commands: ($section | skip 1)
    }}
    | where section not-in ["Command aliases" "External commands"]
    | update commands { str trim | parse "{command} {description}" | str trim }
    | flatten --all
    | upsert data {|it|
        print -n $"(ansi erase_line)extracting `git ($it.command)` from (char dq)($it.section)(char dq)\r"
        $it.command | extract-subcommand-options
    }
    | flatten --all
}
def to-nu [--indent: int = 4] {
    str replace '-(.), --([\w-]*)' '--${2} (-${1})' option  # fix the short/long flag format
    | to md --pretty  # convert to md table to have a nice alignment
    | lines
    | skip 2
    | str replace '^\| ' $'(" " * $indent)'  # remove the md table formatting
    | str replace '\s+\|$' ''
    | str replace ' \| ' '  # '
    | to text
}

export def dump [file?: path] {
    let output = (each {|it|
        if ($it.usage | str join | str contains "is not a git command") {
            print $"skipping ($it.command): not a git command"
        } else {
            let options = ($it.options | to-nu --indent 4 | str trim)

            if ($options | is-empty) {
                print $"skipping ($it.command): no option"
            } else {[
                $"# ($it.section)"
                $"#"
                $"# ($it.usage | str join $"\n(char hash)(char space)")"
                $"export extern (char dq)git ($it.command)(char dq) ["
                $"    ($options)"
                $"]"
            ] | str join "\n"}
        }
    } | str join "\n\n")

    if $file != null {
        $output | save --force $file
    } else {
        $output
    }
}

which can be used with

let commands = (git-commands)
$commands | dump commands.nu

and has to be completed with

export extern git [
    --version                     # Prints the Git suite version that the git program came from.
    --help                        # Prints the synopsis and a list of the most commonly used commands.
    -C <path>                     # Run as if git was started in <path> instead of the current working directory.
    -c <name>=<value>             # Pass a configuration parameter to the command. The value given will override values from configuration files.
    --config-env <name>=<envvar>  # Like -c <name>=<value>, give configuration variable <name> a value, where <envvar> is the name of an environment variable from which to retrieve the value.
    --exec-path[=<path>]          # Path to wherever your core Git programs are installed.
    --html-path                   # Print the path, without trailing slash, where Git’s HTML documentation is installed and exit.
    --man-path                    # Print the manpath (see man(1)) for the man pages for this version of Git and exit.
    --info-path                   # Print the path where the Info files documenting this version of Git are installed and exit.
    --paginate (-p)               # Pipe all output into less (or if set, $PAGER) if standard output is a terminal.
    --no-pager (-P)               # Do not pipe Git output into a pager.
    --git-dir=<path>              # Set the path to the repository (".git" directory).
    --work-tree=<path>            # Set the path to the working tree. It can be an absolute path or a path relative to the current working directory.
    --namespace=<path>            # Set the Git namespace. See gitnamespaces(7) for more details.
    --super-prefix=<path>         # Currently for internal use only.
    --bare                        # Treat the repository as a bare repository.
    --no-replace-objects          # Do not use replacement refs to replace Git objects. See git-replace(1) for more information.
    --literal-pathspecs           # Treat pathspecs literally (i.e. no globbing, no pathspec magic).
    --glob-pathspecs              # Add "glob" magic to all pathspec.
    --noglob-pathspecs            # Add "literal" magic to all pathspec.
    --icase-pathspecs             # Add "icase" magic to all pathspec.
    --no-optional-locks           # Do not perform optional operations that require locks.
    --list-cmds=group[,group...]  # List commands by group. This is an internal/experimental option and may change or be removed in the future.
]

@amtoine amtoine unpinned this issue Nov 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

1 participant