Skip to content

Cannot replace default completions of Option<T> where T is enum #1884

Closed
@KalleOlaviNiemitalo

Description

@KalleOlaviNiemitalo

When T is an enum type, Option<T> gets a default completion source that returns the names of the defined enum values. If I call OptionExtensions.AddCompletions to add a completion callback that returns some of those names but not all, that has no effect because the default completion source returns all of them anyway and Argument.GetCompletions discards my completion items as duplicates, even if they contain documentation and the default completion items don't. Because the Option.Argument property is internal, I cannot call option.Argument.Completions.Clear() to delete the default completion source before I add mine.

Possibly I could hack around this by deriving my own class from Option<T> and overriding GetCompletions there.

To reproduce

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
  </ItemGroup>

</Project>
namespace EnumCompletion;

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

class Program
{
    static void Main(string[] args)
    {
        var option = new Option<DayOfWeek>("-d")
            .AddCompletions(CompleteDayOfWeek);
        foreach (var completion in option.GetCompletions())
        {
            Console.WriteLine($"{completion.Label}: {completion.Documentation}");
        }
    }

    static IEnumerable<CompletionItem> CompleteDayOfWeek(CompletionContext context)
    {
        Console.Error.WriteLine("CompleteDayOfWeek was called.");

        // Omit Saturday and Sunday.
        return new[]
        {
           new CompletionItem("Monday", sortText: "1", documentation: "maanantai"),
           new CompletionItem("Tuesday", sortText: "2", documentation: "tiistai"),
           new CompletionItem("Wednesday", sortText: "3", documentation: "keskiviikko"),
           new CompletionItem("Thursday", sortText: "4", documentation: "torstai"),
           new CompletionItem("Friday", sortText: "5", documentation: "perjantai"),
        };
    }
}

Actual output

CompleteDayOfWeek was called.
Friday:
Monday:
Saturday:
Sunday:
Thursday:
Tuesday:
Wednesday:

Expected output

CompleteDayOfWeek was called.
Monday: maanantai
Tuesday: tiistai
Wednesday: keskiviikko
Thursday: torstai
Friday: perjantai

Metadata

Metadata

Assignees

Labels

Area-CompletionsRelated to support for tab completionbugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions