diff --git a/src/Spectre.Console.Cli/ConfiguratorExtensions.cs b/src/Spectre.Console.Cli/ConfiguratorExtensions.cs
index 630edb49e..e4a234fc1 100644
--- a/src/Spectre.Console.Cli/ConfiguratorExtensions.cs
+++ b/src/Spectre.Console.Cli/ConfiguratorExtensions.cs
@@ -40,6 +40,23 @@ public static IConfigurator SetApplicationVersion(this IConfigurator configurato
return configurator;
}
+ ///
+ /// Hides the DEFAULT column that lists default values coming from the
+ /// in the options help text.
+ ///
+ /// The configurator.
+ /// A configurator that can be used to configure the application further.
+ public static IConfigurator HideOptionDefaultValues(this IConfigurator configurator)
+ {
+ if (configurator == null)
+ {
+ throw new ArgumentNullException(nameof(configurator));
+ }
+
+ configurator.Settings.ShowOptionDefaultValues = false;
+ return configurator;
+ }
+
///
/// Configures the console.
///
diff --git a/src/Spectre.Console.Cli/ICommandAppSettings.cs b/src/Spectre.Console.Cli/ICommandAppSettings.cs
index 6fb579bac..4e3b5b904 100644
--- a/src/Spectre.Console.Cli/ICommandAppSettings.cs
+++ b/src/Spectre.Console.Cli/ICommandAppSettings.cs
@@ -15,6 +15,11 @@ public interface ICommandAppSettings
///
string? ApplicationVersion { get; set; }
+ ///
+ /// Gets or sets a value indicating whether any default values for command options are shown in the help text.
+ ///
+ bool ShowOptionDefaultValues { get; set; }
+
///
/// Gets or sets the .
///
@@ -34,11 +39,11 @@ public interface ICommandAppSettings
///
/// Gets or sets case sensitivity.
///
- CaseSensitivity CaseSensitivity { get; set; }
-
- ///
- /// Gets or sets a value indicating whether trailing period of a description is trimmed.
- ///
+ CaseSensitivity CaseSensitivity { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether trailing period of a description is trimmed.
+ ///
bool TrimTrailingPeriod { get; set; }
///
diff --git a/src/Spectre.Console.Cli/Internal/CommandExecutor.cs b/src/Spectre.Console.Cli/Internal/CommandExecutor.cs
index e4826528b..e80a294c0 100644
--- a/src/Spectre.Console.Cli/Internal/CommandExecutor.cs
+++ b/src/Spectre.Console.Cli/Internal/CommandExecutor.cs
@@ -53,7 +53,7 @@ public async Task Execute(IConfiguration configuration, IEnumerable
if (parsedResult.Tree == null)
{
// Display help.
- configuration.Settings.Console.SafeRender(HelpWriter.Write(model));
+ configuration.Settings.Console.SafeRender(HelpWriter.Write(model, configuration.Settings.ShowOptionDefaultValues));
return 0;
}
@@ -62,7 +62,7 @@ public async Task Execute(IConfiguration configuration, IEnumerable
if (leaf.Command.IsBranch || leaf.ShowHelp)
{
// Branches can't be executed. Show help.
- configuration.Settings.Console.SafeRender(HelpWriter.WriteCommand(model, leaf.Command));
+ configuration.Settings.Console.SafeRender(HelpWriter.WriteCommand(model, leaf.Command, configuration.Settings.ShowOptionDefaultValues));
return leaf.ShowHelp ? 0 : 1;
}
@@ -70,7 +70,7 @@ public async Task Execute(IConfiguration configuration, IEnumerable
if (leaf.Command.IsDefaultCommand && args.Count() == 0 && leaf.Command.Parameters.Any(p => p.Required))
{
// Display help for default command.
- configuration.Settings.Console.SafeRender(HelpWriter.WriteCommand(model, leaf.Command));
+ configuration.Settings.Console.SafeRender(HelpWriter.WriteCommand(model, leaf.Command, configuration.Settings.ShowOptionDefaultValues));
return 1;
}
diff --git a/src/Spectre.Console.Cli/Internal/Configuration/CommandAppSettings.cs b/src/Spectre.Console.Cli/Internal/Configuration/CommandAppSettings.cs
index 4723bcb5a..b1d530023 100644
--- a/src/Spectre.Console.Cli/Internal/Configuration/CommandAppSettings.cs
+++ b/src/Spectre.Console.Cli/Internal/Configuration/CommandAppSettings.cs
@@ -4,6 +4,7 @@ internal sealed class CommandAppSettings : ICommandAppSettings
{
public string? ApplicationName { get; set; }
public string? ApplicationVersion { get; set; }
+ public bool ShowOptionDefaultValues { get; set; }
public IAnsiConsole? Console { get; set; }
public ICommandInterceptor? Interceptor { get; set; }
public ITypeRegistrarFrontend Registrar { get; set; }
@@ -22,6 +23,7 @@ public CommandAppSettings(ITypeRegistrar registrar)
{
Registrar = new TypeRegistrar(registrar);
CaseSensitivity = CaseSensitivity.All;
+ ShowOptionDefaultValues = true;
}
public bool IsTrue(Func func, string environmentVariableName)
diff --git a/src/Spectre.Console.Cli/Internal/HelpWriter.cs b/src/Spectre.Console.Cli/Internal/HelpWriter.cs
index d6b0b3877..da58da88e 100644
--- a/src/Spectre.Console.Cli/Internal/HelpWriter.cs
+++ b/src/Spectre.Console.Cli/Internal/HelpWriter.cs
@@ -34,42 +34,45 @@ private sealed class HelpOption
public string? Value { get; }
public bool? ValueIsOptional { get; }
public string? Description { get; }
+ public object? DefaultValue { get; }
- public HelpOption(string? @short, string? @long, string? @value, bool? valueIsOptional, string? description)
+ public HelpOption(string? @short, string? @long, string? @value, bool? valueIsOptional, string? description, object? defaultValue)
{
Short = @short;
Long = @long;
Value = value;
ValueIsOptional = valueIsOptional;
Description = description;
+ DefaultValue = defaultValue;
}
public static IReadOnlyList Get(CommandModel model, CommandInfo? command)
{
var parameters = new List();
- parameters.Add(new HelpOption("h", "help", null, null, "Prints help information"));
+ parameters.Add(new HelpOption("h", "help", null, null, "Prints help information", null));
// At the root and no default command?
if (command == null && model?.DefaultCommand == null)
{
- parameters.Add(new HelpOption("v", "version", null, null, "Prints version information"));
+ parameters.Add(new HelpOption("v", "version", null, null, "Prints version information", null));
}
parameters.AddRange(command?.Parameters.OfType().Where(o => !o.IsHidden).Select(o =>
new HelpOption(
o.ShortNames.FirstOrDefault(), o.LongNames.FirstOrDefault(),
- o.ValueName, o.ValueIsOptional, o.Description))
+ o.ValueName, o.ValueIsOptional, o.Description,
+ o.ParameterKind == ParameterKind.Flag && o.DefaultValue?.Value is false ? null : o.DefaultValue?.Value))
?? Array.Empty());
return parameters;
}
}
- public static IEnumerable Write(CommandModel model)
+ public static IEnumerable Write(CommandModel model, bool writeOptionsDefaultValues)
{
- return WriteCommand(model, null);
+ return WriteCommand(model, null, writeOptionsDefaultValues);
}
- public static IEnumerable WriteCommand(CommandModel model, CommandInfo? command)
+ public static IEnumerable WriteCommand(CommandModel model, CommandInfo? command, bool writeOptionsDefaultValues)
{
var container = command as ICommandContainer ?? model;
var isDefaultCommand = command?.IsDefaultCommand ?? false;
@@ -79,7 +82,7 @@ public static IEnumerable WriteCommand(CommandModel model, CommandI
result.AddRange(GetUsage(model, command));
result.AddRange(GetExamples(model, command));
result.AddRange(GetArguments(command));
- result.AddRange(GetOptions(model, command));
+ result.AddRange(GetOptions(model, command, writeOptionsDefaultValues));
result.AddRange(GetCommands(model, container, isDefaultCommand));
return result;
@@ -266,7 +269,7 @@ private static IEnumerable GetArguments(CommandInfo? command)
return result;
}
- private static IEnumerable GetOptions(CommandModel model, CommandInfo? command)
+ private static IEnumerable GetOptions(CommandModel model, CommandInfo? command, bool writeDefaultValues)
{
// Collect all options into a single structure.
var parameters = HelpOption.Get(model, command);
@@ -282,8 +285,16 @@ private static IEnumerable GetOptions(CommandModel model, CommandIn
new Markup(Environment.NewLine),
};
+ var helpOptions = parameters.ToArray();
+ var defaultValueColumn = writeDefaultValues && helpOptions.Any(e => e.DefaultValue != null);
+
var grid = new Grid();
grid.AddColumn(new GridColumn { Padding = new Padding(4, 4), NoWrap = true });
+ if (defaultValueColumn)
+ {
+ grid.AddColumn(new GridColumn { Padding = new Padding(0, 0, 4, 0) });
+ }
+
grid.AddColumn(new GridColumn { Padding = new Padding(0, 0) });
static string GetOptionParts(HelpOption option)
@@ -327,11 +338,22 @@ static string GetOptionParts(HelpOption option)
return builder.ToString();
}
- foreach (var option in parameters.ToArray())
+ if (defaultValueColumn)
{
- grid.AddRow(
- GetOptionParts(option),
- option.Description?.TrimEnd('.') ?? " ");
+ grid.AddRow(" ", "[lime]DEFAULT[/]", " ");
+ }
+
+ foreach (var option in helpOptions)
+ {
+ var columns = new List { GetOptionParts(option) };
+ if (defaultValueColumn)
+ {
+ columns.Add(option.DefaultValue == null ? " " : $"[bold]{option.DefaultValue.ToString().EscapeMarkup()}[/]");
+ }
+
+ columns.Add(option.Description?.TrimEnd('.') ?? " ");
+
+ grid.AddRow(columns.ToArray());
}
result.Add(grid);
@@ -373,19 +395,19 @@ private static IEnumerable GetCommands(
{
arguments.Style("silver", $"<{argument.Name.EscapeMarkup()}>");
arguments.Space();
- }
+ }
- if (model.TrimTrailingPeriod)
- {
+ if (model.TrimTrailingPeriod)
+ {
grid.AddRow(
arguments.ToString().TrimEnd(),
child.Description?.TrimEnd('.') ?? " ");
- }
- else
- {
- grid.AddRow(
- arguments.ToString().TrimEnd(),
- child.Description ?? " ");
+ }
+ else
+ {
+ grid.AddRow(
+ arguments.ToString().TrimEnd(),
+ child.Description ?? " ");
}
}
diff --git a/test/Spectre.Console.Cli.Tests/Expectations/Help/Command.Output.verified.txt b/test/Spectre.Console.Cli.Tests/Expectations/Help/Command.Output.verified.txt
index 0cf3f19ca..189faef26 100644
--- a/test/Spectre.Console.Cli.Tests/Expectations/Help/Command.Output.verified.txt
+++ b/test/Spectre.Console.Cli.Tests/Expectations/Help/Command.Output.verified.txt
@@ -8,10 +8,11 @@ ARGUMENTS:
[LEGS] The number of legs
OPTIONS:
- -h, --help Prints help information
- -a, --alive Indicates whether or not the animal is alive
+ DEFAULT
+ -h, --help Prints help information
+ -a, --alive Indicates whether or not the animal is alive
-n, --name
- --agility The agility between 0 and 100
+ --agility 10 The agility between 0 and 100
COMMANDS:
lion The lion command
\ No newline at end of file
diff --git a/test/Spectre.Console.Cli.Tests/Expectations/Help/Command_Hide_Default.Output.verified.txt b/test/Spectre.Console.Cli.Tests/Expectations/Help/Command_Hide_Default.Output.verified.txt
new file mode 100644
index 000000000..0cf3f19ca
--- /dev/null
+++ b/test/Spectre.Console.Cli.Tests/Expectations/Help/Command_Hide_Default.Output.verified.txt
@@ -0,0 +1,17 @@
+DESCRIPTION:
+Contains settings for a cat.
+
+USAGE:
+ myapp cat [LEGS] [OPTIONS]
+
+ARGUMENTS:
+ [LEGS] The number of legs
+
+OPTIONS:
+ -h, --help Prints help information
+ -a, --alive Indicates whether or not the animal is alive
+ -n, --name
+ --agility The agility between 0 and 100
+
+COMMANDS:
+ lion The lion command
\ No newline at end of file
diff --git a/test/Spectre.Console.Cli.Tests/Expectations/Help/Default.Output.verified.txt b/test/Spectre.Console.Cli.Tests/Expectations/Help/Default.Output.verified.txt
index 27df83873..7c2731bba 100644
--- a/test/Spectre.Console.Cli.Tests/Expectations/Help/Default.Output.verified.txt
+++ b/test/Spectre.Console.Cli.Tests/Expectations/Help/Default.Output.verified.txt
@@ -9,8 +9,9 @@ ARGUMENTS:
[LEGS] The number of legs
OPTIONS:
- -h, --help Prints help information
- -a, --alive Indicates whether or not the animal is alive
+ DEFAULT
+ -h, --help Prints help information
+ -a, --alive Indicates whether or not the animal is alive
-n, --name
- --agility The agility between 0 and 100
- -c The number of children the lion has
\ No newline at end of file
+ --agility 10 The agility between 0 and 100
+ -c The number of children the lion has
\ No newline at end of file
diff --git a/test/Spectre.Console.Cli.Tests/Expectations/Help/DefaultExamples.Output.verified.txt b/test/Spectre.Console.Cli.Tests/Expectations/Help/DefaultExamples.Output.verified.txt
index 81c19395a..8fc25ef9e 100644
--- a/test/Spectre.Console.Cli.Tests/Expectations/Help/DefaultExamples.Output.verified.txt
+++ b/test/Spectre.Console.Cli.Tests/Expectations/Help/DefaultExamples.Output.verified.txt
@@ -12,8 +12,9 @@ ARGUMENTS:
[LEGS] The number of legs
OPTIONS:
- -h, --help Prints help information
- -a, --alive Indicates whether or not the animal is alive
+ DEFAULT
+ -h, --help Prints help information
+ -a, --alive Indicates whether or not the animal is alive
-n, --name
- --agility The agility between 0 and 100
- -c The number of children the lion has
\ No newline at end of file
+ --agility 10 The agility between 0 and 100
+ -c The number of children the lion has
\ No newline at end of file
diff --git a/test/Spectre.Console.Cli.Tests/Expectations/Help/Default_Without_Args.Output.verified.txt b/test/Spectre.Console.Cli.Tests/Expectations/Help/Default_Without_Args.Output.verified.txt
index 1794d6628..7c2731bba 100644
--- a/test/Spectre.Console.Cli.Tests/Expectations/Help/Default_Without_Args.Output.verified.txt
+++ b/test/Spectre.Console.Cli.Tests/Expectations/Help/Default_Without_Args.Output.verified.txt
@@ -1,16 +1,17 @@
-DESCRIPTION:
-The lion command.
-
-USAGE:
- myapp [LEGS] [OPTIONS]
-
-ARGUMENTS:
- The number of teeth the lion has
- [LEGS] The number of legs
-
-OPTIONS:
- -h, --help Prints help information
- -a, --alive Indicates whether or not the animal is alive
- -n, --name
- --agility The agility between 0 and 100
- -c The number of children the lion has
\ No newline at end of file
+DESCRIPTION:
+The lion command.
+
+USAGE:
+ myapp [LEGS] [OPTIONS]
+
+ARGUMENTS:
+ The number of teeth the lion has
+ [LEGS] The number of legs
+
+OPTIONS:
+ DEFAULT
+ -h, --help Prints help information
+ -a, --alive Indicates whether or not the animal is alive
+ -n, --name
+ --agility 10 The agility between 0 and 100
+ -c The number of children the lion has
\ No newline at end of file
diff --git a/test/Spectre.Console.Cli.Tests/Expectations/Help/Default_Without_Args_Additional.Output.verified.txt b/test/Spectre.Console.Cli.Tests/Expectations/Help/Default_Without_Args_Additional.Output.verified.txt
index 36cb2f6ab..2c38182a5 100644
--- a/test/Spectre.Console.Cli.Tests/Expectations/Help/Default_Without_Args_Additional.Output.verified.txt
+++ b/test/Spectre.Console.Cli.Tests/Expectations/Help/Default_Without_Args_Additional.Output.verified.txt
@@ -1,4 +1,4 @@
-DESCRIPTION:
+DESCRIPTION:
The lion command.
USAGE:
@@ -9,11 +9,12 @@ ARGUMENTS:
[LEGS] The number of legs
OPTIONS:
- -h, --help Prints help information
- -a, --alive Indicates whether or not the animal is alive
+ DEFAULT
+ -h, --help Prints help information
+ -a, --alive Indicates whether or not the animal is alive
-n, --name
- --agility The agility between 0 and 100
- -c The number of children the lion has
+ --agility 10 The agility between 0 and 100
+ -c The number of children the lion has
COMMANDS:
giraffe The giraffe command
\ No newline at end of file
diff --git a/test/Spectre.Console.Cli.Tests/Unit/CommandAppTests.Help.cs b/test/Spectre.Console.Cli.Tests/Unit/CommandAppTests.Help.cs
index 5def4e409..24fb98426 100644
--- a/test/Spectre.Console.Cli.Tests/Unit/CommandAppTests.Help.cs
+++ b/test/Spectre.Console.Cli.Tests/Unit/CommandAppTests.Help.cs
@@ -99,6 +99,30 @@ public Task Should_Output_Command_Correctly()
return Verifier.Verify(result.Output);
}
+ [Fact]
+ [Expectation("Command_Hide_Default")]
+ public Task Should_Not_Print_Default_Column()
+ {
+ // Given
+ var fixture = new CommandAppTester();
+ fixture.Configure(configurator =>
+ {
+ configurator.SetApplicationName("myapp");
+ configurator.AddBranch("cat", animal =>
+ {
+ animal.SetDescription("Contains settings for a cat.");
+ animal.AddCommand("lion");
+ });
+ configurator.HideOptionDefaultValues();
+ });
+
+ // When
+ var result = fixture.Run("cat", "--help");
+
+ // Then
+ return Verifier.Verify(result.Output);
+ }
+
[Fact]
[Expectation("Leaf")]
public Task Should_Output_Leaf_Correctly()