Skip to content

Custom completion per shell (zsh, bash, or fish) #672

@rgoldberg

Description

@rgoldberg

Problem

Different shells use different syntaxes for their completions.

e.g., zsh's _describe accepts a different syntax than bash's compgen.

The completion: parameter for @Argument & for @Option is used for all shells.

To the best of my knowledge, Swift Argument Parser (SAP) doesn't inform Swift the shell for which completions are being requested.

It is thus difficult to output the correct values to properly configure completion in multiple shells.

Versions

ArgumentParser version:
1.5.0

Swift version:
swift-driver version: 1.62.15 Apple Swift version 5.7.2 (swiftlang-5.7.2.135.5 clang-1400.0.29.51)
Target: x86_64-apple-macosx12.0

Checklist

  • If possible, I've reproduced the issue using the main branch of this package
  • I've searched for existing GitHub issues

Steps to Reproduce

  1. Look for some way to know what shell is requesting completions.
  2. Fail to find some way to know what shell is requesting completions.
  3. Profit!

Expected behavior

Ability to easily output completions that are correct for the current shell.

Actual behavior

Cannot easily output completions that are correct for the current shell.

Solution

There are many ways to solve this, but the simplest way to do so without changing the existing CompletionKinds or the completion: parameter of @Argument or @Option seems to be for SAP to provide a singleton CompletionShell named CompletionShell.requesting (requesting for short) that can be used by code supplying an associated value for a CompletionKind to determine the shell for which completions are being requested.

For .custom(:), requesting must be available at runtime when a completion script requests completions. For the other current CompletionKinds, requesting need only be available when a completion script is generated by using --generate-completion-script <shell>.

For .custom(:), each completion script generated by using --generate-completion-script <shell> will export an environment variable SAP_SHELL = <shell> so SAP can use it to populate requesting before it calls completion from .custom(:).

# bash
export SAP_SHELL=bash
# fish
set -x SAP_SHELL fish
# zsh
export SAP_SHELL=zsh

For the other current CompletionKinds, the *CompletionsGenerator.generateCompletionScript(type:) function will populate requesting with the correct value before calling the shell-specific *CompletionsGenerator.generateCompletionScript(:). Any function called to supply the associated value for these CompletionKinds can read requesting to determine the shell for which completions are being requested.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions