System.CommandLine 的 Tab 自动补全

重要

System.CommandLine 目前为预览版。 本文档适用于版本 2.0 beta 5。 某些信息与预发布产品有关,该产品可能在发布前进行大幅修改。 Microsoft对此处提供的信息不作任何明示或暗示的保证。

使用 System.CommandLine 的应用在某些 shell 中内置了对 Tab 自动补全的支持。 若要启用它,每次启动新的 shell 时,最终用户必须执行几个步骤。 完成此操作后,应用中的静态值(例如枚举值或通过调用 AcceptOnlyFromAmong(String[]) 定义的值)将使用 Tab 键自动补全。 你还可以通过在运行时动态提供值来定制 Tab 键补全功能。

启用Tab键补全

在想要启用 Tab 键补全功能的计算机上,执行以下步骤。

对于 .NET CLI:

对于其他基于System.CommandLine构建的命令行应用:

  • 安装 dotnet-suggest 全局工具。

  • 将适当的填充码脚本添加到 shell 配置文件中。 可能需要创建 shell 配置文件。 桥接脚本会将 shell 中的完成请求转发到 dotnet-suggest 工具,该工具会将这些请求委托给相应的基于 System.CommandLine 的应用程序。

    • 对于 bash,将 dotnet-suggest-shim.bash 的内容添加到 ~/.bash_profile

    • 对于 zsh,将 dotnet-suggest-shim.zsh 的内容添加到 ~/.zshrc

    • 对于 PowerShell,请将 dotnet-suggest-shim.ps1 的内容添加到 PowerShell 配置文件。 可以在控制台中运行以下命令,找到 PowerShell 配置文件的预期路径:

      echo $profile
      
  • 通过调用 dotnet-suggest register --command-path $executableFilePath注册应用,其中 $executableFilePath 是应用的可执行文件的路径。

设置用户的 shell 并注册可执行文件后,补全功能将适用于使用 System.CommandLine 构建的所有应用。

对于 Windows 上的 cmd.exe(Windows 命令提示符),没有可插入的 Tab 自动补全机制,因此没有可用的填充码脚本。 对于其他 shell,请查找标记为 Area-Completions 的 GitHub 问题。 如果找不到问题,可以 打开一个新问题

运行时获取 Tab 自动补全值

以下代码显示了一个应用,该应用在运行时动态检索要通过 Tab 键补全的值。 该代码获取当前日期后的接下来两周日期的列表。 提供给--date选项的列表是通过调用CompletionSources.Add获得的。

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

new DateCommand().Parse(args).Invoke();

class DateCommand : Command
{
    private Argument<string> subjectArgument = new("subject")
    {
        Description = "The subject of the appointment."
    };
    private Option<DateTime> dateOption = new("--date")
    {
        Description = "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.Arguments.Add(subjectArgument);
        this.Options.Add(dateOption);

        dateOption.CompletionSources.Add(ctx => {
            var today = System.DateTime.Today;
            List<CompletionItem> dates = new();
            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.SetAction(parseResult =>
        {
            Console.WriteLine($"Scheduled \"{parseResult.GetValue(subjectArgument)}\" for {parseResult.GetValue(dateOption)}");
        });
    }
}

按下 Tab 键时显示的值是作为 CompletionItem 实例提供的。

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

设置了以下 CompletionItem 属性:

  • Label 是要显示的补全值。
  • SortText 确保列表中的值按正确的顺序显示。 它通过将 i 转换为两位数字符串来设置,这样排序时会基于 01、02、03 等直到 14。 如果未设置此参数,则排序基于 Label本示例中的短日期格式,并且无法正确排序。

CompletionItem还有其他属性,如DocumentationDetail,但它们尚未用于System.CommandLine

此代码创建的动态选项卡完成列表也显示在帮助输出中:

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

另请参阅

System.CommandLine 概述