Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
System.CommandLine
public abstract class Argument : Symbol, System.CommandLine.Binding.IValueDescriptor, System.CommandLine.Completions.ICompletionSource
public abstract class Argument : Symbol, System.CommandLine.Binding.IValueDescriptor
public ArgumentArity Arity { get; set; }
public System.Collections.Generic.ICollection<System.CommandLine.Completions.ICompletionSource> Completions { get; }
public System.Collections.Generic.ICollection<System.Func<System.CommandLine.Completions.CompletionContext,System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem>>> Completions { get; }
public System.Boolean HasDefaultValue { get; }
public System.String HelpName { get; set; }
public System.Type ValueType { get; }
Expand All @@ -12,7 +12,7 @@ System.CommandLine
public System.Void SetDefaultValueFactory(System.Func<System.Object> defaultValueFactory)
public System.Void SetDefaultValueFactory(System.Func<System.CommandLine.Parsing.ArgumentResult,System.Object> defaultValueFactory)
public System.String ToString()
public class Argument<T> : Argument, IValueDescriptor<T>, System.CommandLine.Binding.IValueDescriptor, System.CommandLine.Completions.ICompletionSource
public class Argument<T> : Argument, IValueDescriptor<T>, System.CommandLine.Binding.IValueDescriptor
.ctor()
.ctor(System.String name, System.String description = null)
.ctor(System.String name, Func<T> defaultValueFactory, System.String description = null)
Expand Down Expand Up @@ -45,7 +45,7 @@ System.CommandLine
public static TArgument LegalFilePathsOnly<TArgument>(this TArgument argument)
public static ParseResult Parse(this Argument argument, System.String commandLine)
public static ParseResult Parse(this Argument argument, System.String[] args)
public class Command : IdentifierSymbol, System.Collections.Generic.IEnumerable<Symbol>, System.Collections.IEnumerable, System.CommandLine.Completions.ICompletionSource
public class Command : IdentifierSymbol, System.Collections.Generic.IEnumerable<Symbol>, System.Collections.IEnumerable
.ctor(System.String name, System.String description = null)
public System.Collections.Generic.IReadOnlyList<Argument> Arguments { get; }
public System.Collections.Generic.IEnumerable<Symbol> Children { get; }
Expand Down Expand Up @@ -109,9 +109,8 @@ System.CommandLine
.ctor()
.ctor(System.String message, System.Exception innerException)
public static class CompletionSourceExtensions
public static System.Void Add(this System.Collections.Generic.ICollection<System.CommandLine.Completions.ICompletionSource> completionSources, System.Func<System.CommandLine.Completions.CompletionContext,System.Collections.Generic.IEnumerable<System.String>> complete)
public static System.Void Add(this System.Collections.Generic.ICollection<System.CommandLine.Completions.ICompletionSource> completionSources, System.Func<System.CommandLine.Completions.CompletionContext,System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem>> complete)
public static System.Void Add(this System.Collections.Generic.ICollection<System.CommandLine.Completions.ICompletionSource> completionSources, System.String[] completions)
public static System.Void Add(this System.Collections.Generic.ICollection<System.Func<System.CommandLine.Completions.CompletionContext,System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem>>> completionSources, System.Func<System.CommandLine.Completions.CompletionContext,System.Collections.Generic.IEnumerable<System.String>> complete)
public static System.Void Add(this System.Collections.Generic.ICollection<System.Func<System.CommandLine.Completions.CompletionContext,System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem>>> completionSources, System.String[] completions)
public static class ConsoleExtensions
public static System.Void Write(this IConsole console, System.String value)
public static System.Void WriteLine(this IConsole console, System.String value)
Expand Down Expand Up @@ -145,7 +144,7 @@ System.CommandLine
public System.Int32 Invoke(System.CommandLine.Invocation.InvocationContext context)
public System.Threading.Tasks.Task<System.Int32> InvokeAsync(System.CommandLine.Invocation.InvocationContext context)
public interface IConsole : System.CommandLine.IO.IStandardError, System.CommandLine.IO.IStandardIn, System.CommandLine.IO.IStandardOut
public abstract class IdentifierSymbol : Symbol, System.CommandLine.Completions.ICompletionSource
public abstract class IdentifierSymbol : Symbol
public System.Collections.Generic.IReadOnlyCollection<System.String> Aliases { get; }
public System.String Name { get; set; }
public System.Void AddAlias(System.String alias)
Expand Down Expand Up @@ -188,7 +187,7 @@ System.CommandLine
public System.String UnrecognizedCommandOrArgument(System.String arg)
public System.String VersionOptionCannotBeCombinedWithOtherArguments(System.String optionAlias)
public System.String VersionOptionDescription()
public abstract class Option : IdentifierSymbol, System.CommandLine.Binding.IValueDescriptor, System.CommandLine.Completions.ICompletionSource
public abstract class Option : IdentifierSymbol, System.CommandLine.Binding.IValueDescriptor
public System.Boolean AllowMultipleArgumentsPerToken { get; set; }
public System.String ArgumentHelpName { get; set; }
public ArgumentArity Arity { get; set; }
Expand All @@ -199,7 +198,7 @@ System.CommandLine
public System.Boolean HasAliasIgnoringPrefix(System.String alias)
public System.Void SetDefaultValue(System.Object value)
public System.Void SetDefaultValueFactory(System.Func<System.Object> defaultValueFactory)
public class Option<T> : Option, IValueDescriptor<T>, System.CommandLine.Binding.IValueDescriptor, System.CommandLine.Completions.ICompletionSource
public class Option<T> : Option, IValueDescriptor<T>, System.CommandLine.Binding.IValueDescriptor
.ctor(System.String name, System.String description = null)
.ctor(System.String[] aliases, System.String description = null)
.ctor(System.String name, Func<System.CommandLine.Parsing.ArgumentResult,T> parseArgument, System.Boolean isDefault = False, System.String description = null)
Expand Down Expand Up @@ -239,11 +238,11 @@ System.CommandLine
public T GetValue<T>(Argument<T> argument)
public T GetValue<T>(Option<T> option)
public System.String ToString()
public class RootCommand : Command, System.Collections.Generic.IEnumerable<Symbol>, System.Collections.IEnumerable, System.CommandLine.Completions.ICompletionSource
public class RootCommand : Command, System.Collections.Generic.IEnumerable<Symbol>, System.Collections.IEnumerable
public static System.String ExecutableName { get; }
public static System.String ExecutablePath { get; }
.ctor(System.String description = )
public abstract class Symbol, System.CommandLine.Completions.ICompletionSource
public abstract class Symbol
public System.String Description { get; set; }
public System.Boolean IsHidden { get; set; }
public System.String Name { get; set; }
Expand Down Expand Up @@ -289,8 +288,6 @@ System.CommandLine.Completions
public System.Boolean Equals(System.Object obj)
public System.Int32 GetHashCode()
public System.String ToString()
public interface ICompletionSource
public System.Collections.Generic.IEnumerable<CompletionItem> GetCompletions(CompletionContext context)
public class TextCompletionContext : CompletionContext
public System.String CommandLineText { get; }
public System.Int32 CursorPosition { get; }
Expand Down
6 changes: 3 additions & 3 deletions src/System.CommandLine/Argument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public abstract class Argument : Symbol, IValueDescriptor
private Func<ArgumentResult, object?>? _defaultValueFactory;
private ArgumentArity _arity;
private TryConvertArgument? _convertArguments;
private List<ICompletionSource>? _completions = null;
private List<Func<CompletionContext, IEnumerable<CompletionItem>>>? _completions = null;
private List<Action<ArgumentResult>>? _validators = null;

/// <summary>
Expand Down Expand Up @@ -74,7 +74,7 @@ internal TryConvertArgument? ConvertArguments
/// <summary>
/// Gets the collection of completion sources for the argument.
/// </summary>
public ICollection<ICompletionSource> Completions =>
public ICollection<Func<CompletionContext, IEnumerable<CompletionItem>>> Completions =>
_completions ??= new ()
{
CompletionSource.ForType(ValueType)
Expand Down Expand Up @@ -192,7 +192,7 @@ internal void AddAllowedValues(IReadOnlyList<string> values)
public override IEnumerable<CompletionItem> GetCompletions(CompletionContext context)
{
return Completions
.SelectMany(source => source.GetCompletions(context))
.SelectMany(source => source.Invoke(context))
.Distinct()
.OrderBy(c => c.SortText, StringComparer.OrdinalIgnoreCase);
}
Expand Down
30 changes: 4 additions & 26 deletions src/System.CommandLine/CompletionSourceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static class CompletionSourceExtensions
/// <param name="completionSources">The list of completion sources to add to.</param>
/// <param name="complete">The delegate to be called when calculating completions.</param>
public static void Add(
this ICollection<ICompletionSource> completionSources,
this ICollection<Func<CompletionContext, IEnumerable<CompletionItem>>> completionSources,
Func<CompletionContext, IEnumerable<string>> complete)
{
if (completionSources is null)
Expand All @@ -31,29 +31,7 @@ public static void Add(
throw new ArgumentNullException(nameof(complete));
}

completionSources.Add(new AnonymousCompletionSource(complete));
}

/// <summary>
/// Adds a completion source using a delegate.
/// </summary>
/// <param name="completionSources">The list of completion sources to add to.</param>
/// <param name="complete">The function to be called when calculating completions.</param>
public static void Add(
this ICollection<ICompletionSource> completionSources,
Func<CompletionContext, IEnumerable<CompletionItem>> complete)
{
if (completionSources is null)
{
throw new ArgumentNullException(nameof(completionSources));
}

if (complete is null)
{
throw new ArgumentNullException(nameof(complete));
}

completionSources.Add(new AnonymousCompletionSource(complete));
completionSources.Add(context => complete(context).Select(value => new CompletionItem(value)));
}

/// <summary>
Expand All @@ -62,7 +40,7 @@ public static void Add(
/// <param name="completionSources">The list of completion sources to add to.</param>
/// <param name="completions">A list of strings to be suggested for command line completions.</param>
public static void Add(
this ICollection<ICompletionSource> completionSources,
this ICollection<Func<CompletionContext, IEnumerable<CompletionItem>>> completionSources,
params string[] completions)
{
if (completionSources is null)
Expand All @@ -75,7 +53,7 @@ public static void Add(
throw new ArgumentNullException(nameof(completions));
}

completionSources.Add(new AnonymousCompletionSource(_ => completions.Select(s => new CompletionItem(s))));
completionSources.Add(context => completions.Select(value => new CompletionItem(value)));
}
}
}
28 changes: 0 additions & 28 deletions src/System.CommandLine/Completions/AnonymousCompletionSource.cs

