complete

package module
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 9, 2026 License: MIT Imports: 7 Imported by: 3

README

libgo-complete

Shell auto-completion for a Go program, answered by the program itself. No completion script to write, and nothing to keep in step with the command line as it changes.

go get github.com/mslmio/libgo-complete

Zero dependencies outside the standard library. bash, zsh and fish.

How it works

bash can hand completion to an arbitrary command (complete -C): it runs your binary with COMP_LINE set to what the user has typed and reads candidates from standard output. So the shell integration is one line in a startup file, and the thing that knows your commands is the thing answering.

Using it

Describe the command line as a tree, and complete before you parse flags:

var completions = &complete.Command{
    Sub: map[string]*complete.Command{
        "lookup": {
            Flags: map[string]complete.Predictor{
                "--json":  predict.Nothing,
                "--field": predict.Set([]string{"ip", "is_vpn", "vpn.provider"}),
            },
        },
        "database": {
            Sub: map[string]*complete.Command{
                "list":     {},
                "download": {Flags: map[string]complete.Predictor{
                    "--format": predict.Set([]string{"csvgz", "mmdb"}),
                }},
            },
        },
    },
    Flags: map[string]complete.Predictor{"--help": predict.Nothing},
}

func main() {
    completions.Complete("mytool")
    // ... normal argument handling ...
}

Complete returns immediately unless the shell is asking, so a normal run pays one getenv.

Predictors are predict.Nothing for a boolean flag, after which the level's options are offered again, predict.Something for a flag whose value nothing can predict, predict.Set for a fixed list, predict.Files/predict.Dirs for paths, and predict.Func for anything you compute.

Installing into the user's shell

install.Install("mytool")    // every shell present on the machine
install.Uninstall("mytool")
install.BashCmd("mytool")    // or print the line for manual installation

A startup file is only created for a shell that is actually installed, so a machine without zsh does not grow a ~/.zshrc. Uninstall takes out only the lines Install added, so the bashcompinit line another tool's completion in ~/.zshrc needs stays, and it writes through a neighboring file and renames, so an interrupted run cannot leave a truncated startup file.

Prior art

posener/complete established this approach in Go and is worth reading. This is an independent implementation with a smaller surface and no dependencies.

License

MIT.

Documentation

Overview

Package complete gives a Go program shell auto-completion of its own command line, with no completion script to write or maintain.

The mechanism is the one bash exposes through `complete -C`: the shell runs the binary itself with COMP_LINE set to what the user has typed so far, and reads candidate completions from its standard output. So the program that knows its own commands is the one answering, and the shell integration is a single line in a startup file.

Describe the command line as a tree and hand it to Command.Complete before parsing flags:

var completions = &complete.Command{
    Sub: map[string]*complete.Command{"lookup": completionsLookup},
    Flags: map[string]complete.Predictor{"--json": predict.Nothing},
}

func main() {
    completions.Complete("mytool")
    // ... normal argument handling ...
}

Complete returns immediately when the environment is not a completion request, so the call costs one getenv on a normal run.

Prior art: posener/complete, which established this approach in Go.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Arg

type Arg struct {
	// Text is the word with quoting and escapes resolved.
	Text string
	// Completed is false for the word the cursor sits in, which is the one
	// being completed rather than one already given.
	Completed bool
}

Arg is one word of a command line as the shell would split it.

func Parse

func Parse(line string) []Arg

Parse splits a command line the way a POSIX shell would, honoring single quotes, double quotes and backslash escapes.

The final word is Completed only when the line ends in unquoted whitespace. That distinction is the whole point: "cmd data" is completing the word "data", while "cmd data " is starting a fresh one, and the shell tells the difference only through that trailing space.

type Command

type Command struct {
	// Sub are the subcommands available at this level, keyed by name.
	Sub map[string]*Command

	// Flags are the flags accepted at this level, keyed by the flag as typed
	// including its dashes. The value predicts that flag's VALUE; use
	// predict.Nothing for a boolean flag.
	Flags map[string]Predictor

	// Args predicts positional arguments at this level.
	Args Predictor
}

Command describes one level of a command line.

A nil *Command is a valid leaf that predicts nothing, so a tree may name a subcommand it has nothing to say about yet.

func (*Command) Complete

func (c *Command) Complete(name string)

Complete answers a shell completion request and exits.

It does nothing and returns when COMP_LINE is unset, which is every ordinary run. name is the command as the user types it, used only by installation.

type PredictFunc

type PredictFunc func(prefix string) []string

PredictFunc adapts a function to Predictor. A nil PredictFunc predicts nothing, and as a flag's predictor it marks a flag that takes no value.

func (PredictFunc) Predict

func (f PredictFunc) Predict(prefix string) []string

Predict implements Predictor.

type Predictor

type Predictor interface {
	// Predict returns candidates for prefix. Returning candidates that do not
	// share the prefix is allowed; they are filtered out before they reach the
	// shell, so a predictor may ignore the prefix entirely.
	Predict(prefix string) []string
}

Predictor offers candidate completions for a partly-typed word.

Directories

Path Synopsis
Package install wires a binary's self-completion into the user's shell.
Package install wires a binary's self-completion into the user's shell.
Package predict holds the completion predictors a command tree is built from.
Package predict holds the completion predictors a command tree is built from.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址