diff --git a/CliFx.Tests/SuggestDirectiveSpecs.cs b/CliFx.Tests/SuggestDirectiveSpecs.cs
new file mode 100644
index 00000000..0b410a08
--- /dev/null
+++ b/CliFx.Tests/SuggestDirectiveSpecs.cs
@@ -0,0 +1,77 @@
+using CliFx.Tests.Utils;
+using CliFx.Tests.Utils.Extensions;
+using FluentAssertions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace CliFx.Tests
+{
+ public class SuggestDirectivesSpecs : SpecsBase
+ {
+ public SuggestDirectivesSpecs(ITestOutputHelper testOutput)
+ : base(testOutput)
+ {
+ }
+
+ private string _cmdCommandCs = @"
+[Command(""cmd"")]
+public class Command : ICommand
+{
+ public ValueTask ExecuteAsync(IConsole console) => default;
+}
+";
+
+ public CliApplicationBuilder TestApplicationFactory(params string[] commandClasses)
+ {
+ var builder = new CliApplicationBuilder();
+
+ commandClasses.ToList().ForEach(c =>
+ {
+ var commandType = DynamicCommandBuilder.Compile(c);
+ builder = builder.AddCommand(commandType);
+ });
+
+ return builder.UseConsole(FakeConsole);
+ }
+
+ [Theory]
+ [InlineData(true, 0 )]
+ [InlineData(false, 1)]
+ public async Task Suggest_directive_can_be_configured(bool enabled, int expectedExitCode)
+ {
+ // Arrange
+ var application = TestApplicationFactory(_cmdCommandCs)
+ .AllowSuggestMode(enabled)
+ .Build();
+
+ // Act
+ var exitCode = await application.RunAsync(
+ new[] { "[suggest]", "clifx.exe", "c" }
+ );
+
+ // Assert
+ exitCode.Should().Be(expectedExitCode);
+ }
+
+ [Fact]
+ public async Task Suggest_directive_is_enabled_by_default()
+ {
+ // Arrange
+ var application = TestApplicationFactory(_cmdCommandCs)
+ .Build();
+
+ // Act
+ var exitCode = await application.RunAsync(
+ new[] { "[suggest]", "clifx.exe", "c" }
+ );
+
+ // Assert
+ exitCode.Should().Be(0);
+ }
+ }
+}
\ No newline at end of file
diff --git a/CliFx/ApplicationConfiguration.cs b/CliFx/ApplicationConfiguration.cs
index f03de68c..5078ac6f 100644
--- a/CliFx/ApplicationConfiguration.cs
+++ b/CliFx/ApplicationConfiguration.cs
@@ -23,17 +23,24 @@ public class ApplicationConfiguration
///
public bool IsPreviewModeAllowed { get; }
+ ///
+ /// Whether suggest mode is allowed in this application.
+ ///
+ public bool IsSuggestModeAllowed { get; }
+
///
/// Initializes an instance of .
///
public ApplicationConfiguration(
IReadOnlyList commandTypes,
bool isDebugModeAllowed,
- bool isPreviewModeAllowed)
+ bool isPreviewModeAllowed,
+ bool isSuggestModeAllowed)
{
CommandTypes = commandTypes;
IsDebugModeAllowed = isDebugModeAllowed;
IsPreviewModeAllowed = isPreviewModeAllowed;
+ IsSuggestModeAllowed = isSuggestModeAllowed;
}
}
}
\ No newline at end of file
diff --git a/CliFx/CliApplication.cs b/CliFx/CliApplication.cs
index d0be0b90..6e77306f 100644
--- a/CliFx/CliApplication.cs
+++ b/CliFx/CliApplication.cs
@@ -56,6 +56,9 @@ public class CliApplication
private bool IsPreviewModeEnabled(CommandInput commandInput) =>
Configuration.IsPreviewModeAllowed && commandInput.IsPreviewDirectiveSpecified;
+ private bool IsSuggestModeEnabled(CommandInput commandInput) =>
+ Configuration.IsSuggestModeAllowed && commandInput.IsSuggestDirectiveSpecified;
+
private bool ShouldShowHelpText(CommandSchema commandSchema, CommandInput commandInput) =>
commandSchema.IsHelpOptionAvailable && commandInput.IsHelpOptionSpecified ||
// Show help text also in case the fallback default command is
@@ -103,6 +106,13 @@ private async ValueTask RunAsync(ApplicationSchema applicationSchema, Comma
return 0;
}
+ // Handle suggest directive
+ if (IsSuggestModeEnabled(commandInput))
+ {
+ _console.Output.WriteLine("cmd");
+ return 0;
+ }
+
// Try to get the command schema that matches the input
var commandSchema =
applicationSchema.TryFindCommand(commandInput.CommandName) ??
diff --git a/CliFx/CliApplicationBuilder.cs b/CliFx/CliApplicationBuilder.cs
index e1abb47a..0be83e7e 100644
--- a/CliFx/CliApplicationBuilder.cs
+++ b/CliFx/CliApplicationBuilder.cs
@@ -19,6 +19,7 @@ public partial class CliApplicationBuilder
private bool _isDebugModeAllowed = true;
private bool _isPreviewModeAllowed = true;
+ private bool _isSuggestModeAllowed = true;
private string? _title;
private string? _executableName;
private string? _versionText;
@@ -36,6 +37,7 @@ public CliApplicationBuilder AddCommand(Type commandType)
return this;
}
+
///
/// Adds a command to the application.
///
@@ -110,6 +112,15 @@ public CliApplicationBuilder AllowPreviewMode(bool isAllowed = true)
return this;
}
+ ///
+ /// Specifies whether suggest mode (enabled with the [suggest] directive) is allowed in the application.
+ ///
+ public CliApplicationBuilder AllowSuggestMode(bool isAllowed = true)
+ {
+ _isSuggestModeAllowed = isAllowed;
+ return this;
+ }
+
///
/// Sets application title, which is shown in the help text.
///
@@ -196,7 +207,8 @@ public CliApplication Build()
var configuration = new ApplicationConfiguration(
_commandTypes.ToArray(),
_isDebugModeAllowed,
- _isPreviewModeAllowed
+ _isPreviewModeAllowed,
+ _isSuggestModeAllowed
);
return new CliApplication(
diff --git a/CliFx/Input/CommandInput.cs b/CliFx/Input/CommandInput.cs
index 45d514de..f89e336d 100644
--- a/CliFx/Input/CommandInput.cs
+++ b/CliFx/Input/CommandInput.cs
@@ -22,6 +22,8 @@ internal partial class CommandInput
public bool IsPreviewDirectiveSpecified => Directives.Any(d => d.IsPreviewDirective);
+ public bool IsSuggestDirectiveSpecified => Directives.Any(d => d.IsSuggestDirective);
+
public bool IsHelpOptionSpecified => Options.Any(o => o.IsHelpOption);
public bool IsVersionOptionSpecified => Options.Any(o => o.IsVersionOption);
diff --git a/CliFx/Input/DirectiveInput.cs b/CliFx/Input/DirectiveInput.cs
index 928aa10f..3ac0c1e2 100644
--- a/CliFx/Input/DirectiveInput.cs
+++ b/CliFx/Input/DirectiveInput.cs
@@ -12,6 +12,9 @@ internal class DirectiveInput
public bool IsPreviewDirective =>
string.Equals(Name, "preview", StringComparison.OrdinalIgnoreCase);
+ public bool IsSuggestDirective =>
+ string.Equals(Name, "suggest", StringComparison.OrdinalIgnoreCase);
+
public DirectiveInput(string name) => Name = name;
}
}
\ No newline at end of file