Skip to content

Commit 271efbe

Browse files
committed
add api to replace completion items
1 parent f2512fe commit 271efbe

File tree

10 files changed

+137
-114
lines changed

10 files changed

+137
-114
lines changed

src/System.CommandLine.Benchmarks/CommandLine/Perf_Parser_Directives_Suggest.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,16 @@ public void Setup()
2929
new Option("--fruit")
3030
{
3131
Argument = new Argument<string>()
32-
.WithSuggestions("apple", "banana", "cherry")
32+
{
33+
SuggestionSources = {"apple", "banana", "cherry" }
34+
}
3335
},
3436
new Option("--vegetable")
3537
{
3638
Argument = new Argument<string>()
37-
.WithSuggestions("asparagus", "broccoli", "carrot")
39+
{
40+
SuggestionSources = {"asparagus", "broccoli", "carrot" }
41+
}
3842
}
3943
};
4044

src/System.CommandLine.Benchmarks/CommandLine/Perf_Suggestions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ public void Setup_FromSymbol()
4141
{
4242
Argument = new Argument
4343
{
44-
Arity = ArgumentArity.ExactlyOne
45-
}
46-
.WithSuggestions(GenerateSuggestionsArray(TestSuggestionsCount))
44+
Arity = ArgumentArity.ExactlyOne,
45+
SuggestionSources = { GenerateSuggestionsArray(TestSuggestionsCount) }
46+
}
4747
};
4848
}
4949

src/System.CommandLine.Tests/ApprovalTests/Help/HelpBuilderTests.Approval.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public void Help_describes_default_values_for_complex_root_command_scenario()
6161
Argument = new Argument<FileAccess>("the-root-option-arg", () => FileAccess.Read)
6262
{
6363
Description = "the-root-option-arg-description",
64-
},
64+
}
6565
},
6666
new Option(aliases: new string[] {"--the-root-option-required-enum-arg", "-trorea"}) {
6767
Description = "the-root-option-description",

src/System.CommandLine.Tests/SuggestDirectiveTests.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System.CommandLine.Builder;
5-
using System.CommandLine.Invocation;
65
using System.CommandLine.IO;
76
using System.CommandLine.Parsing;
87
using System.Threading.Tasks;
8+
99
using FluentAssertions;
10+
1011
using Xunit;
12+
1113
using static System.Environment;
1214

1315
namespace System.CommandLine.Tests
@@ -22,11 +24,11 @@ public class SuggestDirectiveTests
2224

2325
public SuggestDirectiveTests()
2426
{
25-
_fruitOption = new Option<string>("--fruit")
26-
.WithSuggestions("apple", "banana", "cherry");
27+
_fruitOption = new Option<string>("--fruit");
28+
_fruitOption.Argument.SuggestionSources.Add( new[] { "apple", "banana", "cherry" });
2729

28-
_vegetableOption = new Option<string>("--vegetable")
29-
.WithSuggestions("asparagus", "broccoli", "carrot");
30+
_vegetableOption = new Option<string>("--vegetable");
31+
_vegetableOption.Argument.SuggestionSources.Add(new[] { "asparagus", "broccoli", "carrot" });
3032

3133
_eatCommand = new Command("eat")
3234
{

src/System.CommandLine.Tests/SuggestionTests.cs

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
using System.CommandLine.Tests.Utility;
99
using System.IO;
1010
using FluentAssertions;
11+
12+
using Microsoft.Extensions.Logging;
13+
1114
using Xunit;
1215
using Xunit.Abstractions;
1316

@@ -29,9 +32,9 @@ public void Option_Suggest_returns_argument_suggestions_if_configured()
2932
{
3033
Argument = new Argument
3134
{
32-
Arity = ArgumentArity.ExactlyOne
35+
Arity = ArgumentArity.ExactlyOne,
36+
SuggestionSources = { "one", "two", "three" }
3337
}
34-
.WithSuggestions("one", "two", "three")
3538
};
3639

3740
var suggestions = option.GetSuggestions();
@@ -102,9 +105,9 @@ public void Command_Suggest_returns_available_subcommands_and_option_aliases_and
102105
new Option("--option", "option"),
103106
new Argument
104107
{
105-
Arity = ArgumentArity.OneOrMore
108+
Arity = ArgumentArity.OneOrMore,
109+
SuggestionSources = { "command-argument" }
106110
}
107-
.WithSuggestions("command-argument")
108111
};
109112

110113
var suggestions = command.GetSuggestions();
@@ -505,9 +508,9 @@ public void Suggestions_can_be_provided_in_the_absence_of_validation()
505508
{
506509
Argument = new Argument
507510
{
508-
Arity = ArgumentArity.ExactlyOne
511+
Arity = ArgumentArity.ExactlyOne,
512+
SuggestionSources = { "vegetable", "mineral", "animal" }
509513
}
510-
.WithSuggestions("vegetable", "mineral", "animal")
511514
}
512515
};
513516

@@ -529,14 +532,9 @@ public void Command_argument_suggestions_can_be_provided_using_a_delegate()
529532
{
530533
new Argument
531534
{
532-
Arity = ArgumentArity.ExactlyOne
535+
Arity = ArgumentArity.ExactlyOne,
536+
SuggestionSources = { _ => new[] { "vegetable", "mineral", "animal" } }
533537
}
534-
.WithSuggestionSource(_ => new[]
535-
{
536-
"vegetable",
537-
"mineral",
538-
"animal"
539-
})
540538
}
541539
};
542540

@@ -551,13 +549,13 @@ public void Option_argument_suggestions_can_be_provided_using_a_delegate()
551549
{
552550
var command = new Command("the-command")
553551
{
554-
new Option<string>("-x")
555-
.WithSuggestionSource(_ => new[]
552+
new Option<string>("-x")
553+
{
554+
Argument = new Argument<string>()
556555
{
557-
"vegetable",
558-
"mineral",
559-
"animal"
560-
})
556+
SuggestionSources = { _ => new[] { "vegetable", "mineral", "animal" } }
557+
}
558+
}
561559
};
562560

563561
var parseResult = command.Parse("the-command -x m");
@@ -997,6 +995,40 @@ public void When_there_are_multiple_arguments_then_suggestions_are_only_offered_
997995
{
998996
Assert.True(false, "Test testname is not written yet.");
999997
}
998+
999+
[Fact]
1000+
public void Enum_suggestions_can_be_configured_with_list_clear()
1001+
{
1002+
var argument = new Argument<LogLevel?>();
1003+
argument.SuggestionSources.Clear();
1004+
argument.SuggestionSources.Add(new[] { "q", "quiet", "m", "minimal", "n", "normal", "d", "detailed", "diag", "diagnostic" });
1005+
var command = new Command("the-command")
1006+
{
1007+
argument
1008+
};
1009+
1010+
var suggestions = command.Parse("the-command d")
1011+
.GetSuggestions();
1012+
1013+
suggestions.Should().BeEquivalentTo("d", "detailed", "diag", "diagnostic");
1014+
}
1015+
1016+
[Fact]
1017+
public void Enum_suggestions_can_be_configured_without_list_clear()
1018+
{
1019+
var command = new Command("the-command")
1020+
{
1021+
new Argument<LogLevel?>()
1022+
{
1023+
SuggestionSources = { "q", "quiet", "m", "minimal", "n", "normal", "d", "detailed", "diag", "diagnostic" }
1024+
}
1025+
};
1026+
1027+
var suggestions = command.Parse("the-command d")
1028+
.GetSuggestions();
1029+
1030+
suggestions.Should().BeEquivalentTo("d", "Debug", "detailed", "diag", "diagnostic");
1031+
}
10001032
}
10011033
}
10021034
}

src/System.CommandLine.Tests/System.CommandLine.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<ItemGroup>
2222
<PackageReference Include="ApprovalTests" Version="5.2.2" />
2323
<PackageReference Include="FluentAssertions" Version="5.10.3" />
24+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.5" />
2425
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
2526
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="2.1.0" />
2627
</ItemGroup>

src/System.CommandLine/Argument.cs

Lines changed: 20 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ namespace System.CommandLine
1212
public class Argument : Symbol, IArgument
1313
{
1414
private Func<ArgumentResult, object?>? _defaultValueFactory;
15-
private readonly List<string> _suggestions = new List<string>();
16-
private readonly List<ISuggestionSource> _suggestionSources = new List<ISuggestionSource>();
1715
private IArgumentArity? _arity;
1816
private TryConvertArgument? _convertArguments;
1917
private Type _argumentType = typeof(void);
@@ -109,6 +107,24 @@ bool DefaultConvert(SymbolResult symbol, out object value)
109107
set => _convertArguments = value;
110108
}
111109

