-
-
Notifications
You must be signed in to change notification settings - Fork 532
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrated&Improved AutoCompletion & Tests
- Loading branch information
Jonas Kamsker
committed
Jul 19, 2023
1 parent
813a53c
commit 8025d0a
Showing
26 changed files
with
835 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -90,4 +90,5 @@ Thumbs.db | |
|
||
*.received.* | ||
|
||
node_modules | ||
node_modules | ||
*.txt.bak |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
src/Spectre.Console.Cli/Completion/CommandParameterMatcher.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
using System.Linq.Expressions; | ||
|
||
namespace Spectre.Console.Cli.Completion; | ||
|
||
/* | ||
Usage: | ||
return new CommandParameterMatcher<LionSettings>() | ||
.Add(x => x.Legs, (prefix) => | ||
{ | ||
if (prefix.Length != 0) | ||
{ | ||
return CompletionResult.Result(FindNextEvenNumber(prefix)).WithPreventDefault(); | ||
} | ||
return CompletionResult.Result("16").WithPreventDefault(); | ||
}) | ||
.Add(x => x.Teeth, (prefix) => | ||
{ | ||
if (prefix.Length != 0) | ||
{ | ||
return CompletionResult.Result(FindNextEvenNumber(prefix)).WithPreventDefault(); | ||
} | ||
return CompletionResult.Result("32").WithPreventDefault(); | ||
}) | ||
.Match(parameter, prefix); | ||
*/ | ||
|
||
public class CommandParameterMatcher<T> | ||
where T : CommandSettings | ||
{ | ||
private readonly List<(PropertyInfo Property, Func<string, ICompletionResult> Func)> _completers; | ||
|
||
public CommandParameterMatcher() | ||
{ | ||
_completers = new(); | ||
} | ||
|
||
private CommandParameterMatcher(IEnumerable<(PropertyInfo, Func<string, ICompletionResult>)>? completers) | ||
{ | ||
_completers = completers?.ToList() ?? new(); | ||
} | ||
|
||
public ICompletionResult Match(ICommandParameterInfo parameter, string prefix) | ||
{ | ||
var property = _completers.FirstOrDefault(x => x.Property.Name == parameter.PropertyName); | ||
if (property.Property == null) | ||
{ | ||
return CompletionResult.None(); | ||
} | ||
|
||
return property.Func(prefix); | ||
} | ||
|
||
public CommandParameterMatcher<T> Add(Expression<Func<T, object>> property, Func<string, ICompletionResult> completer) | ||
{ | ||
var parameter = PropertyOf(property); | ||
_completers.Add((parameter, completer)); | ||
return this; | ||
} | ||
|
||
public static CommandParameterMatcher<T> Create(Dictionary<Expression<Func<T, object>>, Func<string, ICompletionResult>> completers) | ||
{ | ||
var result = new List<(PropertyInfo, Func<string, ICompletionResult>)>(); | ||
|
||
foreach (var completer in completers) | ||
{ | ||
var parameter = PropertyOf(completer.Key); | ||
result.Add((parameter, completer.Value)); | ||
} | ||
|
||
return new CommandParameterMatcher<T>(result); | ||
} | ||
|
||
// params create | ||
public static CommandParameterMatcher<T> Create(params (Expression<Func<T, object>>, Func<string, ICompletionResult>)[] completers) | ||
{ | ||
var result = new List<(PropertyInfo, Func<string, ICompletionResult>)>(); | ||
foreach (var (key, value) in completers) | ||
{ | ||
var parameter = PropertyOf(key); | ||
result.Add((parameter, value)); | ||
} | ||
|
||
return new CommandParameterMatcher<T>(result); | ||
} | ||
|
||
|
||
|
||
private static PropertyInfo PropertyOf(LambdaExpression methodExpression) | ||
{ | ||
var body = RemoveConvert(methodExpression.Body); | ||
var prop = (MemberExpression)body; | ||
return (PropertyInfo)prop.Member; | ||
} | ||
|
||
private static Expression RemoveConvert(Expression expression) | ||
{ | ||
while ( | ||
expression != null | ||
&& ( | ||
expression.NodeType == ExpressionType.Convert | ||
|| expression.NodeType == ExpressionType.ConvertChecked | ||
) | ||
) | ||
{ | ||
expression = RemoveConvert(((UnaryExpression)expression).Operand); | ||
} | ||
|
||
return expression; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
namespace Spectre.Console.Cli.Completion; | ||
|
||
public class CompletionResult : ICompletionResult | ||
{ | ||
public bool PreventDefault { get; } | ||
public IEnumerable<string> Suggestions { get; } = Enumerable.Empty<string>(); | ||
|
||
internal bool IsGenerated { get; private set; } | ||
|
||
public CompletionResult() | ||
{ | ||
} | ||
|
||
public CompletionResult(IEnumerable<string> suggestions, bool preventDefault = false) | ||
{ | ||
Suggestions = suggestions ?? throw new ArgumentNullException(nameof(suggestions)); | ||
PreventDefault = preventDefault; | ||
} | ||
|
||
public CompletionResult(ICompletionResult result) | ||
{ | ||
Suggestions = result.Suggestions; | ||
PreventDefault = result.PreventDefault; | ||
} | ||
|
||
public CompletionResult WithSuggestions(IEnumerable<string> suggestions) | ||
{ | ||
return new(suggestions, PreventDefault); | ||
} | ||
|
||
/// <summary> | ||
/// Disables completions, that are automatically generated | ||
/// </summary> | ||
/// <param name="preventDefault"></param> | ||
/// <returns></returns> | ||
public CompletionResult WithPreventDefault(bool preventDefault = true) | ||
{ | ||
return new(Suggestions, preventDefault); | ||
} | ||
|
||
public CompletionResult WithGeneratedSuggestions() | ||
{ | ||
return new(Suggestions, PreventDefault) { IsGenerated = true }; | ||
} | ||
|
||
public static implicit operator CompletionResult(string[] suggestions) | ||
{ | ||
return new(suggestions); | ||
} | ||
|
||
public static implicit operator CompletionResult(string suggestion) | ||
{ | ||
return new(new[] { suggestion }); | ||
} | ||
|
||
public static CompletionResult None() | ||
{ | ||
return new(); | ||
} | ||
|
||
public static CompletionResult Result(params string[] suggestions) | ||
{ | ||
return new(suggestions); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
src/Spectre.Console.Cli/Completion/ICommandParameterCompleter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System.Linq.Expressions; | ||
|
||
namespace Spectre.Console.Cli.Completion; | ||
|
||
public interface ICommandParameterCompleter | ||
{ | ||
ICompletionResult GetSuggestions(ICommandParameterInfo parameter, string? prefix); | ||
} | ||
|
||
public interface ICompletionResult | ||
{ | ||
bool PreventDefault { get; } | ||
IEnumerable<string> Suggestions { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.