Skip to content

Completion

Generate shell completion scripts with argcomplete.

User guide: Shell completion.

Usage

from clak import CompCmdRender, Command, Parser

class App(Parser):
    completion = Command(CompCmdRender, help="Print shell completion script")
eval "$(python myapp.py completion --executable myapp --shell bash)"

clak.comp.completion

Register a Python executable for use with the argcomplete module.

To perform the registration, source the output of this script in your bash shell (quote the output to avoid interpolation).

Example:

$ eval "$(register-python-argcomplete my-favorite-script.py)"

For Tcsh

$ eval `register-python-argcomplete --shell tcsh my-favorite-script.py`

For Fish

$ register-python-argcomplete --shell fish my-favourite-script.py         > ~/.config/fish/my-favourite-script.py.fish

CompCmdRender

Bases: CompRenderCmdMixin, Parser

Command completion renderer class.

Combines the CompRenderCmdMixin with the base Parser to create a class that can render command completion code. This class provides the core functionality for generating shell completion scripts for command-line tools.

Key features: - Generates shell completion code for bash/tcsh/fish - Supports external completion scripts - Configurable executable names - Default completion behavior

Source code in clak/comp/completion.py
class CompCmdRender(CompRenderCmdMixin, Parser):
    """Command completion renderer class.

    Combines the CompRenderCmdMixin with the base Parser to create a class that can
    render command completion code. This class provides the core functionality for
    generating shell completion scripts for command-line tools.

    Key features:
    - Generates shell completion code for bash/tcsh/fish
    - Supports external completion scripts
    - Configurable executable names
    - Default completion behavior
    """

CompRenderCmdMixin

Bases: CompRenderMixin

Completion command support

Source code in clak/comp/completion.py
class CompRenderCmdMixin(CompRenderMixin):
    "Completion command support"

    use_defaults = Argument(
        "--no-defaults",
        # dest="use_defaults",
        action="store_false",
        default=True,
        help="when no matches are generated, do not fallback to readline's"
        + " default completion (affects bash only)",
    )
    complete_arguments = Argument(
        "--complete-arguments",
        nargs=argparse.REMAINDER,
        help="arguments to call complete with; use of this option discards default"
        + " options (affects bash only)",
    )
    shell = Argument(
        "-s",
        "--shell",
        choices=("bash", "zsh", "tcsh", "fish", "powershell"),
        default="bash",
        help="output code for the specified shell",
    )
    external_argcomplete_script = Argument(
        "-e",
        "--external-argcomplete-script",
        help=argparse.SUPPRESS,
        # help="external argcomplete script for auto completion of the executable"
    )
    executable = Argument(
        "--executable",
        nargs="+",
        help=argparse.SUPPRESS,
        default=None,
    )

    def cli_run(self, ctx, **kwargs):  # pylint: disable=unused-argument
        """Command completion support mixin.

        Adds command completion support to parsers by providing arguments to configure
        shell completion behavior:

        - --no-defaults: Disable fallback to readline defaults (bash only)
        - --complete-arguments: Custom completion arguments (bash only)
        - --shell: Target shell (bash, zsh, tcsh, fish, powershell)
        - --executable: Name of executable to complete

        The mixin generates the appropriate shell completion code when run.
        Supports bash (default), zsh, tcsh, fish and powershell shells.

        Example:
            my-app completion  # Outputs bash completion code
            my-app completion --shell zsh  # Outputs zsh completion code
        """

        args = ctx.args
        executable = getattr(args, "executable", None)
        if not executable:
            prog = getattr(ctx, "app_proc_name", None) or getattr(
                ctx.cli_root, "proc_name", None
            )
            if not prog:
                prog = sys.argv[0]
            args.executable = [prog]
        self.print_completion_stdout(args)

cli_run(ctx, **kwargs)

Command completion support mixin.

Adds command completion support to parsers by providing arguments to configure shell completion behavior:

  • --no-defaults: Disable fallback to readline defaults (bash only)
  • --complete-arguments: Custom completion arguments (bash only)
  • --shell: Target shell (bash, zsh, tcsh, fish, powershell)
  • --executable: Name of executable to complete

The mixin generates the appropriate shell completion code when run. Supports bash (default), zsh, tcsh, fish and powershell shells.

Example

my-app completion # Outputs bash completion code my-app completion --shell zsh # Outputs zsh completion code

Source code in clak/comp/completion.py
def cli_run(self, ctx, **kwargs):  # pylint: disable=unused-argument
    """Command completion support mixin.

    Adds command completion support to parsers by providing arguments to configure
    shell completion behavior:

    - --no-defaults: Disable fallback to readline defaults (bash only)
    - --complete-arguments: Custom completion arguments (bash only)
    - --shell: Target shell (bash, zsh, tcsh, fish, powershell)
    - --executable: Name of executable to complete

    The mixin generates the appropriate shell completion code when run.
    Supports bash (default), zsh, tcsh, fish and powershell shells.

    Example:
        my-app completion  # Outputs bash completion code
        my-app completion --shell zsh  # Outputs zsh completion code
    """

    args = ctx.args
    executable = getattr(args, "executable", None)
    if not executable:
        prog = getattr(ctx, "app_proc_name", None) or getattr(
            ctx.cli_root, "proc_name", None
        )
        if not prog:
            prog = sys.argv[0]
        args.executable = [prog]
    self.print_completion_stdout(args)

