Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort suggestions by match index, then alphabetically #891

Merged
merged 2 commits into from
May 10, 2020
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
31 changes: 31 additions & 0 deletions src/System.CommandLine.Tests/SuggestionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.CommandLine.Builder;
using System.CommandLine.Invocation;
using System.CommandLine.Parsing;
using System.CommandLine.Tests.Utility;
using System.IO;
using FluentAssertions;
using Xunit;
Expand Down Expand Up @@ -112,6 +113,36 @@ public void Command_Suggest_returns_available_subcommands_and_option_aliases_and
.BeEquivalentTo("subcommand", "--option", "command-argument");
}

[Fact]
public void Command_Suggest_without_text_to_match_orders_alphabetically()
{
var command = new Command("command")
{
new Command("andmythirdsubcommand"),
new Command("mysubcommand"),
new Command("andmyothersubcommand"),
};

var suggestions = command.GetSuggestions();

suggestions.Should().BeEquivalentSequenceTo("andmyothersubcommand", "andmythirdsubcommand", "mysubcommand");
}

[Fact]
public void Command_Suggest_with_text_to_match_orders_by_match_position_then_alphabetically()
{
var command = new Command("command")
{
new Command("andmythirdsubcommand"),
new Command("mysubcommand"),
new Command("andmyothersubcommand"),
};

var suggestions = command.GetSuggestions("my");

suggestions.Should().BeEquivalentSequenceTo("mysubcommand", "andmyothersubcommand", "andmythirdsubcommand");
}

[Fact]
public void When_an_option_has_a_default_value_it_will_still_be_suggested()
{
Expand Down
7 changes: 6 additions & 1 deletion src/System.CommandLine/Parsing/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@ public static class StringExtensions
private static readonly string[] _optionPrefixStrings = { "--", "-", "/" };

internal static bool ContainsCaseInsensitive(
this string source,
string value) =>
source.IndexOfCaseInsensitive(value) >= 0;

internal static int IndexOfCaseInsensitive(
this string source,
string value) =>
CultureInfo.InvariantCulture
.CompareInfo
.IndexOf(source,
value ?? "",
CompareOptions.OrdinalIgnoreCase) >= 0;
CompareOptions.OrdinalIgnoreCase);

internal static string RemovePrefix(this string rawAlias)
{
Expand Down
5 changes: 3 additions & 2 deletions src/System.CommandLine/Symbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,9 @@ public virtual IEnumerable<string> GetSuggestions(string textToMatch = null)
return this.ChildSymbolAliases()
.Concat(argumentSuggestions)
.Distinct()
.OrderBy(symbol => symbol, StringComparer.OrdinalIgnoreCase)
.Containing(textToMatch);
.Containing(textToMatch)
.OrderBy(symbol => symbol.IndexOfCaseInsensitive(textToMatch))
.ThenBy(symbol => symbol, StringComparer.OrdinalIgnoreCase);
}

public override string ToString() => $"{GetType().Name}: {Name}";
Expand Down