This file was deleted.

57 changes: 14 additions & 43 deletions src/System.CommandLine/Completions/CompletionSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,67 +9,38 @@
namespace System.CommandLine.Completions
{
/// <summary>
/// Provides extension methods supporting <see cref="ICompletionSource"/> and command line tab completion.
/// Provides extension methods supporting command line tab completion.
/// </summary>
internal static class CompletionSource
{
private static readonly ConcurrentDictionary<Type, ICompletionSource> _completionSourcesByType = new();
private static readonly ConcurrentDictionary<Type, Func<CompletionContext, IEnumerable<CompletionItem>>> _completionSourcesByType = new();

/// <summary>
/// Gets a completion source that provides completions for a type (e.g. enum) with well-known values.
/// </summary>
internal static ICompletionSource ForType(Type type)
internal static Func<CompletionContext, IEnumerable<CompletionItem>> ForType(Type type)
{
return _completionSourcesByType.GetOrAdd(type, t => new CompletionSourceForType(t));
return _completionSourcesByType.GetOrAdd(type, t => GetCompletionSourceForType(t));
}

internal static ICompletionSource Empty { get; } = new AnonymousCompletionSource(static _ => Array.Empty<CompletionItem>());

private class CompletionSourceForType : ICompletionSource
private static Func<CompletionContext, IEnumerable<CompletionItem>> GetCompletionSourceForType(Type type)
{
private readonly Type _type;
private ICompletionSource? _innerCompletionSource;
Type actualType = type.TryGetNullableType(out var nullableType) ? nullableType : type;

public CompletionSourceForType(Type type)
if (actualType.IsEnum)
{
_type = type;
return _ => Enum.GetNames(actualType).Select(n => new CompletionItem(n));
}

public IEnumerable<CompletionItem> GetCompletions(CompletionContext context)
else if (actualType == typeof(bool))
{
if (_innerCompletionSource is null)
return static _ => new CompletionItem[]
{
_innerCompletionSource = CreateForType(_type);
}

return _innerCompletionSource.GetCompletions(context);
new(bool.TrueString),
new(bool.FalseString)
};
}

private static ICompletionSource CreateForType(Type type)
{
if (type.TryGetNullableType(out var nullableType))
{
return CreateForType(nullableType);
}

if (type.IsEnum)
{
return new AnonymousCompletionSource(_ => GetEnumNames());

IEnumerable<CompletionItem> GetEnumNames() => Enum.GetNames(type).Select(n => new CompletionItem(n));
}

if (type == typeof(bool))
{
return new AnonymousCompletionSource(static _ => new CompletionItem[]
{
new(bool.TrueString),
new(bool.FalseString)
});
}

return Empty;
}
return static _ => Array.Empty<CompletionItem>();
}
}
}
18 changes: 0 additions & 18 deletions src/System.CommandLine/Completions/ICompletionSource.cs

This file was deleted.

4 changes: 2 additions & 2 deletions src/System.CommandLine/ParseResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ public IEnumerable<CompletionItem> GetCompletions(
}

var completions =
currentSymbol is ICompletionSource currentCompletionSource
? currentCompletionSource.GetCompletions(context)
currentSymbol is not null
? currentSymbol.GetCompletions(context)
: Array.Empty<CompletionItem>();

completions =
Expand Down
2 changes: 1 addition & 1 deletion src/System.CommandLine/Symbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace System.CommandLine
/// <summary>
/// Defines a named symbol that resides in a hierarchy with parent and child symbols.
/// </summary>
public abstract class Symbol : ICompletionSource
public abstract class Symbol
{
private string? _name;
private ParentNode? _firstParent;
Expand Down