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 appropriateSystem.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 convertingi
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 theLabel
, 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