command argument completion generator for spf13/cobra

carapace

CircleCI PkgGoDev documentation GoReportCard codecov

Command argument completion generator for cobra. You can read more about it here: A pragmatic approach to shell completion.

Supported shells:

Usage

Calling carapace.Gen on the root command is sufficient to enable completion script generation using the hidden command.

import (
    "github.com/rsteube/carapace"
)

carapace.Gen(rootCmd)

Standalone Mode

Carapace can also be used to provide completion for arbitrary commands as well (similar to aws_completer). See rsteube/carapace-bin for examples. There is also a binary to parse flags from gnu help pages at caraparse.

Example

An example implementation can be found in the example folder.

">
cd example
go build .

# bash
PATH=$PATH:$(pwd)
source <(example _carapace bash)

# elvish
paths=[$@paths (pwd)]
eval (example _carapace elvish | slurp)

# fish
set PATH $PATH (pwd) 
example _carapace fish | source

# nushell [needs fork: https://github.com/rsteube/nushell]
example _carapace nushell | save example.nu ; nu -c 'source example.nu'

# oil
PATH=$PATH:$(pwd)
source <(example _carapace oil)

# powershell
Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
$env:PATH += ":$pwd"
example _carapace powershell | out-string | Invoke-Expression

# tcsh
set autolist
eval `example _carapace tcsh`

# xonsh
$COMPLETION_QUERY_LIMIT = 500 # increase limit
$PATH.append($(pwd))
exec($(example _carapace xonsh))

# zsh
PATH=$PATH:$(pwd)
source <(example _carapace zsh)

example <TAB>

or use docker-compose:

docker-compose pull
docker-compose run --rm build
docker-compose run --rm [bash|elvish|fish|ion|nushell|oil|powershell|tcsh|xonsh|zsh]

example <TAB>

Projects

  • carapace-bin multi-shell multi-command argument completer
  • go-jira-cli simple jira command line client
  • knoxite A data storage & backup system
  • lab cli client for GitLab
