Skip to content

Shell Completions

Warning

Shell completions are currently an experimental feature. There is no guarantee that they will work or if the API for using them will be stable. As such, the feature is disabled by default To enable shell completions, add the following to your script:

import arc
arc.configure(autocomplete=True)

The autocompletions will be generated with the following commands. foo is used as an example command entry point / name

Add to ~/.bashrc

eval "$(foo --autocomplete bash)"

Add to ~/.zshrc

eval "$(foo --autocomplete zsh)"

Add to ~/.config/fish/completions/foo.fish

foo --autocomplete fish | source

Type Completions

Argument types can provide shell completions for the argument.

For example, arc's builtin support for enum.Enum provides completions for it's possible options

examples/paint.py
from enum import Enum
import arc

arc.configure(autocomplete=True)


class Color(Enum):
    RED = "red"
    YELLOW = "yellow"
    GREEN = "green"


# Could also use:
# Color = Literal["red", "yellow", "green"]


@arc.command
def paint(color: Color):
    if color is Color.RED:
        arc.print("You painted the walls the bloodiest of reds")
    elif color is Color.YELLOW:
        arc.print("You painted the walls the most fabulous yellow")
    else:
        arc.print("You painted the walls the deepest of greens")


paint()

$ paint <tab>
red yellow green

The following types have builtin completion support:

  • enum.Enum
  • pathlib.Path
  • typing.Literal
  • arc.types.ValidPath
  • arc.types.FilePath
  • arc.types.DirectoryPath
  • arc.types.File.*

Custom Types

When implenting your own types, you can provide completions for them by implementing the __completions__() method on your class.

This method recieves an info object that contains information about the current state of the command line, and param which is the parameter that is being completed (in the below example, that parameter would be foo). The method should return an iterable of arc.Completion() objects that are the possible completions for the parameter.

examples/custom_type_completions.py
import arc


class CustomType:
    def __init__(self, val: int):
        self.val = val

    def __str__(self):
        return f"CustomType(val={self.val})"

    @classmethod
    def __convert__(cls, value: str):
        if value.isnumeric():
            return cls(int(value))
        else:
            raise arc.ConversionError(value, "must be an integer")

    @classmethod
    def __completions__(self, info: arc.CompletionInfo, param: arc.Param):
        yield arc.Completion("1")
        yield arc.Completion("2")


@arc.command
def main(foo: CustomType):
    arc.print(foo)


main()
$ custom_type_example <tab>
1 2

Parameter Completions

You can also provide completions on a parameter basis with the Command.complete decorator.

examples/param_completions.py
import arc


@arc.command
def command(name: str):
    arc.print(name)


@command.complete("name")
def names(info: arc.CompletionInfo, param: arc.Param):
    yield arc.Completion("Sean")
    yield arc.Completion("Brooke")


command()

$ param_completions <tab>
Sean Brooke