CompRenderMixin

Completion support Methods

Source code in clak/comp/completion.py
class CompRenderMixin:  # pylint: disable=too-few-public-methods
    "Completion support Methods"

    def print_completion_stdout(self, args: SimpleNamespace) -> None:
        """Print completion script to stdout.

        Generates and outputs shell completion code for the specified executable using argcomplete.
        The completion script enables tab completion for commands and arguments.

        Args:
            args: Namespace containing completion configuration:
                executable: Name of executable to enable completion for
                use_defaults: Whether to fallback to readline defaults (bash only)
                shell: Target shell (bash, zsh, tcsh, fish, powershell)
                complete_arguments: Optional arguments to pass to complete command
                external_argcomplete_script: Optional external completion script
        """

        sys.stdout.write(
            argcomplete.shellcode(
                args.executable,
                args.use_defaults,
                args.shell,
                args.complete_arguments,
                args.external_argcomplete_script,
            )
        )

print_completion_stdout(args)

Print completion script to stdout.

Generates and outputs shell completion code for the specified executable using argcomplete. The completion script enables tab completion for commands and arguments.

Parameters:

Name Type Description Default
args SimpleNamespace

Namespace containing completion configuration: executable: Name of executable to enable completion for use_defaults: Whether to fallback to readline defaults (bash only) shell: Target shell (bash, zsh, tcsh, fish, powershell) complete_arguments: Optional arguments to pass to complete command external_argcomplete_script: Optional external completion script

required
Source code in clak/comp/completion.py
def print_completion_stdout(self, args: SimpleNamespace) -> None:
    """Print completion script to stdout.

    Generates and outputs shell completion code for the specified executable using argcomplete.
    The completion script enables tab completion for commands and arguments.

    Args:
        args: Namespace containing completion configuration:
            executable: Name of executable to enable completion for
            use_defaults: Whether to fallback to readline defaults (bash only)
            shell: Target shell (bash, zsh, tcsh, fish, powershell)
            complete_arguments: Optional arguments to pass to complete command
            external_argcomplete_script: Optional external completion script
    """

    sys.stdout.write(
        argcomplete.shellcode(
            args.executable,
            args.use_defaults,
            args.shell,
            args.complete_arguments,
            args.external_argcomplete_script,
        )
    )

CompRenderOptMixin

Bases: CompRenderMixin

Completion options support mixin.

Adds a --completion flag that prints bash argcomplete shellcode instead of running the command. Prefer :class:CompCmdRender as a completion subcommand when you need --shell / --executable.

Example::

my-app --completion
Source code in clak/comp/completion.py
class CompRenderOptMixin(CompRenderMixin):
    """Completion options support mixin.

    Adds a ``--completion`` flag that prints bash argcomplete shellcode
    instead of running the command. Prefer :class:`CompCmdRender` as a
    ``completion`` subcommand when you need ``--shell`` / ``--executable``.

    Example::

        my-app --completion
    """

    completion_cmd = Argument(
        "--completion",
        action="store_true",
        help="output code for the specified shell",
    )

    def cli_run(self, ctx, **kwargs):
        """Print bash completion shellcode when ``--completion`` is set.

        Example::

            my-app --completion
        """

        args = ctx.args

        prog = getattr(ctx, "app_proc_name", None) or getattr(
            ctx.cli_root, "proc_name", None
        )
        if not prog:
            prog = sys.argv[0]

        kwargs = {
            "executable": [prog],
            "shell": "bash",
            "use_defaults": True,
            "complete_arguments": [],
            "external_argcomplete_script": None,
        }
        if args.completion_cmd is True:
            self.print_completion_stdout(SimpleNamespace(**kwargs))
        else:
            super().cli_run(ctx, **kwargs)

cli_run(ctx, **kwargs)

Print bash completion shellcode when --completion is set.

Example::

my-app --completion
Source code in clak/comp/completion.py
def cli_run(self, ctx, **kwargs):
    """Print bash completion shellcode when ``--completion`` is set.

    Example::

        my-app --completion
    """

    args = ctx.args

    prog = getattr(ctx, "app_proc_name", None) or getattr(
        ctx.cli_root, "proc_name", None
    )
    if not prog:
        prog = sys.argv[0]

    kwargs = {
        "executable": [prog],
        "shell": "bash",
        "use_defaults": True,
        "complete_arguments": [],
        "external_argcomplete_script": None,
    }
    if args.completion_cmd is True:
        self.print_completion_stdout(SimpleNamespace(**kwargs))
    else:
        super().cli_run(ctx, **kwargs)