Comments
  • global `ActionMap` caching / completion initialization

    global `ActionMap` caching / completion initialization

    I have a json that holds all the information necessary to compose completion. Launching the command that generates that json takes up to 3 seconds in extreme cases (yeah, bad).

    [{"cell":"std","organelles":[{"clade":"runnables","organelle":"cli","readme":"/nix/store/0v43f20l1n9i2gcwrx7k7aab2wfz9qlg-cells/std/cli/Readme.md","targets":[{"actions":[{"description":"exec this target","name":"run"}],"deps":[],"description":"A tui for projects that conform to Standard","name":"default","readme":"/nix/store/0v43f20l1n9i2gcwrx7k7aab2wfz9qlg-cells/std/cli/default.md"}]},{"clade":"functions","organelle":"lib","readme":"/nix/store/0v43f20l1n9i2gcwrx7k7aab2wfz9qlg-cells/std/lib/Readme.md","targets":[{"actions":[],"deps":[],"description":"n/a","name":"fromMakesWith","readme":"/nix/store/0v43f20l1n9i2gcwrx7k7aab2wfz9qlg-cells/std/lib/fromMakesWith.md"},{"actions":[],"deps":[],"description":"n/a","name":"mkShell","readme":""}]},{"clade":"functions","organelle":"devshellProfiles","readme":"/nix/store/0v43f20l1n9i2gcwrx7k7aab2wfz9qlg-cells/std/devshellProfiles/Readme.md","targets":[{"actions":[],"deps":[],"description":"n/a","namestd/devshellProfiles/default.md"}]},{"clade":"devshells","organelle":"devshells","readme":"","targets":[{"actions":[{"description":"enter this devshell","name":"enter"}],"deps":[],"description":"n/a","name":"default","readme":""}]},{}],"readme":"/nix/store/0v43f20l1n9i2gcwrx7k7aab2wfz9qlg-cells/std/Readme.md"}]
    

    After transforming this into an ActionMap of carapace.ActionValues() I want to cache the entire ActionMap for ~30 sec, so that subsequent completions during the same completion "session" don't take 3 seconds each.

    What can I do?

  • ZSH grouped/aliased completions

    ZSH grouped/aliased completions

    arguments options

    Features and enhancements

    This PR enhances ZSH completion with multiple new features. Most of them rely on using the _describe helper rather than compadd.

    ZSH specific

    • Completions can now be grouped together under a description, with action.Group(name).
    • Completions being aliases of each other (-f/--files, or command aliases) are now displayed together in completion listings.
    • Zstyle coloring has been adapted to still work despite those changes.
    • Padding dynamically and smartly computed, depending on the current "profile" of the completions.
    • Messages are now displayed through the _message ZSH helper, which now allows us to pass messages of arbitrary length, and with arbitrary color formatting within them (therefore, and provided left at the discretion of the library user).
    • Better suffix autoremoval, with patterns passed to the compadd calls, for instance autoremoval of a space suffix when another space is entered, or when a non-nil character is typed (with NoOptDefVal flags). Also used in list completions.

    Other/all shells

    • Flags that are marked repeatable (slices and maps) now use a default multiparts completer with a comma list item separator.

    Major changes to the code

    • The ZSH snippet has been modified so as to loop over an arbitrary number of groups, and generate their completions accordingly. It does also parses a header for each group, containing its tag and group description.
    • The ZSH Go code has been rewritten (entirely), in order to account for all the changes and cases to be considered. The code is heavily commented, so as to ease understanding the logic involved, the constraints faced, etc. I pretend this code to be shielded from most edge cases. See below.
    • The action used to generate command completions has been modified to structure them by groups, if there are any (takes advantage of this new cobra v.1.6.0 feature).
    • The ActionMessage() has been rewritten, because I had to find a way to pass messages to the final ActionRawValues() functions, while preserving compatibility with other shells. See below as well. A corresponding function call has been added in all shells Go code, except for ZSH which does different.
    • The common.RawValue type now has a Tag and a Group field. This is so that people can still generate as many actions from a base one (shoutouts to how you devised this library). See this file for an example where I make use of these groups (as well as of the old and new carapace features)
    • Merge() has been slightly modified to preserve the order in which completions (therefore groups) were added.
    • ZSH sanitizers have been very slightly modified, in order to acomodate for the changes, and placed into a file of their own.
  • Alias completion support

    Alias completion support

    I was looking to add support for git aliases in carapace-bin but I'm hitting a wall. To clarify, I don't want it to be able to autocomplete the names of aliases as git subcommands, but I want it to actually resolve the alias into whatever it is and continue autocompletion from there.

    So for example, if I have a git alias po = push origin, not only do I want git p<TAB> to suggest git po but I want git po <TAB> to autocomplete branches as if I typed git push origin <TAB>. I looked into the docs to and the closest thing that seemed relevant was PreInvoke but even then that didn't work when I tried it.

    Currently, I'm working around this by resolving the alias in my shell and then calling carapace to complete it but it would be great if this can be built in to carapace itself.

  • ActionMultiparts: support all divider variants

    ActionMultiparts: support all divider variants

    Not all dividers from the example are working in each shell. This is mostly due to how the shell is handling argument splitting.

    bash:

    • [x] @
    • [x] :
    • [x] ,
    • [x] .
    • [x] ...
    • [x] =
    • [x] (none)
    • [x] /

    elvish:

    • [x] @
    • [x] :
    • [x] ,
    • [x] .
    • [x] ...
    • [x] =
    • [x] (none)
    • [x] /

    fish:

    • [x] @
    • [x] :
    • [x] ,
    • [x] .
    • [x] ...
    • [x] =
    • [x] (none)
    • [x] /

    ion:

    • [x] @
    • [x] :
    • [x] ,
    • [x] .
    • [x] ...
    • [x] =
    • [x] (none)
    • [x] /

    nushell:

    • [x] @
    • [x] :
    • [x] ,
    • [x] .
    • [x] ...
    • [x] =
    • [x] (none)
    • [x] /

    oil:

    • [x] @
    • [x] :
    • [x] ,
    • [x] .
    • [x] ...
    • [x] =
    • [x] (none)
    • [x] /

    powershell:

    • [x] @
    • [x] :
    • [x] ,
    • [x] .
    • [x] ...
    • [x] =
    • [x] (none)
    • [x] /

    xonsh:

    • [x] @
    • [x] :
    • [x] ,
    • [x] .
    • [x] ...
    • [x] =
    • [x] (none)
    • [x] /

    zsh:

    • [x] @
    • [x] :
    • [x] ,
    • [x] .
    • [x] ...
    • [x] =
    • [x] (none)
    • [x] /
  • elvish: should default to `edit:complete-filename` if no match is found by carapace

    elvish: should default to `edit:complete-filename` if no match is found by carapace

    Currently, a lot of the completers feel broken in elvish because it prints an error if carapace cannot find a completion.

    Simple example:

    # navigate to carapace git project
    hx action.go # nake some changes
    # check changes
    git diff a<TAB>
    

    Expected: autocomplete to action, then a new tab will show:

     COMPLETING argument  
    action.go  action_test.go
    

    This would happen if the snippet defaults to edit:complete-filename if carapace fails the match:

    https://github.com/rsteube/carapace/blob/e961a1d209980f253febf405dfdd63ded9786b8c/internal/shell/elvish/snippet.go#L12-L21

  • Error running tests on NixOS

    Error running tests on NixOS

    I'm trying to package carapace 0.12.3 for NixOS, but I get this:

    == RUN   TestActionDirectories
        assert.go:21:
            1c1
            < {Action:{rawValues:[{Value:docs/ Display:docs/ Description:} {Value:example/ Display:example/ Description:} {Value:internal/ Display:internal/ Description:} {Value:pkg/ Display:pkg/ Description:}] callback:<nil> nospace:true skipcache:false}}
            ---
            > {Action:{rawValues:[{Value:docs/ Display:docs/ Description:} {Value:example/ Display:example/ Description:} {Value:internal/ Display:internal/ Description:} {Value:pkg/ Display:pkg/ Description:} {Value:vendor/ Display:vendor/ Description:}] callback:<nil> nospace:true skipcache:false}}
    
        assert.go:21:
            1c1
            < {Action:{rawValues:[{Value:./docs/ Display:docs/ Description:} {Value:./example/ Display:example/ Description:} {Value:./internal/ Display:internal/ Description:} {Value:./pkg/ Display:pkg/ Description:}] callback:<nil> nospace:true skipcache:false}}
            ---
            > {Action:{rawValues:[{Value:./docs/ Display:docs/ Description:} {Value:./example/ Display:example/ Description:} {Value:./internal/ Display:internal/ Description:} {Value:./pkg/ Display:pkg/ Description:} {Value:./vendor/ Display:vendor/ Description:}] callback:<nil> nospace:true skipcache:false}}
    
    --- FAIL: TestActionDirectories (0.00s)
    === RUN   TestActionFiles
        assert.go:21:
            1c1
            < {Action:{rawValues:[{Value:README.md Display:README.md Description:} {Value:docs/ Display:docs/ Description:} {Value:example/ Display:example/ Description:} {Value:internal/ Display:internal/ Description:} {Value:pkg/ Display:pkg/ Description:}] callback:<nil> nospace:true skipcache:false}}
            ---
            > {Action:{rawValues:[{Value:README.md Display:README.md Description:} {Value:docs/ Display:docs/ Description:} {Value:example/ Display:example/ Description:} {Value:internal/ Display:internal/ Description:} {Value:pkg/ Display:pkg/ Description:} {Value:vendor/ Display:vendor/ Description:}] callback:<nil> nospace:true skipcache:false}}
    

    My go is not good enough to understand the problem, though. Can you help?

  • zsh: don't promote sourcing completion file

    zsh: don't promote sourcing completion file

    https://medium.com/@jzelinskie/please-dont-ship-binaries-with-shell-completion-as-commands-a8b1bcb8a0d0

    Sourcing completion files in zsh is common antipattern. Regular completion file should contain only code of completion function (source of _command), there is no need to declare function itself. Especially there shouldn't be any calls from compdef, this breaks completion if you you want to install completion file properly under $fpath, where it can be autoloaded on call. Usually it's task for package manager to put _command file under correct path.

  • zsh:  completion broken

    zsh: completion broken

    #compdef go
    function _go_completion {  
      local vals=("-replace" "-require")
      local displays=("-replace:add a module replacement" "-require:add a requirement")
      _describe -t "sometag" "sometag" displays vals
    }
    compquote '' 2>/dev/null && _go_completion
    compdef _go_completion go
    

    completes to:

    go -reQ
    
  • ActionInvoke: locking mutex

    ActionInvoke: locking mutex

    ActionInvoke cannot be used in Batch as it is changing os.Stdout. either change it that os.Stdout is not needed or somehow ensure concurrency is not a problem (locking mutex - though that would contradict the parallel execution in Batch)

  • Discussion of suffix-autoremoval behaviors in ZSH

    Discussion of suffix-autoremoval behaviors in ZSH

    Hello Rob, Opening this ticket more for the sake of discussion and listing various cases than to propose a precise thing to do. So here I'm basically looking at how the ZSH completion system might play with your SuffixMatcher model.

    A few things outright:

    • Your SuffixMatcher-based model, from what I saw and tested, is reliable and predictable. Also simplifies greatly the logic for people writing completers.
    • Hence the need, if any of the following would be useful, to proceed by little touches and steps, while ensuring each does not produce unwanted edge cases.
    • Again, given the subject considered here, the need to discuss and check all paths before doing anything else.

    Constraints

    • None of the logic and modifications to the values can be done anywhere else than in the shell/zsh package.
    • Carapace is ultimately in control of what should be: zsh "should not take initiatives" on its own, otherwise would risk doing the wrong thing.

    ZSH options of interest

    Three options appear in the documentation that are relevant here (one of which already used as -S ''):

    -S suffix
        Like -P, but gives a string to be inserted after each match.
    
    -q
        The suffix given with -S will be automatically removed if the next character typed is a blank or does not insert anything, 
        or if the suffix consists of only one character and the next character typed is the same character.
        
    -r remove-chars
        This is a more versatile form of the -q option. The suffix given with -S or the slash automatically added after completing 
        directories will be automatically removed if the next character typed inserts one of the characters given in the remove-chars. 
        This string is parsed as a characters class and understands the backslash sequences used by the print command. 
        For example, ‘-r "a-z\t"’ removes the suffix if the next character typed inserts a lower case character or a TAB, and ‘-r "^0-9"’ 
        removes the suffix if the next character typed inserts anything but a digit. One extra backslash sequence is understood in this 
        string: ‘\-’ stands for all characters that insert nothing. Thus ‘-S "=" -q’ is the same as ‘-S "=" -r "= \t\n\-"’.
    
        This option may also be used without the -S option; then any automatically added space will be removed when one of the characters 
        in the list is typed.
    

    Notes:

    • -q is interesting in that it applies relatively sane suffix-autoremoval without carapace having to mess with populating -r with the right patterns: hence -q is useful for things like paths slashes and list separators.
    • -r gives much finer-grained control, but at the expense of more things to take care of, thus more work upfront.

    Example with slashes in directory paths

    Note that this example cannot be taken as a general rule, but just as first step to visualize the process.

    Consider the following values returned by carapace (here all values are strictly equal to their display values):

    Downloads/ Public/ code/
    

    Those values are probably invoked with either NoSpace() or NoSpace('/'). Thus, what might done:

    1. The SuffixMatcher matches the values.
    2. Remove the suffix from the value (but never put it in the display, because might introduce redundancies)
    3. Pass the removed suffix / to the -S flag in zsh code.
    4. Either:
      • Simply pass -q to zsh completions, which will remove the slah if either a slash or a blank char is inserted after.
      • Pass the removed suffix to -r. (I strongly fear, writing this, that -r will be overkill in most cases, and will actually introduce many behavior inconsistencies.)

    Example with list separators in option args

    Consider the following command line (| is the cursor here):

    command -f value1,|
    

    and the following completions (with trailing spaces not in the completions themselves):

    value2 value3 value4
    

    Those values are probably invoked with either NoSpace() or NoSpace(','). Thus, similarly to paths:

    1. The SuffixMatcher does not match any value (if NoSpace(',')): add the trailing comma with -S instead of appending the values themselves.
    2. The -q flag in zsh here will ensure that:
      • If a space/blank char is then typed, the net result is nil: a space is left after value1
      • If a comma is inserted, the same behavior applies; net result is 0, comma is left, completion continues with value2, 3, etc ...
      • If any non-nil character is typed, it is assumed its another item of the list: keep the comma.

    Hope this will be useful in some way or another !

  • Enable use of carapace completer as a library

    Enable use of carapace completer as a library

    Hello Rob, here again for a feature request, which will litterally save me.

    Main subject

    In the context of three projects of mine,

    ... I need to be able to use the carapace completer from within a shell program. Not only that, but on top of it (and that is because the Complete() function of this commit also returns the common.Meta), it enables the readline shell library to have as fine-grained a control over the suffix pattern matchers.

    So basically this commit is way, way less complex than the previous PRs I've submitted: it just Exports the main Complete() function, and returns the RawValues and the Meta. It makes the necessary adjustements for the traditional cobra _carapace command.

    Needless to say it again, on this PR rests the entire future of the projects above, and be sure that if accepted, they would have a definite edge over what exists in the space at present. Having a full-fledged CLI application will become as trivial as it can be.

    I would love to present you a demonstration of the results right now: it's running great. It's just in my go workspace for now and I'm polishing a few things before pushing it.

    Remarks on this PR code

    • If I were to object to my own work: so your exported API is clean and small. Additionally, there is no way to move any further completion logic internally (and there is absolutely no problem with that, don't get me wrong), so maybe the name of the exported Complete() could be changed to something more explicit, or something that would ensure no one will use it mistakingly. (On the other hand, Complete() is fine if one considers that none of your API functions start with this verb)
    • Your last 4 commits (flags tests) have not been merged in this branch, although it seems to me that they are not conflicting.
    • I added a / NoSpace suffix matcher to path completion: as far as my library is concerned (but I guess it applies to all), it further enhances the default spacing and autosuffix removal for path completion/insertion when the candidate is a directory (and only if a directory).
    • A thousand times sorry for my pesky editor adding dots to comments everywhere. I'll find a way to deactivate that, just did'nt look into it yet...

    Additional things.

    So I got over your code /recent commits (which I get to know quite well by now), or just used it within the course of the aforementioned projects, and I got to remember that there were a few side-fixes in my other PRs (for instance, better error filtering when flags raise errors because they've not been fed a result yet). And some other things, or suggestions. I'll open separate (and each of them very small, I promess) PRs for those, so that you can cherry pick.

    Once again, really great, great work with this library. I don't cease to be amazed at what you've done.

  • Export `install` command, too

    Export `install` command, too

    Since carapace has context awareness for a lot of shells, it is a good place to improve dx for users to implement install which would typically append a shell-specific string to a shell-specific rc-file.

  • allow skipping of flag parse errors

    allow skipping of flag parse errors

    Allow flag parse errors when a specific environment variable is set (CARAPACE_LENIENT?).

    • set FParseErrWhitelist on every (sub)command
    	FParseErrWhitelist: cobra.FParseErrWhitelist{
    		UnknownFlags: true,
    	},
    
    • assume unknown flags to be bool/optarg (or whatever pflag does)
    • default to file completion

    This won't give correct completion but might provide a temporary solution when a completer in carapace-bin is missing a flag.

    related https://github.com/rsteube/carapace-bin/issues/1417

bash completion written in go + bash completion for go command

complete Package complete is everything for bash completion and Go. The main development is done on the master branch, please follow the link to see a

Dec 20, 2022
minigli is a tiny command argument parser for Go.

minigli is a tiny command argument parser for Go.

Jan 29, 2022
Fully featured Go (golang) command line option parser with built-in auto-completion support.

go-getoptions Go option parser inspired on the flexibility of Perl’s GetOpt::Long. Table of Contents Quick overview Examples Simple script Program wit

Dec 14, 2022
Pure Go command line prompt with history, kill-ring, and tab completion

Prompt Prompt is a command line prompt editor with history, kill-ring, and tab completion. It was inspired by linenoise and derivatives which eschew u

Nov 20, 2021
This project is used to get familiar with GoLang cli apps, along with cobra generator.

SecretCTL SecretCTL About the project Status Getting started Layout Notes About the project This project is used to get familiar with GoLang cli apps,

Jan 11, 2022
A collection of CLI argument types for the Go `flag` package.

flagvar A collection of CLI argument types for the flag package. import "github.com/sgreben/flagvar" Or just copy & paste what you need. It's public d

Sep 26, 2022
Struct-based argument parsing in Go
Struct-based argument parsing in Go

go-arg Struct-based argument parsing for Go Declare command line arguments for your program by defining a struct. var args struct { Foo string Bar b

Jan 8, 2023
The blackbean is a command tool for elasticsearch operations by using cobra.
The blackbean is a command tool for elasticsearch operations by using cobra.

The blackbean is a command tool for elasticsearch operations by using cobra. Besides, blackbean is the name of my lovely French bulldog.

Mar 3, 2022
cod is a completion daemon for bash/fish/zsh

Cod is a completion daemon for {bash,fish,zsh}. It detects usage of --help commands parses their output and generates auto-completions for your shell.

Dec 25, 2022
Simple trie based auto-completion engine implementation in golang.
Simple trie based auto-completion engine implementation in golang.

Simple auto-complete engine implementation in golang. Quick start $ git clone https://github.com/benbarron/trie-auto-completion-engine $ cd trie-auto-

Jul 12, 2022
Build an interactive CLI application with Go, Cobra and promptui. Video tutorial available on the Div Rhino YouTube channel.

Build an interactive CLI app with Go, Cobra and promptui Text tutorial: https://divrhino.com/articles/build-interactive-cli-app-with-go-cobra-promptui

Dec 8, 2022
Prompts users to enter values for required flags in Cobra CLI applications

Cobra Flag Prompt Cobra Flag Prompt prompts users to enter values for required flags. It is an extension of Cobra, and requires that you use Cobra to

Nov 13, 2021
Generate an interactive, autocompleting shell for any Cobra CLI
Generate an interactive, autocompleting shell for any Cobra CLI

cobra-shell Description Leverages the Cobra completion API to generate an interactive shell for any Cobra CLI, powered by go-prompt. On-the-fly autoco

Dec 19, 2022
A cli client-server app with cobra
A cli client-server app with cobra

cli-client-server-calculator a cli client-server app with cobra overview this project is a cli client-server app in which client gives a bunch of numb

Dec 7, 2021
Cobra CLI challenge Segsalerty

Banking app done using Cobra CLI - Segsalerty challenge c/o Segun Mustafa It uses a database.json file as datastore for queries - createCustomer, Upda

Dec 14, 2021
Reusable golang-migrate library using cobra utility

shift Reusable golang-migrate library using cobra utility Example Usage package main import ( "sql/db" "github.com/purwandi/shift" "github.com

Dec 16, 2021
CLI to run a docker image with R. CLI built using cobra library in go.
CLI  to run a docker image with R. CLI built using cobra library in go.

BlueBeak Installation Guide Task 1: Building the CLI The directory structure looks like Fastest process: 1)cd into bbtools 2)cd into bbtools/bin 3)I h

Dec 20, 2021
Go-file-downloader-ftctl - A file downloader cli built using golang. Makes use of cobra for building the cli and go concurrent feature to download files.

ftctl This is a file downloader cli written in Golang which uses the concurrent feature of go to download files. The cli is built using cobra. How to

Jan 2, 2022