110+
111+
private List<ISuggestionSource>? _suggestionSources = null;
112+
public List<ISuggestionSource> SuggestionSources
113+
{
114+
get
115+
{
116+
if (_suggestionSources is null)
117+
{
118+
_suggestionSources = new List<ISuggestionSource>()
119+
{
120+
SuggestionSource.ForType(ArgumentType)
121+
};
122+
}
123+
124+
return _suggestionSources;
125+
}
126+
}
127+
112128
public Type ArgumentType
113129
{
114130
get => _argumentType;
@@ -158,36 +174,6 @@ public void SetDefaultValueFactory(Func<ArgumentResult, object?> getDefaultValue
158174

159175
internal static Argument None => new Argument { Arity = ArgumentArity.Zero };
160176

161-
public void AddSuggestions(IReadOnlyCollection<string> suggestions)
162-
{
163-
if (suggestions is null)
164-
{
165-
throw new ArgumentNullException(nameof(suggestions));
166-
}
167-
168-
_suggestions.AddRange(suggestions);
169-
}
170-
171-
public void AddSuggestionSource(ISuggestionSource suggest)
172-
{
173-
if (suggest is null)
174-
{
175-
throw new ArgumentNullException(nameof(suggest));
176-
}
177-
178-
_suggestionSources.Add(suggest);
179-
}
180-
181-
public void AddSuggestionSource(Suggest suggest)
182-
{
183-
if (suggest is null)
184-
{
185-
throw new ArgumentNullException(nameof(suggest));
186-
}
187-
188-
AddSuggestionSource(new AnonymousSuggestionSource(suggest));
189-
}
190-
191177
internal void AddAllowedValues(IEnumerable<string> values)
192178
{
193179
if (AllowedValues is null)
@@ -200,17 +186,10 @@ internal void AddAllowedValues(IEnumerable<string> values)
200186

201187
public override IEnumerable<string?> GetSuggestions(string? textToMatch = null)
202188
{
203-
var fixedSuggestions = _suggestions;
204-
205-
var dynamicSuggestions = _suggestionSources
189+
var dynamicSuggestions = SuggestionSources
206190
.SelectMany(source => source.GetSuggestions(textToMatch));
207191

208-
var typeSuggestions = SuggestionSource.ForType(ArgumentType)
209-
.GetSuggestions(textToMatch);
210-
211-
return fixedSuggestions
212-
.Concat(dynamicSuggestions)
213-
.Concat(typeSuggestions)
192+
return dynamicSuggestions
214193
.Distinct()
215194
.OrderBy(c => c, StringComparer.OrdinalIgnoreCase)
216195
.Containing(textToMatch);

src/System.CommandLine/ArgumentExtensions.cs

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
using System.Collections.Generic;
55
using System.CommandLine.Parsing;
6-
using System.CommandLine.Suggestions;
76
using System.Linq;
87
using System.IO;
8+
using System.CommandLine.Suggestions;
99

1010
namespace System.CommandLine
1111
{
@@ -17,30 +17,11 @@ public static TArgument FromAmong<TArgument>(
1717
where TArgument : Argument
1818
{
1919
argument.AddAllowedValues(values);
20-
argument.AddSuggestions(values);
20+
argument.SuggestionSources.Add(values);
2121

2222
return argument;
2323
}
2424

25-
public static TArgument WithSuggestions<TArgument>(
26-
this TArgument argument,
27-
params string[] suggestions)
28-
where TArgument : Argument
29-
{
30-
argument.AddSuggestions(suggestions);
31-
32-
return argument;
33-
}
34-
35-
public static TArgument WithSuggestionSource<TArgument>(
36-
this TArgument argument,
37-
Suggest suggest)
38-
where TArgument : Argument
39-
{
40-
argument.AddSuggestionSource(suggest);
41-
42-
return argument;
43-
}
4425
public static Argument<FileInfo> ExistingOnly(this Argument<FileInfo> argument)
4526
{
4627
argument.AddValidator(symbol =>

src/System.CommandLine/OptionExtensions.cs

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation and contributors. All rights reserved.
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System.Collections.Generic;
@@ -17,27 +17,7 @@ public static TOption FromAmong<TOption>(
1717
where TOption : Option
1818
{
1919
option.Argument.AddAllowedValues(values);
20-
option.Argument.AddSuggestions(values);
21-
22-
return option;
23-
}
24-
25-
public static TOption WithSuggestions<TOption>(
26-
this TOption option,
27-
params string[] suggestions)
28-
where TOption : Option
29-
{
30-
option.Argument.AddSuggestions(suggestions);
31-
32-
return option;
33-
}
34-
35-
public static TOption WithSuggestionSource<TOption>(
36-
this TOption option,
37-
Suggest suggest)
38-
where TOption : Option
39-
{
40-
option.Argument.AddSuggestionSource(suggest);
20+
option.Argument.SuggestionSources.Add(values);
4121

4222
return option;
4323
}

0 commit comments

Comments
 (0)