Tab completion for System.CommandLine

Important

System.CommandLine is currently in PREVIEW, and this documentation is for version 2.0 beta 4. Some information relates to prerelease product that may be substantially modified before it's released. Microsoft makes no warranties, express or implied, with respect to the information provided here.

Apps that use System.CommandLine have built-in support for tab completion in certain shells. To enable it, the end user has to take a few steps once per shell. Once the user does this, tab completion is automatic for static values in your app, such as enum values or values you define by calling FromAmong. You can also customize the tab completion by getting values dynamically at runtime.

Enable tab completion

On the machine where you'd like to enable tab completion, do the following steps.

For the .NET CLI:

For other command-line apps built on System.CommandLine:

  • Install the dotnet-suggest global tool.

  • Add the appropriate shim script to your shell profile. You may have to create a shell profile file. The shim script forwards completion requests from your shell to the dotnet-suggest tool, which delegates to the appropriate System.CommandLine-based app.

    • For bash, add the contents of dotnet-suggest-shim.bash to ~/.bash_profile.

    • For zsh, add the contents of dotnet-suggest-shim.zsh to ~/.zshrc.

    • For PowerShell, add the contents of dotnet-suggest-shim.ps1 to your PowerShell profile. You can find the expected path to your PowerShell profile by running the following command in your console:

      echo $profile
      

Once the user's shell is set up, completions will work for all apps that are built by using System.CommandLine.

For cmd.exe on Windows (the Windows Command Prompt) there is no pluggable tab completion mechanism, so no shim script is available. For other shells, look for a GitHub issue that is labeled Area-Completions. If you don't find an issue, you can open a new one.

Get tab completion values at run-time

The following code shows an app that gets values for tab completion dynamically at runtime. The code gets a list of the next two weeks of dates following the current date. The list is provided to the --date option by calling AddCompletions:

using System.CommandLine;
using System.CommandLine.Completions;
using System.CommandLine.Parsing;

await new DateCommand().InvokeAsync(args);

class DateCommand : Command
{
    private Argument<string> subjectArgument = 
        new ("subject", "The subject of the appointment.");
    private Option<DateTime> dateOption = 
        new ("--date", "The day of week to schedule. Should be within one week.");
    
    public DateCommand() : base("schedule", "Makes an appointment for sometime in the next week.")
    {
        this.AddArgument(subjectArgument);
        this.AddOption(dateOption);

        dateOption.AddCompletions((ctx) => {
            var today = System.DateTime.Today;
            var dates = new List<CompletionItem>();
            foreach (var i in Enumerable.Range(1, 7))
            {
                var date = today.AddDays(i);
                dates.Add(new CompletionItem(
                    label: date.ToShortDateString(),
                    sortText: $"{i:2}"));
            }
            return dates;
        });

        this.SetHandler((subject, date) =>
            {
                Console.WriteLine($"Scheduled \"{subject}\" for {date}");
            },
            subjectArgument, dateOption);
    }
}

The values shown when the tab key is pressed are provided as CompletionItem instances:

dates.Add(new CompletionItem(
    label: date.ToShortDateString(),
    sortText: $"{i:2}"));

The following CompletionItem properties are set:

  • Label is the completion value to be shown.
  • SortText ensures that the values in the list are presented in the right order. It's set by converting i to a two-digit string, so that sorting is based on 01, 02, 03, and so on, through 14. If you don't set this parameter, sorting is based on the Label, which in this example is in short date format and won't sort correctly.

There are other CompletionItem properties, such as Documentation and Detail, but they aren't used yet in System.CommandLine.

The dynamic tab completion list created by this code also appears in help output:

Description:
  Makes an appointment for sometime in the next week.

Usage:
  schedule <subject> [options]

Arguments:
  <subject>  The subject of the appointment.

Options:
  --date                                                                          The day of week to schedule. Should be within one week.
  <2/4/2022|2/5/2022|2/6/2022|2/7/2022|2/8/2022|2/9/2022|2/10/2022>
  --version                                                                       Show version information
  -?, -h, --help

See also

System.CommandLine overview