mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-14 16:02:50 +08:00
Use file scoped namespace declarations
This commit is contained in:
parent
1dbaf50935
commit
ec1188b837
@ -30,6 +30,9 @@ trim_trailing_whitespace = false
|
||||
end_of_line = lf
|
||||
|
||||
[*.cs]
|
||||
# Prefer file scoped namespace declarations
|
||||
csharp_style_namespace_declarations = file_scoped:warning
|
||||
|
||||
# Sort using and Import directives with System.* appearing first
|
||||
dotnet_sort_system_directives_first = true
|
||||
dotnet_separate_import_directive_groups = false
|
||||
|
@ -1,16 +1,15 @@
|
||||
using System.ComponentModel;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static partial class Program
|
||||
{
|
||||
public static partial class Program
|
||||
public sealed class BarSettings : CommandSettings
|
||||
{
|
||||
public sealed class BarSettings : CommandSettings
|
||||
{
|
||||
[CommandOption("--count")]
|
||||
[Description("The number of bars to print")]
|
||||
[DefaultValue(1)]
|
||||
public int Count { get; set; }
|
||||
}
|
||||
[CommandOption("--count")]
|
||||
[Description("The number of bars to print")]
|
||||
[DefaultValue(1)]
|
||||
public int Count { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +1,37 @@
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static partial class Program
|
||||
{
|
||||
public static partial class Program
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
var app = new CommandApp();
|
||||
app.Configure(config =>
|
||||
{
|
||||
var app = new CommandApp();
|
||||
app.Configure(config =>
|
||||
{
|
||||
config.AddDelegate("foo", Foo)
|
||||
.WithDescription("Foos the bars");
|
||||
config.AddDelegate("foo", Foo)
|
||||
.WithDescription("Foos the bars");
|
||||
|
||||
config.AddDelegate<BarSettings>("bar", Bar)
|
||||
.WithDescription("Bars the foos"); ;
|
||||
});
|
||||
config.AddDelegate<BarSettings>("bar", Bar)
|
||||
.WithDescription("Bars the foos"); ;
|
||||
});
|
||||
|
||||
return app.Run(args);
|
||||
return app.Run(args);
|
||||
}
|
||||
|
||||
private static int Foo(CommandContext context)
|
||||
{
|
||||
AnsiConsole.WriteLine("Foo");
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int Bar(CommandContext context, BarSettings settings)
|
||||
{
|
||||
for (var index = 0; index < settings.Count; index++)
|
||||
{
|
||||
AnsiConsole.WriteLine("Bar");
|
||||
}
|
||||
|
||||
private static int Foo(CommandContext context)
|
||||
{
|
||||
AnsiConsole.WriteLine("Foo");
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int Bar(CommandContext context, BarSettings settings)
|
||||
{
|
||||
for (var index = 0; index < settings.Count; index++)
|
||||
{
|
||||
AnsiConsole.WriteLine("Bar");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -2,46 +2,45 @@ using System.ComponentModel;
|
||||
using Demo.Utilities;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo.Commands
|
||||
namespace Demo.Commands;
|
||||
|
||||
[Description("Add a NuGet package reference to the project.")]
|
||||
public sealed class AddPackageCommand : Command<AddPackageCommand.Settings>
|
||||
{
|
||||
[Description("Add a NuGet package reference to the project.")]
|
||||
public sealed class AddPackageCommand : Command<AddPackageCommand.Settings>
|
||||
public sealed class Settings : AddSettings
|
||||
{
|
||||
public sealed class Settings : AddSettings
|
||||
{
|
||||
[CommandArgument(0, "<PACKAGENAME>")]
|
||||
[Description("The package reference to add.")]
|
||||
public string PackageName { get; set; }
|
||||
[CommandArgument(0, "<PACKAGENAME>")]
|
||||
[Description("The package reference to add.")]
|
||||
public string PackageName { get; set; }
|
||||
|
||||
[CommandOption("-v|--version <VERSION>")]
|
||||
[Description("The version of the package to add.")]
|
||||
public string Version { get; set; }
|
||||
[CommandOption("-v|--version <VERSION>")]
|
||||
[Description("The version of the package to add.")]
|
||||
public string Version { get; set; }
|
||||
|
||||
[CommandOption("-f|--framework <FRAMEWORK>")]
|
||||
[Description("Add the reference only when targeting a specific framework.")]
|
||||
public string Framework { get; set; }
|
||||
[CommandOption("-f|--framework <FRAMEWORK>")]
|
||||
[Description("Add the reference only when targeting a specific framework.")]
|
||||
public string Framework { get; set; }
|
||||
|
||||
[CommandOption("--no-restore")]
|
||||
[Description("Add the reference without performing restore preview and compatibility check.")]
|
||||
public bool NoRestore { get; set; }
|
||||
[CommandOption("--no-restore")]
|
||||
[Description("Add the reference without performing restore preview and compatibility check.")]
|
||||
public bool NoRestore { get; set; }
|
||||
|
||||
[CommandOption("--source <SOURCE>")]
|
||||
[Description("The NuGet package source to use during the restore.")]
|
||||
public string Source { get; set; }
|
||||
[CommandOption("--source <SOURCE>")]
|
||||
[Description("The NuGet package source to use during the restore.")]
|
||||
public string Source { get; set; }
|
||||
|
||||
[CommandOption("--package-directory <PACKAGEDIR>")]
|
||||
[Description("The directory to restore packages to.")]
|
||||
public string PackageDirectory { get; set; }
|
||||
[CommandOption("--package-directory <PACKAGEDIR>")]
|
||||
[Description("The directory to restore packages to.")]
|
||||
public string PackageDirectory { get; set; }
|
||||
|
||||
[CommandOption("--interactive")]
|
||||
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
||||
public bool Interactive { get; set; }
|
||||
}
|
||||
[CommandOption("--interactive")]
|
||||
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
||||
public bool Interactive { get; set; }
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
SettingsDumper.Dump(settings);
|
||||
return 0;
|
||||
}
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
SettingsDumper.Dump(settings);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -2,29 +2,28 @@ using System.ComponentModel;
|
||||
using Demo.Utilities;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo.Commands
|
||||
namespace Demo.Commands;
|
||||
|
||||
public sealed class AddReferenceCommand : Command<AddReferenceCommand.Settings>
|
||||
{
|
||||
public sealed class AddReferenceCommand : Command<AddReferenceCommand.Settings>
|
||||
public sealed class Settings : AddSettings
|
||||
{
|
||||
public sealed class Settings : AddSettings
|
||||
{
|
||||
[CommandArgument(0, "<PROJECTPATH>")]
|
||||
[Description("The package reference to add.")]
|
||||
public string ProjectPath { get; set; }
|
||||
[CommandArgument(0, "<PROJECTPATH>")]
|
||||
[Description("The package reference to add.")]
|
||||
public string ProjectPath { get; set; }
|
||||
|
||||
[CommandOption("-f|--framework <FRAMEWORK>")]
|
||||
[Description("Add the reference only when targeting a specific framework.")]
|
||||
public string Framework { get; set; }
|
||||
[CommandOption("-f|--framework <FRAMEWORK>")]
|
||||
[Description("Add the reference only when targeting a specific framework.")]
|
||||
public string Framework { get; set; }
|
||||
|
||||
[CommandOption("--interactive")]
|
||||
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
||||
public bool Interactive { get; set; }
|
||||
}
|
||||
[CommandOption("--interactive")]
|
||||
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
||||
public bool Interactive { get; set; }
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
SettingsDumper.Dump(settings);
|
||||
return 0;
|
||||
}
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
SettingsDumper.Dump(settings);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
using System.ComponentModel;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo.Commands
|
||||
namespace Demo.Commands;
|
||||
|
||||
public abstract class AddSettings : CommandSettings
|
||||
{
|
||||
public abstract class AddSettings : CommandSettings
|
||||
{
|
||||
[CommandArgument(0, "<PROJECT>")]
|
||||
[Description("The project file to operate on. If a file is not specified, the command will search the current directory for one.")]
|
||||
public string Project { get; set; }
|
||||
}
|
||||
[CommandArgument(0, "<PROJECT>")]
|
||||
[Description("The project file to operate on. If a file is not specified, the command will search the current directory for one.")]
|
||||
public string Project { get; set; }
|
||||
}
|
||||
|
@ -2,69 +2,68 @@ using System.ComponentModel;
|
||||
using Demo.Utilities;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo.Commands
|
||||
namespace Demo.Commands;
|
||||
|
||||
[Description("Build and run a .NET project output.")]
|
||||
public sealed class RunCommand : Command<RunCommand.Settings>
|
||||
{
|
||||
[Description("Build and run a .NET project output.")]
|
||||
public sealed class RunCommand : Command<RunCommand.Settings>
|
||||
public sealed class Settings : CommandSettings
|
||||
{
|
||||
public sealed class Settings : CommandSettings
|
||||
{
|
||||
[CommandOption("-c|--configuration <CONFIGURATION>")]
|
||||
[Description("The configuration to run for. The default for most projects is '[grey]Debug[/]'.")]
|
||||
[DefaultValue("Debug")]
|
||||
public string Configuration { get; set; }
|
||||
[CommandOption("-c|--configuration <CONFIGURATION>")]
|
||||
[Description("The configuration to run for. The default for most projects is '[grey]Debug[/]'.")]
|
||||
[DefaultValue("Debug")]
|
||||
public string Configuration { get; set; }
|
||||
|
||||
[CommandOption("-f|--framework <FRAMEWORK>")]
|
||||
[Description("The target framework to run for. The target framework must also be specified in the project file.")]
|
||||
public string Framework { get; set; }
|
||||
[CommandOption("-f|--framework <FRAMEWORK>")]
|
||||
[Description("The target framework to run for. The target framework must also be specified in the project file.")]
|
||||
public string Framework { get; set; }
|
||||
|
||||
[CommandOption("-r|--runtime <RUNTIMEIDENTIFIER>")]
|
||||
[Description("The target runtime to run for.")]
|
||||
public string RuntimeIdentifier { get; set; }
|
||||
[CommandOption("-r|--runtime <RUNTIMEIDENTIFIER>")]
|
||||
[Description("The target runtime to run for.")]
|
||||
public string RuntimeIdentifier { get; set; }
|
||||
|
||||
[CommandOption("-p|--project <PROJECTPATH>")]
|
||||
[Description("The path to the project file to run (defaults to the current directory if there is only one project).")]
|
||||
public string ProjectPath { get; set; }
|
||||
[CommandOption("-p|--project <PROJECTPATH>")]
|
||||
[Description("The path to the project file to run (defaults to the current directory if there is only one project).")]
|
||||
public string ProjectPath { get; set; }
|
||||
|
||||
[CommandOption("--launch-profile <LAUNCHPROFILE>")]
|
||||
[Description("The name of the launch profile (if any) to use when launching the application.")]
|
||||
public string LaunchProfile { get; set; }
|
||||
[CommandOption("--launch-profile <LAUNCHPROFILE>")]
|
||||
[Description("The name of the launch profile (if any) to use when launching the application.")]
|
||||
public string LaunchProfile { get; set; }
|
||||
|
||||
[CommandOption("--no-launch-profile")]
|
||||
[Description("Do not attempt to use [grey]launchSettings.json[/] to configure the application.")]
|
||||
public bool NoLaunchProfile { get; set; }
|
||||
[CommandOption("--no-launch-profile")]
|
||||
[Description("Do not attempt to use [grey]launchSettings.json[/] to configure the application.")]
|
||||
public bool NoLaunchProfile { get; set; }
|
||||
|
||||
[CommandOption("--no-build")]
|
||||
[Description("Do not build the project before running. Implies [grey]--no-restore[/].")]
|
||||
public bool NoBuild { get; set; }
|
||||
[CommandOption("--no-build")]
|
||||
[Description("Do not build the project before running. Implies [grey]--no-restore[/].")]
|
||||
public bool NoBuild { get; set; }
|
||||
|
||||
[CommandOption("--interactive")]
|
||||
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
||||
public string Interactive { get; set; }
|
||||
[CommandOption("--interactive")]
|
||||
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
||||
public string Interactive { get; set; }
|
||||
|
||||
[CommandOption("--no-restore")]
|
||||
[Description("Do not restore the project before building.")]
|
||||
public bool NoRestore { get; set; }
|
||||
[CommandOption("--no-restore")]
|
||||
[Description("Do not restore the project before building.")]
|
||||
public bool NoRestore { get; set; }
|
||||
|
||||
[CommandOption("--verbosity <VERBOSITY>")]
|
||||
[Description("Set the MSBuild verbosity level. Allowed values are q[grey]uiet[/], m[grey]inimal[/], n[grey]ormal[/], d[grey]etailed[/], and diag[grey]nostic[/].")]
|
||||
[TypeConverter(typeof(VerbosityConverter))]
|
||||
[DefaultValue(Verbosity.Normal)]
|
||||
public Verbosity Verbosity { get; set; }
|
||||
[CommandOption("--verbosity <VERBOSITY>")]
|
||||
[Description("Set the MSBuild verbosity level. Allowed values are q[grey]uiet[/], m[grey]inimal[/], n[grey]ormal[/], d[grey]etailed[/], and diag[grey]nostic[/].")]
|
||||
[TypeConverter(typeof(VerbosityConverter))]
|
||||
[DefaultValue(Verbosity.Normal)]
|
||||
public Verbosity Verbosity { get; set; }
|
||||
|
||||
[CommandOption("--no-dependencies")]
|
||||
[Description("Do not restore project-to-project references and only restore the specified project.")]
|
||||
public bool NoDependencies { get; set; }
|
||||
[CommandOption("--no-dependencies")]
|
||||
[Description("Do not restore project-to-project references and only restore the specified project.")]
|
||||
public bool NoDependencies { get; set; }
|
||||
|
||||
[CommandOption("--force")]
|
||||
[Description("Force all dependencies to be resolved even if the last restore was successful. This is equivalent to deleting [grey]project.assets.json[/].")]
|
||||
public bool Force { get; set; }
|
||||
}
|
||||
[CommandOption("--force")]
|
||||
[Description("Force all dependencies to be resolved even if the last restore was successful. This is equivalent to deleting [grey]project.assets.json[/].")]
|
||||
public bool Force { get; set; }
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
SettingsDumper.Dump(settings);
|
||||
return 0;
|
||||
}
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
SettingsDumper.Dump(settings);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -3,39 +3,38 @@ using System.ComponentModel;
|
||||
using Demo.Utilities;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo.Commands
|
||||
namespace Demo.Commands;
|
||||
|
||||
[Description("Launches a web server in the current working directory and serves all files in it.")]
|
||||
public sealed class ServeCommand : Command<ServeCommand.Settings>
|
||||
{
|
||||
[Description("Launches a web server in the current working directory and serves all files in it.")]
|
||||
public sealed class ServeCommand : Command<ServeCommand.Settings>
|
||||
public sealed class Settings : CommandSettings
|
||||
{
|
||||
public sealed class Settings : CommandSettings
|
||||
{
|
||||
[CommandOption("-p|--port <PORT>")]
|
||||
[Description("Port to use. Defaults to [grey]8080[/]. Use [grey]0[/] for a dynamic port.")]
|
||||
public int Port { get; set; }
|
||||
[CommandOption("-p|--port <PORT>")]
|
||||
[Description("Port to use. Defaults to [grey]8080[/]. Use [grey]0[/] for a dynamic port.")]
|
||||
public int Port { get; set; }
|
||||
|
||||
[CommandOption("-o|--open-browser [BROWSER]")]
|
||||
[Description("Open a web browser when the server starts. You can also specify which browser to use. If none is specified, the default one will be used.")]
|
||||
public FlagValue<string> OpenBrowser { get; set; }
|
||||
}
|
||||
[CommandOption("-o|--open-browser [BROWSER]")]
|
||||
[Description("Open a web browser when the server starts. You can also specify which browser to use. If none is specified, the default one will be used.")]
|
||||
public FlagValue<string> OpenBrowser { get; set; }
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
if (settings.OpenBrowser.IsSet)
|
||||
{
|
||||
if (settings.OpenBrowser.IsSet)
|
||||
var browser = settings.OpenBrowser.Value;
|
||||
if (browser != null)
|
||||
{
|
||||
var browser = settings.OpenBrowser.Value;
|
||||
if (browser != null)
|
||||
{
|
||||
Console.WriteLine($"Open in {browser}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Open in default browser.");
|
||||
}
|
||||
Console.WriteLine($"Open in {browser}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Open in default browser.");
|
||||
}
|
||||
|
||||
SettingsDumper.Dump(settings);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SettingsDumper.Dump(settings);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +1,36 @@
|
||||
using Demo.Commands;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo
|
||||
namespace Demo;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
var app = new CommandApp();
|
||||
app.Configure(config =>
|
||||
{
|
||||
var app = new CommandApp();
|
||||
app.Configure(config =>
|
||||
{
|
||||
config.SetApplicationName("fake-dotnet");
|
||||
config.ValidateExamples();
|
||||
config.AddExample(new[] { "run", "--no-build" });
|
||||
config.SetApplicationName("fake-dotnet");
|
||||
config.ValidateExamples();
|
||||
config.AddExample(new[] { "run", "--no-build" });
|
||||
|
||||
// Run
|
||||
config.AddCommand<RunCommand>("run");
|
||||
|
||||
// Add
|
||||
config.AddBranch<AddSettings>("add", add =>
|
||||
{
|
||||
add.SetDescription("Add a package or reference to a .NET project");
|
||||
add.AddCommand<AddPackageCommand>("package");
|
||||
add.AddCommand<AddReferenceCommand>("reference");
|
||||
});
|
||||
{
|
||||
add.SetDescription("Add a package or reference to a .NET project");
|
||||
add.AddCommand<AddPackageCommand>("package");
|
||||
add.AddCommand<AddReferenceCommand>("reference");
|
||||
});
|
||||
|
||||
// Serve
|
||||
config.AddCommand<ServeCommand>("serve")
|
||||
.WithExample(new[] { "serve", "-o", "firefox" })
|
||||
.WithExample(new[] { "serve", "--port", "80", "-o", "firefox" });
|
||||
});
|
||||
.WithExample(new[] { "serve", "-o", "firefox" })
|
||||
.WithExample(new[] { "serve", "--port", "80", "-o", "firefox" });
|
||||
});
|
||||
|
||||
return app.Run(args);
|
||||
}
|
||||
return app.Run(args);
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,28 @@
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo.Utilities
|
||||
namespace Demo.Utilities;
|
||||
|
||||
public static class SettingsDumper
|
||||
{
|
||||
public static class SettingsDumper
|
||||
public static void Dump(CommandSettings settings)
|
||||
{
|
||||
public static void Dump(CommandSettings settings)
|
||||
var table = new Table().RoundedBorder();
|
||||
table.AddColumn("[grey]Name[/]");
|
||||
table.AddColumn("[grey]Value[/]");
|
||||
|
||||
var properties = settings.GetType().GetProperties();
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var table = new Table().RoundedBorder();
|
||||
table.AddColumn("[grey]Name[/]");
|
||||
table.AddColumn("[grey]Value[/]");
|
||||
var value = property.GetValue(settings)
|
||||
?.ToString()
|
||||
?.Replace("[", "[[");
|
||||
|
||||
var properties = settings.GetType().GetProperties();
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var value = property.GetValue(settings)
|
||||
?.ToString()
|
||||
?.Replace("[", "[[");
|
||||
|
||||
table.AddRow(
|
||||
property.Name,
|
||||
value ?? "[grey]null[/]");
|
||||
}
|
||||
|
||||
AnsiConsole.Write(table);
|
||||
table.AddRow(
|
||||
property.Name,
|
||||
value ?? "[grey]null[/]");
|
||||
}
|
||||
|
||||
AnsiConsole.Write(table);
|
||||
}
|
||||
}
|
||||
|
@ -3,24 +3,24 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Demo
|
||||
namespace Demo;
|
||||
|
||||
public enum Verbosity
|
||||
{
|
||||
public enum Verbosity
|
||||
{
|
||||
Quiet,
|
||||
Minimal,
|
||||
Normal,
|
||||
Detailed,
|
||||
Diagnostic
|
||||
}
|
||||
Quiet,
|
||||
Minimal,
|
||||
Normal,
|
||||
Detailed,
|
||||
Diagnostic
|
||||
}
|
||||
|
||||
public sealed class VerbosityConverter : TypeConverter
|
||||
{
|
||||
private readonly Dictionary<string, Verbosity> _lookup;
|
||||
public sealed class VerbosityConverter : TypeConverter
|
||||
{
|
||||
private readonly Dictionary<string, Verbosity> _lookup;
|
||||
|
||||
public VerbosityConverter()
|
||||
{
|
||||
_lookup = new Dictionary<string, Verbosity>(StringComparer.OrdinalIgnoreCase)
|
||||
public VerbosityConverter()
|
||||
{
|
||||
_lookup = new Dictionary<string, Verbosity>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "q", Verbosity.Quiet },
|
||||
{ "quiet", Verbosity.Quiet },
|
||||
@ -33,22 +33,21 @@ namespace Demo
|
||||
{ "diag", Verbosity.Diagnostic },
|
||||
{ "diagnostic", Verbosity.Diagnostic }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
if (value is string stringValue)
|
||||
{
|
||||
if (value is string stringValue)
|
||||
var result = _lookup.TryGetValue(stringValue, out var verbosity);
|
||||
if (!result)
|
||||
{
|
||||
var result = _lookup.TryGetValue(stringValue, out var verbosity);
|
||||
if (!result)
|
||||
{
|
||||
const string format = "The value '{0}' is not a valid verbosity.";
|
||||
var message = string.Format(CultureInfo.InvariantCulture, format, value);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
return verbosity;
|
||||
const string format = "The value '{0}' is not a valid verbosity.";
|
||||
var message = string.Format(CultureInfo.InvariantCulture, format, value);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
throw new NotSupportedException("Can't convert value to verbosity.");
|
||||
return verbosity;
|
||||
}
|
||||
throw new NotSupportedException("Can't convert value to verbosity.");
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,19 @@
|
||||
using System;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
{
|
||||
public sealed class MyCommand : Command
|
||||
{
|
||||
public override int Execute(CommandContext context)
|
||||
{
|
||||
if (!(context.Data is int data))
|
||||
{
|
||||
throw new InvalidOperationException("Command has no associated data.");
|
||||
|
||||
}
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public sealed class MyCommand : Command
|
||||
{
|
||||
public override int Execute(CommandContext context)
|
||||
{
|
||||
if (!(context.Data is int data))
|
||||
{
|
||||
throw new InvalidOperationException("Command has no associated data.");
|
||||
|
||||
AnsiConsole.WriteLine("Value = {0}", data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AnsiConsole.WriteLine("Value = {0}", data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,23 @@
|
||||
using System.Linq;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
var app = new CommandApp();
|
||||
app.Configure(config =>
|
||||
{
|
||||
foreach(var index in Enumerable.Range(1, 10))
|
||||
{
|
||||
config.AddCommand<MyCommand>($"c{index}")
|
||||
.WithDescription($"Prints the number {index}")
|
||||
.WithData(index);
|
||||
}
|
||||
});
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
return app.Run(args);
|
||||
}
|
||||
public static class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
var app = new CommandApp();
|
||||
app.Configure(config =>
|
||||
{
|
||||
foreach (var index in Enumerable.Range(1, 10))
|
||||
{
|
||||
config.AddCommand<MyCommand>($"c{index}")
|
||||
.WithDescription($"Prints the number {index}")
|
||||
.WithData(index);
|
||||
}
|
||||
});
|
||||
|
||||
return app.Run(args);
|
||||
}
|
||||
}
|
||||
|
@ -2,29 +2,28 @@ using System;
|
||||
using System.ComponentModel;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public sealed class DefaultCommand : Command<DefaultCommand.Settings>
|
||||
{
|
||||
public sealed class DefaultCommand : Command<DefaultCommand.Settings>
|
||||
private readonly IGreeter _greeter;
|
||||
|
||||
public sealed class Settings : CommandSettings
|
||||
{
|
||||
private readonly IGreeter _greeter;
|
||||
[CommandOption("-n|--name <NAME>")]
|
||||
[Description("The person or thing to greet.")]
|
||||
[DefaultValue("World")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public sealed class Settings : CommandSettings
|
||||
{
|
||||
[CommandOption("-n|--name <NAME>")]
|
||||
[Description("The person or thing to greet.")]
|
||||
[DefaultValue("World")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
public DefaultCommand(IGreeter greeter)
|
||||
{
|
||||
_greeter = greeter ?? throw new ArgumentNullException(nameof(greeter));
|
||||
}
|
||||
|
||||
public DefaultCommand(IGreeter greeter)
|
||||
{
|
||||
_greeter = greeter ?? throw new ArgumentNullException(nameof(greeter));
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
_greeter.Greet(settings.Name);
|
||||
return 0;
|
||||
}
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
_greeter.Greet(settings.Name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
namespace Spectre.Console.Examples
|
||||
{
|
||||
public interface IGreeter
|
||||
{
|
||||
void Greet(string name);
|
||||
}
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public sealed class HelloWorldGreeter : IGreeter
|
||||
public interface IGreeter
|
||||
{
|
||||
void Greet(string name);
|
||||
}
|
||||
|
||||
public sealed class HelloWorldGreeter : IGreeter
|
||||
{
|
||||
public void Greet(string name)
|
||||
{
|
||||
public void Greet(string name)
|
||||
{
|
||||
AnsiConsole.WriteLine($"Hello {name}!");
|
||||
}
|
||||
AnsiConsole.WriteLine($"Hello {name}!");
|
||||
}
|
||||
}
|
||||
|
@ -2,40 +2,39 @@ using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public sealed class TypeRegistrar : ITypeRegistrar
|
||||
{
|
||||
public sealed class TypeRegistrar : ITypeRegistrar
|
||||
private readonly IServiceCollection _builder;
|
||||
|
||||
public TypeRegistrar(IServiceCollection builder)
|
||||
{
|
||||
private readonly IServiceCollection _builder;
|
||||
_builder = builder;
|
||||
}
|
||||
|
||||
public TypeRegistrar(IServiceCollection builder)
|
||||
public ITypeResolver Build()
|
||||
{
|
||||
return new TypeResolver(_builder.BuildServiceProvider());
|
||||
}
|
||||
|
||||
public void Register(Type service, Type implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterInstance(Type service, object implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterLazy(Type service, Func<object> func)
|
||||
{
|
||||
if (func is null)
|
||||
{
|
||||
_builder = builder;
|
||||
throw new ArgumentNullException(nameof(func));
|
||||
}
|
||||
|
||||
public ITypeResolver Build()
|
||||
{
|
||||
return new TypeResolver(_builder.BuildServiceProvider());
|
||||
}
|
||||
|
||||
public void Register(Type service, Type implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterInstance(Type service, object implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterLazy(Type service, Func<object> func)
|
||||
{
|
||||
if (func is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(func));
|
||||
}
|
||||
|
||||
_builder.AddSingleton(service, (provider) => func());
|
||||
}
|
||||
_builder.AddSingleton(service, (provider) => func());
|
||||
}
|
||||
}
|
||||
|
@ -2,33 +2,32 @@ using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public sealed class TypeResolver : ITypeResolver, IDisposable
|
||||
{
|
||||
public sealed class TypeResolver : ITypeResolver, IDisposable
|
||||
private readonly IServiceProvider _provider;
|
||||
|
||||
public TypeResolver(IServiceProvider provider)
|
||||
{
|
||||
private readonly IServiceProvider _provider;
|
||||
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||
}
|
||||
|
||||
public TypeResolver(IServiceProvider provider)
|
||||
public object Resolve(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||
return null;
|
||||
}
|
||||
|
||||
public object Resolve(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return _provider.GetService(type);
|
||||
}
|
||||
|
||||
return _provider.GetService(type);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public void Dispose()
|
||||
{
|
||||
if (_provider is IDisposable disposable)
|
||||
{
|
||||
if (_provider is IDisposable disposable)
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
disposable.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,21 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
// Create a type registrar and register any dependencies.
|
||||
// A type registrar is an adapter for a DI framework.
|
||||
var registrations = new ServiceCollection();
|
||||
registrations.AddSingleton<IGreeter, HelloWorldGreeter>();
|
||||
var registrar = new TypeRegistrar(registrations);
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
// Create a new command app with the registrar
|
||||
// and run it with the provided arguments.
|
||||
var app = new CommandApp<DefaultCommand>(registrar);
|
||||
return app.Run(args);
|
||||
}
|
||||
public class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
// Create a type registrar and register any dependencies.
|
||||
// A type registrar is an adapter for a DI framework.
|
||||
var registrations = new ServiceCollection();
|
||||
registrations.AddSingleton<IGreeter, HelloWorldGreeter>();
|
||||
var registrar = new TypeRegistrar(registrations);
|
||||
|
||||
// Create a new command app with the registrar
|
||||
// and run it with the provided arguments.
|
||||
var app = new CommandApp<DefaultCommand>(registrar);
|
||||
return app.Run(args);
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,33 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public class HelloCommand : Command<HelloCommand.Settings>
|
||||
{
|
||||
public class HelloCommand : Command<HelloCommand.Settings>
|
||||
private ILogger<HelloCommand> _logger;
|
||||
private IAnsiConsole _console;
|
||||
|
||||
public HelloCommand(IAnsiConsole console, ILogger<HelloCommand> logger)
|
||||
{
|
||||
private ILogger<HelloCommand> _logger;
|
||||
private IAnsiConsole _console;
|
||||
|
||||
public HelloCommand(IAnsiConsole console, ILogger<HelloCommand> logger)
|
||||
{
|
||||
_console = console;
|
||||
_logger = logger;
|
||||
_logger.LogDebug("{0} initialized", nameof(HelloCommand));
|
||||
}
|
||||
|
||||
public class Settings : LogCommandSettings
|
||||
{
|
||||
[CommandArgument(0, "[Name]")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
_logger.LogInformation("Starting my command");
|
||||
AnsiConsole.MarkupLine($"Hello, [blue]{settings.Name}[/]");
|
||||
_logger.LogInformation("Completed my command");
|
||||
|
||||
return 0;
|
||||
}
|
||||
_console = console;
|
||||
_logger = logger;
|
||||
_logger.LogDebug("{0} initialized", nameof(HelloCommand));
|
||||
}
|
||||
}
|
||||
|
||||
public class Settings : LogCommandSettings
|
||||
{
|
||||
[CommandArgument(0, "[Name]")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
_logger.LogInformation("Starting my command");
|
||||
AnsiConsole.MarkupLine($"Hello, [blue]{settings.Name}[/]");
|
||||
_logger.LogInformation("Completed my command");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -5,28 +5,28 @@ using System.Globalization;
|
||||
using Serilog.Events;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public class LogCommandSettings : CommandSettings
|
||||
{
|
||||
public class LogCommandSettings : CommandSettings
|
||||
[CommandOption("--logFile")]
|
||||
[Description("Path and file name for logging")]
|
||||
public string LogFile { get; set; }
|
||||
|
||||
[CommandOption("--logLevel")]
|
||||
[Description("Minimum level for logging")]
|
||||
[TypeConverter(typeof(VerbosityConverter))]
|
||||
[DefaultValue(LogEventLevel.Information)]
|
||||
public LogEventLevel LogLevel { get; set; }
|
||||
}
|
||||
|
||||
public sealed class VerbosityConverter : TypeConverter
|
||||
{
|
||||
private readonly Dictionary<string, LogEventLevel> _lookup;
|
||||
|
||||
public VerbosityConverter()
|
||||
{
|
||||
[CommandOption("--logFile")]
|
||||
[Description("Path and file name for logging")]
|
||||
public string LogFile { get; set; }
|
||||
|
||||
[CommandOption("--logLevel")]
|
||||
[Description("Minimum level for logging")]
|
||||
[TypeConverter(typeof(VerbosityConverter))]
|
||||
[DefaultValue(LogEventLevel.Information)]
|
||||
public LogEventLevel LogLevel { get; set; }
|
||||
}
|
||||
|
||||
public sealed class VerbosityConverter : TypeConverter
|
||||
{
|
||||
private readonly Dictionary<string, LogEventLevel> _lookup;
|
||||
|
||||
public VerbosityConverter()
|
||||
{
|
||||
_lookup = new Dictionary<string, LogEventLevel>(StringComparer.OrdinalIgnoreCase)
|
||||
_lookup = new Dictionary<string, LogEventLevel>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{"d", LogEventLevel.Debug},
|
||||
{"v", LogEventLevel.Verbose},
|
||||
@ -35,22 +35,21 @@ namespace Spectre.Console.Examples
|
||||
{"e", LogEventLevel.Error},
|
||||
{"f", LogEventLevel.Fatal}
|
||||
};
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
if (value is string stringValue)
|
||||
{
|
||||
var result = _lookup.TryGetValue(stringValue, out var verbosity);
|
||||
if (!result)
|
||||
{
|
||||
const string format = "The value '{0}' is not a valid verbosity.";
|
||||
var message = string.Format(CultureInfo.InvariantCulture, format, value);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
return verbosity;
|
||||
}
|
||||
throw new NotSupportedException("Can't convert value to verbosity.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
if (value is string stringValue)
|
||||
{
|
||||
var result = _lookup.TryGetValue(stringValue, out var verbosity);
|
||||
if (!result)
|
||||
{
|
||||
const string format = "The value '{0}' is not a valid verbosity.";
|
||||
var message = string.Format(CultureInfo.InvariantCulture, format, value);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
return verbosity;
|
||||
}
|
||||
throw new NotSupportedException("Can't convert value to verbosity.");
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
using Serilog.Core;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
{
|
||||
public class LogInterceptor : ICommandInterceptor
|
||||
{
|
||||
public static readonly LoggingLevelSwitch LogLevel = new();
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public void Intercept(CommandContext context, CommandSettings settings)
|
||||
public class LogInterceptor : ICommandInterceptor
|
||||
{
|
||||
public static readonly LoggingLevelSwitch LogLevel = new();
|
||||
|
||||
public void Intercept(CommandContext context, CommandSettings settings)
|
||||
{
|
||||
if (settings is LogCommandSettings logSettings)
|
||||
{
|
||||
if (settings is LogCommandSettings logSettings)
|
||||
{
|
||||
LoggingEnricher.Path = logSettings.LogFile ?? "application.log";
|
||||
LogLevel.MinimumLevel = logSettings.LogLevel;
|
||||
}
|
||||
LoggingEnricher.Path = logSettings.LogFile ?? "application.log";
|
||||
LogLevel.MinimumLevel = logSettings.LogLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +1,37 @@
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
internal class LoggingEnricher : ILogEventEnricher
|
||||
{
|
||||
internal class LoggingEnricher : ILogEventEnricher
|
||||
private string _cachedLogFilePath;
|
||||
private LogEventProperty _cachedLogFilePathProperty;
|
||||
|
||||
// this path and level will be set by the LogInterceptor.cs after parsing the settings
|
||||
public static string Path = string.Empty;
|
||||
|
||||
public const string LogFilePathPropertyName = "LogFilePath";
|
||||
|
||||
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
|
||||
{
|
||||
private string _cachedLogFilePath;
|
||||
private LogEventProperty _cachedLogFilePathProperty;
|
||||
// the settings might not have a path or we might not be within a command in which case
|
||||
// we won't have the setting so a default value for the log file will be required
|
||||
LogEventProperty logFilePathProperty;
|
||||
|
||||
// this path and level will be set by the LogInterceptor.cs after parsing the settings
|
||||
public static string Path = string.Empty;
|
||||
|
||||
public const string LogFilePathPropertyName = "LogFilePath";
|
||||
|
||||
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
|
||||
if (_cachedLogFilePathProperty != null && Path.Equals(_cachedLogFilePath))
|
||||
{
|
||||
// the settings might not have a path or we might not be within a command in which case
|
||||
// we won't have the setting so a default value for the log file will be required
|
||||
LogEventProperty logFilePathProperty;
|
||||
|
||||
if (_cachedLogFilePathProperty != null && Path.Equals(_cachedLogFilePath))
|
||||
{
|
||||
// Path hasn't changed, so let's use the cached property
|
||||
logFilePathProperty = _cachedLogFilePathProperty;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We've got a new path for the log. Let's create a new property
|
||||
// and cache it for future log events to use
|
||||
_cachedLogFilePath = Path;
|
||||
_cachedLogFilePathProperty = logFilePathProperty = propertyFactory.CreateProperty(LogFilePathPropertyName, Path);
|
||||
}
|
||||
|
||||
logEvent.AddPropertyIfAbsent(logFilePathProperty);
|
||||
// Path hasn't changed, so let's use the cached property
|
||||
logFilePathProperty = _cachedLogFilePathProperty;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We've got a new path for the log. Let's create a new property
|
||||
// and cache it for future log events to use
|
||||
_cachedLogFilePath = Path;
|
||||
_cachedLogFilePathProperty = logFilePathProperty = propertyFactory.CreateProperty(LogFilePathPropertyName, Path);
|
||||
}
|
||||
|
||||
logEvent.AddPropertyIfAbsent(logFilePathProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,40 +2,39 @@ using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public sealed class TypeRegistrar : ITypeRegistrar
|
||||
{
|
||||
public sealed class TypeRegistrar : ITypeRegistrar
|
||||
private readonly IServiceCollection _builder;
|
||||
|
||||
public TypeRegistrar(IServiceCollection builder)
|
||||
{
|
||||
private readonly IServiceCollection _builder;
|
||||
|
||||
public TypeRegistrar(IServiceCollection builder)
|
||||
{
|
||||
_builder = builder;
|
||||
}
|
||||
|
||||
public ITypeResolver Build()
|
||||
{
|
||||
return new TypeResolver(_builder.BuildServiceProvider());
|
||||
}
|
||||
|
||||
public void Register(Type service, Type implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterInstance(Type service, object implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterLazy(Type service, Func<object> func)
|
||||
{
|
||||
if (func is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(func));
|
||||
}
|
||||
|
||||
_builder.AddSingleton(service, _ => func());
|
||||
}
|
||||
_builder = builder;
|
||||
}
|
||||
}
|
||||
|
||||
public ITypeResolver Build()
|
||||
{
|
||||
return new TypeResolver(_builder.BuildServiceProvider());
|
||||
}
|
||||
|
||||
public void Register(Type service, Type implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterInstance(Type service, object implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterLazy(Type service, Func<object> func)
|
||||
{
|
||||
if (func is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(func));
|
||||
}
|
||||
|
||||
_builder.AddSingleton(service, _ => func());
|
||||
}
|
||||
}
|
||||
|
@ -2,20 +2,19 @@ using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public sealed class TypeResolver : ITypeResolver
|
||||
{
|
||||
public sealed class TypeResolver : ITypeResolver
|
||||
private readonly IServiceProvider _provider;
|
||||
|
||||
public TypeResolver(IServiceProvider provider)
|
||||
{
|
||||
private readonly IServiceProvider _provider;
|
||||
|
||||
public TypeResolver(IServiceProvider provider)
|
||||
{
|
||||
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||
}
|
||||
|
||||
public object Resolve(Type type)
|
||||
{
|
||||
return _provider.GetRequiredService(type);
|
||||
}
|
||||
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||
}
|
||||
}
|
||||
|
||||
public object Resolve(Type type)
|
||||
{
|
||||
return _provider.GetRequiredService(type);
|
||||
}
|
||||
}
|
||||
|
@ -12,42 +12,41 @@ using Spectre.Console.Cli;
|
||||
* Spectre.Console CommandInterceptor
|
||||
*/
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public class Program
|
||||
{
|
||||
public class Program
|
||||
static int Main(string[] args)
|
||||
{
|
||||
static int Main(string[] args)
|
||||
// to retrieve the log file name, we must first parse the command settings
|
||||
// this will require us to delay setting the file path for the file writer.
|
||||
// With serilog we can use an enricher and Serilog.Sinks.Map to dynamically
|
||||
// pull this setting.
|
||||
var serviceCollection = new ServiceCollection()
|
||||
.AddLogging(configure =>
|
||||
configure.AddSerilog(new LoggerConfiguration()
|
||||
// log level will be dynamically be controlled by our log interceptor upon running
|
||||
.MinimumLevel.ControlledBy(LogInterceptor.LogLevel)
|
||||
// the log enricher will add a new property with the log file path from the settings
|
||||
// that we can use to set the path dynamically
|
||||
.Enrich.With<LoggingEnricher>()
|
||||
// serilog.sinks.map will defer the configuration of the sink to be ondemand
|
||||
// allowing us to look at the properties set by the enricher to set the path appropriately
|
||||
.WriteTo.Map(LoggingEnricher.LogFilePathPropertyName,
|
||||
(logFilePath, wt) => wt.File($"{logFilePath}"), 1)
|
||||
.CreateLogger()
|
||||
)
|
||||
);
|
||||
|
||||
var registrar = new TypeRegistrar(serviceCollection);
|
||||
var app = new CommandApp(registrar);
|
||||
|
||||
app.Configure(config =>
|
||||
{
|
||||
// to retrieve the log file name, we must first parse the command settings
|
||||
// this will require us to delay setting the file path for the file writer.
|
||||
// With serilog we can use an enricher and Serilog.Sinks.Map to dynamically
|
||||
// pull this setting.
|
||||
var serviceCollection = new ServiceCollection()
|
||||
.AddLogging(configure =>
|
||||
configure.AddSerilog(new LoggerConfiguration()
|
||||
// log level will be dynamically be controlled by our log interceptor upon running
|
||||
.MinimumLevel.ControlledBy(LogInterceptor.LogLevel)
|
||||
// the log enricher will add a new property with the log file path from the settings
|
||||
// that we can use to set the path dynamically
|
||||
.Enrich.With<LoggingEnricher>()
|
||||
// serilog.sinks.map will defer the configuration of the sink to be ondemand
|
||||
// allowing us to look at the properties set by the enricher to set the path appropriately
|
||||
.WriteTo.Map(LoggingEnricher.LogFilePathPropertyName,
|
||||
(logFilePath, wt) => wt.File($"{logFilePath}"), 1)
|
||||
.CreateLogger()
|
||||
)
|
||||
);
|
||||
|
||||
var registrar = new TypeRegistrar(serviceCollection);
|
||||
var app = new CommandApp(registrar);
|
||||
|
||||
app.Configure(config =>
|
||||
{
|
||||
config.SetInterceptor(new LogInterceptor()); // add the interceptor
|
||||
config.SetInterceptor(new LogInterceptor()); // add the interceptor
|
||||
config.AddCommand<HelloCommand>("hello");
|
||||
});
|
||||
});
|
||||
|
||||
return app.Run(args);
|
||||
}
|
||||
return app.Run(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +1,32 @@
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
// Render panel borders
|
||||
HorizontalRule("PANEL BORDERS");
|
||||
PanelBorders();
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
// Render table borders
|
||||
HorizontalRule("TABLE BORDERS");
|
||||
TableBorders();
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
// Render panel borders
|
||||
HorizontalRule("PANEL BORDERS");
|
||||
PanelBorders();
|
||||
|
||||
// Render table borders
|
||||
HorizontalRule("TABLE BORDERS");
|
||||
TableBorders();
|
||||
}
|
||||
|
||||
private static void PanelBorders()
|
||||
{
|
||||
static IRenderable CreatePanel(string name, BoxBorder border)
|
||||
{
|
||||
return new Panel($"This is a panel with\nthe [yellow]{name}[/] border.")
|
||||
.Header($" [blue]{name}[/] ", Justify.Center)
|
||||
.Border(border)
|
||||
.BorderStyle(Style.Parse("grey"));
|
||||
}
|
||||
|
||||
private static void PanelBorders()
|
||||
var items = new[]
|
||||
{
|
||||
static IRenderable CreatePanel(string name, BoxBorder border)
|
||||
{
|
||||
return new Panel($"This is a panel with\nthe [yellow]{name}[/] border.")
|
||||
.Header($" [blue]{name}[/] ", Justify.Center)
|
||||
.Border(border)
|
||||
.BorderStyle(Style.Parse("grey"));
|
||||
}
|
||||
|
||||
var items = new[]
|
||||
{
|
||||
CreatePanel("Ascii", BoxBorder.Ascii),
|
||||
CreatePanel("Square", BoxBorder.Square),
|
||||
CreatePanel("Rounded", BoxBorder.Rounded),
|
||||
@ -35,29 +35,29 @@ namespace Spectre.Console.Examples
|
||||
CreatePanel("None", BoxBorder.None),
|
||||
};
|
||||
|
||||
AnsiConsole.Write(
|
||||
new Padder(
|
||||
new Columns(items).PadRight(2),
|
||||
new Padding(2,0,0,0)));
|
||||
AnsiConsole.Write(
|
||||
new Padder(
|
||||
new Columns(items).PadRight(2),
|
||||
new Padding(2, 0, 0, 0)));
|
||||
}
|
||||
|
||||
private static void TableBorders()
|
||||
{
|
||||
static IRenderable CreateTable(string name, TableBorder border)
|
||||
{
|
||||
var table = new Table().Border(border);
|
||||
table.AddColumn("[yellow]Header 1[/]", c => c.Footer("[grey]Footer 1[/]"));
|
||||
table.AddColumn("[yellow]Header 2[/]", col => col.Footer("[grey]Footer 2[/]").RightAligned());
|
||||
table.AddRow("Cell", "Cell");
|
||||
table.AddRow("Cell", "Cell");
|
||||
|
||||
return new Panel(table)
|
||||
.Header($" [blue]{name}[/] ", Justify.Center)
|
||||
.NoBorder();
|
||||
}
|
||||
|
||||
private static void TableBorders()
|
||||
var items = new[]
|
||||
{
|
||||
static IRenderable CreateTable(string name, TableBorder border)
|
||||
{
|
||||
var table = new Table().Border(border);
|
||||
table.AddColumn("[yellow]Header 1[/]", c => c.Footer("[grey]Footer 1[/]"));
|
||||
table.AddColumn("[yellow]Header 2[/]", col => col.Footer("[grey]Footer 2[/]").RightAligned());
|
||||
table.AddRow("Cell", "Cell");
|
||||
table.AddRow("Cell", "Cell");
|
||||
|
||||
return new Panel(table)
|
||||
.Header($" [blue]{name}[/] ", Justify.Center)
|
||||
.NoBorder();
|
||||
}
|
||||
|
||||
var items = new[]
|
||||
{
|
||||
CreateTable("Ascii", TableBorder.Ascii),
|
||||
CreateTable("Ascii2", TableBorder.Ascii2),
|
||||
CreateTable("AsciiDoubleHead", TableBorder.AsciiDoubleHead),
|
||||
@ -77,14 +77,13 @@ namespace Spectre.Console.Examples
|
||||
CreateTable("Markdown", TableBorder.Markdown),
|
||||
};
|
||||
|
||||
AnsiConsole.Write(new Columns(items).Collapse());
|
||||
}
|
||||
AnsiConsole.Write(new Columns(items).Collapse());
|
||||
}
|
||||
|
||||
private static void HorizontalRule(string title)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule($"[white bold]{title}[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
private static void HorizontalRule(string title)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule($"[white bold]{title}[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,16 @@
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Calendar(2020, 10)
|
||||
.RoundedBorder()
|
||||
.HighlightStyle(Style.Parse("red"))
|
||||
.HeaderStyle(Style.Parse("yellow"))
|
||||
.AddCalendarEvent("An event", 2020, 9, 22)
|
||||
.AddCalendarEvent("Another event", 2020, 10, 2)
|
||||
.AddCalendarEvent("A third event", 2020, 10, 13));
|
||||
}
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Calendar(2020, 10)
|
||||
.RoundedBorder()
|
||||
.HighlightStyle(Style.Parse("red"))
|
||||
.HeaderStyle(Style.Parse("yellow"))
|
||||
.AddCalendarEvent("An event", 2020, 9, 22)
|
||||
.AddCalendarEvent("Another event", 2020, 10, 2)
|
||||
.AddCalendarEvent("A third event", 2020, 10, 13));
|
||||
}
|
||||
}
|
||||
|
@ -5,82 +5,81 @@ Licensed under GNU Free Documentation License 1.2
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Mandelbrot
|
||||
{
|
||||
public static class Mandelbrot
|
||||
private const double MaxValueExtent = 2.0;
|
||||
|
||||
private struct ComplexNumber
|
||||
{
|
||||
private const double MaxValueExtent = 2.0;
|
||||
public double Real { get; }
|
||||
public double Imaginary { get; }
|
||||
|
||||
private struct ComplexNumber
|
||||
public ComplexNumber(double real, double imaginary)
|
||||
{
|
||||
public double Real { get; }
|
||||
public double Imaginary { get; }
|
||||
|
||||
public ComplexNumber(double real, double imaginary)
|
||||
{
|
||||
Real = real;
|
||||
Imaginary = imaginary;
|
||||
}
|
||||
|
||||
public static ComplexNumber operator +(ComplexNumber x, ComplexNumber y)
|
||||
{
|
||||
return new ComplexNumber(x.Real + y.Real, x.Imaginary + y.Imaginary);
|
||||
}
|
||||
|
||||
public static ComplexNumber operator *(ComplexNumber x, ComplexNumber y)
|
||||
{
|
||||
return new ComplexNumber(x.Real * y.Real - x.Imaginary * y.Imaginary,
|
||||
x.Real * y.Imaginary + x.Imaginary * y.Real);
|
||||
}
|
||||
|
||||
public double Abs()
|
||||
{
|
||||
return Real * Real + Imaginary * Imaginary;
|
||||
}
|
||||
Real = real;
|
||||
Imaginary = imaginary;
|
||||
}
|
||||
|
||||
public static Canvas Generate(int width, int height)
|
||||
public static ComplexNumber operator +(ComplexNumber x, ComplexNumber y)
|
||||
{
|
||||
var canvas = new Canvas(width, height);
|
||||
|
||||
var scale = 2 * MaxValueExtent / Math.Min(canvas.Width, canvas.Height);
|
||||
for (var i = 0; i < canvas.Height; i++)
|
||||
{
|
||||
var y = (canvas.Height / 2 - i) * scale;
|
||||
for (var j = 0; j < canvas.Width; j++)
|
||||
{
|
||||
var x = (j - canvas.Width / 2) * scale;
|
||||
var value = Calculate(new ComplexNumber(x, y));
|
||||
canvas.SetPixel(j, i, GetColor(value));
|
||||
}
|
||||
}
|
||||
|
||||
return canvas;
|
||||
return new ComplexNumber(x.Real + y.Real, x.Imaginary + y.Imaginary);
|
||||
}
|
||||
|
||||
private static double Calculate(ComplexNumber c)
|
||||
public static ComplexNumber operator *(ComplexNumber x, ComplexNumber y)
|
||||
{
|
||||
const int MaxIterations = 1000;
|
||||
const double MaxNorm = MaxValueExtent * MaxValueExtent;
|
||||
|
||||
var iteration = 0;
|
||||
var z = new ComplexNumber();
|
||||
do
|
||||
{
|
||||
z = z * z + c;
|
||||
iteration++;
|
||||
} while (z.Abs() < MaxNorm && iteration < MaxIterations);
|
||||
|
||||
return iteration < MaxIterations
|
||||
? (double)iteration / MaxIterations
|
||||
: 0;
|
||||
return new ComplexNumber(x.Real * y.Real - x.Imaginary * y.Imaginary,
|
||||
x.Real * y.Imaginary + x.Imaginary * y.Real);
|
||||
}
|
||||
|
||||
private static Color GetColor(double value)
|
||||
public double Abs()
|
||||
{
|
||||
const double MaxColor = 256;
|
||||
const double ContrastValue = 0.2;
|
||||
return new Color(0, 0, (byte)(MaxColor * Math.Pow(value, ContrastValue)));
|
||||
return Real * Real + Imaginary * Imaginary;
|
||||
}
|
||||
}
|
||||
|
||||
public static Canvas Generate(int width, int height)
|
||||
{
|
||||
var canvas = new Canvas(width, height);
|
||||
|
||||
var scale = 2 * MaxValueExtent / Math.Min(canvas.Width, canvas.Height);
|
||||
for (var i = 0; i < canvas.Height; i++)
|
||||
{
|
||||
var y = (canvas.Height / 2 - i) * scale;
|
||||
for (var j = 0; j < canvas.Width; j++)
|
||||
{
|
||||
var x = (j - canvas.Width / 2) * scale;
|
||||
var value = Calculate(new ComplexNumber(x, y));
|
||||
canvas.SetPixel(j, i, GetColor(value));
|
||||
}
|
||||
}
|
||||
|
||||
return canvas;
|
||||
}
|
||||
|
||||
private static double Calculate(ComplexNumber c)
|
||||
{
|
||||
const int MaxIterations = 1000;
|
||||
const double MaxNorm = MaxValueExtent * MaxValueExtent;
|
||||
|
||||
var iteration = 0;
|
||||
var z = new ComplexNumber();
|
||||
do
|
||||
{
|
||||
z = z * z + c;
|
||||
iteration++;
|
||||
} while (z.Abs() < MaxNorm && iteration < MaxIterations);
|
||||
|
||||
return iteration < MaxIterations
|
||||
? (double)iteration / MaxIterations
|
||||
: 0;
|
||||
}
|
||||
|
||||
private static Color GetColor(double value)
|
||||
{
|
||||
const double MaxColor = 256;
|
||||
const double ContrastValue = 0.2;
|
||||
return new Color(0, 0, (byte)(MaxColor * Math.Pow(value, ContrastValue)));
|
||||
}
|
||||
}
|
||||
|
@ -3,45 +3,44 @@ using System.Reflection;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main()
|
||||
{
|
||||
public static void Main()
|
||||
// Draw a mandelbrot set using a Canvas
|
||||
var mandelbrot = Mandelbrot.Generate(32, 32);
|
||||
Render(mandelbrot, "Mandelbrot");
|
||||
|
||||
// Draw an image using CanvasImage powered by ImageSharp.
|
||||
// This requires the "Spectre.Console.ImageSharp" NuGet package.
|
||||
var image = new CanvasImage("cake.png");
|
||||
image.BilinearResampler();
|
||||
image.MaxWidth(16);
|
||||
Render(image, "Image from file (16 wide)");
|
||||
|
||||
// Draw image again, but without render width
|
||||
image.NoMaxWidth();
|
||||
image.Mutate(ctx => ctx.Grayscale().Rotate(-45).EntropyCrop());
|
||||
Render(image, "Image from file (fit, greyscale, rotated)");
|
||||
|
||||
// Draw image again, but load from embedded resource rather than file
|
||||
using (var fileStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Canvas.cake.png"))
|
||||
{
|
||||
// Draw a mandelbrot set using a Canvas
|
||||
var mandelbrot = Mandelbrot.Generate(32, 32);
|
||||
Render(mandelbrot, "Mandelbrot");
|
||||
|
||||
// Draw an image using CanvasImage powered by ImageSharp.
|
||||
// This requires the "Spectre.Console.ImageSharp" NuGet package.
|
||||
var image = new CanvasImage("cake.png");
|
||||
image.BilinearResampler();
|
||||
image.MaxWidth(16);
|
||||
Render(image, "Image from file (16 wide)");
|
||||
|
||||
// Draw image again, but without render width
|
||||
image.NoMaxWidth();
|
||||
image.Mutate(ctx => ctx.Grayscale().Rotate(-45).EntropyCrop());
|
||||
Render(image, "Image from file (fit, greyscale, rotated)");
|
||||
|
||||
// Draw image again, but load from embedded resource rather than file
|
||||
using (var fileStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Canvas.cake.png"))
|
||||
{
|
||||
Debug.Assert(fileStream != null);
|
||||
var embeddedImage = new CanvasImage(fileStream);
|
||||
embeddedImage.BilinearResampler();
|
||||
embeddedImage.MaxWidth(16);
|
||||
Render(embeddedImage, "Image from embedded resource (16 wide)");
|
||||
}
|
||||
}
|
||||
|
||||
private static void Render(IRenderable canvas, string title)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule($"[yellow]{title}[/]").LeftAligned().RuleStyle("grey"));
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(canvas);
|
||||
Debug.Assert(fileStream != null);
|
||||
var embeddedImage = new CanvasImage(fileStream);
|
||||
embeddedImage.BilinearResampler();
|
||||
embeddedImage.MaxWidth(16);
|
||||
Render(embeddedImage, "Image from embedded resource (16 wide)");
|
||||
}
|
||||
}
|
||||
|
||||
private static void Render(IRenderable canvas, string title)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule($"[yellow]{title}[/]").LeftAligned().RuleStyle("grey"));
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(canvas);
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +1,40 @@
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main()
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
// Render a bar chart
|
||||
AnsiConsole.WriteLine();
|
||||
Render("Fruits per month", new BarChart()
|
||||
.Width(60)
|
||||
.Label("[green bold underline]Number of fruits[/]")
|
||||
.CenterLabel()
|
||||
.AddItem("Apple", 12, Color.Yellow)
|
||||
.AddItem("Orange", 54, Color.Green)
|
||||
.AddItem("Banana", 33, Color.Red));
|
||||
// Render a bar chart
|
||||
AnsiConsole.WriteLine();
|
||||
Render("Fruits per month", new BarChart()
|
||||
.Width(60)
|
||||
.Label("[green bold underline]Number of fruits[/]")
|
||||
.CenterLabel()
|
||||
.AddItem("Apple", 12, Color.Yellow)
|
||||
.AddItem("Orange", 54, Color.Green)
|
||||
.AddItem("Banana", 33, Color.Red));
|
||||
|
||||
// Render a breakdown chart
|
||||
AnsiConsole.WriteLine();
|
||||
Render("Languages used", new BreakdownChart()
|
||||
.FullSize()
|
||||
.Width(60)
|
||||
.ShowPercentage()
|
||||
.AddItem("SCSS", 37, Color.Red)
|
||||
.AddItem("HTML", 28.3, Color.Blue)
|
||||
.AddItem("C#", 22.6, Color.Green)
|
||||
.AddItem("JavaScript", 6, Color.Yellow)
|
||||
.AddItem("Ruby", 6, Color.LightGreen)
|
||||
.AddItem("Shell", 0.1, Color.Aqua));
|
||||
}
|
||||
// Render a breakdown chart
|
||||
AnsiConsole.WriteLine();
|
||||
Render("Languages used", new BreakdownChart()
|
||||
.FullSize()
|
||||
.Width(60)
|
||||
.ShowPercentage()
|
||||
.AddItem("SCSS", 37, Color.Red)
|
||||
.AddItem("HTML", 28.3, Color.Blue)
|
||||
.AddItem("C#", 22.6, Color.Green)
|
||||
.AddItem("JavaScript", 6, Color.Yellow)
|
||||
.AddItem("Ruby", 6, Color.LightGreen)
|
||||
.AddItem("Shell", 0.1, Color.Aqua));
|
||||
}
|
||||
|
||||
private static void Render(string title, IRenderable chart)
|
||||
{
|
||||
AnsiConsole.Write(
|
||||
new Panel(chart)
|
||||
.Padding(1, 1)
|
||||
.Header(title));
|
||||
}
|
||||
private static void Render(string title, IRenderable chart)
|
||||
{
|
||||
AnsiConsole.Write(
|
||||
new Panel(chart)
|
||||
.Padding(1, 1)
|
||||
.Header(title));
|
||||
}
|
||||
}
|
||||
|
@ -1,103 +1,102 @@
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main()
|
||||
{
|
||||
public static void Main()
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// No colors
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Capabilities.ColorSystem == ColorSystem.NoColors)
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// No colors
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Capabilities.ColorSystem == ColorSystem.NoColors)
|
||||
{
|
||||
AnsiConsole.WriteLine("No colors are supported.");
|
||||
return;
|
||||
}
|
||||
AnsiConsole.WriteLine("No colors are supported.");
|
||||
return;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 3-BIT
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.Legacy))
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 3-BIT
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.Legacy))
|
||||
{
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("[yellow bold underline]3-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
AnsiConsole.Background = Color.FromInt32(i);
|
||||
AnsiConsole.Foreground = AnsiConsole.Background.GetInvertedColor();
|
||||
AnsiConsole.Write(string.Format(" {0,-9}", AnsiConsole.Background.ToString()));
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("[yellow bold underline]3-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
for (var i = 0; i < 8; i++)
|
||||
if ((i + 1) % 8 == 0)
|
||||
{
|
||||
AnsiConsole.Background = Color.FromInt32(i);
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 4-BIT
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.Standard))
|
||||
{
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("[yellow bold underline]4-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
for (var i = 0; i < 16; i++)
|
||||
{
|
||||
AnsiConsole.Background = Color.FromInt32(i);
|
||||
AnsiConsole.Foreground = AnsiConsole.Background.GetInvertedColor();
|
||||
AnsiConsole.Write(string.Format(" {0,-9}", AnsiConsole.Background.ToString()));
|
||||
AnsiConsole.ResetColors();
|
||||
if ((i + 1) % 8 == 0)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 8-BIT
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.EightBit))
|
||||
{
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("[yellow bold underline]8-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
for (var i = 0; i < 16; i++)
|
||||
{
|
||||
for (var j = 0; j < 16; j++)
|
||||
{
|
||||
var number = i * 16 + j;
|
||||
AnsiConsole.Background = Color.FromInt32(number);
|
||||
AnsiConsole.Foreground = AnsiConsole.Background.GetInvertedColor();
|
||||
AnsiConsole.Write(string.Format(" {0,-9}", AnsiConsole.Background.ToString()));
|
||||
AnsiConsole.Write(string.Format(" {0,-4}", number));
|
||||
AnsiConsole.ResetColors();
|
||||
if ((i + 1) % 8 == 0)
|
||||
if ((number + 1) % 16 == 0)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 4-BIT
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.Standard))
|
||||
{
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("[yellow bold underline]4-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 24-BIT
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.TrueColor))
|
||||
{
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("[yellow bold underline]24-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
for (var i = 0; i < 16; i++)
|
||||
{
|
||||
AnsiConsole.Background = Color.FromInt32(i);
|
||||
AnsiConsole.Foreground = AnsiConsole.Background.GetInvertedColor();
|
||||
AnsiConsole.Write(string.Format(" {0,-9}", AnsiConsole.Background.ToString()));
|
||||
AnsiConsole.ResetColors();
|
||||
if ((i + 1) % 8 == 0)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 8-BIT
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.EightBit))
|
||||
{
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("[yellow bold underline]8-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
for (var i = 0; i < 16; i++)
|
||||
{
|
||||
for (var j = 0; j < 16; j++)
|
||||
{
|
||||
var number = i * 16 + j;
|
||||
AnsiConsole.Background = Color.FromInt32(number);
|
||||
AnsiConsole.Foreground = AnsiConsole.Background.GetInvertedColor();
|
||||
AnsiConsole.Write(string.Format(" {0,-4}", number));
|
||||
AnsiConsole.ResetColors();
|
||||
if ((number + 1) % 16 == 0)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 24-BIT
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.TrueColor))
|
||||
{
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("[yellow bold underline]24-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
AnsiConsole.Write(new ColorBox(width: 80, height: 15));
|
||||
}
|
||||
AnsiConsole.Write(new ColorBox(width: 80, height: 15));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main()
|
||||
{
|
||||
public static void Main()
|
||||
var cards = new List<Panel>();
|
||||
foreach (var user in User.LoadUsers())
|
||||
{
|
||||
var cards = new List<Panel>();
|
||||
foreach(var user in User.LoadUsers())
|
||||
{
|
||||
cards.Add(
|
||||
new Panel(GetCardContent(user))
|
||||
.Header($"{user.Country}")
|
||||
.RoundedBorder().Expand());
|
||||
}
|
||||
|
||||
// Render all cards in columns
|
||||
AnsiConsole.Write(new Columns(cards));
|
||||
cards.Add(
|
||||
new Panel(GetCardContent(user))
|
||||
.Header($"{user.Country}")
|
||||
.RoundedBorder().Expand());
|
||||
}
|
||||
|
||||
private static string GetCardContent(User user)
|
||||
{
|
||||
var name = $"{user.FirstName} {user.LastName}";
|
||||
var city = $"{user.City}";
|
||||
// Render all cards in columns
|
||||
AnsiConsole.Write(new Columns(cards));
|
||||
}
|
||||
|
||||
return $"[b]{name}[/]\n[yellow]{city}[/]";
|
||||
}
|
||||
private static string GetCardContent(User user)
|
||||
{
|
||||
var name = $"{user.FirstName} {user.LastName}";
|
||||
var city = $"{user.City}";
|
||||
|
||||
return $"[b]{name}[/]\n[yellow]{city}[/]";
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
{
|
||||
public sealed class User
|
||||
{
|
||||
public string FirstName { get; set; }
|
||||
public string LastName { get; set; }
|
||||
public string City { get; set; }
|
||||
public string Country { get; set; }
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static List<User> LoadUsers()
|
||||
{
|
||||
return new List<User>
|
||||
public sealed class User
|
||||
{
|
||||
public string FirstName { get; set; }
|
||||
public string LastName { get; set; }
|
||||
public string City { get; set; }
|
||||
public string Country { get; set; }
|
||||
|
||||
public static List<User> LoadUsers()
|
||||
{
|
||||
return new List<User>
|
||||
{
|
||||
new User
|
||||
{
|
||||
@ -84,6 +84,5 @@ namespace Spectre.Console.Examples
|
||||
Country = "Ireland",
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,17 @@
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
AnsiConsole.Write("Hello");
|
||||
AnsiConsole.Write("Hello");
|
||||
|
||||
// Move the cursor 3 cells to the right
|
||||
AnsiConsole.Cursor.Move(CursorDirection.Right, 3);
|
||||
AnsiConsole.Write("World");
|
||||
// Move the cursor 3 cells to the right
|
||||
AnsiConsole.Cursor.Move(CursorDirection.Right, 3);
|
||||
AnsiConsole.Write("World");
|
||||
|
||||
// Move the cursor 5 cells to the left.
|
||||
AnsiConsole.Cursor.Move(CursorDirection.Left, 5);
|
||||
AnsiConsole.WriteLine("Universe");
|
||||
}
|
||||
// Move the cursor 5 cells to the left.
|
||||
AnsiConsole.Cursor.Move(CursorDirection.Left, 5);
|
||||
AnsiConsole.WriteLine("Universe");
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,21 @@
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// Show a known emoji
|
||||
RenderEmoji();
|
||||
// Show a known emoji
|
||||
RenderEmoji();
|
||||
|
||||
// Show a remapped emoji
|
||||
Emoji.Remap("globe_showing_europe_africa", Emoji.Known.GrinningFaceWithSmilingEyes);
|
||||
RenderEmoji();
|
||||
}
|
||||
// Show a remapped emoji
|
||||
Emoji.Remap("globe_showing_europe_africa", Emoji.Known.GrinningFaceWithSmilingEyes);
|
||||
RenderEmoji();
|
||||
}
|
||||
|
||||
private static void RenderEmoji()
|
||||
{
|
||||
AnsiConsole.Write(
|
||||
new Panel("[yellow]Hello :globe_showing_europe_africa:![/]")
|
||||
.RoundedBorder());
|
||||
}
|
||||
private static void RenderEmoji()
|
||||
{
|
||||
AnsiConsole.Write(
|
||||
new Panel("[yellow]Hello :globe_showing_europe_africa:![/]")
|
||||
.RoundedBorder());
|
||||
}
|
||||
}
|
||||
|
@ -1,65 +1,64 @@
|
||||
using System;
|
||||
using System.Security.Authentication;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
DoMagic(42, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("Default").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex);
|
||||
DoMagic(42, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("Default").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex);
|
||||
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("Compact").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks);
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("Compact").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks);
|
||||
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("Compact + Custom colors").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex, new ExceptionSettings
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("Compact + Custom colors").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex, new ExceptionSettings
|
||||
{
|
||||
Format = ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks,
|
||||
Style = new ExceptionStyle
|
||||
{
|
||||
Format = ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks,
|
||||
Style = new ExceptionStyle
|
||||
{
|
||||
Exception = new Style().Foreground(Color.Grey),
|
||||
Message = new Style().Foreground(Color.White),
|
||||
NonEmphasized = new Style().Foreground(Color.Cornsilk1),
|
||||
Parenthesis = new Style().Foreground(Color.Cornsilk1),
|
||||
Method = new Style().Foreground(Color.Red),
|
||||
ParameterName = new Style().Foreground(Color.Cornsilk1),
|
||||
ParameterType = new Style().Foreground(Color.Red),
|
||||
Path = new Style().Foreground(Color.Red),
|
||||
LineNumber = new Style().Foreground(Color.Cornsilk1),
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static void DoMagic(int foo, string[,] bar)
|
||||
{
|
||||
try
|
||||
{
|
||||
CheckCredentials(foo, bar);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException("Whaaat?", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckCredentials(int qux, string[,] corgi)
|
||||
{
|
||||
throw new InvalidCredentialException("The credentials are invalid.");
|
||||
Exception = new Style().Foreground(Color.Grey),
|
||||
Message = new Style().Foreground(Color.White),
|
||||
NonEmphasized = new Style().Foreground(Color.Cornsilk1),
|
||||
Parenthesis = new Style().Foreground(Color.Cornsilk1),
|
||||
Method = new Style().Foreground(Color.Red),
|
||||
ParameterName = new Style().Foreground(Color.Cornsilk1),
|
||||
ParameterType = new Style().Foreground(Color.Red),
|
||||
Path = new Style().Foreground(Color.Red),
|
||||
LineNumber = new Style().Foreground(Color.Cornsilk1),
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static void DoMagic(int foo, string[,] bar)
|
||||
{
|
||||
try
|
||||
{
|
||||
CheckCredentials(foo, bar);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException("Whaaat?", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckCredentials(int qux, string[,] corgi)
|
||||
{
|
||||
throw new InvalidCredentialException("The credentials are invalid.");
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
AnsiConsole.Write(new FigletText("Left aligned").LeftAligned().Color(Color.Red));
|
||||
AnsiConsole.Write(new FigletText("Centered").Centered().Color(Color.Green));
|
||||
AnsiConsole.Write(new FigletText("Right aligned").RightAligned().Color(Color.Blue));
|
||||
}
|
||||
AnsiConsole.Write(new FigletText("Left aligned").LeftAligned().Color(Color.Red));
|
||||
AnsiConsole.Write(new FigletText("Centered").Centered().Color(Color.Green));
|
||||
AnsiConsole.Write(new FigletText("Right aligned").RightAligned().Color(Color.Blue));
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,21 @@
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main()
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.MarkupLine("Usage: [grey]dotnet [blue]run[/] [[options]] [[[[--]] <additional arguments>...]]]][/]");
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.MarkupLine("Usage: [grey]dotnet [blue]run[/] [[options]] [[[[--]] <additional arguments>...]]]][/]");
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
var grid = new Grid();
|
||||
grid.AddColumn(new GridColumn().NoWrap());
|
||||
grid.AddColumn(new GridColumn().PadLeft(2));
|
||||
grid.AddRow("Options:");
|
||||
grid.AddRow(" [blue]-h[/], [blue]--help[/]", "Show command line help.");
|
||||
grid.AddRow(" [blue]-c[/], [blue]--configuration[/] <CONFIGURATION>", "The configuration to run for.");
|
||||
grid.AddRow(" [blue]-v[/], [blue]--verbosity[/] <LEVEL>", "Set the [grey]MSBuild[/] verbosity level.");
|
||||
var grid = new Grid();
|
||||
grid.AddColumn(new GridColumn().NoWrap());
|
||||
grid.AddColumn(new GridColumn().PadLeft(2));
|
||||
grid.AddRow("Options:");
|
||||
grid.AddRow(" [blue]-h[/], [blue]--help[/]", "Show command line help.");
|
||||
grid.AddRow(" [blue]-c[/], [blue]--configuration[/] <CONFIGURATION>", "The configuration to run for.");
|
||||
grid.AddRow(" [blue]-v[/], [blue]--verbosity[/] <LEVEL>", "Set the [grey]MSBuild[/] verbosity level.");
|
||||
|
||||
AnsiConsole.Write(grid);
|
||||
}
|
||||
AnsiConsole.Write(grid);
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +1,31 @@
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main()
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
var grid = new Grid()
|
||||
.AddColumn(new GridColumn().NoWrap().PadRight(4))
|
||||
.AddColumn()
|
||||
.AddRow("[b]Enrichers[/]", string.Join(", ", AnsiConsole.Profile.Enrichers))
|
||||
.AddRow("[b]Color system[/]", $"{AnsiConsole.Profile.Capabilities.ColorSystem}")
|
||||
.AddRow("[b]Unicode?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Unicode)}")
|
||||
.AddRow("[b]Supports ansi?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Ansi)}")
|
||||
.AddRow("[b]Supports links?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Links)}")
|
||||
.AddRow("[b]Legacy console?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Legacy)}")
|
||||
.AddRow("[b]Interactive?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Interactive)}")
|
||||
.AddRow("[b]Terminal?[/]", $"{YesNo(AnsiConsole.Profile.Out.IsTerminal)}")
|
||||
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Profile.Width}")
|
||||
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Profile.Height}")
|
||||
.AddRow("[b]Encoding[/]", $"{AnsiConsole.Console.Profile.Encoding.EncodingName}");
|
||||
var grid = new Grid()
|
||||
.AddColumn(new GridColumn().NoWrap().PadRight(4))
|
||||
.AddColumn()
|
||||
.AddRow("[b]Enrichers[/]", string.Join(", ", AnsiConsole.Profile.Enrichers))
|
||||
.AddRow("[b]Color system[/]", $"{AnsiConsole.Profile.Capabilities.ColorSystem}")
|
||||
.AddRow("[b]Unicode?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Unicode)}")
|
||||
.AddRow("[b]Supports ansi?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Ansi)}")
|
||||
.AddRow("[b]Supports links?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Links)}")
|
||||
.AddRow("[b]Legacy console?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Legacy)}")
|
||||
.AddRow("[b]Interactive?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Interactive)}")
|
||||
.AddRow("[b]Terminal?[/]", $"{YesNo(AnsiConsole.Profile.Out.IsTerminal)}")
|
||||
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Profile.Width}")
|
||||
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Profile.Height}")
|
||||
.AddRow("[b]Encoding[/]", $"{AnsiConsole.Console.Profile.Encoding.EncodingName}");
|
||||
|
||||
AnsiConsole.Write(
|
||||
new Panel(grid)
|
||||
.Header("Information"));
|
||||
}
|
||||
AnsiConsole.Write(
|
||||
new Panel(grid)
|
||||
.Header("Information"));
|
||||
}
|
||||
|
||||
private static string YesNo(bool value)
|
||||
{
|
||||
return value ? "Yes" : "No";
|
||||
}
|
||||
private static string YesNo(bool value)
|
||||
{
|
||||
return value ? "Yes" : "No";
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main()
|
||||
{
|
||||
public static void Main()
|
||||
if (AnsiConsole.Profile.Capabilities.Links)
|
||||
{
|
||||
if (AnsiConsole.Profile.Capabilities.Links)
|
||||
{
|
||||
AnsiConsole.MarkupLine("[link=https://patriksvensson.se]Click to visit my blog[/]!");
|
||||
}
|
||||
else
|
||||
{
|
||||
AnsiConsole.MarkupLine("[red]It looks like your terminal doesn't support links[/]");
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.MarkupLine("[yellow](╯°□°)╯[/]︵ [blue]┻━┻[/]");
|
||||
}
|
||||
AnsiConsole.MarkupLine("[link=https://patriksvensson.se]Click to visit my blog[/]!");
|
||||
}
|
||||
else
|
||||
{
|
||||
AnsiConsole.MarkupLine("[red]It looks like your terminal doesn't support links[/]");
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.MarkupLine("[yellow](╯°□°)╯[/]︵ [blue]┻━┻[/]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,81 +1,80 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
var table = new Table().Centered();
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
// Animate
|
||||
AnsiConsole.Live(table)
|
||||
.AutoClear(false)
|
||||
.Overflow(VerticalOverflow.Ellipsis)
|
||||
.Cropping(VerticalOverflowCropping.Top)
|
||||
.Start(ctx =>
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
var table = new Table().Centered();
|
||||
|
||||
// Animate
|
||||
AnsiConsole.Live(table)
|
||||
.AutoClear(false)
|
||||
.Overflow(VerticalOverflow.Ellipsis)
|
||||
.Cropping(VerticalOverflowCropping.Top)
|
||||
.Start(ctx =>
|
||||
{
|
||||
void Update(int delay, Action action)
|
||||
{
|
||||
void Update(int delay, Action action)
|
||||
{
|
||||
action();
|
||||
ctx.Refresh();
|
||||
Thread.Sleep(delay);
|
||||
}
|
||||
action();
|
||||
ctx.Refresh();
|
||||
Thread.Sleep(delay);
|
||||
}
|
||||
|
||||
// Columns
|
||||
Update(230, () => table.AddColumn("Release date"));
|
||||
Update(230, () => table.AddColumn("Title"));
|
||||
Update(230, () => table.AddColumn("Budget"));
|
||||
Update(230, () => table.AddColumn("Opening Weekend"));
|
||||
Update(230, () => table.AddColumn("Box office"));
|
||||
Update(230, () => table.AddColumn("Title"));
|
||||
Update(230, () => table.AddColumn("Budget"));
|
||||
Update(230, () => table.AddColumn("Opening Weekend"));
|
||||
Update(230, () => table.AddColumn("Box office"));
|
||||
|
||||
// Rows
|
||||
Update(70, () => table.AddRow("May 25, 1977", "[yellow]Star Wars[/] [grey]Ep.[/] [u]IV[/]", "$11,000,000", "$1,554,475", "$775,398,007"));
|
||||
Update(70, () => table.AddRow("May 21, 1980", "[yellow]Star Wars[/] [grey]Ep.[/] [u]V[/]", "$18,000,000", "$4,910,483", "$547,969,004"));
|
||||
Update(70, () => table.AddRow("May 25, 1983", "[yellow]Star Wars[/] [grey]Ep.[/] [u]VI[/]", "$32,500,000", "$23,019,618", "$475,106,177"));
|
||||
Update(70, () => table.AddRow("May 19, 1999", "[yellow]Star Wars[/] [grey]Ep.[/] [u]I[/]", "$115,000,000", "$64,810,870", "$1,027,044,677"));
|
||||
Update(70, () => table.AddRow("May 16, 2002", "[yellow]Star Wars[/] [grey]Ep.[/] [u]II[/]", "$115,000,000", "$80,027,814", "$649,436,358"));
|
||||
Update(70, () => table.AddRow("May 19, 2005", "[yellow]Star Wars[/] [grey]Ep.[/] [u]III[/]", "$113,000,000", "$108,435,841", "$850,035,635"));
|
||||
Update(70, () => table.AddRow("Dec 18, 2015", "[yellow]Star Wars[/] [grey]Ep.[/] [u]VII[/]", "$245,000,000", "$247,966,675", "$2,068,223,624"));
|
||||
Update(70, () => table.AddRow("Dec 15, 2017", "[yellow]Star Wars[/] [grey]Ep.[/] [u]VIII[/]", "$317,000,000", "$220,009,584", "$1,333,539,889"));
|
||||
Update(70, () => table.AddRow("Dec 20, 2019", "[yellow]Star Wars[/] [grey]Ep.[/] [u]IX[/]", "$245,000,000", "$177,383,864", "$1,074,114,248"));
|
||||
Update(70, () => table.AddRow("May 21, 1980", "[yellow]Star Wars[/] [grey]Ep.[/] [u]V[/]", "$18,000,000", "$4,910,483", "$547,969,004"));
|
||||
Update(70, () => table.AddRow("May 25, 1983", "[yellow]Star Wars[/] [grey]Ep.[/] [u]VI[/]", "$32,500,000", "$23,019,618", "$475,106,177"));
|
||||
Update(70, () => table.AddRow("May 19, 1999", "[yellow]Star Wars[/] [grey]Ep.[/] [u]I[/]", "$115,000,000", "$64,810,870", "$1,027,044,677"));
|
||||
Update(70, () => table.AddRow("May 16, 2002", "[yellow]Star Wars[/] [grey]Ep.[/] [u]II[/]", "$115,000,000", "$80,027,814", "$649,436,358"));
|
||||
Update(70, () => table.AddRow("May 19, 2005", "[yellow]Star Wars[/] [grey]Ep.[/] [u]III[/]", "$113,000,000", "$108,435,841", "$850,035,635"));
|
||||
Update(70, () => table.AddRow("Dec 18, 2015", "[yellow]Star Wars[/] [grey]Ep.[/] [u]VII[/]", "$245,000,000", "$247,966,675", "$2,068,223,624"));
|
||||
Update(70, () => table.AddRow("Dec 15, 2017", "[yellow]Star Wars[/] [grey]Ep.[/] [u]VIII[/]", "$317,000,000", "$220,009,584", "$1,333,539,889"));
|
||||
Update(70, () => table.AddRow("Dec 20, 2019", "[yellow]Star Wars[/] [grey]Ep.[/] [u]IX[/]", "$245,000,000", "$177,383,864", "$1,074,114,248"));
|
||||
|
||||
// Column footer
|
||||
Update(230, () => table.Columns[2].Footer("$1,633,000,000"));
|
||||
Update(230, () => table.Columns[3].Footer("$928,119,224"));
|
||||
Update(400, () => table.Columns[4].Footer("$10,318,030,576"));
|
||||
Update(230, () => table.Columns[3].Footer("$928,119,224"));
|
||||
Update(400, () => table.Columns[4].Footer("$10,318,030,576"));
|
||||
|
||||
// Column alignment
|
||||
Update(230, () => table.Columns[2].RightAligned());
|
||||
Update(230, () => table.Columns[3].RightAligned());
|
||||
Update(400, () => table.Columns[4].RightAligned());
|
||||
Update(230, () => table.Columns[3].RightAligned());
|
||||
Update(400, () => table.Columns[4].RightAligned());
|
||||
|
||||
// Column titles
|
||||
Update(70, () => table.Columns[0].Header("[bold]Release date[/]"));
|
||||
Update(70, () => table.Columns[1].Header("[bold]Title[/]"));
|
||||
Update(70, () => table.Columns[2].Header("[red bold]Budget[/]"));
|
||||
Update(70, () => table.Columns[3].Header("[green bold]Opening Weekend[/]"));
|
||||
Update(400, () => table.Columns[4].Header("[blue bold]Box office[/]"));
|
||||
Update(70, () => table.Columns[1].Header("[bold]Title[/]"));
|
||||
Update(70, () => table.Columns[2].Header("[red bold]Budget[/]"));
|
||||
Update(70, () => table.Columns[3].Header("[green bold]Opening Weekend[/]"));
|
||||
Update(400, () => table.Columns[4].Header("[blue bold]Box office[/]"));
|
||||
|
||||
// Footers
|
||||
Update(70, () => table.Columns[2].Footer("[red bold]$1,633,000,000[/]"));
|
||||
Update(70, () => table.Columns[3].Footer("[green bold]$928,119,224[/]"));
|
||||
Update(400, () => table.Columns[4].Footer("[blue bold]$10,318,030,576[/]"));
|
||||
Update(70, () => table.Columns[3].Footer("[green bold]$928,119,224[/]"));
|
||||
Update(400, () => table.Columns[4].Footer("[blue bold]$10,318,030,576[/]"));
|
||||
|
||||
// Title
|
||||
Update(500, () => table.Title("Star Wars Movies"));
|
||||
Update(400, () => table.Title("[[ [yellow]Star Wars Movies[/] ]]"));
|
||||
Update(400, () => table.Title("[[ [yellow]Star Wars Movies[/] ]]"));
|
||||
|
||||
// Borders
|
||||
Update(230, () => table.BorderColor(Color.Yellow));
|
||||
Update(230, () => table.MinimalBorder());
|
||||
Update(230, () => table.SimpleBorder());
|
||||
Update(230, () => table.SimpleHeavyBorder());
|
||||
Update(230, () => table.MinimalBorder());
|
||||
Update(230, () => table.SimpleBorder());
|
||||
Update(230, () => table.SimpleHeavyBorder());
|
||||
|
||||
// Caption
|
||||
Update(400, () => table.Caption("[[ [blue]THE END[/] ]]"));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,15 @@ using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
private const int NumberOfRows = 10;
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
private static readonly Random _random = new();
|
||||
private static readonly string[] _exchanges = new string[]
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
private const int NumberOfRows = 10;
|
||||
|
||||
private static readonly Random _random = new();
|
||||
private static readonly string[] _exchanges = new string[]
|
||||
{
|
||||
"SGD", "SEK", "PLN",
|
||||
"MYR", "EUR", "USD",
|
||||
"AUD", "JPY", "CNH",
|
||||
@ -18,69 +18,68 @@ namespace Spectre.Console.Examples
|
||||
"DKK", "GBP", "RUB",
|
||||
"NZD", "MXN", "IDR",
|
||||
"TWD", "THB", "VND",
|
||||
};
|
||||
};
|
||||
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
var table = new Table().Expand().BorderColor(Color.Grey);
|
||||
table.AddColumn("[yellow]Source currency[/]");
|
||||
table.AddColumn("[yellow]Destination currency[/]");
|
||||
table.AddColumn("[yellow]Exchange rate[/]");
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
var table = new Table().Expand().BorderColor(Color.Grey);
|
||||
table.AddColumn("[yellow]Source currency[/]");
|
||||
table.AddColumn("[yellow]Destination currency[/]");
|
||||
table.AddColumn("[yellow]Exchange rate[/]");
|
||||
|
||||
AnsiConsole.MarkupLine("Press [yellow]CTRL+C[/] to exit");
|
||||
AnsiConsole.MarkupLine("Press [yellow]CTRL+C[/] to exit");
|
||||
|
||||
await AnsiConsole.Live(table)
|
||||
.AutoClear(false)
|
||||
.Overflow(VerticalOverflow.Ellipsis)
|
||||
.Cropping(VerticalOverflowCropping.Bottom)
|
||||
.StartAsync(async ctx =>
|
||||
{
|
||||
await AnsiConsole.Live(table)
|
||||
.AutoClear(false)
|
||||
.Overflow(VerticalOverflow.Ellipsis)
|
||||
.Cropping(VerticalOverflowCropping.Bottom)
|
||||
.StartAsync(async ctx =>
|
||||
{
|
||||
// Add some initial rows
|
||||
foreach (var _ in Enumerable.Range(0, NumberOfRows))
|
||||
{
|
||||
AddExchangeRateRow(table);
|
||||
}
|
||||
{
|
||||
AddExchangeRateRow(table);
|
||||
}
|
||||
|
||||
// Continously update the table
|
||||
while (true)
|
||||
{
|
||||
{
|
||||
// More rows than we want?
|
||||
if (table.Rows.Count > NumberOfRows)
|
||||
{
|
||||
{
|
||||
// Remove the first one
|
||||
table.Rows.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new row
|
||||
AddExchangeRateRow(table);
|
||||
|
||||
// Refresh and wait for a while
|
||||
ctx.Refresh();
|
||||
await Task.Delay(400);
|
||||
}
|
||||
});
|
||||
}
|
||||
await Task.Delay(400);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void AddExchangeRateRow(Table table)
|
||||
private static void AddExchangeRateRow(Table table)
|
||||
{
|
||||
var (source, destination, rate) = GetExchangeRate();
|
||||
table.AddRow(
|
||||
source, destination,
|
||||
_random.NextDouble() > 0.35D ? $"[green]{rate}[/]" : $"[red]{rate}[/]");
|
||||
}
|
||||
|
||||
private static (string Source, string Destination, double Rate) GetExchangeRate()
|
||||
{
|
||||
var source = _exchanges[_random.Next(0, _exchanges.Length)];
|
||||
var dest = _exchanges[_random.Next(0, _exchanges.Length)];
|
||||
var rate = 200 / ((_random.NextDouble() * 320) + 1);
|
||||
|
||||
while (source == dest)
|
||||
{
|
||||
var (source, destination, rate) = GetExchangeRate();
|
||||
table.AddRow(
|
||||
source, destination,
|
||||
_random.NextDouble() > 0.35D ? $"[green]{rate}[/]" : $"[red]{rate}[/]");
|
||||
dest = _exchanges[_random.Next(0, _exchanges.Length)];
|
||||
}
|
||||
|
||||
private static (string Source, string Destination, double Rate) GetExchangeRate()
|
||||
{
|
||||
var source = _exchanges[_random.Next(0, _exchanges.Length)];
|
||||
var dest = _exchanges[_random.Next(0, _exchanges.Length)];
|
||||
var rate = 200 / ((_random.NextDouble() * 320) + 1);
|
||||
|
||||
while (source == dest)
|
||||
{
|
||||
dest = _exchanges[_random.Next(0, _exchanges.Length)];
|
||||
}
|
||||
|
||||
return (source, dest, rate);
|
||||
}
|
||||
return (source, dest, rate);
|
||||
}
|
||||
}
|
||||
|
@ -9,5 +9,4 @@ Write(new Table()
|
||||
.RoundedBorder()
|
||||
.AddColumns("[red]Greeting[/]", "[red]Subject[/]")
|
||||
.AddRow("[yellow]Hello[/]", "World")
|
||||
.AddRow("[green]Oh hi[/]", "[blue u]Mark[/]"));
|
||||
|
||||
.AddRow("[green]Oh hi[/]", "[blue u]Mark[/]"));
|
@ -1,40 +1,39 @@
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main()
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
var content = new Markup(
|
||||
"[underline]I[/] heard [underline on blue]you[/] like panels\n\n\n\n" +
|
||||
"So I put a panel in a panel").Centered();
|
||||
var content = new Markup(
|
||||
"[underline]I[/] heard [underline on blue]you[/] like panels\n\n\n\n" +
|
||||
"So I put a panel in a panel").Centered();
|
||||
|
||||
AnsiConsole.Write(
|
||||
new Panel(
|
||||
new Panel(content)
|
||||
.Border(BoxBorder.Rounded)));
|
||||
AnsiConsole.Write(
|
||||
new Panel(
|
||||
new Panel(content)
|
||||
.Border(BoxBorder.Rounded)));
|
||||
|
||||
// Left adjusted panel with text
|
||||
AnsiConsole.Write(
|
||||
new Panel(new Text("Left adjusted\nLeft").LeftAligned())
|
||||
.Expand()
|
||||
.SquareBorder()
|
||||
.Header("[red]Left[/]"));
|
||||
// Left adjusted panel with text
|
||||
AnsiConsole.Write(
|
||||
new Panel(new Text("Left adjusted\nLeft").LeftAligned())
|
||||
.Expand()
|
||||
.SquareBorder()
|
||||
.Header("[red]Left[/]"));
|
||||
|
||||
// Centered ASCII panel with text
|
||||
AnsiConsole.Write(
|
||||
new Panel(new Text("Centered\nCenter").Centered())
|
||||
.Expand()
|
||||
.AsciiBorder()
|
||||
.Header("[green]Center[/]")
|
||||
.HeaderAlignment(Justify.Center));
|
||||
// Centered ASCII panel with text
|
||||
AnsiConsole.Write(
|
||||
new Panel(new Text("Centered\nCenter").Centered())
|
||||
.Expand()
|
||||
.AsciiBorder()
|
||||
.Header("[green]Center[/]")
|
||||
.HeaderAlignment(Justify.Center));
|
||||
|
||||
// Right adjusted, rounded panel with text
|
||||
AnsiConsole.Write(
|
||||
new Panel(new Text("Right adjusted\nRight").RightAligned())
|
||||
.Expand()
|
||||
.RoundedBorder()
|
||||
.Header("[blue]Right[/]")
|
||||
.HeaderAlignment(Justify.Right));
|
||||
}
|
||||
// Right adjusted, rounded panel with text
|
||||
AnsiConsole.Write(
|
||||
new Panel(new Text("Right adjusted\nRight").RightAligned())
|
||||
.Expand()
|
||||
.RoundedBorder()
|
||||
.Header("[blue]Right[/]")
|
||||
.HeaderAlignment(Justify.Right));
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class DescriptionGenerator
|
||||
{
|
||||
public static class DescriptionGenerator
|
||||
private static readonly string[] _verbs = new[] { "Downloading", "Rerouting", "Retriculating", "Collapsing", "Folding", "Solving", "Colliding", "Measuring" };
|
||||
private static readonly string[] _nouns = new[] { "internet", "splines", "space", "capacitators", "quarks", "algorithms", "data structures", "spacetime" };
|
||||
|
||||
private static readonly Random _random;
|
||||
private static readonly HashSet<string> _used;
|
||||
|
||||
static DescriptionGenerator()
|
||||
{
|
||||
private static readonly string[] _verbs = new[] { "Downloading", "Rerouting", "Retriculating", "Collapsing", "Folding", "Solving", "Colliding", "Measuring" };
|
||||
private static readonly string[] _nouns = new[] { "internet", "splines", "space", "capacitators", "quarks", "algorithms", "data structures", "spacetime" };
|
||||
_random = new Random(DateTime.Now.Millisecond);
|
||||
_used = new HashSet<string>();
|
||||
}
|
||||
|
||||
private static readonly Random _random;
|
||||
private static readonly HashSet<string> _used;
|
||||
|
||||
static DescriptionGenerator()
|
||||
public static bool TryGenerate(out string name)
|
||||
{
|
||||
var iterations = 0;
|
||||
while (iterations < 25)
|
||||
{
|
||||
_random = new Random(DateTime.Now.Millisecond);
|
||||
_used = new HashSet<string>();
|
||||
}
|
||||
|
||||
public static bool TryGenerate(out string name)
|
||||
{
|
||||
var iterations = 0;
|
||||
while (iterations < 25)
|
||||
name = Generate();
|
||||
if (!_used.Contains(name))
|
||||
{
|
||||
name = Generate();
|
||||
if (!_used.Contains(name))
|
||||
{
|
||||
_used.Add(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
iterations++;
|
||||
_used.Add(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
name = Generate();
|
||||
return false;
|
||||
iterations++;
|
||||
}
|
||||
|
||||
public static string Generate()
|
||||
{
|
||||
return _verbs[_random.Next(0, _verbs.Length)]
|
||||
+ " " + _nouns[_random.Next(0, _nouns.Length)];
|
||||
}
|
||||
name = Generate();
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string Generate()
|
||||
{
|
||||
return _verbs[_random.Next(0, _verbs.Length)]
|
||||
+ " " + _nouns[_random.Next(0, _nouns.Length)];
|
||||
}
|
||||
}
|
||||
|
@ -2,88 +2,87 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
AnsiConsole.MarkupLine("[yellow]Initializing warp drive[/]...");
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
// Show progress
|
||||
AnsiConsole.Progress()
|
||||
.AutoClear(false)
|
||||
.Columns(new ProgressColumn[]
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
AnsiConsole.MarkupLine("[yellow]Initializing warp drive[/]...");
|
||||
|
||||
// Show progress
|
||||
AnsiConsole.Progress()
|
||||
.AutoClear(false)
|
||||
.Columns(new ProgressColumn[]
|
||||
{
|
||||
new TaskDescriptionColumn(), // Task description
|
||||
new ProgressBarColumn(), // Progress bar
|
||||
new PercentageColumn(), // Percentage
|
||||
new RemainingTimeColumn(), // Remaining time
|
||||
new SpinnerColumn(), // Spinner
|
||||
})
|
||||
.Start(ctx =>
|
||||
{
|
||||
var random = new Random(DateTime.Now.Millisecond);
|
||||
})
|
||||
.Start(ctx =>
|
||||
{
|
||||
var random = new Random(DateTime.Now.Millisecond);
|
||||
|
||||
// Create some tasks
|
||||
var tasks = CreateTasks(ctx, random);
|
||||
var warpTask = ctx.AddTask("Going to warp", autoStart: false).IsIndeterminate();
|
||||
var warpTask = ctx.AddTask("Going to warp", autoStart: false).IsIndeterminate();
|
||||
|
||||
// Wait for all tasks (except the indeterminate one) to complete
|
||||
while (!ctx.IsFinished)
|
||||
{
|
||||
{
|
||||
// Increment progress
|
||||
foreach (var (task, increment) in tasks)
|
||||
{
|
||||
task.Increment(random.NextDouble() * increment);
|
||||
}
|
||||
{
|
||||
task.Increment(random.NextDouble() * increment);
|
||||
}
|
||||
|
||||
// Write some random things to the terminal
|
||||
if (random.NextDouble() < 0.1)
|
||||
{
|
||||
WriteLogMessage();
|
||||
}
|
||||
{
|
||||
WriteLogMessage();
|
||||
}
|
||||
|
||||
// Simulate some delay
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
// Now start the "warp" task
|
||||
warpTask.StartTask();
|
||||
warpTask.IsIndeterminate(false);
|
||||
while (!ctx.IsFinished)
|
||||
{
|
||||
warpTask.Increment(12 * random.NextDouble());
|
||||
warpTask.IsIndeterminate(false);
|
||||
while (!ctx.IsFinished)
|
||||
{
|
||||
warpTask.Increment(12 * random.NextDouble());
|
||||
|
||||
// Simulate some delay
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
});
|
||||
|
||||
// Done
|
||||
AnsiConsole.MarkupLine("[green]Done![/]");
|
||||
}
|
||||
|
||||
private static List<(ProgressTask Task, int Delay)> CreateTasks(ProgressContext progress, Random random)
|
||||
{
|
||||
var tasks = new List<(ProgressTask, int)>();
|
||||
while (tasks.Count < 5)
|
||||
{
|
||||
if (DescriptionGenerator.TryGenerate(out var name))
|
||||
{
|
||||
tasks.Add((progress.AddTask(name), random.Next(2, 10)));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return tasks;
|
||||
}
|
||||
// Done
|
||||
AnsiConsole.MarkupLine("[green]Done![/]");
|
||||
}
|
||||
|
||||
private static void WriteLogMessage()
|
||||
private static List<(ProgressTask Task, int Delay)> CreateTasks(ProgressContext progress, Random random)
|
||||
{
|
||||
var tasks = new List<(ProgressTask, int)>();
|
||||
while (tasks.Count < 5)
|
||||
{
|
||||
AnsiConsole.MarkupLine(
|
||||
"[grey]LOG:[/] " +
|
||||
DescriptionGenerator.Generate() +
|
||||
"[grey]...[/]");
|
||||
if (DescriptionGenerator.TryGenerate(out var name))
|
||||
{
|
||||
tasks.Add((progress.AddTask(name), random.Next(2, 10)));
|
||||
}
|
||||
}
|
||||
|
||||
return tasks;
|
||||
}
|
||||
|
||||
private static void WriteLogMessage()
|
||||
{
|
||||
AnsiConsole.MarkupLine(
|
||||
"[grey]LOG:[/] " +
|
||||
DescriptionGenerator.Generate() +
|
||||
"[grey]...[/]");
|
||||
}
|
||||
}
|
||||
|
@ -142,4 +142,4 @@ namespace Spectre.Console.Examples
|
||||
.AllowEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,41 +1,40 @@
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// No title
|
||||
Render(
|
||||
new Rule()
|
||||
.RuleStyle(Style.Parse("yellow"))
|
||||
.AsciiBorder()
|
||||
.LeftAligned());
|
||||
// No title
|
||||
Render(
|
||||
new Rule()
|
||||
.RuleStyle(Style.Parse("yellow"))
|
||||
.AsciiBorder()
|
||||
.LeftAligned());
|
||||
|
||||
// Left aligned title
|
||||
Render(
|
||||
new Rule("[blue]Left aligned[/]")
|
||||
.RuleStyle(Style.Parse("red"))
|
||||
.DoubleBorder()
|
||||
.LeftAligned());
|
||||
// Left aligned title
|
||||
Render(
|
||||
new Rule("[blue]Left aligned[/]")
|
||||
.RuleStyle(Style.Parse("red"))
|
||||
.DoubleBorder()
|
||||
.LeftAligned());
|
||||
|
||||
// Centered title
|
||||
Render(
|
||||
new Rule("[green]Centered[/]")
|
||||
.RuleStyle(Style.Parse("green"))
|
||||
.HeavyBorder()
|
||||
.Centered());
|
||||
// Centered title
|
||||
Render(
|
||||
new Rule("[green]Centered[/]")
|
||||
.RuleStyle(Style.Parse("green"))
|
||||
.HeavyBorder()
|
||||
.Centered());
|
||||
|
||||
// Right aligned title
|
||||
Render(
|
||||
new Rule("[red]Right aligned[/]")
|
||||
.RuleStyle(Style.Parse("blue"))
|
||||
.RightAligned());
|
||||
}
|
||||
// Right aligned title
|
||||
Render(
|
||||
new Rule("[red]Right aligned[/]")
|
||||
.RuleStyle(Style.Parse("blue"))
|
||||
.RightAligned());
|
||||
}
|
||||
|
||||
private static void Render(Rule rule)
|
||||
{
|
||||
AnsiConsole.Write(rule);
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
private static void Render(Rule rule)
|
||||
{
|
||||
AnsiConsole.Write(rule);
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,29 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class ExceptionGenerator
|
||||
{
|
||||
public static class ExceptionGenerator
|
||||
public static Exception GenerateException()
|
||||
{
|
||||
public static Exception GenerateException()
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
SomeOperation();
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return ex;
|
||||
}
|
||||
SomeOperation();
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
private static void SomeOperation()
|
||||
catch (Exception ex)
|
||||
{
|
||||
SomeOperationGoingWrong();
|
||||
}
|
||||
|
||||
private static void SomeOperationGoingWrong()
|
||||
{
|
||||
throw new InvalidOperationException("Something went very wrong!");
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SomeOperation()
|
||||
{
|
||||
SomeOperationGoingWrong();
|
||||
}
|
||||
|
||||
private static void SomeOperationGoingWrong()
|
||||
{
|
||||
throw new InvalidOperationException("Something went very wrong!");
|
||||
}
|
||||
}
|
||||
|
@ -1,153 +1,152 @@
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static partial class Program
|
||||
{
|
||||
public static partial class Program
|
||||
public static void Main()
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
var table = new Table().HideHeaders().NoBorder();
|
||||
table.Title("[u][yellow]Spectre.Console[/] [b]Features[/][/]");
|
||||
table.AddColumn("Feature", c => c.NoWrap().RightAligned().Width(10).PadRight(3));
|
||||
table.AddColumn("Demonstration", c => c.PadRight(0));
|
||||
table.AddEmptyRow();
|
||||
var table = new Table().HideHeaders().NoBorder();
|
||||
table.Title("[u][yellow]Spectre.Console[/] [b]Features[/][/]");
|
||||
table.AddColumn("Feature", c => c.NoWrap().RightAligned().Width(10).PadRight(3));
|
||||
table.AddColumn("Demonstration", c => c.PadRight(0));
|
||||
table.AddEmptyRow();
|
||||
|
||||
// Colors
|
||||
table.AddRow(
|
||||
new Markup("[red]Colors[/]"),
|
||||
GetColorTable());
|
||||
// Colors
|
||||
table.AddRow(
|
||||
new Markup("[red]Colors[/]"),
|
||||
GetColorTable());
|
||||
|
||||
// Styles
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
new Markup("[red]OS[/]"),
|
||||
new Grid().Expand().AddColumns(3)
|
||||
.AddRow(
|
||||
"[bold green]Windows[/]",
|
||||
"[bold blue]macOS[/]",
|
||||
"[bold yellow]Linux[/]"));
|
||||
// Styles
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
new Markup("[red]OS[/]"),
|
||||
new Grid().Expand().AddColumns(3)
|
||||
.AddRow(
|
||||
"[bold green]Windows[/]",
|
||||
"[bold blue]macOS[/]",
|
||||
"[bold yellow]Linux[/]"));
|
||||
|
||||
// Styles
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
"[red]Styles[/]",
|
||||
"All ansi styles: [bold]bold[/], [dim]dim[/], [italic]italic[/], [underline]underline[/], "
|
||||
+ "[strikethrough]strikethrough[/], [reverse]reverse[/], and even [blink]blink[/].");
|
||||
// Styles
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
"[red]Styles[/]",
|
||||
"All ansi styles: [bold]bold[/], [dim]dim[/], [italic]italic[/], [underline]underline[/], "
|
||||
+ "[strikethrough]strikethrough[/], [reverse]reverse[/], and even [blink]blink[/].");
|
||||
|
||||
// Text
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
new Markup("[red]Text[/]"),
|
||||
new Markup("Word wrap text. Justify [green]left[/], [yellow]center[/] or [blue]right[/]."));
|
||||
// Text
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
new Markup("[red]Text[/]"),
|
||||
new Markup("Word wrap text. Justify [green]left[/], [yellow]center[/] or [blue]right[/]."));
|
||||
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
Text.Empty,
|
||||
GetTextGrid());
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
Text.Empty,
|
||||
GetTextGrid());
|
||||
|
||||
// Markup
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
"[red]Markup[/]",
|
||||
"[bold purple]Spectre.Console[/] supports a simple [i]bbcode[/] like "
|
||||
+ "[b]markup[/] for [yellow]color[/], [underline]style[/], and emoji! "
|
||||
+ ":thumbs_up: :red_apple: :ant: :bear: :baguette_bread: :bus:");
|
||||
// Markup
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
"[red]Markup[/]",
|
||||
"[bold purple]Spectre.Console[/] supports a simple [i]bbcode[/] like "
|
||||
+ "[b]markup[/] for [yellow]color[/], [underline]style[/], and emoji! "
|
||||
+ ":thumbs_up: :red_apple: :ant: :bear: :baguette_bread: :bus:");
|
||||
|
||||
// Trees and tables
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
new Markup("[red]Tables and Trees[/]"),
|
||||
GetTreeTable());
|
||||
// Trees and tables
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
new Markup("[red]Tables and Trees[/]"),
|
||||
GetTreeTable());
|
||||
|
||||
// Charts
|
||||
table.AddRow(
|
||||
new Markup("[red]Charts[/]"),
|
||||
new Grid().Collapse().AddColumns(2).AddRow(
|
||||
new Panel(GetBreakdownChart()).BorderColor(Color.Grey),
|
||||
new Panel(GetBarChart()).BorderColor(Color.Grey)));
|
||||
// Charts
|
||||
table.AddRow(
|
||||
new Markup("[red]Charts[/]"),
|
||||
new Grid().Collapse().AddColumns(2).AddRow(
|
||||
new Panel(GetBreakdownChart()).BorderColor(Color.Grey),
|
||||
new Panel(GetBarChart()).BorderColor(Color.Grey)));
|
||||
|
||||
|
||||
// Exceptions
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
new Markup("[red]Exceptions[/]"),
|
||||
ExceptionGenerator.GenerateException().GetRenderable());
|
||||
// Exceptions
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
new Markup("[red]Exceptions[/]"),
|
||||
ExceptionGenerator.GenerateException().GetRenderable());
|
||||
|
||||
// Much more
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
"[red]+ Much more![/]",
|
||||
"Tables, Grids, Trees, Progress bars, Status, Bar charts, Calendars, Figlet, Images, Text prompts, "
|
||||
+ "List boxes, Separators, Pretty exceptions, Canvas, CLI parsing");
|
||||
table.AddEmptyRow();
|
||||
// Much more
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
"[red]+ Much more![/]",
|
||||
"Tables, Grids, Trees, Progress bars, Status, Bar charts, Calendars, Figlet, Images, Text prompts, "
|
||||
+ "List boxes, Separators, Pretty exceptions, Canvas, CLI parsing");
|
||||
table.AddEmptyRow();
|
||||
|
||||
// Render the table
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(table);
|
||||
}
|
||||
// Render the table
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(table);
|
||||
}
|
||||
|
||||
private static IRenderable GetColorTable()
|
||||
{
|
||||
var colorTable = new Table().Collapse().HideHeaders().NoBorder();
|
||||
colorTable.AddColumn("Desc", c => c.PadRight(3)).AddColumn("Colors", c => c.PadRight(0));
|
||||
colorTable.AddRow(
|
||||
new Markup(
|
||||
"✓ [bold grey]NO_COLOR support[/]\n" +
|
||||
"✓ [bold green]3-bit color[/]\n" +
|
||||
"✓ [bold blue]4-bit color[/]\n" +
|
||||
"✓ [bold purple]8-bit color[/]\n" +
|
||||
"✓ [bold yellow]Truecolor (16.7 million)[/]\n" +
|
||||
"✓ [bold aqua]Automatic color conversion[/]"),
|
||||
new ColorBox(height: 6));
|
||||
private static IRenderable GetColorTable()
|
||||
{
|
||||
var colorTable = new Table().Collapse().HideHeaders().NoBorder();
|
||||
colorTable.AddColumn("Desc", c => c.PadRight(3)).AddColumn("Colors", c => c.PadRight(0));
|
||||
colorTable.AddRow(
|
||||
new Markup(
|
||||
"✓ [bold grey]NO_COLOR support[/]\n" +
|
||||
"✓ [bold green]3-bit color[/]\n" +
|
||||
"✓ [bold blue]4-bit color[/]\n" +
|
||||
"✓ [bold purple]8-bit color[/]\n" +
|
||||
"✓ [bold yellow]Truecolor (16.7 million)[/]\n" +
|
||||
"✓ [bold aqua]Automatic color conversion[/]"),
|
||||
new ColorBox(height: 6));
|
||||
|
||||
return colorTable;
|
||||
}
|
||||
return colorTable;
|
||||
}
|
||||
|
||||
private static IRenderable GetTextGrid()
|
||||
{
|
||||
var loremTable = new Grid();
|
||||
var lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque in metus sed sapien ultricies pretium a at justo. Maecenas luctus velit et auctor maximus.";
|
||||
loremTable.AddColumn(new GridColumn().LeftAligned());
|
||||
loremTable.AddColumn(new GridColumn().Centered());
|
||||
loremTable.AddColumn(new GridColumn().RightAligned());
|
||||
loremTable.AddRow($"[green]{lorem}[/]", $"[yellow]{lorem}[/]", $"[blue]{lorem}[/]");
|
||||
return loremTable;
|
||||
}
|
||||
private static IRenderable GetTextGrid()
|
||||
{
|
||||
var loremTable = new Grid();
|
||||
var lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque in metus sed sapien ultricies pretium a at justo. Maecenas luctus velit et auctor maximus.";
|
||||
loremTable.AddColumn(new GridColumn().LeftAligned());
|
||||
loremTable.AddColumn(new GridColumn().Centered());
|
||||
loremTable.AddColumn(new GridColumn().RightAligned());
|
||||
loremTable.AddRow($"[green]{lorem}[/]", $"[yellow]{lorem}[/]", $"[blue]{lorem}[/]");
|
||||
return loremTable;
|
||||
}
|
||||
|
||||
private static IRenderable GetTreeTable()
|
||||
{
|
||||
var tree = new Tree("📁 src");
|
||||
tree.AddNode("📁 foo").AddNode("📄 bar.cs");
|
||||
tree.AddNode("📁 baz").AddNode("📁 qux").AddNode("📄 corgi.txt");
|
||||
tree.AddNode("📄 waldo.xml");
|
||||
private static IRenderable GetTreeTable()
|
||||
{
|
||||
var tree = new Tree("📁 src");
|
||||
tree.AddNode("📁 foo").AddNode("📄 bar.cs");
|
||||
tree.AddNode("📁 baz").AddNode("📁 qux").AddNode("📄 corgi.txt");
|
||||
tree.AddNode("📄 waldo.xml");
|
||||
|
||||
var table = new Table().SimpleBorder().BorderColor(Color.Grey);
|
||||
table.AddColumn(new TableColumn("Overview"));
|
||||
table.AddColumn(new TableColumn("").Footer("[grey]3 Files, 225 KiB[/]"));
|
||||
table.AddRow(new Markup("[yellow]Files[/]"), tree);
|
||||
var table = new Table().SimpleBorder().BorderColor(Color.Grey);
|
||||
table.AddColumn(new TableColumn("Overview"));
|
||||
table.AddColumn(new TableColumn("").Footer("[grey]3 Files, 225 KiB[/]"));
|
||||
table.AddRow(new Markup("[yellow]Files[/]"), tree);
|
||||
|
||||
return new Table().RoundedBorder().Collapse().BorderColor(Color.Yellow)
|
||||
.AddColumn("Foo").AddColumn("Bar")
|
||||
.AddRow(new Text("Baz"), table)
|
||||
.AddRow("Qux", "Corgi");
|
||||
}
|
||||
return new Table().RoundedBorder().Collapse().BorderColor(Color.Yellow)
|
||||
.AddColumn("Foo").AddColumn("Bar")
|
||||
.AddRow(new Text("Baz"), table)
|
||||
.AddRow("Qux", "Corgi");
|
||||
}
|
||||
|
||||
private static IRenderable GetBarChart()
|
||||
{
|
||||
return new BarChart()
|
||||
.AddItem("Apple", 32, Color.Green)
|
||||
.AddItem("Oranges", 13, Color.Orange1)
|
||||
.AddItem("Bananas", 22, Color.Yellow);
|
||||
}
|
||||
private static IRenderable GetBarChart()
|
||||
{
|
||||
return new BarChart()
|
||||
.AddItem("Apple", 32, Color.Green)
|
||||
.AddItem("Oranges", 13, Color.Orange1)
|
||||
.AddItem("Bananas", 22, Color.Yellow);
|
||||
}
|
||||
|
||||
private static IRenderable GetBreakdownChart()
|
||||
{
|
||||
return new BreakdownChart()
|
||||
.ShowPercentage()
|
||||
.FullSize()
|
||||
.AddItem("C#", 82, Color.Green)
|
||||
.AddItem("PowerShell", 13, Color.Red)
|
||||
.AddItem("Bash", 5, Color.Blue);
|
||||
}
|
||||
private static IRenderable GetBreakdownChart()
|
||||
{
|
||||
return new BreakdownChart()
|
||||
.ShowPercentage()
|
||||
.FullSize()
|
||||
.AddItem("C#", 82, Color.Green)
|
||||
.AddItem("PowerShell", 13, Color.Red)
|
||||
.AddItem("Bash", 5, Color.Blue);
|
||||
}
|
||||
}
|
||||
|
@ -1,69 +1,68 @@
|
||||
using System.Threading;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main()
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
AnsiConsole.Status()
|
||||
.AutoRefresh(true)
|
||||
.Spinner(Spinner.Known.Default)
|
||||
.Start("[yellow]Initializing warp drive[/]", ctx =>
|
||||
{
|
||||
AnsiConsole.Status()
|
||||
.AutoRefresh(true)
|
||||
.Spinner(Spinner.Known.Default)
|
||||
.Start("[yellow]Initializing warp drive[/]", ctx =>
|
||||
{
|
||||
// Initialize
|
||||
Thread.Sleep(3000);
|
||||
WriteLogMessage("Starting gravimetric field displacement manifold");
|
||||
Thread.Sleep(1000);
|
||||
WriteLogMessage("Warming up deuterium chamber");
|
||||
Thread.Sleep(2000);
|
||||
WriteLogMessage("Generating antideuterium");
|
||||
WriteLogMessage("Starting gravimetric field displacement manifold");
|
||||
Thread.Sleep(1000);
|
||||
WriteLogMessage("Warming up deuterium chamber");
|
||||
Thread.Sleep(2000);
|
||||
WriteLogMessage("Generating antideuterium");
|
||||
|
||||
// Warp nacelles
|
||||
Thread.Sleep(3000);
|
||||
ctx.Spinner(Spinner.Known.BouncingBar);
|
||||
ctx.Status("[bold blue]Unfolding warp nacelles[/]");
|
||||
WriteLogMessage("Unfolding left warp nacelle");
|
||||
Thread.Sleep(2000);
|
||||
WriteLogMessage("Left warp nacelle [green]online[/]");
|
||||
WriteLogMessage("Unfolding right warp nacelle");
|
||||
Thread.Sleep(1000);
|
||||
WriteLogMessage("Right warp nacelle [green]online[/]");
|
||||
ctx.Spinner(Spinner.Known.BouncingBar);
|
||||
ctx.Status("[bold blue]Unfolding warp nacelles[/]");
|
||||
WriteLogMessage("Unfolding left warp nacelle");
|
||||
Thread.Sleep(2000);
|
||||
WriteLogMessage("Left warp nacelle [green]online[/]");
|
||||
WriteLogMessage("Unfolding right warp nacelle");
|
||||
Thread.Sleep(1000);
|
||||
WriteLogMessage("Right warp nacelle [green]online[/]");
|
||||
|
||||
// Warp bubble
|
||||
Thread.Sleep(3000);
|
||||
ctx.Spinner(Spinner.Known.Star2);
|
||||
ctx.Status("[bold blue]Generating warp bubble[/]");
|
||||
Thread.Sleep(3000);
|
||||
ctx.Spinner(Spinner.Known.Star);
|
||||
ctx.Status("[bold blue]Stabilizing warp bubble[/]");
|
||||
ctx.Spinner(Spinner.Known.Star2);
|
||||
ctx.Status("[bold blue]Generating warp bubble[/]");
|
||||
Thread.Sleep(3000);
|
||||
ctx.Spinner(Spinner.Known.Star);
|
||||
ctx.Status("[bold blue]Stabilizing warp bubble[/]");
|
||||
|
||||
// Safety
|
||||
ctx.Spinner(Spinner.Known.Monkey);
|
||||
ctx.Status("[bold blue]Performing safety checks[/]");
|
||||
WriteLogMessage("Enabling interior dampening");
|
||||
Thread.Sleep(2000);
|
||||
WriteLogMessage("Interior dampening [green]enabled[/]");
|
||||
ctx.Status("[bold blue]Performing safety checks[/]");
|
||||
WriteLogMessage("Enabling interior dampening");
|
||||
Thread.Sleep(2000);
|
||||
WriteLogMessage("Interior dampening [green]enabled[/]");
|
||||
|
||||
// Warp!
|
||||
Thread.Sleep(3000);
|
||||
ctx.Spinner(Spinner.Known.Moon);
|
||||
WriteLogMessage("Preparing for warp");
|
||||
Thread.Sleep(1000);
|
||||
for (var warp = 1; warp < 10; warp++)
|
||||
{
|
||||
ctx.Status($"[bold blue]Warp {warp}[/]");
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
});
|
||||
ctx.Spinner(Spinner.Known.Moon);
|
||||
WriteLogMessage("Preparing for warp");
|
||||
Thread.Sleep(1000);
|
||||
for (var warp = 1; warp < 10; warp++)
|
||||
{
|
||||
ctx.Status($"[bold blue]Warp {warp}[/]");
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
});
|
||||
|
||||
// Done
|
||||
AnsiConsole.MarkupLine("[bold green]Crusing at Warp 9.8[/]");
|
||||
}
|
||||
// Done
|
||||
AnsiConsole.MarkupLine("[bold green]Crusing at Warp 9.8[/]");
|
||||
}
|
||||
|
||||
private static void WriteLogMessage(string message)
|
||||
{
|
||||
AnsiConsole.MarkupLine($"[grey]LOG:[/] {message}[grey]...[/]");
|
||||
}
|
||||
private static void WriteLogMessage(string message)
|
||||
{
|
||||
AnsiConsole.MarkupLine($"[grey]LOG:[/] {message}[grey]...[/]");
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,44 @@
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main()
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
AnsiConsole.Write(CreateTable());
|
||||
}
|
||||
AnsiConsole.Write(CreateTable());
|
||||
}
|
||||
|
||||
private static Table CreateTable()
|
||||
{
|
||||
var simple = new Table()
|
||||
.Border(TableBorder.Square)
|
||||
.BorderColor(Color.Red)
|
||||
.AddColumn(new TableColumn("[u]CDE[/]").Footer("EDC").Centered())
|
||||
.AddColumn(new TableColumn("[u]FED[/]").Footer("DEF"))
|
||||
.AddColumn(new TableColumn("[u]IHG[/]").Footer("GHI"))
|
||||
.AddRow("Hello", "[red]World![/]", "")
|
||||
.AddRow("[blue]Bonjour[/]", "[white]le[/]", "[red]monde![/]")
|
||||
.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
||||
private static Table CreateTable()
|
||||
{
|
||||
var simple = new Table()
|
||||
.Border(TableBorder.Square)
|
||||
.BorderColor(Color.Red)
|
||||
.AddColumn(new TableColumn("[u]CDE[/]").Footer("EDC").Centered())
|
||||
.AddColumn(new TableColumn("[u]FED[/]").Footer("DEF"))
|
||||
.AddColumn(new TableColumn("[u]IHG[/]").Footer("GHI"))
|
||||
.AddRow("Hello", "[red]World![/]", "")
|
||||
.AddRow("[blue]Bonjour[/]", "[white]le[/]", "[red]monde![/]")
|
||||
.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
||||
|
||||
var second = new Table()
|
||||
.Border(TableBorder.Rounded)
|
||||
.BorderColor(Color.Green)
|
||||
.AddColumn(new TableColumn("[u]Foo[/]"))
|
||||
.AddColumn(new TableColumn("[u]Bar[/]"))
|
||||
.AddColumn(new TableColumn("[u]Baz[/]"))
|
||||
.AddRow("Hello", "[red]World![/]", "")
|
||||
.AddRow(simple, new Text("Whaaat"), new Text("Lolz"))
|
||||
.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
||||
var second = new Table()
|
||||
.Border(TableBorder.Rounded)
|
||||
.BorderColor(Color.Green)
|
||||
.AddColumn(new TableColumn("[u]Foo[/]"))
|
||||
.AddColumn(new TableColumn("[u]Bar[/]"))
|
||||
.AddColumn(new TableColumn("[u]Baz[/]"))
|
||||
.AddRow("Hello", "[red]World![/]", "")
|
||||
.AddRow(simple, new Text("Whaaat"), new Text("Lolz"))
|
||||
.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
||||
|
||||
return new Table()
|
||||
.Centered()
|
||||
.Border(TableBorder.DoubleEdge)
|
||||
.Title("TABLE [yellow]TITLE[/]")
|
||||
.Caption("TABLE [yellow]CAPTION[/]")
|
||||
.AddColumn(new TableColumn(new Panel("[u]ABC[/]").BorderColor(Color.Red)).Footer("[u]FOOTER 1[/]"))
|
||||
.AddColumn(new TableColumn(new Panel("[u]DEF[/]").BorderColor(Color.Green)).Footer("[u]FOOTER 2[/]"))
|
||||
.AddColumn(new TableColumn(new Panel("[u]GHI[/]").BorderColor(Color.Blue)).Footer("[u]FOOTER 3[/]"))
|
||||
.AddRow(new Text("Hello").Centered(), new Markup("[red]World![/]"), Text.Empty)
|
||||
.AddRow(second, new Text("Whaaat"), new Text("Lol"))
|
||||
.AddRow(new Markup("[blue]Hej[/]").Centered(), new Markup("[yellow]Världen![/]"), Text.Empty);
|
||||
}
|
||||
return new Table()
|
||||
.Centered()
|
||||
.Border(TableBorder.DoubleEdge)
|
||||
.Title("TABLE [yellow]TITLE[/]")
|
||||
.Caption("TABLE [yellow]CAPTION[/]")
|
||||
.AddColumn(new TableColumn(new Panel("[u]ABC[/]").BorderColor(Color.Red)).Footer("[u]FOOTER 1[/]"))
|
||||
.AddColumn(new TableColumn(new Panel("[u]DEF[/]").BorderColor(Color.Green)).Footer("[u]FOOTER 2[/]"))
|
||||
.AddColumn(new TableColumn(new Panel("[u]GHI[/]").BorderColor(Color.Blue)).Footer("[u]FOOTER 3[/]"))
|
||||
.AddRow(new Text("Hello").Centered(), new Markup("[red]World![/]"), Text.Empty)
|
||||
.AddRow(second, new Text("Whaaat"), new Text("Lol"))
|
||||
.AddRow(new Markup("[blue]Hej[/]").Centered(), new Markup("[yellow]Världen![/]"), Text.Empty);
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +1,42 @@
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static void Main()
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
// Render the tree
|
||||
var tree = BuildTree();
|
||||
AnsiConsole.Write(tree);
|
||||
}
|
||||
// Render the tree
|
||||
var tree = BuildTree();
|
||||
AnsiConsole.Write(tree);
|
||||
}
|
||||
|
||||
private static Tree BuildTree()
|
||||
{
|
||||
// Create the tree
|
||||
var tree = new Tree("Root")
|
||||
.Style(Style.Parse("red"))
|
||||
.Guide(TreeGuide.Line);
|
||||
private static Tree BuildTree()
|
||||
{
|
||||
// Create the tree
|
||||
var tree = new Tree("Root")
|
||||
.Style(Style.Parse("red"))
|
||||
.Guide(TreeGuide.Line);
|
||||
|
||||
// Add some nodes
|
||||
var foo = tree.AddNode("[yellow]Foo[/]");
|
||||
var table = foo.AddNode(new Table()
|
||||
.RoundedBorder()
|
||||
.AddColumn("First")
|
||||
.AddColumn("Second")
|
||||
.AddRow("1", "2")
|
||||
.AddRow("3", "4")
|
||||
.AddRow("5", "6"));
|
||||
// Add some nodes
|
||||
var foo = tree.AddNode("[yellow]Foo[/]");
|
||||
var table = foo.AddNode(new Table()
|
||||
.RoundedBorder()
|
||||
.AddColumn("First")
|
||||
.AddColumn("Second")
|
||||
.AddRow("1", "2")
|
||||
.AddRow("3", "4")
|
||||
.AddRow("5", "6"));
|
||||
|
||||
table.AddNode("[blue]Baz[/]");
|
||||
foo.AddNode("Qux");
|
||||
table.AddNode("[blue]Baz[/]");
|
||||
foo.AddNode("Qux");
|
||||
|
||||
var bar = tree.AddNode("[yellow]Bar[/]");
|
||||
bar.AddNode(new Calendar(2020, 12)
|
||||
.AddCalendarEvent(2020, 12, 12)
|
||||
.HideHeader());
|
||||
var bar = tree.AddNode("[yellow]Bar[/]");
|
||||
bar.AddNode(new Calendar(2020, 12)
|
||||
.AddCalendarEvent(2020, 12, 12)
|
||||
.HideHeader());
|
||||
|
||||
// Return the tree
|
||||
return tree;
|
||||
}
|
||||
// Return the tree
|
||||
return tree;
|
||||
}
|
||||
}
|
||||
|
@ -2,123 +2,122 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Examples
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
public sealed class ColorBox : Renderable
|
||||
{
|
||||
public sealed class ColorBox : Renderable
|
||||
private readonly int _height;
|
||||
private int? _width;
|
||||
|
||||
public ColorBox(int height)
|
||||
{
|
||||
private readonly int _height;
|
||||
private int? _width;
|
||||
_height = height;
|
||||
}
|
||||
|
||||
public ColorBox(int height)
|
||||
public ColorBox(int width, int height)
|
||||
: this(height)
|
||||
{
|
||||
_width = width;
|
||||
}
|
||||
|
||||
protected override Measurement Measure(RenderContext context, int maxWidth)
|
||||
{
|
||||
return new Measurement(1, GetWidth(maxWidth));
|
||||
}
|
||||
|
||||
protected override IEnumerable<Segment> Render(RenderContext context, int maxWidth)
|
||||
{
|
||||
maxWidth = GetWidth(maxWidth);
|
||||
|
||||
for (var y = 0; y < _height; y++)
|
||||
{
|
||||
_height = height;
|
||||
for (var x = 0; x < maxWidth; x++)
|
||||
{
|
||||
var h = x / (float)maxWidth;
|
||||
var l = 0.1f + ((y / (float)_height) * 0.7f);
|
||||
var (r1, g1, b1) = ColorFromHSL(h, l, 1.0f);
|
||||
var (r2, g2, b2) = ColorFromHSL(h, l + (0.7f / 10), 1.0f);
|
||||
|
||||
var background = new Color((byte)(r1 * 255), (byte)(g1 * 255), (byte)(b1 * 255));
|
||||
var foreground = new Color((byte)(r2 * 255), (byte)(g2 * 255), (byte)(b2 * 255));
|
||||
|
||||
yield return new Segment("▄", new Style(foreground, background));
|
||||
}
|
||||
|
||||
yield return Segment.LineBreak;
|
||||
}
|
||||
}
|
||||
|
||||
private int GetWidth(int maxWidth)
|
||||
{
|
||||
var width = maxWidth;
|
||||
if (_width != null)
|
||||
{
|
||||
width = Math.Min(_width.Value, width);
|
||||
}
|
||||
|
||||
public ColorBox(int width, int height)
|
||||
: this(height)
|
||||
return width;
|
||||
}
|
||||
|
||||
private static (float, float, float) ColorFromHSL(double h, double l, double s)
|
||||
{
|
||||
double r = 0, g = 0, b = 0;
|
||||
if (l != 0)
|
||||
{
|
||||
_width = width;
|
||||
}
|
||||
|
||||
protected override Measurement Measure(RenderContext context, int maxWidth)
|
||||
{
|
||||
return new Measurement(1, GetWidth(maxWidth));
|
||||
}
|
||||
|
||||
protected override IEnumerable<Segment> Render(RenderContext context, int maxWidth)
|
||||
{
|
||||
maxWidth = GetWidth(maxWidth);
|
||||
|
||||
for (var y = 0; y < _height; y++)
|
||||
if (s == 0)
|
||||
{
|
||||
for (var x = 0; x < maxWidth; x++)
|
||||
{
|
||||
var h = x / (float)maxWidth;
|
||||
var l = 0.1f + ((y / (float)_height) * 0.7f);
|
||||
var (r1, g1, b1) = ColorFromHSL(h, l, 1.0f);
|
||||
var (r2, g2, b2) = ColorFromHSL(h, l + (0.7f / 10), 1.0f);
|
||||
|
||||
var background = new Color((byte)(r1 * 255), (byte)(g1 * 255), (byte)(b1 * 255));
|
||||
var foreground = new Color((byte)(r2 * 255), (byte)(g2 * 255), (byte)(b2 * 255));
|
||||
|
||||
yield return new Segment("▄", new Style(foreground, background));
|
||||
}
|
||||
|
||||
yield return Segment.LineBreak;
|
||||
}
|
||||
}
|
||||
|
||||
private int GetWidth(int maxWidth)
|
||||
{
|
||||
var width = maxWidth;
|
||||
if (_width != null)
|
||||
{
|
||||
width = Math.Min(_width.Value, width);
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
private static (float, float, float) ColorFromHSL(double h, double l, double s)
|
||||
{
|
||||
double r = 0, g = 0, b = 0;
|
||||
if (l != 0)
|
||||
{
|
||||
if (s == 0)
|
||||
{
|
||||
r = g = b = l;
|
||||
}
|
||||
else
|
||||
{
|
||||
double temp2;
|
||||
if (l < 0.5)
|
||||
{
|
||||
temp2 = l * (1.0 + s);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp2 = l + s - (l * s);
|
||||
}
|
||||
|
||||
var temp1 = 2.0 * l - temp2;
|
||||
|
||||
r = GetColorComponent(temp1, temp2, h + 1.0 / 3.0);
|
||||
g = GetColorComponent(temp1, temp2, h);
|
||||
b = GetColorComponent(temp1, temp2, h - 1.0 / 3.0);
|
||||
}
|
||||
}
|
||||
|
||||
return ((float)r, (float)g, (float)b);
|
||||
|
||||
}
|
||||
|
||||
private static double GetColorComponent(double temp1, double temp2, double temp3)
|
||||
{
|
||||
if (temp3 < 0.0)
|
||||
{
|
||||
temp3 += 1.0;
|
||||
}
|
||||
else if (temp3 > 1.0)
|
||||
{
|
||||
temp3 -= 1.0;
|
||||
}
|
||||
|
||||
if (temp3 < 1.0 / 6.0)
|
||||
{
|
||||
return temp1 + (temp2 - temp1) * 6.0 * temp3;
|
||||
}
|
||||
else if (temp3 < 0.5)
|
||||
{
|
||||
return temp2;
|
||||
}
|
||||
else if (temp3 < 2.0 / 3.0)
|
||||
{
|
||||
return temp1 + ((temp2 - temp1) * ((2.0 / 3.0) - temp3) * 6.0);
|
||||
r = g = b = l;
|
||||
}
|
||||
else
|
||||
{
|
||||
return temp1;
|
||||
double temp2;
|
||||
if (l < 0.5)
|
||||
{
|
||||
temp2 = l * (1.0 + s);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp2 = l + s - (l * s);
|
||||
}
|
||||
|
||||
var temp1 = 2.0 * l - temp2;
|
||||
|
||||
r = GetColorComponent(temp1, temp2, h + 1.0 / 3.0);
|
||||
g = GetColorComponent(temp1, temp2, h);
|
||||
b = GetColorComponent(temp1, temp2, h - 1.0 / 3.0);
|
||||
}
|
||||
}
|
||||
|
||||
return ((float)r, (float)g, (float)b);
|
||||
|
||||
}
|
||||
|
||||
private static double GetColorComponent(double temp1, double temp2, double temp3)
|
||||
{
|
||||
if (temp3 < 0.0)
|
||||
{
|
||||
temp3 += 1.0;
|
||||
}
|
||||
else if (temp3 > 1.0)
|
||||
{
|
||||
temp3 -= 1.0;
|
||||
}
|
||||
|
||||
if (temp3 < 1.0 / 6.0)
|
||||
{
|
||||
return temp1 + (temp2 - temp1) * 6.0 * temp3;
|
||||
}
|
||||
else if (temp3 < 0.5)
|
||||
{
|
||||
return temp2;
|
||||
}
|
||||
else if (temp3 < 2.0 / 3.0)
|
||||
{
|
||||
return temp1 + ((temp2 - temp1) * ((2.0 / 3.0) - temp3) * 6.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return temp1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
namespace Spectre.Console.Examples
|
||||
{
|
||||
public static class ColorExtensions
|
||||
{
|
||||
public static Color GetInvertedColor(this Color color)
|
||||
{
|
||||
return GetLuminance(color) < 140 ? Color.White : Color.Black;
|
||||
}
|
||||
namespace Spectre.Console.Examples;
|
||||
|
||||
private static float GetLuminance(this Color color)
|
||||
{
|
||||
return (float)((0.2126 * color.R) + (0.7152 * color.G) + (0.0722 * color.B));
|
||||
}
|
||||
public static class ColorExtensions
|
||||
{
|
||||
public static Color GetInvertedColor(this Color color)
|
||||
{
|
||||
return GetLuminance(color) < 140 ? Color.White : Color.Black;
|
||||
}
|
||||
|
||||
private static float GetLuminance(this Color color)
|
||||
{
|
||||
return (float)((0.2126 * color.R) + (0.7152 * color.G) + (0.0722 * color.B));
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project>
|
||||
<PropertyGroup Label="Settings">
|
||||
<Deterministic>true</Deterministic>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<LangVersion>10</LangVersion>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>embedded</DebugType>
|
||||
<MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip>
|
||||
|
@ -1,16 +1,15 @@
|
||||
namespace Spectre.Console.Analyzer.Sandbox
|
||||
namespace Spectre.Console.Analyzer.Sandbox;
|
||||
|
||||
/// <summary>
|
||||
/// Sample sandbox for testing out analyzers.
|
||||
/// </summary>
|
||||
public static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// Sample sandbox for testing out analyzers.
|
||||
/// The program's entry point.
|
||||
/// </summary>
|
||||
public static class Program
|
||||
public static void Main()
|
||||
{
|
||||
/// <summary>
|
||||
/// The program's entry point.
|
||||
/// </summary>
|
||||
public static void Main()
|
||||
{
|
||||
AnsiConsole.WriteLine("Project is set up with a reference to Spectre.Console.Analyzer");
|
||||
}
|
||||
AnsiConsole.WriteLine("Project is set up with a reference to Spectre.Console.Analyzer");
|
||||
}
|
||||
}
|
||||
|
@ -6,90 +6,89 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Operations;
|
||||
|
||||
namespace Spectre.Console.Analyzer
|
||||
namespace Spectre.Console.Analyzer;
|
||||
|
||||
/// <summary>
|
||||
/// Analyzer to suggest using available instances of AnsiConsole over the static methods.
|
||||
/// </summary>
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
public class FavorInstanceAnsiConsoleOverStaticAnalyzer : SpectreAnalyzer
|
||||
{
|
||||
/// <summary>
|
||||
/// Analyzer to suggest using available instances of AnsiConsole over the static methods.
|
||||
/// </summary>
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
public class FavorInstanceAnsiConsoleOverStaticAnalyzer : SpectreAnalyzer
|
||||
private static readonly DiagnosticDescriptor _diagnosticDescriptor =
|
||||
Descriptors.S1010_FavorInstanceAnsiConsoleOverStatic;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
|
||||
ImmutableArray.Create(_diagnosticDescriptor);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext)
|
||||
{
|
||||
private static readonly DiagnosticDescriptor _diagnosticDescriptor =
|
||||
Descriptors.S1010_FavorInstanceAnsiConsoleOverStatic;
|
||||
compilationStartContext.RegisterOperationAction(
|
||||
context =>
|
||||
{
|
||||
var ansiConsoleType = context.Compilation.GetTypeByMetadataName("Spectre.Console.AnsiConsole");
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
|
||||
ImmutableArray.Create(_diagnosticDescriptor);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext)
|
||||
{
|
||||
compilationStartContext.RegisterOperationAction(
|
||||
context =>
|
||||
// if this operation isn't an invocation against one of the System.Console methods
|
||||
// defined in _methods then we can safely stop analyzing and return;
|
||||
var invocationOperation = (IInvocationOperation)context.Operation;
|
||||
if (!Equals(invocationOperation.TargetMethod.ContainingType, ansiConsoleType))
|
||||
{
|
||||
var ansiConsoleType = context.Compilation.GetTypeByMetadataName("Spectre.Console.AnsiConsole");
|
||||
return;
|
||||
}
|
||||
|
||||
// if this operation isn't an invocation against one of the System.Console methods
|
||||
// defined in _methods then we can safely stop analyzing and return;
|
||||
var invocationOperation = (IInvocationOperation)context.Operation;
|
||||
if (!Equals(invocationOperation.TargetMethod.ContainingType, ansiConsoleType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// if we aren't in a method then it might be too complex for us to handle.
|
||||
if (!invocationOperation.Syntax.Ancestors().OfType<MethodDeclarationSyntax>().Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if we aren't in a method then it might be too complex for us to handle.
|
||||
if (!invocationOperation.Syntax.Ancestors().OfType<MethodDeclarationSyntax>().Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!HasFieldAnsiConsole(invocationOperation.Syntax) &&
|
||||
!HasParameterAnsiConsole(invocationOperation.Syntax))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasFieldAnsiConsole(invocationOperation.Syntax) &&
|
||||
!HasParameterAnsiConsole(invocationOperation.Syntax))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var methodSymbol = invocationOperation.TargetMethod;
|
||||
|
||||
var methodSymbol = invocationOperation.TargetMethod;
|
||||
var displayString = SymbolDisplay.ToDisplayString(
|
||||
methodSymbol,
|
||||
SymbolDisplayFormat.CSharpShortErrorMessageFormat
|
||||
.WithParameterOptions(SymbolDisplayParameterOptions.None)
|
||||
.WithGenericsOptions(SymbolDisplayGenericsOptions.None));
|
||||
|
||||
var displayString = SymbolDisplay.ToDisplayString(
|
||||
methodSymbol,
|
||||
SymbolDisplayFormat.CSharpShortErrorMessageFormat
|
||||
.WithParameterOptions(SymbolDisplayParameterOptions.None)
|
||||
.WithGenericsOptions(SymbolDisplayGenericsOptions.None));
|
||||
|
||||
context.ReportDiagnostic(
|
||||
Diagnostic.Create(
|
||||
_diagnosticDescriptor,
|
||||
invocationOperation.Syntax.GetLocation(),
|
||||
displayString));
|
||||
}, OperationKind.Invocation);
|
||||
}
|
||||
|
||||
private static bool HasParameterAnsiConsole(SyntaxNode syntaxNode)
|
||||
{
|
||||
return syntaxNode
|
||||
.Ancestors().OfType<MethodDeclarationSyntax>()
|
||||
.First()
|
||||
.ParameterList.Parameters
|
||||
.Any(i => i.Type.NormalizeWhitespace().ToString() == "IAnsiConsole");
|
||||
}
|
||||
|
||||
private static bool HasFieldAnsiConsole(SyntaxNode syntaxNode)
|
||||
{
|
||||
var isStatic = syntaxNode
|
||||
.Ancestors()
|
||||
.OfType<MethodDeclarationSyntax>()
|
||||
.First()
|
||||
.Modifiers.Any(i => i.Kind() == SyntaxKind.StaticKeyword);
|
||||
|
||||
return syntaxNode
|
||||
.Ancestors().OfType<ClassDeclarationSyntax>()
|
||||
.First()
|
||||
.Members
|
||||
.OfType<FieldDeclarationSyntax>()
|
||||
.Any(i =>
|
||||
i.Declaration.Type.NormalizeWhitespace().ToString() == "IAnsiConsole" &&
|
||||
(!isStatic ^ i.Modifiers.Any(modifier => modifier.Kind() == SyntaxKind.StaticKeyword)));
|
||||
}
|
||||
context.ReportDiagnostic(
|
||||
Diagnostic.Create(
|
||||
_diagnosticDescriptor,
|
||||
invocationOperation.Syntax.GetLocation(),
|
||||
displayString));
|
||||
}, OperationKind.Invocation);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool HasParameterAnsiConsole(SyntaxNode syntaxNode)
|
||||
{
|
||||
return syntaxNode
|
||||
.Ancestors().OfType<MethodDeclarationSyntax>()
|
||||
.First()
|
||||
.ParameterList.Parameters
|
||||
.Any(i => i.Type.NormalizeWhitespace().ToString() == "IAnsiConsole");
|
||||
}
|
||||
|
||||
private static bool HasFieldAnsiConsole(SyntaxNode syntaxNode)
|
||||
{
|
||||
var isStatic = syntaxNode
|
||||
.Ancestors()
|
||||
.OfType<MethodDeclarationSyntax>()
|
||||
.First()
|
||||
.Modifiers.Any(i => i.Kind() == SyntaxKind.StaticKeyword);
|
||||
|
||||
return syntaxNode
|
||||
.Ancestors().OfType<ClassDeclarationSyntax>()
|
||||
.First()
|
||||
.Members
|
||||
.OfType<FieldDeclarationSyntax>()
|
||||
.Any(i =>
|
||||
i.Declaration.Type.NormalizeWhitespace().ToString() == "IAnsiConsole" &&
|
||||
(!isStatic ^ i.Modifiers.Any(modifier => modifier.Kind() == SyntaxKind.StaticKeyword)));
|
||||
}
|
||||
}
|
||||
|
@ -7,72 +7,71 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Operations;
|
||||
|
||||
namespace Spectre.Console.Analyzer
|
||||
namespace Spectre.Console.Analyzer;
|
||||
|
||||
/// <summary>
|
||||
/// Analyzer to detect calls to live renderables within a live renderable context.
|
||||
/// </summary>
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
[Shared]
|
||||
public class NoConcurrentLiveRenderablesAnalyzer : SpectreAnalyzer
|
||||
{
|
||||
/// <summary>
|
||||
/// Analyzer to detect calls to live renderables within a live renderable context.
|
||||
/// </summary>
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
[Shared]
|
||||
public class NoConcurrentLiveRenderablesAnalyzer : SpectreAnalyzer
|
||||
private static readonly DiagnosticDescriptor _diagnosticDescriptor =
|
||||
Descriptors.S1020_AvoidConcurrentCallsToMultipleLiveRenderables;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
|
||||
ImmutableArray.Create(_diagnosticDescriptor);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext)
|
||||
{
|
||||
private static readonly DiagnosticDescriptor _diagnosticDescriptor =
|
||||
Descriptors.S1020_AvoidConcurrentCallsToMultipleLiveRenderables;
|
||||
compilationStartContext.RegisterOperationAction(
|
||||
context =>
|
||||
{
|
||||
var invocationOperation = (IInvocationOperation)context.Operation;
|
||||
var methodSymbol = invocationOperation.TargetMethod;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
|
||||
ImmutableArray.Create(_diagnosticDescriptor);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext)
|
||||
{
|
||||
compilationStartContext.RegisterOperationAction(
|
||||
context =>
|
||||
const string StartMethod = "Start";
|
||||
if (methodSymbol.Name != StartMethod)
|
||||
{
|
||||
var invocationOperation = (IInvocationOperation)context.Operation;
|
||||
var methodSymbol = invocationOperation.TargetMethod;
|
||||
return;
|
||||
}
|
||||
|
||||
const string StartMethod = "Start";
|
||||
if (methodSymbol.Name != StartMethod)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var liveTypes = Constants.LiveRenderables
|
||||
.Select(i => context.Compilation.GetTypeByMetadataName(i))
|
||||
.ToImmutableArray();
|
||||
|
||||
var liveTypes = Constants.LiveRenderables
|
||||
.Select(i => context.Compilation.GetTypeByMetadataName(i))
|
||||
.ToImmutableArray();
|
||||
if (liveTypes.All(i => !Equals(i, methodSymbol.ContainingType)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (liveTypes.All(i => !Equals(i, methodSymbol.ContainingType)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var model = context.Compilation.GetSemanticModel(context.Operation.Syntax.SyntaxTree);
|
||||
var parentInvocations = invocationOperation
|
||||
.Syntax.Ancestors()
|
||||
.OfType<InvocationExpressionSyntax>()
|
||||
.Select(i => model.GetOperation(i))
|
||||
.OfType<IInvocationOperation>()
|
||||
.ToList();
|
||||
|
||||
var model = context.Compilation.GetSemanticModel(context.Operation.Syntax.SyntaxTree);
|
||||
var parentInvocations = invocationOperation
|
||||
.Syntax.Ancestors()
|
||||
.OfType<InvocationExpressionSyntax>()
|
||||
.Select(i => model.GetOperation(i))
|
||||
.OfType<IInvocationOperation>()
|
||||
.ToList();
|
||||
if (parentInvocations.All(parent =>
|
||||
parent.TargetMethod.Name != StartMethod || !liveTypes.Contains(parent.TargetMethod.ContainingType)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (parentInvocations.All(parent =>
|
||||
parent.TargetMethod.Name != StartMethod || !liveTypes.Contains(parent.TargetMethod.ContainingType)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var displayString = SymbolDisplay.ToDisplayString(
|
||||
methodSymbol,
|
||||
SymbolDisplayFormat.CSharpShortErrorMessageFormat
|
||||
.WithParameterOptions(SymbolDisplayParameterOptions.None)
|
||||
.WithGenericsOptions(SymbolDisplayGenericsOptions.None));
|
||||
|
||||
var displayString = SymbolDisplay.ToDisplayString(
|
||||
methodSymbol,
|
||||
SymbolDisplayFormat.CSharpShortErrorMessageFormat
|
||||
.WithParameterOptions(SymbolDisplayParameterOptions.None)
|
||||
.WithGenericsOptions(SymbolDisplayGenericsOptions.None));
|
||||
|
||||
context.ReportDiagnostic(
|
||||
Diagnostic.Create(
|
||||
_diagnosticDescriptor,
|
||||
invocationOperation.Syntax.GetLocation(),
|
||||
displayString));
|
||||
}, OperationKind.Invocation);
|
||||
}
|
||||
context.ReportDiagnostic(
|
||||
Diagnostic.Create(
|
||||
_diagnosticDescriptor,
|
||||
invocationOperation.Syntax.GetLocation(),
|
||||
displayString));
|
||||
}, OperationKind.Invocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,78 +7,77 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Operations;
|
||||
|
||||
namespace Spectre.Console.Analyzer
|
||||
namespace Spectre.Console.Analyzer;
|
||||
|
||||
/// <summary>
|
||||
/// Analyzer to detect calls to live renderables within a live renderable context.
|
||||
/// </summary>
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
[Shared]
|
||||
public class NoPromptsDuringLiveRenderablesAnalyzer : SpectreAnalyzer
|
||||
{
|
||||
/// <summary>
|
||||
/// Analyzer to detect calls to live renderables within a live renderable context.
|
||||
/// </summary>
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
[Shared]
|
||||
public class NoPromptsDuringLiveRenderablesAnalyzer : SpectreAnalyzer
|
||||
private static readonly DiagnosticDescriptor _diagnosticDescriptor =
|
||||
Descriptors.S1021_AvoidPromptCallsDuringLiveRenderables;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
|
||||
ImmutableArray.Create(_diagnosticDescriptor);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext)
|
||||
{
|
||||
private static readonly DiagnosticDescriptor _diagnosticDescriptor =
|
||||
Descriptors.S1021_AvoidPromptCallsDuringLiveRenderables;
|
||||
compilationStartContext.RegisterOperationAction(
|
||||
context =>
|
||||
{
|
||||
// if this operation isn't an invocation against one of the System.Console methods
|
||||
// defined in _methods then we can safely stop analyzing and return;
|
||||
var invocationOperation = (IInvocationOperation)context.Operation;
|
||||
var methodSymbol = invocationOperation.TargetMethod;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
|
||||
ImmutableArray.Create(_diagnosticDescriptor);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext)
|
||||
{
|
||||
compilationStartContext.RegisterOperationAction(
|
||||
context =>
|
||||
var promptMethods = ImmutableArray.Create("Ask", "Confirm", "Prompt");
|
||||
if (!promptMethods.Contains(methodSymbol.Name))
|
||||
{
|
||||
// if this operation isn't an invocation against one of the System.Console methods
|
||||
// defined in _methods then we can safely stop analyzing and return;
|
||||
var invocationOperation = (IInvocationOperation)context.Operation;
|
||||
var methodSymbol = invocationOperation.TargetMethod;
|
||||
return;
|
||||
}
|
||||
|
||||
var promptMethods = ImmutableArray.Create("Ask", "Confirm", "Prompt");
|
||||
if (!promptMethods.Contains(methodSymbol.Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var ansiConsoleType = context.Compilation.GetTypeByMetadataName("Spectre.Console.AnsiConsole");
|
||||
var ansiConsoleExtensionsType = context.Compilation.GetTypeByMetadataName("Spectre.Console.AnsiConsoleExtensions");
|
||||
|
||||
var ansiConsoleType = context.Compilation.GetTypeByMetadataName("Spectre.Console.AnsiConsole");
|
||||
var ansiConsoleExtensionsType = context.Compilation.GetTypeByMetadataName("Spectre.Console.AnsiConsoleExtensions");
|
||||
if (!Equals(methodSymbol.ContainingType, ansiConsoleType) && !Equals(methodSymbol.ContainingType, ansiConsoleExtensionsType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Equals(methodSymbol.ContainingType, ansiConsoleType) && !Equals(methodSymbol.ContainingType, ansiConsoleExtensionsType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var model = context.Compilation.GetSemanticModel(context.Operation.Syntax.SyntaxTree);
|
||||
var parentInvocations = invocationOperation
|
||||
.Syntax.Ancestors()
|
||||
.OfType<InvocationExpressionSyntax>()
|
||||
.Select(i => model.GetOperation(i))
|
||||
.OfType<IInvocationOperation>()
|
||||
.ToList();
|
||||
|
||||
var model = context.Compilation.GetSemanticModel(context.Operation.Syntax.SyntaxTree);
|
||||
var parentInvocations = invocationOperation
|
||||
.Syntax.Ancestors()
|
||||
.OfType<InvocationExpressionSyntax>()
|
||||
.Select(i => model.GetOperation(i))
|
||||
.OfType<IInvocationOperation>()
|
||||
.ToList();
|
||||
var liveTypes = Constants.LiveRenderables
|
||||
.Select(i => context.Compilation.GetTypeByMetadataName(i))
|
||||
.ToImmutableArray();
|
||||
|
||||
var liveTypes = Constants.LiveRenderables
|
||||
.Select(i => context.Compilation.GetTypeByMetadataName(i))
|
||||
.ToImmutableArray();
|
||||
if (parentInvocations.All(parent =>
|
||||
parent.TargetMethod.Name != "Start" ||
|
||||
!liveTypes.Contains(parent.TargetMethod.ContainingType)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (parentInvocations.All(parent =>
|
||||
parent.TargetMethod.Name != "Start" ||
|
||||
!liveTypes.Contains(parent.TargetMethod.ContainingType)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var displayString = SymbolDisplay.ToDisplayString(
|
||||
methodSymbol,
|
||||
SymbolDisplayFormat.CSharpShortErrorMessageFormat
|
||||
.WithParameterOptions(SymbolDisplayParameterOptions.None)
|
||||
.WithGenericsOptions(SymbolDisplayGenericsOptions.None));
|
||||
|
||||
var displayString = SymbolDisplay.ToDisplayString(
|
||||
methodSymbol,
|
||||
SymbolDisplayFormat.CSharpShortErrorMessageFormat
|
||||
.WithParameterOptions(SymbolDisplayParameterOptions.None)
|
||||
.WithGenericsOptions(SymbolDisplayGenericsOptions.None));
|
||||
|
||||
context.ReportDiagnostic(
|
||||
Diagnostic.Create(
|
||||
_diagnosticDescriptor,
|
||||
invocationOperation.Syntax.GetLocation(),
|
||||
displayString));
|
||||
}, OperationKind.Invocation);
|
||||
}
|
||||
context.ReportDiagnostic(
|
||||
Diagnostic.Create(
|
||||
_diagnosticDescriptor,
|
||||
invocationOperation.Syntax.GetLocation(),
|
||||
displayString));
|
||||
}, OperationKind.Invocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,24 @@
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
|
||||
namespace Spectre.Console.Analyzer
|
||||
namespace Spectre.Console.Analyzer;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for Spectre analyzers.
|
||||
/// </summary>
|
||||
public abstract class SpectreAnalyzer : DiagnosticAnalyzer
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for Spectre analyzers.
|
||||
/// </summary>
|
||||
public abstract class SpectreAnalyzer : DiagnosticAnalyzer
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(AnalysisContext context)
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(AnalysisContext context)
|
||||
{
|
||||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
|
||||
context.EnableConcurrentExecution();
|
||||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
|
||||
context.EnableConcurrentExecution();
|
||||
|
||||
context.RegisterCompilationStartAction(AnalyzeCompilation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Analyze compilation.
|
||||
/// </summary>
|
||||
/// <param name="compilationStartContext">Compilation Start Analysis Context.</param>
|
||||
protected abstract void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext);
|
||||
context.RegisterCompilationStartAction(AnalyzeCompilation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Analyze compilation.
|
||||
/// </summary>
|
||||
/// <param name="compilationStartContext">Compilation Start Analysis Context.</param>
|
||||
protected abstract void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext);
|
||||
}
|
||||
|
@ -4,60 +4,59 @@ using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Operations;
|
||||
|
||||
namespace Spectre.Console.Analyzer
|
||||
namespace Spectre.Console.Analyzer;
|
||||
|
||||
/// <summary>
|
||||
/// Analyzer to enforce the use of AnsiConsole over System.Console for known methods.
|
||||
/// </summary>
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
public class UseSpectreInsteadOfSystemConsoleAnalyzer : SpectreAnalyzer
|
||||
{
|
||||
/// <summary>
|
||||
/// Analyzer to enforce the use of AnsiConsole over System.Console for known methods.
|
||||
/// </summary>
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
public class UseSpectreInsteadOfSystemConsoleAnalyzer : SpectreAnalyzer
|
||||
private static readonly DiagnosticDescriptor _diagnosticDescriptor =
|
||||
Descriptors.S1000_UseAnsiConsoleOverSystemConsole;
|
||||
|
||||
private static readonly string[] _methods = { "WriteLine", "Write" };
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
|
||||
ImmutableArray.Create(_diagnosticDescriptor);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext)
|
||||
{
|
||||
private static readonly DiagnosticDescriptor _diagnosticDescriptor =
|
||||
Descriptors.S1000_UseAnsiConsoleOverSystemConsole;
|
||||
compilationStartContext.RegisterOperationAction(
|
||||
context =>
|
||||
{
|
||||
// if this operation isn't an invocation against one of the System.Console methods
|
||||
// defined in _methods then we can safely stop analyzing and return;
|
||||
var invocationOperation = (IInvocationOperation)context.Operation;
|
||||
|
||||
private static readonly string[] _methods = { "WriteLine", "Write" };
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
|
||||
ImmutableArray.Create(_diagnosticDescriptor);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext)
|
||||
{
|
||||
compilationStartContext.RegisterOperationAction(
|
||||
context =>
|
||||
var methodName = System.Array.Find(_methods, i => i.Equals(invocationOperation.TargetMethod.Name));
|
||||
if (methodName == null)
|
||||
{
|
||||
// if this operation isn't an invocation against one of the System.Console methods
|
||||
// defined in _methods then we can safely stop analyzing and return;
|
||||
var invocationOperation = (IInvocationOperation)context.Operation;
|
||||
return;
|
||||
}
|
||||
|
||||
var methodName = System.Array.Find(_methods, i => i.Equals(invocationOperation.TargetMethod.Name));
|
||||
if (methodName == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var systemConsoleType = context.Compilation.GetTypeByMetadataName("System.Console");
|
||||
|
||||
var systemConsoleType = context.Compilation.GetTypeByMetadataName("System.Console");
|
||||
if (!Equals(invocationOperation.TargetMethod.ContainingType, systemConsoleType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Equals(invocationOperation.TargetMethod.ContainingType, systemConsoleType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var methodSymbol = invocationOperation.TargetMethod;
|
||||
|
||||
var methodSymbol = invocationOperation.TargetMethod;
|
||||
var displayString = SymbolDisplay.ToDisplayString(
|
||||
methodSymbol,
|
||||
SymbolDisplayFormat.CSharpShortErrorMessageFormat
|
||||
.WithParameterOptions(SymbolDisplayParameterOptions.None)
|
||||
.WithGenericsOptions(SymbolDisplayGenericsOptions.None));
|
||||
|
||||
var displayString = SymbolDisplay.ToDisplayString(
|
||||
methodSymbol,
|
||||
SymbolDisplayFormat.CSharpShortErrorMessageFormat
|
||||
.WithParameterOptions(SymbolDisplayParameterOptions.None)
|
||||
.WithGenericsOptions(SymbolDisplayGenericsOptions.None));
|
||||
|
||||
context.ReportDiagnostic(
|
||||
Diagnostic.Create(
|
||||
_diagnosticDescriptor,
|
||||
invocationOperation.Syntax.GetLocation(),
|
||||
displayString));
|
||||
}, OperationKind.Invocation);
|
||||
}
|
||||
context.ReportDiagnostic(
|
||||
Diagnostic.Create(
|
||||
_diagnosticDescriptor,
|
||||
invocationOperation.Syntax.GetLocation(),
|
||||
displayString));
|
||||
}, OperationKind.Invocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
namespace Spectre.Console.Analyzer
|
||||
{
|
||||
internal static class Constants
|
||||
{
|
||||
internal const string StaticInstance = "AnsiConsole";
|
||||
internal const string SpectreConsole = "Spectre.Console";
|
||||
namespace Spectre.Console.Analyzer;
|
||||
|
||||
internal static readonly string[] LiveRenderables =
|
||||
{
|
||||
"Spectre.Console.LiveDisplay",
|
||||
"Spectre.Console.Progress",
|
||||
"Spectre.Console.Status",
|
||||
};
|
||||
}
|
||||
}
|
||||
internal static class Constants
|
||||
{
|
||||
internal const string StaticInstance = "AnsiConsole";
|
||||
internal const string SpectreConsole = "Spectre.Console";
|
||||
|
||||
internal static readonly string[] LiveRenderables =
|
||||
{
|
||||
"Spectre.Console.LiveDisplay",
|
||||
"Spectre.Console.Progress",
|
||||
"Spectre.Console.Status",
|
||||
};
|
||||
}
|
||||
|
@ -3,77 +3,76 @@ using Microsoft.CodeAnalysis;
|
||||
using static Microsoft.CodeAnalysis.DiagnosticSeverity;
|
||||
using static Spectre.Console.Analyzer.Descriptors.Category;
|
||||
|
||||
namespace Spectre.Console.Analyzer
|
||||
namespace Spectre.Console.Analyzer;
|
||||
|
||||
/// <summary>
|
||||
/// Code analysis descriptors.
|
||||
/// </summary>
|
||||
public static class Descriptors
|
||||
{
|
||||
/// <summary>
|
||||
/// Code analysis descriptors.
|
||||
/// </summary>
|
||||
public static class Descriptors
|
||||
internal enum Category
|
||||
{
|
||||
internal enum Category
|
||||
{
|
||||
Usage, // 1xxx
|
||||
}
|
||||
|
||||
private static readonly ConcurrentDictionary<Category, string> _categoryMapping = new();
|
||||
|
||||
private static DiagnosticDescriptor Rule(string id, string title, Category category, DiagnosticSeverity defaultSeverity, string messageFormat, string? description = null)
|
||||
{
|
||||
var helpLink = $"https://spectreconsole.net/analyzer/rules/{id.ToLowerInvariant()}";
|
||||
const bool IsEnabledByDefault = true;
|
||||
return new DiagnosticDescriptor(
|
||||
id,
|
||||
title,
|
||||
messageFormat,
|
||||
_categoryMapping.GetOrAdd(category, c => c.ToString()),
|
||||
defaultSeverity,
|
||||
IsEnabledByDefault,
|
||||
description,
|
||||
helpLink);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets definitions of diagnostics Spectre1000.
|
||||
/// </summary>
|
||||
public static DiagnosticDescriptor S1000_UseAnsiConsoleOverSystemConsole { get; } =
|
||||
Rule(
|
||||
"Spectre1000",
|
||||
"Use AnsiConsole instead of System.Console",
|
||||
Usage,
|
||||
Warning,
|
||||
"Use AnsiConsole instead of System.Console");
|
||||
|
||||
/// <summary>
|
||||
/// Gets definitions of diagnostics Spectre1010.
|
||||
/// </summary>
|
||||
public static DiagnosticDescriptor S1010_FavorInstanceAnsiConsoleOverStatic { get; } =
|
||||
Rule(
|
||||
"Spectre1010",
|
||||
"Favor the use of the instance of AnsiConsole over the static helper.",
|
||||
Usage,
|
||||
Info,
|
||||
"Favor the use of the instance of AnsiConsole over the static helper.");
|
||||
|
||||
/// <summary>
|
||||
/// Gets definitions of diagnostics Spectre1020.
|
||||
/// </summary>
|
||||
public static DiagnosticDescriptor S1020_AvoidConcurrentCallsToMultipleLiveRenderables { get; } =
|
||||
Rule(
|
||||
"Spectre1020",
|
||||
"Avoid calling other live renderables while a current renderable is running.",
|
||||
Usage,
|
||||
Warning,
|
||||
"Avoid calling other live renderables while a current renderable is running.");
|
||||
|
||||
/// <summary>
|
||||
/// Gets definitions of diagnostics Spectre1020.
|
||||
/// </summary>
|
||||
public static DiagnosticDescriptor S1021_AvoidPromptCallsDuringLiveRenderables { get; } =
|
||||
Rule(
|
||||
"Spectre1021",
|
||||
"Avoid prompting for input while a current renderable is running.",
|
||||
Usage,
|
||||
Warning,
|
||||
"Avoid prompting for input while a current renderable is running.");
|
||||
Usage, // 1xxx
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly ConcurrentDictionary<Category, string> _categoryMapping = new();
|
||||
|
||||
private static DiagnosticDescriptor Rule(string id, string title, Category category, DiagnosticSeverity defaultSeverity, string messageFormat, string? description = null)
|
||||
{
|
||||
var helpLink = $"https://spectreconsole.net/analyzer/rules/{id.ToLowerInvariant()}";
|
||||
const bool IsEnabledByDefault = true;
|
||||
return new DiagnosticDescriptor(
|
||||
id,
|
||||
title,
|
||||
messageFormat,
|
||||
_categoryMapping.GetOrAdd(category, c => c.ToString()),
|
||||
defaultSeverity,
|
||||
IsEnabledByDefault,
|
||||
description,
|
||||
helpLink);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets definitions of diagnostics Spectre1000.
|
||||
/// </summary>
|
||||
public static DiagnosticDescriptor S1000_UseAnsiConsoleOverSystemConsole { get; } =
|
||||
Rule(
|
||||
"Spectre1000",
|
||||
"Use AnsiConsole instead of System.Console",
|
||||
Usage,
|
||||
Warning,
|
||||
"Use AnsiConsole instead of System.Console");
|
||||
|
||||
/// <summary>
|
||||
/// Gets definitions of diagnostics Spectre1010.
|
||||
/// </summary>
|
||||
public static DiagnosticDescriptor S1010_FavorInstanceAnsiConsoleOverStatic { get; } =
|
||||
Rule(
|
||||
"Spectre1010",
|
||||
"Favor the use of the instance of AnsiConsole over the static helper.",
|
||||
Usage,
|
||||
Info,
|
||||
"Favor the use of the instance of AnsiConsole over the static helper.");
|
||||
|
||||
/// <summary>
|
||||
/// Gets definitions of diagnostics Spectre1020.
|
||||
/// </summary>
|
||||
public static DiagnosticDescriptor S1020_AvoidConcurrentCallsToMultipleLiveRenderables { get; } =
|
||||
Rule(
|
||||
"Spectre1020",
|
||||
"Avoid calling other live renderables while a current renderable is running.",
|
||||
Usage,
|
||||
Warning,
|
||||
"Avoid calling other live renderables while a current renderable is running.");
|
||||
|
||||
/// <summary>
|
||||
/// Gets definitions of diagnostics Spectre1020.
|
||||
/// </summary>
|
||||
public static DiagnosticDescriptor S1021_AvoidPromptCallsDuringLiveRenderables { get; } =
|
||||
Rule(
|
||||
"Spectre1021",
|
||||
"Avoid prompting for input while a current renderable is running.",
|
||||
Usage,
|
||||
Warning,
|
||||
"Avoid prompting for input while a current renderable is running.");
|
||||
}
|
||||
|
@ -7,110 +7,109 @@ using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
namespace Spectre.Console.Analyzer.CodeActions
|
||||
namespace Spectre.Console.Analyzer.CodeActions;
|
||||
|
||||
/// <summary>
|
||||
/// Code action to change calls to System.Console to AnsiConsole.
|
||||
/// </summary>
|
||||
public class SwitchToAnsiConsoleAction : CodeAction
|
||||
{
|
||||
private readonly Document _document;
|
||||
private readonly InvocationExpressionSyntax _originalInvocation;
|
||||
|
||||
/// <summary>
|
||||
/// Code action to change calls to System.Console to AnsiConsole.
|
||||
/// Initializes a new instance of the <see cref="SwitchToAnsiConsoleAction"/> class.
|
||||
/// </summary>
|
||||
public class SwitchToAnsiConsoleAction : CodeAction
|
||||
/// <param name="document">Document to change.</param>
|
||||
/// <param name="originalInvocation">The method to change.</param>
|
||||
/// <param name="title">Title of the fix.</param>
|
||||
public SwitchToAnsiConsoleAction(Document document, InvocationExpressionSyntax originalInvocation, string title)
|
||||
{
|
||||
private readonly Document _document;
|
||||
private readonly InvocationExpressionSyntax _originalInvocation;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SwitchToAnsiConsoleAction"/> class.
|
||||
/// </summary>
|
||||
/// <param name="document">Document to change.</param>
|
||||
/// <param name="originalInvocation">The method to change.</param>
|
||||
/// <param name="title">Title of the fix.</param>
|
||||
public SwitchToAnsiConsoleAction(Document document, InvocationExpressionSyntax originalInvocation, string title)
|
||||
{
|
||||
_document = document;
|
||||
_originalInvocation = originalInvocation;
|
||||
Title = title;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Title { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string EquivalenceKey => Title;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task<Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var originalCaller = ((MemberAccessExpressionSyntax)_originalInvocation.Expression).Name.ToString();
|
||||
|
||||
var syntaxTree = await _document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
|
||||
var root = (CompilationUnitSyntax)await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// If there is an ansiConsole passed into the method then we'll use it.
|
||||
// otherwise we'll check for a field level instance.
|
||||
// if neither of those exist we'll fall back to the static param.
|
||||
var ansiConsoleParameterDeclaration = GetAnsiConsoleParameterDeclaration();
|
||||
var ansiConsoleFieldIdentifier = GetAnsiConsoleFieldDeclaration();
|
||||
var ansiConsoleIdentifier = ansiConsoleParameterDeclaration ??
|
||||
ansiConsoleFieldIdentifier ??
|
||||
Constants.StaticInstance;
|
||||
|
||||
// Replace the System.Console call with a call to the identifier above.
|
||||
var newRoot = root.ReplaceNode(
|
||||
_originalInvocation,
|
||||
GetImportedSpectreCall(originalCaller, ansiConsoleIdentifier));
|
||||
|
||||
// If we are calling the static instance and Spectre isn't imported yet we should do so.
|
||||
if (ansiConsoleIdentifier == Constants.StaticInstance && root.Usings.ToList().All(i => i.Name.ToString() != Constants.SpectreConsole))
|
||||
{
|
||||
newRoot = newRoot.AddUsings(Syntax.SpectreUsing);
|
||||
}
|
||||
|
||||
return _document.WithSyntaxRoot(newRoot);
|
||||
}
|
||||
|
||||
private string? GetAnsiConsoleParameterDeclaration()
|
||||
{
|
||||
return _originalInvocation
|
||||
.Ancestors().OfType<MethodDeclarationSyntax>()
|
||||
.First()
|
||||
.ParameterList.Parameters
|
||||
.FirstOrDefault(i => i.Type.NormalizeWhitespace().ToString() == "IAnsiConsole")
|
||||
?.Identifier.Text;
|
||||
}
|
||||
|
||||
private string? GetAnsiConsoleFieldDeclaration()
|
||||
{
|
||||
// let's look to see if our call is in a static method.
|
||||
// if so we'll only want to look for static IAnsiConsoles
|
||||
// and vice-versa if we aren't.
|
||||
var isStatic = _originalInvocation
|
||||
.Ancestors()
|
||||
.OfType<MethodDeclarationSyntax>()
|
||||
.First()
|
||||
.Modifiers.Any(i => i.Kind() == SyntaxKind.StaticKeyword);
|
||||
|
||||
return _originalInvocation
|
||||
.Ancestors().OfType<ClassDeclarationSyntax>()
|
||||
.First()
|
||||
.Members
|
||||
.OfType<FieldDeclarationSyntax>()
|
||||
.FirstOrDefault(i =>
|
||||
i.Declaration.Type.NormalizeWhitespace().ToString() == "IAnsiConsole" &&
|
||||
(!isStatic ^ i.Modifiers.Any(modifier => modifier.Kind() == SyntaxKind.StaticKeyword)))
|
||||
?.Declaration.Variables.First().Identifier.Text;
|
||||
}
|
||||
|
||||
private ExpressionSyntax GetImportedSpectreCall(string originalCaller, string ansiConsoleIdentifier)
|
||||
{
|
||||
return ExpressionStatement(
|
||||
InvocationExpression(
|
||||
MemberAccessExpression(
|
||||
SyntaxKind.SimpleMemberAccessExpression,
|
||||
IdentifierName(ansiConsoleIdentifier),
|
||||
IdentifierName(originalCaller)))
|
||||
.WithArgumentList(_originalInvocation.ArgumentList)
|
||||
.WithTrailingTrivia(_originalInvocation.GetTrailingTrivia())
|
||||
.WithLeadingTrivia(_originalInvocation.GetLeadingTrivia()))
|
||||
.Expression;
|
||||
}
|
||||
_document = document;
|
||||
_originalInvocation = originalInvocation;
|
||||
Title = title;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Title { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string EquivalenceKey => Title;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task<Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var originalCaller = ((MemberAccessExpressionSyntax)_originalInvocation.Expression).Name.ToString();
|
||||
|
||||
var syntaxTree = await _document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
|
||||
var root = (CompilationUnitSyntax)await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// If there is an ansiConsole passed into the method then we'll use it.
|
||||
// otherwise we'll check for a field level instance.
|
||||
// if neither of those exist we'll fall back to the static param.
|
||||
var ansiConsoleParameterDeclaration = GetAnsiConsoleParameterDeclaration();
|
||||
var ansiConsoleFieldIdentifier = GetAnsiConsoleFieldDeclaration();
|
||||
var ansiConsoleIdentifier = ansiConsoleParameterDeclaration ??
|
||||
ansiConsoleFieldIdentifier ??
|
||||
Constants.StaticInstance;
|
||||
|
||||
// Replace the System.Console call with a call to the identifier above.
|
||||
var newRoot = root.ReplaceNode(
|
||||
_originalInvocation,
|
||||
GetImportedSpectreCall(originalCaller, ansiConsoleIdentifier));
|
||||
|
||||
// If we are calling the static instance and Spectre isn't imported yet we should do so.
|
||||
if (ansiConsoleIdentifier == Constants.StaticInstance && root.Usings.ToList().All(i => i.Name.ToString() != Constants.SpectreConsole))
|
||||
{
|
||||
newRoot = newRoot.AddUsings(Syntax.SpectreUsing);
|
||||
}
|
||||
|
||||
return _document.WithSyntaxRoot(newRoot);
|
||||
}
|
||||
|
||||
private string? GetAnsiConsoleParameterDeclaration()
|
||||
{
|
||||
return _originalInvocation
|
||||
.Ancestors().OfType<MethodDeclarationSyntax>()
|
||||
.First()
|
||||
.ParameterList.Parameters
|
||||
.FirstOrDefault(i => i.Type.NormalizeWhitespace().ToString() == "IAnsiConsole")
|
||||
?.Identifier.Text;
|
||||
}
|
||||
|
||||
private string? GetAnsiConsoleFieldDeclaration()
|
||||
{
|
||||
// let's look to see if our call is in a static method.
|
||||
// if so we'll only want to look for static IAnsiConsoles
|
||||
// and vice-versa if we aren't.
|
||||
var isStatic = _originalInvocation
|
||||
.Ancestors()
|
||||
.OfType<MethodDeclarationSyntax>()
|
||||
.First()
|
||||
.Modifiers.Any(i => i.Kind() == SyntaxKind.StaticKeyword);
|
||||
|
||||
return _originalInvocation
|
||||
.Ancestors().OfType<ClassDeclarationSyntax>()
|
||||
.First()
|
||||
.Members
|
||||
.OfType<FieldDeclarationSyntax>()
|
||||
.FirstOrDefault(i =>
|
||||
i.Declaration.Type.NormalizeWhitespace().ToString() == "IAnsiConsole" &&
|
||||
(!isStatic ^ i.Modifiers.Any(modifier => modifier.Kind() == SyntaxKind.StaticKeyword)))
|
||||
?.Declaration.Variables.First().Identifier.Text;
|
||||
}
|
||||
|
||||
private ExpressionSyntax GetImportedSpectreCall(string originalCaller, string ansiConsoleIdentifier)
|
||||
{
|
||||
return ExpressionStatement(
|
||||
InvocationExpression(
|
||||
MemberAccessExpression(
|
||||
SyntaxKind.SimpleMemberAccessExpression,
|
||||
IdentifierName(ansiConsoleIdentifier),
|
||||
IdentifierName(originalCaller)))
|
||||
.WithArgumentList(_originalInvocation.ArgumentList)
|
||||
.WithTrailingTrivia(_originalInvocation.GetTrailingTrivia())
|
||||
.WithLeadingTrivia(_originalInvocation.GetLeadingTrivia()))
|
||||
.Expression;
|
||||
}
|
||||
}
|
||||
|
@ -6,30 +6,29 @@ using Microsoft.CodeAnalysis.CodeFixes;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Spectre.Console.Analyzer.CodeActions;
|
||||
|
||||
namespace Spectre.Console.Analyzer.FixProviders
|
||||
namespace Spectre.Console.Analyzer.FixProviders;
|
||||
|
||||
/// <summary>
|
||||
/// Fix provider to change System.Console calls to AnsiConsole calls.
|
||||
/// </summary>
|
||||
[ExportCodeFixProvider(LanguageNames.CSharp)]
|
||||
[Shared]
|
||||
public class StaticAnsiConsoleToInstanceFix : CodeFixProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Fix provider to change System.Console calls to AnsiConsole calls.
|
||||
/// </summary>
|
||||
[ExportCodeFixProvider(LanguageNames.CSharp)]
|
||||
[Shared]
|
||||
public class StaticAnsiConsoleToInstanceFix : CodeFixProvider
|
||||
/// <inheritdoc />
|
||||
public sealed override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(
|
||||
Descriptors.S1010_FavorInstanceAnsiConsoleOverStatic.Id);
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public sealed override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(
|
||||
Descriptors.S1010_FavorInstanceAnsiConsoleOverStatic.Id);
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
|
||||
{
|
||||
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
|
||||
var methodDeclaration = root.FindNode(context.Span).FirstAncestorOrSelf<InvocationExpressionSyntax>();
|
||||
context.RegisterCodeFix(
|
||||
new SwitchToAnsiConsoleAction(context.Document, methodDeclaration, "Convert static AnsiConsole calls to local instance."),
|
||||
context.Diagnostics);
|
||||
}
|
||||
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
|
||||
var methodDeclaration = root.FindNode(context.Span).FirstAncestorOrSelf<InvocationExpressionSyntax>();
|
||||
context.RegisterCodeFix(
|
||||
new SwitchToAnsiConsoleAction(context.Document, methodDeclaration, "Convert static AnsiConsole calls to local instance."),
|
||||
context.Diagnostics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,30 +6,29 @@ using Microsoft.CodeAnalysis.CodeFixes;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Spectre.Console.Analyzer.CodeActions;
|
||||
|
||||
namespace Spectre.Console.Analyzer.FixProviders
|
||||
namespace Spectre.Console.Analyzer.FixProviders;
|
||||
|
||||
/// <summary>
|
||||
/// Fix provider to change System.Console calls to AnsiConsole calls.
|
||||
/// </summary>
|
||||
[ExportCodeFixProvider(LanguageNames.CSharp)]
|
||||
[Shared]
|
||||
public class SystemConsoleToAnsiConsoleFix : CodeFixProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Fix provider to change System.Console calls to AnsiConsole calls.
|
||||
/// </summary>
|
||||
[ExportCodeFixProvider(LanguageNames.CSharp)]
|
||||
[Shared]
|
||||
public class SystemConsoleToAnsiConsoleFix : CodeFixProvider
|
||||
/// <inheritdoc />
|
||||
public sealed override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(
|
||||
Descriptors.S1000_UseAnsiConsoleOverSystemConsole.Id);
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public sealed override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(
|
||||
Descriptors.S1000_UseAnsiConsoleOverSystemConsole.Id);
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
|
||||
{
|
||||
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
|
||||
var methodDeclaration = root.FindNode(context.Span).FirstAncestorOrSelf<InvocationExpressionSyntax>();
|
||||
context.RegisterCodeFix(
|
||||
new SwitchToAnsiConsoleAction(context.Document, methodDeclaration, "Convert static call to AnsiConsole to Spectre.Console.AnsiConsole"),
|
||||
context.Diagnostics);
|
||||
}
|
||||
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
|
||||
var methodDeclaration = root.FindNode(context.Span).FirstAncestorOrSelf<InvocationExpressionSyntax>();
|
||||
context.RegisterCodeFix(
|
||||
new SwitchToAnsiConsoleAction(context.Document, methodDeclaration, "Convert static call to AnsiConsole to Spectre.Console.AnsiConsole"),
|
||||
context.Diagnostics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
namespace Spectre.Console.Analyzer
|
||||
namespace Spectre.Console.Analyzer;
|
||||
|
||||
internal static class Syntax
|
||||
{
|
||||
internal static class Syntax
|
||||
{
|
||||
public static readonly UsingDirectiveSyntax SpectreUsing = UsingDirective(QualifiedName(IdentifierName("Spectre"), IdentifierName("Console")));
|
||||
}
|
||||
}
|
||||
public static readonly UsingDirectiveSyntax SpectreUsing = UsingDirective(QualifiedName(IdentifierName("Spectre"), IdentifierName("Console")));
|
||||
}
|
||||
|
@ -6,139 +6,138 @@ using SixLabors.ImageSharp.Processing;
|
||||
using SixLabors.ImageSharp.Processing.Processors.Transforms;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a renderable image.
|
||||
/// </summary>
|
||||
public sealed class CanvasImage : Renderable
|
||||
{
|
||||
private static readonly IResampler _defaultResampler = KnownResamplers.Bicubic;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a renderable image.
|
||||
/// Gets the image width.
|
||||
/// </summary>
|
||||
public sealed class CanvasImage : Renderable
|
||||
public int Width => Image.Width;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image height.
|
||||
/// </summary>
|
||||
public int Height => Image.Height;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the render width of the canvas.
|
||||
/// </summary>
|
||||
public int? MaxWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the render width of the canvas.
|
||||
/// </summary>
|
||||
public int PixelWidth { get; set; } = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IResampler"/> that should
|
||||
/// be used when scaling the image. Defaults to bicubic sampling.
|
||||
/// </summary>
|
||||
public IResampler? Resampler { get; set; }
|
||||
|
||||
internal SixLabors.ImageSharp.Image<Rgba32> Image { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CanvasImage"/> class.
|
||||
/// </summary>
|
||||
/// <param name="filename">The image filename.</param>
|
||||
public CanvasImage(string filename)
|
||||
{
|
||||
private static readonly IResampler _defaultResampler = KnownResamplers.Bicubic;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image width.
|
||||
/// </summary>
|
||||
public int Width => Image.Width;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image height.
|
||||
/// </summary>
|
||||
public int Height => Image.Height;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the render width of the canvas.
|
||||
/// </summary>
|
||||
public int? MaxWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the render width of the canvas.
|
||||
/// </summary>
|
||||
public int PixelWidth { get; set; } = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IResampler"/> that should
|
||||
/// be used when scaling the image. Defaults to bicubic sampling.
|
||||
/// </summary>
|
||||
public IResampler? Resampler { get; set; }
|
||||
|
||||
internal SixLabors.ImageSharp.Image<Rgba32> Image { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CanvasImage"/> class.
|
||||
/// </summary>
|
||||
/// <param name="filename">The image filename.</param>
|
||||
public CanvasImage(string filename)
|
||||
{
|
||||
Image = SixLabors.ImageSharp.Image.Load<Rgba32>(filename);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CanvasImage"/> class.
|
||||
/// </summary>
|
||||
/// <param name="data">Buffer containing an image.</param>
|
||||
public CanvasImage(ReadOnlySpan<byte> data)
|
||||
{
|
||||
Image = SixLabors.ImageSharp.Image.Load<Rgba32>(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CanvasImage"/> class.
|
||||
/// </summary>
|
||||
/// <param name="data">Stream containing an image.</param>
|
||||
public CanvasImage(Stream data)
|
||||
{
|
||||
Image = SixLabors.ImageSharp.Image.Load<Rgba32>(data);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Measurement Measure(RenderContext context, int maxWidth)
|
||||
{
|
||||
if (PixelWidth < 0)
|
||||
{
|
||||
throw new InvalidOperationException("Pixel width must be greater than zero.");
|
||||
}
|
||||
|
||||
var width = MaxWidth ?? Width;
|
||||
if (maxWidth < width * PixelWidth)
|
||||
{
|
||||
return new Measurement(maxWidth, maxWidth);
|
||||
}
|
||||
|
||||
return new Measurement(width * PixelWidth, width * PixelWidth);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override IEnumerable<Segment> Render(RenderContext context, int maxWidth)
|
||||
{
|
||||
var image = Image;
|
||||
|
||||
var width = Width;
|
||||
var height = Height;
|
||||
|
||||
// Got a max width?
|
||||
if (MaxWidth != null)
|
||||
{
|
||||
height = (int)(height * ((float)MaxWidth.Value) / Width);
|
||||
width = MaxWidth.Value;
|
||||
}
|
||||
|
||||
// Exceed the max width when we take pixel width into account?
|
||||
if (width * PixelWidth > maxWidth)
|
||||
{
|
||||
height = (int)(height * (maxWidth / (float)(width * PixelWidth)));
|
||||
width = maxWidth / PixelWidth;
|
||||
}
|
||||
|
||||
// Need to rescale the pixel buffer?
|
||||
if (width != Width || height != Height)
|
||||
{
|
||||
var resampler = Resampler ?? _defaultResampler;
|
||||
image = image.Clone(); // Clone the original image
|
||||
image.Mutate(i => i.Resize(width, height, resampler));
|
||||
}
|
||||
|
||||
var canvas = new Canvas(width, height)
|
||||
{
|
||||
MaxWidth = MaxWidth,
|
||||
PixelWidth = PixelWidth,
|
||||
Scale = false,
|
||||
};
|
||||
|
||||
for (var y = 0; y < image.Height; y++)
|
||||
{
|
||||
for (var x = 0; x < image.Width; x++)
|
||||
{
|
||||
if (image[x, y].A == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
canvas.SetPixel(x, y, new Color(
|
||||
image[x, y].R, image[x, y].G, image[x, y].B));
|
||||
}
|
||||
}
|
||||
|
||||
return ((IRenderable)canvas).Render(context, maxWidth);
|
||||
}
|
||||
Image = SixLabors.ImageSharp.Image.Load<Rgba32>(filename);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CanvasImage"/> class.
|
||||
/// </summary>
|
||||
/// <param name="data">Buffer containing an image.</param>
|
||||
public CanvasImage(ReadOnlySpan<byte> data)
|
||||
{
|
||||
Image = SixLabors.ImageSharp.Image.Load<Rgba32>(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CanvasImage"/> class.
|
||||
/// </summary>
|
||||
/// <param name="data">Stream containing an image.</param>
|
||||
public CanvasImage(Stream data)
|
||||
{
|
||||
Image = SixLabors.ImageSharp.Image.Load<Rgba32>(data);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Measurement Measure(RenderContext context, int maxWidth)
|
||||
{
|
||||
if (PixelWidth < 0)
|
||||
{
|
||||
throw new InvalidOperationException("Pixel width must be greater than zero.");
|
||||
}
|
||||
|
||||
var width = MaxWidth ?? Width;
|
||||
if (maxWidth < width * PixelWidth)
|
||||
{
|
||||
return new Measurement(maxWidth, maxWidth);
|
||||
}
|
||||
|
||||
return new Measurement(width * PixelWidth, width * PixelWidth);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override IEnumerable<Segment> Render(RenderContext context, int maxWidth)
|
||||
{
|
||||
var image = Image;
|
||||
|
||||
var width = Width;
|
||||
var height = Height;
|
||||
|
||||
// Got a max width?
|
||||
if (MaxWidth != null)
|
||||
{
|
||||
height = (int)(height * ((float)MaxWidth.Value) / Width);
|
||||
width = MaxWidth.Value;
|
||||
}
|
||||
|
||||
// Exceed the max width when we take pixel width into account?
|
||||
if (width * PixelWidth > maxWidth)
|
||||
{
|
||||
height = (int)(height * (maxWidth / (float)(width * PixelWidth)));
|
||||
width = maxWidth / PixelWidth;
|
||||
}
|
||||
|
||||
// Need to rescale the pixel buffer?
|
||||
if (width != Width || height != Height)
|
||||
{
|
||||
var resampler = Resampler ?? _defaultResampler;
|
||||
image = image.Clone(); // Clone the original image
|
||||
image.Mutate(i => i.Resize(width, height, resampler));
|
||||
}
|
||||
|
||||
var canvas = new Canvas(width, height)
|
||||
{
|
||||
MaxWidth = MaxWidth,
|
||||
PixelWidth = PixelWidth,
|
||||
Scale = false,
|
||||
};
|
||||
|
||||
for (var y = 0; y < image.Height; y++)
|
||||
{
|
||||
for (var x = 0; x < image.Width; x++)
|
||||
{
|
||||
if (image[x, y].A == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
canvas.SetPixel(x, y, new Color(
|
||||
image[x, y].R, image[x, y].G, image[x, y].B));
|
||||
}
|
||||
}
|
||||
|
||||
return ((IRenderable)canvas).Render(context, maxWidth);
|
||||
}
|
||||
}
|
@ -1,135 +1,134 @@
|
||||
using System;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="CanvasImage"/>.
|
||||
/// </summary>
|
||||
public static class CanvasImageExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="CanvasImage"/>.
|
||||
/// Sets the maximum width of the rendered image.
|
||||
/// </summary>
|
||||
public static class CanvasImageExtensions
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <param name="maxWidth">The maximum width.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage MaxWidth(this CanvasImage image, int? maxWidth)
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the maximum width of the rendered image.
|
||||
/// </summary>
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <param name="maxWidth">The maximum width.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage MaxWidth(this CanvasImage image, int? maxWidth)
|
||||
if (image is null)
|
||||
{
|
||||
if (image is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
image.MaxWidth = maxWidth;
|
||||
return image;
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables the maximum width of the rendered image.
|
||||
/// </summary>
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage NoMaxWidth(this CanvasImage image)
|
||||
{
|
||||
if (image is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
image.MaxWidth = null;
|
||||
return image;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the pixel width.
|
||||
/// </summary>
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <param name="width">The pixel width.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage PixelWidth(this CanvasImage image, int width)
|
||||
{
|
||||
if (image is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
image.PixelWidth = width;
|
||||
return image;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mutates the underlying image.
|
||||
/// </summary>
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <param name="action">The action that mutates the underlying image.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage Mutate(this CanvasImage image, Action<IImageProcessingContext> action)
|
||||
{
|
||||
if (image is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
if (action is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(action));
|
||||
}
|
||||
|
||||
image.Image.Mutate(action);
|
||||
return image;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses a bicubic sampler that implements the bicubic kernel algorithm W(x).
|
||||
/// </summary>
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage BicubicResampler(this CanvasImage image)
|
||||
{
|
||||
if (image is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
image.Resampler = KnownResamplers.Bicubic;
|
||||
return image;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses a bilinear sampler. This interpolation algorithm
|
||||
/// can be used where perfect image transformation with pixel matching is impossible,
|
||||
/// so that one can calculate and assign appropriate intensity values to pixels.
|
||||
/// </summary>
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage BilinearResampler(this CanvasImage image)
|
||||
{
|
||||
if (image is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
image.Resampler = KnownResamplers.Triangle;
|
||||
return image;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses a Nearest-Neighbour sampler that implements the nearest neighbor algorithm.
|
||||
/// This uses a very fast, unscaled filter which will select the closest pixel to
|
||||
/// the new pixels position.
|
||||
/// </summary>
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage NearestNeighborResampler(this CanvasImage image)
|
||||
{
|
||||
if (image is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
image.Resampler = KnownResamplers.NearestNeighbor;
|
||||
return image;
|
||||
}
|
||||
image.MaxWidth = maxWidth;
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables the maximum width of the rendered image.
|
||||
/// </summary>
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage NoMaxWidth(this CanvasImage image)
|
||||
{
|
||||
if (image is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
image.MaxWidth = null;
|
||||
return image;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the pixel width.
|
||||
/// </summary>
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <param name="width">The pixel width.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage PixelWidth(this CanvasImage image, int width)
|
||||
{
|
||||
if (image is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
image.PixelWidth = width;
|
||||
return image;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mutates the underlying image.
|
||||
/// </summary>
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <param name="action">The action that mutates the underlying image.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage Mutate(this CanvasImage image, Action<IImageProcessingContext> action)
|
||||
{
|
||||
if (image is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
if (action is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(action));
|
||||
}
|
||||
|
||||
image.Image.Mutate(action);
|
||||
return image;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses a bicubic sampler that implements the bicubic kernel algorithm W(x).
|
||||
/// </summary>
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage BicubicResampler(this CanvasImage image)
|
||||
{
|
||||
if (image is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
image.Resampler = KnownResamplers.Bicubic;
|
||||
return image;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses a bilinear sampler. This interpolation algorithm
|
||||
/// can be used where perfect image transformation with pixel matching is impossible,
|
||||
/// so that one can calculate and assign appropriate intensity values to pixels.
|
||||
/// </summary>
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage BilinearResampler(this CanvasImage image)
|
||||
{
|
||||
if (image is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
image.Resampler = KnownResamplers.Triangle;
|
||||
return image;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses a Nearest-Neighbour sampler that implements the nearest neighbor algorithm.
|
||||
/// This uses a very fast, unscaled filter which will select the closest pixel to
|
||||
/// the new pixels position.
|
||||
/// </summary>
|
||||
/// <param name="image">The canvas image.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static CanvasImage NearestNeighborResampler(this CanvasImage image)
|
||||
{
|
||||
if (image is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(image));
|
||||
}
|
||||
|
||||
image.Resampler = KnownResamplers.NearestNeighbor;
|
||||
return image;
|
||||
}
|
||||
}
|
@ -1,28 +1,27 @@
|
||||
using System;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Testing
|
||||
namespace Spectre.Console.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="ICommandInterceptor"/> that triggers a callback when invoked.
|
||||
/// </summary>
|
||||
public sealed class CallbackCommandInterceptor : ICommandInterceptor
|
||||
{
|
||||
private readonly Action<CommandContext, CommandSettings> _callback;
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="ICommandInterceptor"/> that triggers a callback when invoked.
|
||||
/// Initializes a new instance of the <see cref="CallbackCommandInterceptor"/> class.
|
||||
/// </summary>
|
||||
public sealed class CallbackCommandInterceptor : ICommandInterceptor
|
||||
/// <param name="callback">The callback to call when the interceptor is invoked.</param>
|
||||
public CallbackCommandInterceptor(Action<CommandContext, CommandSettings> callback)
|
||||
{
|
||||
private readonly Action<CommandContext, CommandSettings> _callback;
|
||||
_callback = callback ?? throw new ArgumentNullException(nameof(callback));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CallbackCommandInterceptor"/> class.
|
||||
/// </summary>
|
||||
/// <param name="callback">The callback to call when the interceptor is invoked.</param>
|
||||
public CallbackCommandInterceptor(Action<CommandContext, CommandSettings> callback)
|
||||
{
|
||||
_callback = callback ?? throw new ArgumentNullException(nameof(callback));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Intercept(CommandContext context, CommandSettings settings)
|
||||
{
|
||||
_callback(context, settings);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void Intercept(CommandContext context, CommandSettings settings)
|
||||
{
|
||||
_callback(context, settings);
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,28 @@
|
||||
using System;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Testing
|
||||
namespace Spectre.Console.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a <see cref="CommandApp"/> runtime failure.
|
||||
/// </summary>
|
||||
public sealed class CommandAppFailure
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="CommandApp"/> runtime failure.
|
||||
/// Gets the exception that was thrown.
|
||||
/// </summary>
|
||||
public sealed class CommandAppFailure
|
||||
public Exception Exception { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the console output.
|
||||
/// </summary>
|
||||
public string Output { get; }
|
||||
|
||||
internal CommandAppFailure(Exception exception, string output)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the exception that was thrown.
|
||||
/// </summary>
|
||||
public Exception Exception { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the console output.
|
||||
/// </summary>
|
||||
public string Output { get; }
|
||||
|
||||
internal CommandAppFailure(Exception exception, string output)
|
||||
{
|
||||
Exception = exception ?? throw new ArgumentNullException(nameof(exception));
|
||||
Output = output.NormalizeLineEndings()
|
||||
.TrimLines()
|
||||
.Trim();
|
||||
}
|
||||
Exception = exception ?? throw new ArgumentNullException(nameof(exception));
|
||||
Output = output.NormalizeLineEndings()
|
||||
.TrimLines()
|
||||
.Trim();
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +1,42 @@
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Testing
|
||||
namespace Spectre.Console.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the result of a completed <see cref="CommandApp"/> run.
|
||||
/// </summary>
|
||||
public sealed class CommandAppResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the result of a completed <see cref="CommandApp"/> run.
|
||||
/// Gets the exit code.
|
||||
/// </summary>
|
||||
public sealed class CommandAppResult
|
||||
public int ExitCode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the console output.
|
||||
/// </summary>
|
||||
public string Output { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the command context.
|
||||
/// </summary>
|
||||
public CommandContext? Context { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the command settings.
|
||||
/// </summary>
|
||||
public CommandSettings? Settings { get; }
|
||||
|
||||
internal CommandAppResult(int exitCode, string output, CommandContext? context, CommandSettings? settings)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the exit code.
|
||||
/// </summary>
|
||||
public int ExitCode { get; }
|
||||
ExitCode = exitCode;
|
||||
Output = output ?? string.Empty;
|
||||
Context = context;
|
||||
Settings = settings;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the console output.
|
||||
/// </summary>
|
||||
public string Output { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the command context.
|
||||
/// </summary>
|
||||
public CommandContext? Context { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the command settings.
|
||||
/// </summary>
|
||||
public CommandSettings? Settings { get; }
|
||||
|
||||
internal CommandAppResult(int exitCode, string output, CommandContext? context, CommandSettings? settings)
|
||||
{
|
||||
ExitCode = exitCode;
|
||||
Output = output ?? string.Empty;
|
||||
Context = context;
|
||||
Settings = settings;
|
||||
|
||||
Output = Output
|
||||
.NormalizeLineEndings()
|
||||
.TrimLines()
|
||||
.Trim();
|
||||
}
|
||||
Output = Output
|
||||
.NormalizeLineEndings()
|
||||
.TrimLines()
|
||||
.Trim();
|
||||
}
|
||||
}
|
||||
|
@ -1,135 +1,134 @@
|
||||
using System;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Testing
|
||||
namespace Spectre.Console.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="CommandApp"/> test harness.
|
||||
/// </summary>
|
||||
public sealed class CommandAppTester
|
||||
{
|
||||
private Action<CommandApp>? _appConfiguration;
|
||||
private Action<IConfigurator>? _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="CommandApp"/> test harness.
|
||||
/// Initializes a new instance of the <see cref="CommandAppTester"/> class.
|
||||
/// </summary>
|
||||
public sealed class CommandAppTester
|
||||
/// <param name="registrar">The registrar.</param>
|
||||
public CommandAppTester(ITypeRegistrar? registrar = null)
|
||||
{
|
||||
private Action<CommandApp>? _appConfiguration;
|
||||
private Action<IConfigurator>? _configuration;
|
||||
Registrar = registrar;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CommandAppTester"/> class.
|
||||
/// </summary>
|
||||
/// <param name="registrar">The registrar.</param>
|
||||
public CommandAppTester(ITypeRegistrar? registrar = null)
|
||||
/// <summary>
|
||||
/// Gets or sets the Registrar to use in the CommandApp.
|
||||
/// </summary>
|
||||
public ITypeRegistrar? Registrar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the default command.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The default command type.</typeparam>
|
||||
public void SetDefaultCommand<T>()
|
||||
where T : class, ICommand
|
||||
{
|
||||
_appConfiguration = (app) => app.SetDefaultCommand<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the command application.
|
||||
/// </summary>
|
||||
/// <param name="action">The configuration action.</param>
|
||||
public void Configure(Action<IConfigurator> action)
|
||||
{
|
||||
if (_configuration != null)
|
||||
{
|
||||
Registrar = registrar;
|
||||
throw new InvalidOperationException("The command app harnest have already been configured.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Registrar to use in the CommandApp.
|
||||
/// </summary>
|
||||
public ITypeRegistrar? Registrar { get; set; }
|
||||
_configuration = action;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the default command.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The default command type.</typeparam>
|
||||
public void SetDefaultCommand<T>()
|
||||
where T : class, ICommand
|
||||
/// <summary>
|
||||
/// Runs the command application and expects an exception of a specific type to be thrown.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The expected exception type.</typeparam>
|
||||
/// <param name="args">The arguments.</param>
|
||||
/// <returns>The information about the failure.</returns>
|
||||
public CommandAppFailure RunAndCatch<T>(params string[] args)
|
||||
where T : Exception
|
||||
{
|
||||
var console = new TestConsole().Width(int.MaxValue);
|
||||
|
||||
try
|
||||
{
|
||||
_appConfiguration = (app) => app.SetDefaultCommand<T>();
|
||||
Run(args, console, c => c.PropagateExceptions());
|
||||
throw new InvalidOperationException("Expected an exception to be thrown, but there was none.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the command application.
|
||||
/// </summary>
|
||||
/// <param name="action">The configuration action.</param>
|
||||
public void Configure(Action<IConfigurator> action)
|
||||
catch (T ex)
|
||||
{
|
||||
if (_configuration != null)
|
||||
if (ex is CommandAppException commandAppException && commandAppException.Pretty != null)
|
||||
{
|
||||
throw new InvalidOperationException("The command app harnest have already been configured.");
|
||||
console.Write(commandAppException.Pretty);
|
||||
}
|
||||
else
|
||||
{
|
||||
console.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
_configuration = action;
|
||||
return new CommandAppFailure(ex, console.Output);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the command application and expects an exception of a specific type to be thrown.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The expected exception type.</typeparam>
|
||||
/// <param name="args">The arguments.</param>
|
||||
/// <returns>The information about the failure.</returns>
|
||||
public CommandAppFailure RunAndCatch<T>(params string[] args)
|
||||
where T : Exception
|
||||
catch (Exception ex)
|
||||
{
|
||||
var console = new TestConsole().Width(int.MaxValue);
|
||||
|
||||
try
|
||||
{
|
||||
Run(args, console, c => c.PropagateExceptions());
|
||||
throw new InvalidOperationException("Expected an exception to be thrown, but there was none.");
|
||||
}
|
||||
catch (T ex)
|
||||
{
|
||||
if (ex is CommandAppException commandAppException && commandAppException.Pretty != null)
|
||||
{
|
||||
console.Write(commandAppException.Pretty);
|
||||
}
|
||||
else
|
||||
{
|
||||
console.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
return new CommandAppFailure(ex, console.Output);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Expected an exception of type '{typeof(T).FullName}' to be thrown, "
|
||||
+ $"but received {ex.GetType().FullName}.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the command application.
|
||||
/// </summary>
|
||||
/// <param name="args">The arguments.</param>
|
||||
/// <returns>The result.</returns>
|
||||
public CommandAppResult Run(params string[] args)
|
||||
{
|
||||
var console = new TestConsole().Width(int.MaxValue);
|
||||
return Run(args, console);
|
||||
}
|
||||
|
||||
private CommandAppResult Run(string[] args, TestConsole console, Action<IConfigurator>? config = null)
|
||||
{
|
||||
CommandContext? context = null;
|
||||
CommandSettings? settings = null;
|
||||
|
||||
var app = new CommandApp(Registrar);
|
||||
_appConfiguration?.Invoke(app);
|
||||
|
||||
if (_configuration != null)
|
||||
{
|
||||
app.Configure(_configuration);
|
||||
}
|
||||
|
||||
if (config != null)
|
||||
{
|
||||
app.Configure(config);
|
||||
}
|
||||
|
||||
app.Configure(c => c.ConfigureConsole(console));
|
||||
app.Configure(c => c.SetInterceptor(new CallbackCommandInterceptor((ctx, s) =>
|
||||
{
|
||||
context = ctx;
|
||||
settings = s;
|
||||
})));
|
||||
|
||||
var result = app.Run(args);
|
||||
|
||||
var output = console.Output
|
||||
.NormalizeLineEndings()
|
||||
.TrimLines()
|
||||
.Trim();
|
||||
|
||||
return new CommandAppResult(result, output, context, settings);
|
||||
throw new InvalidOperationException(
|
||||
$"Expected an exception of type '{typeof(T).FullName}' to be thrown, "
|
||||
+ $"but received {ex.GetType().FullName}.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the command application.
|
||||
/// </summary>
|
||||
/// <param name="args">The arguments.</param>
|
||||
/// <returns>The result.</returns>
|
||||
public CommandAppResult Run(params string[] args)
|
||||
{
|
||||
var console = new TestConsole().Width(int.MaxValue);
|
||||
return Run(args, console);
|
||||
}
|
||||
|
||||
private CommandAppResult Run(string[] args, TestConsole console, Action<IConfigurator>? config = null)
|
||||
{
|
||||
CommandContext? context = null;
|
||||
CommandSettings? settings = null;
|
||||
|
||||
var app = new CommandApp(Registrar);
|
||||
_appConfiguration?.Invoke(app);
|
||||
|
||||
if (_configuration != null)
|
||||
{
|
||||
app.Configure(_configuration);
|
||||
}
|
||||
|
||||
if (config != null)
|
||||
{
|
||||
app.Configure(config);
|
||||
}
|
||||
|
||||
app.Configure(c => c.ConfigureConsole(console));
|
||||
app.Configure(c => c.SetInterceptor(new CallbackCommandInterceptor((ctx, s) =>
|
||||
{
|
||||
context = ctx;
|
||||
settings = s;
|
||||
})));
|
||||
|
||||
var result = app.Run(args);
|
||||
|
||||
var output = console.Output
|
||||
.NormalizeLineEndings()
|
||||
.TrimLines()
|
||||
.Trim();
|
||||
|
||||
return new CommandAppResult(result, output, context, settings);
|
||||
}
|
||||
}
|
||||
|
@ -1,191 +1,190 @@
|
||||
using System;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Testing
|
||||
namespace Spectre.Console.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// This is a utility class for implementors of
|
||||
/// <see cref="ITypeRegistrar"/> and corresponding <see cref="ITypeResolver"/>.
|
||||
/// </summary>
|
||||
public sealed class TypeRegistrarBaseTests
|
||||
{
|
||||
private readonly Func<ITypeRegistrar> _registrarFactory;
|
||||
|
||||
/// <summary>
|
||||
/// This is a utility class for implementors of
|
||||
/// <see cref="ITypeRegistrar"/> and corresponding <see cref="ITypeResolver"/>.
|
||||
/// Initializes a new instance of the <see cref="TypeRegistrarBaseTests"/> class.
|
||||
/// </summary>
|
||||
public sealed class TypeRegistrarBaseTests
|
||||
/// <param name="registrarFactory">The factory to create a new, clean <see cref="ITypeRegistrar"/> to be used for each test.</param>
|
||||
public TypeRegistrarBaseTests(Func<ITypeRegistrar> registrarFactory)
|
||||
{
|
||||
private readonly Func<ITypeRegistrar> _registrarFactory;
|
||||
_registrarFactory = registrarFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TypeRegistrarBaseTests"/> class.
|
||||
/// </summary>
|
||||
/// <param name="registrarFactory">The factory to create a new, clean <see cref="ITypeRegistrar"/> to be used for each test.</param>
|
||||
public TypeRegistrarBaseTests(Func<ITypeRegistrar> registrarFactory)
|
||||
/// <summary>
|
||||
/// Runs all tests.
|
||||
/// </summary>
|
||||
/// <exception cref="TestFailedException">This exception is raised, if a test fails.</exception>
|
||||
public void RunAllTests()
|
||||
{
|
||||
var testCases = new Action<ITypeRegistrar>[]
|
||||
{
|
||||
_registrarFactory = registrarFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs all tests.
|
||||
/// </summary>
|
||||
/// <exception cref="TestFailedException">This exception is raised, if a test fails.</exception>
|
||||
public void RunAllTests()
|
||||
{
|
||||
var testCases = new Action<ITypeRegistrar>[]
|
||||
{
|
||||
RegistrationsCanBeResolved,
|
||||
InstanceRegistrationsCanBeResolved,
|
||||
LazyRegistrationsCanBeResolved,
|
||||
ResolvingNotRegisteredServiceReturnsNull,
|
||||
ResolvingNullTypeReturnsNull,
|
||||
};
|
||||
};
|
||||
|
||||
foreach (var test in testCases)
|
||||
{
|
||||
test(_registrarFactory());
|
||||
}
|
||||
}
|
||||
|
||||
private static void ResolvingNullTypeReturnsNull(ITypeRegistrar registrar)
|
||||
foreach (var test in testCases)
|
||||
{
|
||||
// Given no registration
|
||||
var resolver = registrar.Build();
|
||||
|
||||
try
|
||||
{
|
||||
// When
|
||||
var actual = resolver.Resolve(null);
|
||||
|
||||
// Then
|
||||
if (actual != null)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
$"Expected the resolver to resolve null, since null was requested as the service type. Actually resolved {actual.GetType().Name}.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
$"Expected the resolver not to throw, but caught {ex.GetType().Name}.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ResolvingNotRegisteredServiceReturnsNull(ITypeRegistrar registrar)
|
||||
{
|
||||
// Given no registration
|
||||
var resolver = registrar.Build();
|
||||
|
||||
try
|
||||
{
|
||||
// When
|
||||
var actual = resolver.Resolve(typeof(IMockService));
|
||||
|
||||
// Then
|
||||
if (actual != null)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
$"Expected the resolver to resolve null, since no service was registered. Actually resolved {actual.GetType().Name}.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
$"Expected the resolver not to throw, but caught {ex.GetType().Name}.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegistrationsCanBeResolved(ITypeRegistrar registrar)
|
||||
{
|
||||
// Given
|
||||
registrar.Register(typeof(IMockService), typeof(MockService));
|
||||
var resolver = registrar.Build();
|
||||
|
||||
// When
|
||||
var actual = resolver.Resolve(typeof(IMockService));
|
||||
|
||||
// Then
|
||||
if (actual == null)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
$"Expected the resolver to resolve an instance of {nameof(MockService)}. Actually resolved null.");
|
||||
}
|
||||
|
||||
if (actual is not MockService)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
$"Expected the resolver to resolve an instance of {nameof(MockService)}. Actually resolved {actual.GetType().Name}.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void InstanceRegistrationsCanBeResolved(ITypeRegistrar registrar)
|
||||
{
|
||||
// Given
|
||||
var instance = new MockService();
|
||||
registrar.RegisterInstance(typeof(IMockService), instance);
|
||||
var resolver = registrar.Build();
|
||||
|
||||
// When
|
||||
var actual = resolver.Resolve(typeof(IMockService));
|
||||
|
||||
// Then
|
||||
if (!ReferenceEquals(actual, instance))
|
||||
{
|
||||
throw new TestFailedException(
|
||||
"Expected the resolver to resolve exactly the registered instance.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void LazyRegistrationsCanBeResolved(ITypeRegistrar registrar)
|
||||
{
|
||||
// Given
|
||||
var instance = new MockService();
|
||||
var factoryCalled = false;
|
||||
registrar.RegisterLazy(typeof(IMockService), () =>
|
||||
{
|
||||
factoryCalled = true;
|
||||
return instance;
|
||||
});
|
||||
var resolver = registrar.Build();
|
||||
|
||||
// When
|
||||
var actual = resolver.Resolve(typeof(IMockService));
|
||||
|
||||
// Then
|
||||
if (!factoryCalled)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
"Expected the factory to be called, to resolve the lazy registration.");
|
||||
}
|
||||
|
||||
if (!ReferenceEquals(actual, instance))
|
||||
{
|
||||
throw new TestFailedException(
|
||||
"Expected the resolver to return exactly the result of the lazy-registered factory.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// internal use only.
|
||||
/// </summary>
|
||||
private interface IMockService
|
||||
{
|
||||
}
|
||||
|
||||
private class MockService : IMockService
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exception, to be raised when a test fails.
|
||||
/// </summary>
|
||||
public sealed class TestFailedException : Exception
|
||||
{
|
||||
/// <inheritdoc cref="Exception" />
|
||||
public TestFailedException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Exception" />
|
||||
public TestFailedException(string message, Exception inner)
|
||||
: base(message, inner)
|
||||
{
|
||||
}
|
||||
test(_registrarFactory());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ResolvingNullTypeReturnsNull(ITypeRegistrar registrar)
|
||||
{
|
||||
// Given no registration
|
||||
var resolver = registrar.Build();
|
||||
|
||||
try
|
||||
{
|
||||
// When
|
||||
var actual = resolver.Resolve(null);
|
||||
|
||||
// Then
|
||||
if (actual != null)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
$"Expected the resolver to resolve null, since null was requested as the service type. Actually resolved {actual.GetType().Name}.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
$"Expected the resolver not to throw, but caught {ex.GetType().Name}.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ResolvingNotRegisteredServiceReturnsNull(ITypeRegistrar registrar)
|
||||
{
|
||||
// Given no registration
|
||||
var resolver = registrar.Build();
|
||||
|
||||
try
|
||||
{
|
||||
// When
|
||||
var actual = resolver.Resolve(typeof(IMockService));
|
||||
|
||||
// Then
|
||||
if (actual != null)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
$"Expected the resolver to resolve null, since no service was registered. Actually resolved {actual.GetType().Name}.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
$"Expected the resolver not to throw, but caught {ex.GetType().Name}.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegistrationsCanBeResolved(ITypeRegistrar registrar)
|
||||
{
|
||||
// Given
|
||||
registrar.Register(typeof(IMockService), typeof(MockService));
|
||||
var resolver = registrar.Build();
|
||||
|
||||
// When
|
||||
var actual = resolver.Resolve(typeof(IMockService));
|
||||
|
||||
// Then
|
||||
if (actual == null)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
$"Expected the resolver to resolve an instance of {nameof(MockService)}. Actually resolved null.");
|
||||
}
|
||||
|
||||
if (actual is not MockService)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
$"Expected the resolver to resolve an instance of {nameof(MockService)}. Actually resolved {actual.GetType().Name}.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void InstanceRegistrationsCanBeResolved(ITypeRegistrar registrar)
|
||||
{
|
||||
// Given
|
||||
var instance = new MockService();
|
||||
registrar.RegisterInstance(typeof(IMockService), instance);
|
||||
var resolver = registrar.Build();
|
||||
|
||||
// When
|
||||
var actual = resolver.Resolve(typeof(IMockService));
|
||||
|
||||
// Then
|
||||
if (!ReferenceEquals(actual, instance))
|
||||
{
|
||||
throw new TestFailedException(
|
||||
"Expected the resolver to resolve exactly the registered instance.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void LazyRegistrationsCanBeResolved(ITypeRegistrar registrar)
|
||||
{
|
||||
// Given
|
||||
var instance = new MockService();
|
||||
var factoryCalled = false;
|
||||
registrar.RegisterLazy(typeof(IMockService), () =>
|
||||
{
|
||||
factoryCalled = true;
|
||||
return instance;
|
||||
});
|
||||
var resolver = registrar.Build();
|
||||
|
||||
// When
|
||||
var actual = resolver.Resolve(typeof(IMockService));
|
||||
|
||||
// Then
|
||||
if (!factoryCalled)
|
||||
{
|
||||
throw new TestFailedException(
|
||||
"Expected the factory to be called, to resolve the lazy registration.");
|
||||
}
|
||||
|
||||
if (!ReferenceEquals(actual, instance))
|
||||
{
|
||||
throw new TestFailedException(
|
||||
"Expected the resolver to return exactly the result of the lazy-registered factory.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// internal use only.
|
||||
/// </summary>
|
||||
private interface IMockService
|
||||
{
|
||||
}
|
||||
|
||||
private class MockService : IMockService
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exception, to be raised when a test fails.
|
||||
/// </summary>
|
||||
public sealed class TestFailedException : Exception
|
||||
{
|
||||
/// <inheritdoc cref="Exception" />
|
||||
public TestFailedException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Exception" />
|
||||
public TestFailedException(string message, Exception inner)
|
||||
: base(message, inner)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,47 +1,46 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console.Testing
|
||||
namespace Spectre.Console.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// Contains extensions for <see cref="string"/>.
|
||||
/// </summary>
|
||||
public static class StringExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extensions for <see cref="string"/>.
|
||||
/// Returns a new string with all lines trimmed of trailing whitespace.
|
||||
/// </summary>
|
||||
public static class StringExtensions
|
||||
/// <param name="value">The string to trim.</param>
|
||||
/// <returns>A new string with all lines trimmed of trailing whitespace.</returns>
|
||||
public static string TrimLines(this string value)
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a new string with all lines trimmed of trailing whitespace.
|
||||
/// </summary>
|
||||
/// <param name="value">The string to trim.</param>
|
||||
/// <returns>A new string with all lines trimmed of trailing whitespace.</returns>
|
||||
public static string TrimLines(this string value)
|
||||
if (value is null)
|
||||
{
|
||||
if (value is null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var result = new List<string>();
|
||||
foreach (var line in value.NormalizeLineEndings().Split(new[] { '\n' }))
|
||||
{
|
||||
result.Add(line.TrimEnd());
|
||||
}
|
||||
|
||||
return string.Join("\n", result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new string with normalized line endings.
|
||||
/// </summary>
|
||||
/// <param name="value">The string to normalize line endings for.</param>
|
||||
/// <returns>A new string with normalized line endings.</returns>
|
||||
public static string NormalizeLineEndings(this string value)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
value = value.Replace("\r\n", "\n");
|
||||
return value.Replace("\r", string.Empty);
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var result = new List<string>();
|
||||
foreach (var line in value.NormalizeLineEndings().Split(new[] { '\n' }))
|
||||
{
|
||||
result.Add(line.TrimEnd());
|
||||
}
|
||||
|
||||
return string.Join("\n", result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new string with normalized line endings.
|
||||
/// </summary>
|
||||
/// <param name="value">The string to normalize line endings for.</param>
|
||||
/// <returns>A new string with normalized line endings.</returns>
|
||||
public static string NormalizeLineEndings(this string value)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
value = value.Replace("\r\n", "\n");
|
||||
return value.Replace("\r", string.Empty);
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,24 @@
|
||||
namespace Spectre.Console.Testing
|
||||
namespace Spectre.Console.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// Contains extensions for <see cref="Style"/>.
|
||||
/// </summary>
|
||||
public static class StyleExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extensions for <see cref="Style"/>.
|
||||
/// Sets the foreground or background color of the specified style.
|
||||
/// </summary>
|
||||
public static class StyleExtensions
|
||||
/// <param name="style">The style.</param>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <param name="foreground">Whether or not to set the foreground color.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static Style SetColor(this Style style, Color color, bool foreground)
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the foreground or background color of the specified style.
|
||||
/// </summary>
|
||||
/// <param name="style">The style.</param>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <param name="foreground">Whether or not to set the foreground color.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static Style SetColor(this Style style, Color color, bool foreground)
|
||||
if (foreground)
|
||||
{
|
||||
if (foreground)
|
||||
{
|
||||
return style.Foreground(color);
|
||||
}
|
||||
|
||||
return style.Background(color);
|
||||
return style.Foreground(color);
|
||||
}
|
||||
|
||||
return style.Background(color);
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,16 @@
|
||||
namespace Spectre.Console.Testing
|
||||
namespace Spectre.Console.Testing;
|
||||
|
||||
internal sealed class NoopCursor : IAnsiConsoleCursor
|
||||
{
|
||||
internal sealed class NoopCursor : IAnsiConsoleCursor
|
||||
public void Move(CursorDirection direction, int steps)
|
||||
{
|
||||
public void Move(CursorDirection direction, int steps)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPosition(int column, int line)
|
||||
{
|
||||
}
|
||||
public void SetPosition(int column, int line)
|
||||
{
|
||||
}
|
||||
|
||||
public void Show(bool show)
|
||||
{
|
||||
}
|
||||
public void Show(bool show)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,17 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spectre.Console.Testing
|
||||
{
|
||||
internal sealed class NoopExclusivityMode : IExclusivityMode
|
||||
{
|
||||
public T Run<T>(Func<T> func)
|
||||
{
|
||||
return func();
|
||||
}
|
||||
namespace Spectre.Console.Testing;
|
||||
|
||||
public async Task<T> RunAsync<T>(Func<Task<T>> func)
|
||||
{
|
||||
return await func().ConfigureAwait(false);
|
||||
}
|
||||
internal sealed class NoopExclusivityMode : IExclusivityMode
|
||||
{
|
||||
public T Run<T>(Func<T> func)
|
||||
{
|
||||
return func();
|
||||
}
|
||||
|
||||
public async Task<T> RunAsync<T>(Func<Task<T>> func)
|
||||
{
|
||||
return await func().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
@ -1,40 +1,39 @@
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Testing
|
||||
namespace Spectre.Console.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// Represents fake capabilities useful in tests.
|
||||
/// </summary>
|
||||
public sealed class TestCapabilities : IReadOnlyCapabilities
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public ColorSystem ColorSystem { get; set; } = ColorSystem.TrueColor;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ansi { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Links { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Legacy { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsTerminal { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Interactive { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Unicode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents fake capabilities useful in tests.
|
||||
/// Creates a <see cref="RenderContext"/> with the same capabilities as this instace.
|
||||
/// </summary>
|
||||
public sealed class TestCapabilities : IReadOnlyCapabilities
|
||||
/// <returns>A <see cref="RenderContext"/> with the same capabilities as this instace.</returns>
|
||||
public RenderContext CreateRenderContext()
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public ColorSystem ColorSystem { get; set; } = ColorSystem.TrueColor;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Ansi { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Links { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Legacy { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsTerminal { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Interactive { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Unicode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="RenderContext"/> with the same capabilities as this instace.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="RenderContext"/> with the same capabilities as this instace.</returns>
|
||||
public RenderContext CreateRenderContext()
|
||||
{
|
||||
return new RenderContext(this);
|
||||
}
|
||||
return new RenderContext(this);
|
||||
}
|
||||
}
|
||||
|
@ -3,120 +3,119 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Testing
|
||||
namespace Spectre.Console.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// A testable console.
|
||||
/// </summary>
|
||||
public sealed class TestConsole : IAnsiConsole, IDisposable
|
||||
{
|
||||
private readonly IAnsiConsole _console;
|
||||
private readonly StringWriter _writer;
|
||||
private IAnsiConsoleCursor? _cursor;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Profile Profile => _console.Profile;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IExclusivityMode ExclusivityMode => _console.ExclusivityMode;
|
||||
|
||||
/// <summary>
|
||||
/// A testable console.
|
||||
/// Gets the console input.
|
||||
/// </summary>
|
||||
public sealed class TestConsole : IAnsiConsole, IDisposable
|
||||
public TestConsoleInput Input { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RenderPipeline Pipeline => _console.Pipeline;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAnsiConsoleCursor Cursor => _cursor ?? _console.Cursor;
|
||||
|
||||
/// <inheritdoc/>
|
||||
IAnsiConsoleInput IAnsiConsole.Input => Input;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the console output.
|
||||
/// </summary>
|
||||
public string Output => _writer.ToString();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the console output lines.
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> Lines => Output.NormalizeLineEndings().TrimEnd('\n').Split(new char[] { '\n' });
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not VT/ANSI sequences
|
||||
/// should be emitted to the console.
|
||||
/// </summary>
|
||||
public bool EmitAnsiSequences { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TestConsole"/> class.
|
||||
/// </summary>
|
||||
public TestConsole()
|
||||
{
|
||||
private readonly IAnsiConsole _console;
|
||||
private readonly StringWriter _writer;
|
||||
private IAnsiConsoleCursor? _cursor;
|
||||
_writer = new StringWriter();
|
||||
_cursor = new NoopCursor();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Profile Profile => _console.Profile;
|
||||
Input = new TestConsoleInput();
|
||||
EmitAnsiSequences = false;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IExclusivityMode ExclusivityMode => _console.ExclusivityMode;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the console input.
|
||||
/// </summary>
|
||||
public TestConsoleInput Input { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RenderPipeline Pipeline => _console.Pipeline;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAnsiConsoleCursor Cursor => _cursor ?? _console.Cursor;
|
||||
|
||||
/// <inheritdoc/>
|
||||
IAnsiConsoleInput IAnsiConsole.Input => Input;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the console output.
|
||||
/// </summary>
|
||||
public string Output => _writer.ToString();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the console output lines.
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> Lines => Output.NormalizeLineEndings().TrimEnd('\n').Split(new char[] { '\n' });
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not VT/ANSI sequences
|
||||
/// should be emitted to the console.
|
||||
/// </summary>
|
||||
public bool EmitAnsiSequences { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TestConsole"/> class.
|
||||
/// </summary>
|
||||
public TestConsole()
|
||||
var factory = new AnsiConsoleFactory();
|
||||
_console = factory.Create(new AnsiConsoleSettings
|
||||
{
|
||||
_writer = new StringWriter();
|
||||
_cursor = new NoopCursor();
|
||||
|
||||
Input = new TestConsoleInput();
|
||||
EmitAnsiSequences = false;
|
||||
|
||||
var factory = new AnsiConsoleFactory();
|
||||
_console = factory.Create(new AnsiConsoleSettings
|
||||
Ansi = AnsiSupport.Yes,
|
||||
ColorSystem = (ColorSystemSupport)ColorSystem.TrueColor,
|
||||
Out = new AnsiConsoleOutput(_writer),
|
||||
Interactive = InteractionSupport.No,
|
||||
ExclusivityMode = new NoopExclusivityMode(),
|
||||
Enrichment = new ProfileEnrichment
|
||||
{
|
||||
Ansi = AnsiSupport.Yes,
|
||||
ColorSystem = (ColorSystemSupport)ColorSystem.TrueColor,
|
||||
Out = new AnsiConsoleOutput(_writer),
|
||||
Interactive = InteractionSupport.No,
|
||||
ExclusivityMode = new NoopExclusivityMode(),
|
||||
Enrichment = new ProfileEnrichment
|
||||
UseDefaultEnrichers = false,
|
||||
},
|
||||
});
|
||||
|
||||
_console.Profile.Width = 80;
|
||||
_console.Profile.Height = 24;
|
||||
_console.Profile.Capabilities.Ansi = true;
|
||||
_console.Profile.Capabilities.Unicode = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
_writer.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Clear(bool home)
|
||||
{
|
||||
_console.Clear(home);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Write(IRenderable renderable)
|
||||
{
|
||||
if (EmitAnsiSequences)
|
||||
{
|
||||
_console.Write(renderable);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var segment in renderable.GetSegments(this))
|
||||
{
|
||||
if (segment.IsControlCode)
|
||||
{
|
||||
UseDefaultEnrichers = false,
|
||||
},
|
||||
});
|
||||
|
||||
_console.Profile.Width = 80;
|
||||
_console.Profile.Height = 24;
|
||||
_console.Profile.Capabilities.Ansi = true;
|
||||
_console.Profile.Capabilities.Unicode = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
_writer.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Clear(bool home)
|
||||
{
|
||||
_console.Clear(home);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Write(IRenderable renderable)
|
||||
{
|
||||
if (EmitAnsiSequences)
|
||||
{
|
||||
_console.Write(renderable);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var segment in renderable.GetSegments(this))
|
||||
{
|
||||
if (segment.IsControlCode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Profile.Out.Writer.Write(segment.Text);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetCursor(IAnsiConsoleCursor? cursor)
|
||||
{
|
||||
_cursor = cursor;
|
||||
Profile.Out.Writer.Write(segment.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetCursor(IAnsiConsoleCursor? cursor)
|
||||
{
|
||||
_cursor = cursor;
|
||||
}
|
||||
}
|
||||
|
@ -1,67 +1,66 @@
|
||||
namespace Spectre.Console.Testing
|
||||
namespace Spectre.Console.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// Contains extensions for <see cref="TestConsole"/>.
|
||||
/// </summary>
|
||||
public static class TestConsoleExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extensions for <see cref="TestConsole"/>.
|
||||
/// Sets the console's color system.
|
||||
/// </summary>
|
||||
public static class TestConsoleExtensions
|
||||
/// <param name="console">The console.</param>
|
||||
/// <param name="colors">The color system to use.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static TestConsole Colors(this TestConsole console, ColorSystem colors)
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the console's color system.
|
||||
/// </summary>
|
||||
/// <param name="console">The console.</param>
|
||||
/// <param name="colors">The color system to use.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static TestConsole Colors(this TestConsole console, ColorSystem colors)
|
||||
{
|
||||
console.Profile.Capabilities.ColorSystem = colors;
|
||||
return console;
|
||||
}
|
||||
console.Profile.Capabilities.ColorSystem = colors;
|
||||
return console;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets whether or not ANSI is supported.
|
||||
/// </summary>
|
||||
/// <param name="console">The console.</param>
|
||||
/// <param name="enable">Whether or not VT/ANSI control codes are supported.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static TestConsole SupportsAnsi(this TestConsole console, bool enable)
|
||||
{
|
||||
console.Profile.Capabilities.Ansi = enable;
|
||||
return console;
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets whether or not ANSI is supported.
|
||||
/// </summary>
|
||||
/// <param name="console">The console.</param>
|
||||
/// <param name="enable">Whether or not VT/ANSI control codes are supported.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static TestConsole SupportsAnsi(this TestConsole console, bool enable)
|
||||
{
|
||||
console.Profile.Capabilities.Ansi = enable;
|
||||
return console;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes the console interactive.
|
||||
/// </summary>
|
||||
/// <param name="console">The console.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static TestConsole Interactive(this TestConsole console)
|
||||
{
|
||||
console.Profile.Capabilities.Interactive = true;
|
||||
return console;
|
||||
}
|
||||
/// <summary>
|
||||
/// Makes the console interactive.
|
||||
/// </summary>
|
||||
/// <param name="console">The console.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static TestConsole Interactive(this TestConsole console)
|
||||
{
|
||||
console.Profile.Capabilities.Interactive = true;
|
||||
return console;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the console width.
|
||||
/// </summary>
|
||||
/// <param name="console">The console.</param>
|
||||
/// <param name="width">The console width.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static TestConsole Width(this TestConsole console, int width)
|
||||
{
|
||||
console.Profile.Width = width;
|
||||
return console;
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets the console width.
|
||||
/// </summary>
|
||||
/// <param name="console">The console.</param>
|
||||
/// <param name="width">The console width.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static TestConsole Width(this TestConsole console, int width)
|
||||
{
|
||||
console.Profile.Width = width;
|
||||
return console;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turns on emitting of VT/ANSI sequences.
|
||||
/// </summary>
|
||||
/// <param name="console">The console.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static TestConsole EmitAnsiSequences(this TestConsole console)
|
||||
{
|
||||
console.SetCursor(null);
|
||||
console.EmitAnsiSequences = true;
|
||||
return console;
|
||||
}
|
||||
/// <summary>
|
||||
/// Turns on emitting of VT/ANSI sequences.
|
||||
/// </summary>
|
||||
/// <param name="console">The console.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static TestConsole EmitAnsiSequences(this TestConsole console)
|
||||
{
|
||||
console.SetCursor(null);
|
||||
console.EmitAnsiSequences = true;
|
||||
return console;
|
||||
}
|
||||
}
|
||||
|
@ -3,90 +3,89 @@ using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spectre.Console.Testing
|
||||
namespace Spectre.Console.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a testable console input mechanism.
|
||||
/// </summary>
|
||||
public sealed class TestConsoleInput : IAnsiConsoleInput
|
||||
{
|
||||
private readonly Queue<ConsoleKeyInfo> _input;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a testable console input mechanism.
|
||||
/// Initializes a new instance of the <see cref="TestConsoleInput"/> class.
|
||||
/// </summary>
|
||||
public sealed class TestConsoleInput : IAnsiConsoleInput
|
||||
public TestConsoleInput()
|
||||
{
|
||||
private readonly Queue<ConsoleKeyInfo> _input;
|
||||
_input = new Queue<ConsoleKeyInfo>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TestConsoleInput"/> class.
|
||||
/// </summary>
|
||||
public TestConsoleInput()
|
||||
/// <summary>
|
||||
/// Pushes the specified text to the input queue.
|
||||
/// </summary>
|
||||
/// <param name="input">The input string.</param>
|
||||
public void PushText(string input)
|
||||
{
|
||||
if (input is null)
|
||||
{
|
||||
_input = new Queue<ConsoleKeyInfo>();
|
||||
throw new ArgumentNullException(nameof(input));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pushes the specified text to the input queue.
|
||||
/// </summary>
|
||||
/// <param name="input">The input string.</param>
|
||||
public void PushText(string input)
|
||||
foreach (var character in input)
|
||||
{
|
||||
if (input is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(input));
|
||||
}
|
||||
|
||||
foreach (var character in input)
|
||||
{
|
||||
PushCharacter(character);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pushes the specified text followed by 'Enter' to the input queue.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
public void PushTextWithEnter(string input)
|
||||
{
|
||||
PushText(input);
|
||||
PushKey(ConsoleKey.Enter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pushes the specified character to the input queue.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
public void PushCharacter(char input)
|
||||
{
|
||||
var control = char.IsUpper(input);
|
||||
_input.Enqueue(new ConsoleKeyInfo(input, (ConsoleKey)input, false, false, control));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pushes the specified key to the input queue.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
public void PushKey(ConsoleKey input)
|
||||
{
|
||||
_input.Enqueue(new ConsoleKeyInfo((char)input, input, false, false, false));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsKeyAvailable()
|
||||
{
|
||||
return _input.Count > 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConsoleKeyInfo? ReadKey(bool intercept)
|
||||
{
|
||||
if (_input.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("No input available.");
|
||||
}
|
||||
|
||||
return _input.Dequeue();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<ConsoleKeyInfo?> ReadKeyAsync(bool intercept, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(ReadKey(intercept));
|
||||
PushCharacter(character);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pushes the specified text followed by 'Enter' to the input queue.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
public void PushTextWithEnter(string input)
|
||||
{
|
||||
PushText(input);
|
||||
PushKey(ConsoleKey.Enter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pushes the specified character to the input queue.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
public void PushCharacter(char input)
|
||||
{
|
||||
var control = char.IsUpper(input);
|
||||
_input.Enqueue(new ConsoleKeyInfo(input, (ConsoleKey)input, false, false, control));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pushes the specified key to the input queue.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
public void PushKey(ConsoleKey input)
|
||||
{
|
||||
_input.Enqueue(new ConsoleKeyInfo((char)input, input, false, false, false));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsKeyAvailable()
|
||||
{
|
||||
return _input.Count > 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ConsoleKeyInfo? ReadKey(bool intercept)
|
||||
{
|
||||
if (_input.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("No input available.");
|
||||
}
|
||||
|
||||
return _input.Dequeue();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task<ConsoleKeyInfo?> ReadKeyAsync(bool intercept, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(ReadKey(intercept));
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,29 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// Writes an exception to the console.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
/// <param name="exception">The exception to write to the console.</param>
|
||||
/// <param name="format">The exception format options.</param>
|
||||
public static void WriteException(Exception exception, ExceptionFormats format = ExceptionFormats.Default)
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes an exception to the console.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to write to the console.</param>
|
||||
/// <param name="format">The exception format options.</param>
|
||||
public static void WriteException(Exception exception, ExceptionFormats format = ExceptionFormats.Default)
|
||||
{
|
||||
Console.WriteException(exception, format);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an exception to the console.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to write to the console.</param>
|
||||
/// <param name="settings">The exception settings.</param>
|
||||
public static void WriteException(Exception exception, ExceptionSettings settings)
|
||||
{
|
||||
Console.WriteException(exception, settings);
|
||||
}
|
||||
Console.WriteException(exception, format);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an exception to the console.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to write to the console.</param>
|
||||
/// <param name="settings">The exception settings.</param>
|
||||
public static void WriteException(Exception exception, ExceptionSettings settings)
|
||||
{
|
||||
Console.WriteException(exception, settings);
|
||||
}
|
||||
}
|
@ -1,20 +1,19 @@
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// Creates a new <see cref="LiveDisplay"/> instance.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
/// <param name="target">The target renderable to update.</param>
|
||||
/// <returns>A <see cref="LiveDisplay"/> instance.</returns>
|
||||
public static LiveDisplay Live(IRenderable target)
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="LiveDisplay"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="target">The target renderable to update.</param>
|
||||
/// <returns>A <see cref="LiveDisplay"/> instance.</returns>
|
||||
public static LiveDisplay Live(IRenderable target)
|
||||
{
|
||||
return Console.Live(target);
|
||||
}
|
||||
return Console.Live(target);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,70 +1,69 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// Writes the specified markup to the console.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Markup(string value)
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes the specified markup to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Markup(string value)
|
||||
{
|
||||
Console.Markup(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified markup to the console.
|
||||
/// </summary>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void Markup(string format, params object[] args)
|
||||
{
|
||||
Console.Markup(format, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified markup to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void Markup(IFormatProvider provider, string format, params object[] args)
|
||||
{
|
||||
Console.Markup(provider, format, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified markup, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void MarkupLine(string value)
|
||||
{
|
||||
Console.MarkupLine(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified markup, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void MarkupLine(string format, params object[] args)
|
||||
{
|
||||
Console.MarkupLine(format, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified markup, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void MarkupLine(IFormatProvider provider, string format, params object[] args)
|
||||
{
|
||||
Console.MarkupLine(provider, format, args);
|
||||
}
|
||||
Console.Markup(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified markup to the console.
|
||||
/// </summary>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void Markup(string format, params object[] args)
|
||||
{
|
||||
Console.Markup(format, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified markup to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void Markup(IFormatProvider provider, string format, params object[] args)
|
||||
{
|
||||
Console.Markup(provider, format, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified markup, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void MarkupLine(string value)
|
||||
{
|
||||
Console.MarkupLine(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified markup, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void MarkupLine(string format, params object[] args)
|
||||
{
|
||||
Console.MarkupLine(format, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified markup, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void MarkupLine(IFormatProvider provider, string format, params object[] args)
|
||||
{
|
||||
Console.MarkupLine(provider, format, args);
|
||||
}
|
||||
}
|
@ -1,26 +1,25 @@
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// Creates a new <see cref="Progress"/> instance.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
/// <returns>A <see cref="Progress"/> instance.</returns>
|
||||
public static Progress Progress()
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Progress"/> instance.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="Progress"/> instance.</returns>
|
||||
public static Progress Progress()
|
||||
{
|
||||
return Console.Progress();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Status"/> instance.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="Status"/> instance.</returns>
|
||||
public static Status Status()
|
||||
{
|
||||
return Console.Status();
|
||||
}
|
||||
return Console.Progress();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Status"/> instance.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="Status"/> instance.</returns>
|
||||
public static Status Status()
|
||||
{
|
||||
return Console.Status();
|
||||
}
|
||||
}
|
@ -1,66 +1,65 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// Displays a prompt to the user.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
/// <typeparam name="T">The prompt result type.</typeparam>
|
||||
/// <param name="prompt">The prompt to display.</param>
|
||||
/// <returns>The prompt input result.</returns>
|
||||
public static T Prompt<T>(IPrompt<T> prompt)
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays a prompt to the user.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The prompt result type.</typeparam>
|
||||
/// <param name="prompt">The prompt to display.</param>
|
||||
/// <returns>The prompt input result.</returns>
|
||||
public static T Prompt<T>(IPrompt<T> prompt)
|
||||
if (prompt is null)
|
||||
{
|
||||
if (prompt is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(prompt));
|
||||
}
|
||||
|
||||
return prompt.Show(Console);
|
||||
throw new ArgumentNullException(nameof(prompt));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a prompt to the user.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The prompt result type.</typeparam>
|
||||
/// <param name="prompt">The prompt markup text.</param>
|
||||
/// <returns>The prompt input result.</returns>
|
||||
public static T Ask<T>(string prompt)
|
||||
{
|
||||
return new TextPrompt<T>(prompt).Show(Console);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a prompt to the user with a given default.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The prompt result type.</typeparam>
|
||||
/// <param name="prompt">The prompt markup text.</param>
|
||||
/// <param name="defaultValue">The default value.</param>
|
||||
/// <returns>The prompt input result.</returns>
|
||||
public static T Ask<T>(string prompt, T defaultValue)
|
||||
{
|
||||
return new TextPrompt<T>(prompt)
|
||||
.DefaultValue(defaultValue)
|
||||
.Show(Console);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a prompt with two choices, yes or no.
|
||||
/// </summary>
|
||||
/// <param name="prompt">The prompt markup text.</param>
|
||||
/// <param name="defaultValue">Specifies the default answer.</param>
|
||||
/// <returns><c>true</c> if the user selected "yes", otherwise <c>false</c>.</returns>
|
||||
public static bool Confirm(string prompt, bool defaultValue = true)
|
||||
{
|
||||
return new ConfirmationPrompt(prompt)
|
||||
{
|
||||
DefaultValue = defaultValue,
|
||||
}
|
||||
.Show(Console);
|
||||
}
|
||||
return prompt.Show(Console);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a prompt to the user.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The prompt result type.</typeparam>
|
||||
/// <param name="prompt">The prompt markup text.</param>
|
||||
/// <returns>The prompt input result.</returns>
|
||||
public static T Ask<T>(string prompt)
|
||||
{
|
||||
return new TextPrompt<T>(prompt).Show(Console);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a prompt to the user with a given default.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The prompt result type.</typeparam>
|
||||
/// <param name="prompt">The prompt markup text.</param>
|
||||
/// <param name="defaultValue">The default value.</param>
|
||||
/// <returns>The prompt input result.</returns>
|
||||
public static T Ask<T>(string prompt, T defaultValue)
|
||||
{
|
||||
return new TextPrompt<T>(prompt)
|
||||
.DefaultValue(defaultValue)
|
||||
.Show(Console);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a prompt with two choices, yes or no.
|
||||
/// </summary>
|
||||
/// <param name="prompt">The prompt markup text.</param>
|
||||
/// <param name="defaultValue">Specifies the default answer.</param>
|
||||
/// <returns><c>true</c> if the user selected "yes", otherwise <c>false</c>.</returns>
|
||||
public static bool Confirm(string prompt, bool defaultValue = true)
|
||||
{
|
||||
return new ConfirmationPrompt(prompt)
|
||||
{
|
||||
DefaultValue = defaultValue,
|
||||
}
|
||||
.Show(Console);
|
||||
}
|
||||
}
|
@ -1,70 +1,69 @@
|
||||
using System;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// Starts recording the console output.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
public static void Record()
|
||||
{
|
||||
/// <summary>
|
||||
/// Starts recording the console output.
|
||||
/// </summary>
|
||||
public static void Record()
|
||||
if (_recorder == null)
|
||||
{
|
||||
if (_recorder == null)
|
||||
{
|
||||
_recorder = new Recorder(Console);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports all recorded console output as text.
|
||||
/// </summary>
|
||||
/// <returns>The recorded output as text.</returns>
|
||||
public static string ExportText()
|
||||
{
|
||||
if (_recorder == null)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot export text since a recording hasn't been started.");
|
||||
}
|
||||
|
||||
return _recorder.ExportText();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports all recorded console output as HTML text.
|
||||
/// </summary>
|
||||
/// <returns>The recorded output as HTML text.</returns>
|
||||
public static string ExportHtml()
|
||||
{
|
||||
if (_recorder == null)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot export HTML since a recording hasn't been started.");
|
||||
}
|
||||
|
||||
return _recorder.ExportHtml();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports all recorded console output using a custom encoder.
|
||||
/// </summary>
|
||||
/// <param name="encoder">The encoder to use.</param>
|
||||
/// <returns>The recorded output.</returns>
|
||||
public static string ExportCustom(IAnsiConsoleEncoder encoder)
|
||||
{
|
||||
if (_recorder == null)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot export HTML since a recording hasn't been started.");
|
||||
}
|
||||
|
||||
if (encoder is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(encoder));
|
||||
}
|
||||
|
||||
return _recorder.Export(encoder);
|
||||
_recorder = new Recorder(Console);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports all recorded console output as text.
|
||||
/// </summary>
|
||||
/// <returns>The recorded output as text.</returns>
|
||||
public static string ExportText()
|
||||
{
|
||||
if (_recorder == null)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot export text since a recording hasn't been started.");
|
||||
}
|
||||
|
||||
return _recorder.ExportText();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports all recorded console output as HTML text.
|
||||
/// </summary>
|
||||
/// <returns>The recorded output as HTML text.</returns>
|
||||
public static string ExportHtml()
|
||||
{
|
||||
if (_recorder == null)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot export HTML since a recording hasn't been started.");
|
||||
}
|
||||
|
||||
return _recorder.ExportHtml();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports all recorded console output using a custom encoder.
|
||||
/// </summary>
|
||||
/// <param name="encoder">The encoder to use.</param>
|
||||
/// <returns>The recorded output.</returns>
|
||||
public static string ExportCustom(IAnsiConsoleEncoder encoder)
|
||||
{
|
||||
if (_recorder == null)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot export HTML since a recording hasn't been started.");
|
||||
}
|
||||
|
||||
if (encoder is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(encoder));
|
||||
}
|
||||
|
||||
return _recorder.Export(encoder);
|
||||
}
|
||||
}
|
@ -1,35 +1,34 @@
|
||||
using System;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// Renders the specified object to the console.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
/// <param name="renderable">The object to render.</param>
|
||||
[Obsolete("Consider using AnsiConsole.Write instead.")]
|
||||
public static void Render(IRenderable renderable)
|
||||
{
|
||||
/// <summary>
|
||||
/// Renders the specified object to the console.
|
||||
/// </summary>
|
||||
/// <param name="renderable">The object to render.</param>
|
||||
[Obsolete("Consider using AnsiConsole.Write instead.")]
|
||||
public static void Render(IRenderable renderable)
|
||||
{
|
||||
Write(renderable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the specified <see cref="IRenderable"/> to the console.
|
||||
/// </summary>
|
||||
/// <param name="renderable">The object to render.</param>
|
||||
public static void Write(IRenderable renderable)
|
||||
{
|
||||
if (renderable is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(renderable));
|
||||
}
|
||||
|
||||
Console.Write(renderable);
|
||||
}
|
||||
Write(renderable);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the specified <see cref="IRenderable"/> to the console.
|
||||
/// </summary>
|
||||
/// <param name="renderable">The object to render.</param>
|
||||
public static void Write(IRenderable renderable)
|
||||
{
|
||||
if (renderable is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(renderable));
|
||||
}
|
||||
|
||||
Console.Write(renderable);
|
||||
}
|
||||
}
|
@ -1,19 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// Switches to an alternate screen buffer if the terminal supports it.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
/// <param name="action">The action to execute within the alternate screen buffer.</param>
|
||||
public static void AlternateScreen(Action action)
|
||||
{
|
||||
/// <summary>
|
||||
/// Switches to an alternate screen buffer if the terminal supports it.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to execute within the alternate screen buffer.</param>
|
||||
public static void AlternateScreen(Action action)
|
||||
{
|
||||
Console.AlternateScreen(action);
|
||||
}
|
||||
Console.AlternateScreen(action);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,63 +1,62 @@
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
internal static Style CurrentStyle { get; private set; } = Style.Plain;
|
||||
internal static bool Created { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// Gets or sets the foreground color.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
public static Color Foreground
|
||||
{
|
||||
internal static Style CurrentStyle { get; private set; } = Style.Plain;
|
||||
internal static bool Created { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the foreground color.
|
||||
/// </summary>
|
||||
public static Color Foreground
|
||||
{
|
||||
get => CurrentStyle.Foreground;
|
||||
set => CurrentStyle = CurrentStyle.Foreground(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the background color.
|
||||
/// </summary>
|
||||
public static Color Background
|
||||
{
|
||||
get => CurrentStyle.Background;
|
||||
set => CurrentStyle = CurrentStyle.Background(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the text decoration.
|
||||
/// </summary>
|
||||
public static Decoration Decoration
|
||||
{
|
||||
get => CurrentStyle.Decoration;
|
||||
set => CurrentStyle = CurrentStyle.Decoration(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets colors and text decorations.
|
||||
/// </summary>
|
||||
public static void Reset()
|
||||
{
|
||||
ResetColors();
|
||||
ResetDecoration();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the current applied text decorations.
|
||||
/// </summary>
|
||||
public static void ResetDecoration()
|
||||
{
|
||||
Decoration = Decoration.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the current applied foreground and background colors.
|
||||
/// </summary>
|
||||
public static void ResetColors()
|
||||
{
|
||||
CurrentStyle = Style.Plain;
|
||||
}
|
||||
get => CurrentStyle.Foreground;
|
||||
set => CurrentStyle = CurrentStyle.Foreground(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the background color.
|
||||
/// </summary>
|
||||
public static Color Background
|
||||
{
|
||||
get => CurrentStyle.Background;
|
||||
set => CurrentStyle = CurrentStyle.Background(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the text decoration.
|
||||
/// </summary>
|
||||
public static Decoration Decoration
|
||||
{
|
||||
get => CurrentStyle.Decoration;
|
||||
set => CurrentStyle = CurrentStyle.Decoration(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets colors and text decorations.
|
||||
/// </summary>
|
||||
public static void Reset()
|
||||
{
|
||||
ResetColors();
|
||||
ResetDecoration();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the current applied text decorations.
|
||||
/// </summary>
|
||||
public static void ResetDecoration()
|
||||
{
|
||||
Decoration = Decoration.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the current applied foreground and background colors.
|
||||
/// </summary>
|
||||
public static void ResetColors()
|
||||
{
|
||||
CurrentStyle = Style.Plain;
|
||||
}
|
||||
}
|
@ -1,253 +1,252 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// Writes the specified string value to the console.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(string value)
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes the specified string value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(string value)
|
||||
Write(value, CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit
|
||||
/// signed integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(int value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit
|
||||
/// signed integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, int value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit
|
||||
/// unsigned integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(uint value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit
|
||||
/// unsigned integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, uint value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit
|
||||
/// signed integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(long value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit
|
||||
/// signed integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, long value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit
|
||||
/// unsigned integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(ulong value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit
|
||||
/// unsigned integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, ulong value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified single-precision
|
||||
/// floating-point value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(float value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified single-precision
|
||||
/// floating-point value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, float value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified double-precision
|
||||
/// floating-point value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(double value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified double-precision
|
||||
/// floating-point value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, double value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified decimal value, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(decimal value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified decimal value, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, decimal value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified boolean value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(bool value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified boolean value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, bool value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified Unicode character to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(char value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified Unicode character to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, char value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified array of Unicode characters to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(char[] value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified array of Unicode characters to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, char[] value)
|
||||
{
|
||||
if (value is null)
|
||||
{
|
||||
Write(value, CurrentStyle);
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit
|
||||
/// signed integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(int value)
|
||||
for (var index = 0; index < value.Length; index++)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit
|
||||
/// signed integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, int value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit
|
||||
/// unsigned integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(uint value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit
|
||||
/// unsigned integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, uint value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit
|
||||
/// signed integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(long value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit
|
||||
/// signed integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, long value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit
|
||||
/// unsigned integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(ulong value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit
|
||||
/// unsigned integer value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, ulong value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified single-precision
|
||||
/// floating-point value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(float value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified single-precision
|
||||
/// floating-point value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, float value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified double-precision
|
||||
/// floating-point value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(double value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified double-precision
|
||||
/// floating-point value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, double value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified decimal value, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(decimal value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified decimal value, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, decimal value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified boolean value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(bool value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified boolean value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, bool value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified Unicode character to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(char value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified Unicode character to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, char value)
|
||||
{
|
||||
Console.Write(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified array of Unicode characters to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(char[] value)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified array of Unicode characters to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(IFormatProvider provider, char[] value)
|
||||
{
|
||||
if (value is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
for (var index = 0; index < value.Length; index++)
|
||||
{
|
||||
Console.Write(value[index].ToString(provider), CurrentStyle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified array of objects,
|
||||
/// to the console using the specified format information.
|
||||
/// </summary>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void Write(string format, params object[] args)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, format, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified array of objects,
|
||||
/// to the console using the specified format information.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void Write(IFormatProvider provider, string format, params object[] args)
|
||||
{
|
||||
Console.Write(string.Format(provider, format, args), CurrentStyle);
|
||||
Console.Write(value[index].ToString(provider), CurrentStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified array of objects,
|
||||
/// to the console using the specified format information.
|
||||
/// </summary>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void Write(string format, params object[] args)
|
||||
{
|
||||
Write(CultureInfo.CurrentCulture, format, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified array of objects,
|
||||
/// to the console using the specified format information.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void Write(IFormatProvider provider, string format, params object[] args)
|
||||
{
|
||||
Console.Write(string.Format(provider, format, args), CurrentStyle);
|
||||
}
|
||||
}
|
@ -1,273 +1,272 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// Writes an empty line to the console.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
public static void WriteLine()
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes an empty line to the console.
|
||||
/// </summary>
|
||||
public static void WriteLine()
|
||||
{
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified string value, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(string value)
|
||||
{
|
||||
Console.WriteLine(value, CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit signed integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(int value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit signed integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, int value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit unsigned integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(uint value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit unsigned integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, uint value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit signed integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(long value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit signed integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, long value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit unsigned integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(ulong value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit unsigned integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, ulong value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified single-precision floating-point
|
||||
/// value, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(float value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified single-precision floating-point
|
||||
/// value, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, float value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified double-precision floating-point
|
||||
/// value, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(double value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified double-precision floating-point
|
||||
/// value, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, double value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified decimal value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(decimal value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified decimal value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, decimal value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified boolean value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(bool value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified boolean value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, bool value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified Unicode character, followed by the current
|
||||
/// line terminator, value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(char value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified Unicode character, followed by the current
|
||||
/// line terminator, value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, char value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified array of Unicode characters, followed by the current
|
||||
/// line terminator, value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(char[] value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified array of Unicode characters, followed by the current
|
||||
/// line terminator, value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, char[] value)
|
||||
{
|
||||
if (value is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
for (var index = 0; index < value.Length; index++)
|
||||
{
|
||||
Console.Write(value[index].ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified array of objects,
|
||||
/// followed by the current line terminator, to the console
|
||||
/// using the specified format information.
|
||||
/// </summary>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void WriteLine(string format, params object[] args)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, format, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified array of objects,
|
||||
/// followed by the current line terminator, to the console
|
||||
/// using the specified format information.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, string format, params object[] args)
|
||||
{
|
||||
Console.WriteLine(string.Format(provider, format, args), CurrentStyle);
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified string value, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(string value)
|
||||
{
|
||||
Console.WriteLine(value, CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit signed integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(int value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit signed integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, int value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit unsigned integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(uint value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 32-bit unsigned integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, uint value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit signed integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(long value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit signed integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, long value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit unsigned integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(ulong value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified 64-bit unsigned integer value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, ulong value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified single-precision floating-point
|
||||
/// value, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(float value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified single-precision floating-point
|
||||
/// value, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, float value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified double-precision floating-point
|
||||
/// value, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(double value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified double-precision floating-point
|
||||
/// value, followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, double value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified decimal value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(decimal value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified decimal value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, decimal value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified boolean value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(bool value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified boolean value,
|
||||
/// followed by the current line terminator, to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, bool value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified Unicode character, followed by the current
|
||||
/// line terminator, value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(char value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified Unicode character, followed by the current
|
||||
/// line terminator, value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, char value)
|
||||
{
|
||||
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified array of Unicode characters, followed by the current
|
||||
/// line terminator, value to the console.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(char[] value)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified array of Unicode characters, followed by the current
|
||||
/// line terminator, value to the console.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, char[] value)
|
||||
{
|
||||
if (value is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
for (var index = 0; index < value.Length; index++)
|
||||
{
|
||||
Console.Write(value[index].ToString(provider), CurrentStyle);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified array of objects,
|
||||
/// followed by the current line terminator, to the console
|
||||
/// using the specified format information.
|
||||
/// </summary>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void WriteLine(string format, params object[] args)
|
||||
{
|
||||
WriteLine(CultureInfo.CurrentCulture, format, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the text representation of the specified array of objects,
|
||||
/// followed by the current line terminator, to the console
|
||||
/// using the specified format information.
|
||||
/// </summary>
|
||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An array of objects to write.</param>
|
||||
public static void WriteLine(IFormatProvider provider, string format, params object[] args)
|
||||
{
|
||||
Console.WriteLine(string.Format(provider, format, args), CurrentStyle);
|
||||
}
|
||||
}
|
@ -1,78 +1,77 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
private static Recorder? _recorder;
|
||||
private static Lazy<IAnsiConsole> _console = new Lazy<IAnsiConsole>(
|
||||
() =>
|
||||
{
|
||||
var console = Create(new AnsiConsoleSettings
|
||||
{
|
||||
Ansi = AnsiSupport.Detect,
|
||||
ColorSystem = ColorSystemSupport.Detect,
|
||||
Out = new AnsiConsoleOutput(System.Console.Out),
|
||||
});
|
||||
namespace Spectre.Console;
|
||||
|
||||
Created = true;
|
||||
return console;
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
private static Recorder? _recorder;
|
||||
private static Lazy<IAnsiConsole> _console = new Lazy<IAnsiConsole>(
|
||||
() =>
|
||||
{
|
||||
var console = Create(new AnsiConsoleSettings
|
||||
{
|
||||
Ansi = AnsiSupport.Detect,
|
||||
ColorSystem = ColorSystemSupport.Detect,
|
||||
Out = new AnsiConsoleOutput(System.Console.Out),
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the underlying <see cref="IAnsiConsole"/>.
|
||||
/// </summary>
|
||||
public static IAnsiConsole Console
|
||||
Created = true;
|
||||
return console;
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the underlying <see cref="IAnsiConsole"/>.
|
||||
/// </summary>
|
||||
public static IAnsiConsole Console
|
||||
{
|
||||
get
|
||||
{
|
||||
get
|
||||
{
|
||||
return _recorder ?? _console.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
_console = new Lazy<IAnsiConsole>(() => value);
|
||||
|
||||
if (_recorder != null)
|
||||
{
|
||||
// Recreate the recorder
|
||||
_recorder = _recorder.Clone(value);
|
||||
}
|
||||
|
||||
Created = true;
|
||||
}
|
||||
return _recorder ?? _console.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IAnsiConsoleCursor"/>.
|
||||
/// </summary>
|
||||
public static IAnsiConsoleCursor Cursor => _recorder?.Cursor ?? _console.Value.Cursor;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the console profile.
|
||||
/// </summary>
|
||||
public static Profile Profile => Console.Profile;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="IAnsiConsole"/> instance
|
||||
/// from the provided settings.
|
||||
/// </summary>
|
||||
/// <param name="settings">The settings to use.</param>
|
||||
/// <returns>An <see cref="IAnsiConsole"/> instance.</returns>
|
||||
public static IAnsiConsole Create(AnsiConsoleSettings settings)
|
||||
set
|
||||
{
|
||||
var factory = new AnsiConsoleFactory();
|
||||
return factory.Create(settings);
|
||||
}
|
||||
_console = new Lazy<IAnsiConsole>(() => value);
|
||||
|
||||
/// <summary>
|
||||
/// Clears the console.
|
||||
/// </summary>
|
||||
public static void Clear()
|
||||
{
|
||||
Console.Clear();
|
||||
if (_recorder != null)
|
||||
{
|
||||
// Recreate the recorder
|
||||
_recorder = _recorder.Clone(value);
|
||||
}
|
||||
|
||||
Created = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IAnsiConsoleCursor"/>.
|
||||
/// </summary>
|
||||
public static IAnsiConsoleCursor Cursor => _recorder?.Cursor ?? _console.Value.Cursor;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the console profile.
|
||||
/// </summary>
|
||||
public static Profile Profile => Console.Profile;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="IAnsiConsole"/> instance
|
||||
/// from the provided settings.
|
||||
/// </summary>
|
||||
/// <param name="settings">The settings to use.</param>
|
||||
/// <returns>An <see cref="IAnsiConsole"/> instance.</returns>
|
||||
public static IAnsiConsole Create(AnsiConsoleSettings settings)
|
||||
{
|
||||
var factory = new AnsiConsoleFactory();
|
||||
return factory.Create(settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the console.
|
||||
/// </summary>
|
||||
public static void Clear()
|
||||
{
|
||||
Console.Clear();
|
||||
}
|
||||
}
|
@ -3,110 +3,109 @@ using System.Runtime.InteropServices;
|
||||
using Spectre.Console.Enrichment;
|
||||
using Spectre.Console.Internal;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// Factory for creating an ANSI console.
|
||||
/// </summary>
|
||||
public sealed class AnsiConsoleFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory for creating an ANSI console.
|
||||
/// Creates an ANSI console.
|
||||
/// </summary>
|
||||
public sealed class AnsiConsoleFactory
|
||||
/// <param name="settings">The settings.</param>
|
||||
/// <returns>An implementation of <see cref="IAnsiConsole"/>.</returns>
|
||||
public IAnsiConsole Create(AnsiConsoleSettings settings)
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an ANSI console.
|
||||
/// </summary>
|
||||
/// <param name="settings">The settings.</param>
|
||||
/// <returns>An implementation of <see cref="IAnsiConsole"/>.</returns>
|
||||
public IAnsiConsole Create(AnsiConsoleSettings settings)
|
||||
if (settings is null)
|
||||
{
|
||||
if (settings is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settings));
|
||||
}
|
||||
|
||||
var output = settings.Out ?? new AnsiConsoleOutput(System.Console.Out);
|
||||
if (output.Writer == null)
|
||||
{
|
||||
throw new InvalidOperationException("Output writer was null");
|
||||
}
|
||||
|
||||
// Detect if the terminal support ANSI or not
|
||||
var (supportsAnsi, legacyConsole) = DetectAnsi(settings, output.Writer);
|
||||
|
||||
// Use console encoding or fall back to provided encoding
|
||||
var encoding = output.Writer.IsStandardOut() || output.Writer.IsStandardError()
|
||||
? System.Console.OutputEncoding : output.Writer.Encoding;
|
||||
|
||||
// Get the color system
|
||||
var colorSystem = settings.ColorSystem == ColorSystemSupport.Detect
|
||||
? ColorSystemDetector.Detect(supportsAnsi)
|
||||
: (ColorSystem)settings.ColorSystem;
|
||||
|
||||
// Get whether or not we consider the terminal interactive
|
||||
var interactive = settings.Interactive == InteractionSupport.Yes;
|
||||
if (settings.Interactive == InteractionSupport.Detect)
|
||||
{
|
||||
interactive = Environment.UserInteractive;
|
||||
}
|
||||
|
||||
var profile = new Profile(output, encoding);
|
||||
|
||||
profile.Capabilities.ColorSystem = colorSystem;
|
||||
profile.Capabilities.Ansi = supportsAnsi;
|
||||
profile.Capabilities.Links = supportsAnsi && !legacyConsole;
|
||||
profile.Capabilities.Legacy = legacyConsole;
|
||||
profile.Capabilities.Interactive = interactive;
|
||||
profile.Capabilities.Unicode = encoding.EncodingName.ContainsExact("Unicode");
|
||||
profile.Capabilities.AlternateBuffer = supportsAnsi && !legacyConsole;
|
||||
|
||||
// Enrich the profile
|
||||
ProfileEnricher.Enrich(
|
||||
profile,
|
||||
settings.Enrichment,
|
||||
settings.EnvironmentVariables);
|
||||
|
||||
return new AnsiConsoleFacade(
|
||||
profile,
|
||||
settings.ExclusivityMode ?? new DefaultExclusivityMode());
|
||||
throw new ArgumentNullException(nameof(settings));
|
||||
}
|
||||
|
||||
private static (bool Ansi, bool Legacy) DetectAnsi(AnsiConsoleSettings settings, System.IO.TextWriter buffer)
|
||||
var output = settings.Out ?? new AnsiConsoleOutput(System.Console.Out);
|
||||
if (output.Writer == null)
|
||||
{
|
||||
var supportsAnsi = settings.Ansi == AnsiSupport.Yes;
|
||||
var legacyConsole = false;
|
||||
throw new InvalidOperationException("Output writer was null");
|
||||
}
|
||||
|
||||
if (settings.Ansi == AnsiSupport.Detect)
|
||||
// Detect if the terminal support ANSI or not
|
||||
var (supportsAnsi, legacyConsole) = DetectAnsi(settings, output.Writer);
|
||||
|
||||
// Use console encoding or fall back to provided encoding
|
||||
var encoding = output.Writer.IsStandardOut() || output.Writer.IsStandardError()
|
||||
? System.Console.OutputEncoding : output.Writer.Encoding;
|
||||
|
||||
// Get the color system
|
||||
var colorSystem = settings.ColorSystem == ColorSystemSupport.Detect
|
||||
? ColorSystemDetector.Detect(supportsAnsi)
|
||||
: (ColorSystem)settings.ColorSystem;
|
||||
|
||||
// Get whether or not we consider the terminal interactive
|
||||
var interactive = settings.Interactive == InteractionSupport.Yes;
|
||||
if (settings.Interactive == InteractionSupport.Detect)
|
||||
{
|
||||
interactive = Environment.UserInteractive;
|
||||
}
|
||||
|
||||
var profile = new Profile(output, encoding);
|
||||
|
||||
profile.Capabilities.ColorSystem = colorSystem;
|
||||
profile.Capabilities.Ansi = supportsAnsi;
|
||||
profile.Capabilities.Links = supportsAnsi && !legacyConsole;
|
||||
profile.Capabilities.Legacy = legacyConsole;
|
||||
profile.Capabilities.Interactive = interactive;
|
||||
profile.Capabilities.Unicode = encoding.EncodingName.ContainsExact("Unicode");
|
||||
profile.Capabilities.AlternateBuffer = supportsAnsi && !legacyConsole;
|
||||
|
||||
// Enrich the profile
|
||||
ProfileEnricher.Enrich(
|
||||
profile,
|
||||
settings.Enrichment,
|
||||
settings.EnvironmentVariables);
|
||||
|
||||
return new AnsiConsoleFacade(
|
||||
profile,
|
||||
settings.ExclusivityMode ?? new DefaultExclusivityMode());
|
||||
}
|
||||
|
||||
private static (bool Ansi, bool Legacy) DetectAnsi(AnsiConsoleSettings settings, System.IO.TextWriter buffer)
|
||||
{
|
||||
var supportsAnsi = settings.Ansi == AnsiSupport.Yes;
|
||||
var legacyConsole = false;
|
||||
|
||||
if (settings.Ansi == AnsiSupport.Detect)
|
||||
{
|
||||
(supportsAnsi, legacyConsole) = AnsiDetector.Detect(buffer.IsStandardError(), true);
|
||||
|
||||
// Check whether or not this is a legacy console from the existing instance (if any).
|
||||
// We need to do this because once we upgrade the console to support ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||
// on Windows, there is no way of detecting whether or not we're running on a legacy console or not.
|
||||
if (AnsiConsole.Created && !legacyConsole && (buffer.IsStandardOut() || buffer.IsStandardError()) && AnsiConsole.Profile.Capabilities.Legacy)
|
||||
{
|
||||
(supportsAnsi, legacyConsole) = AnsiDetector.Detect(buffer.IsStandardError(), true);
|
||||
|
||||
// Check whether or not this is a legacy console from the existing instance (if any).
|
||||
// We need to do this because once we upgrade the console to support ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||
// on Windows, there is no way of detecting whether or not we're running on a legacy console or not.
|
||||
if (AnsiConsole.Created && !legacyConsole && (buffer.IsStandardOut() || buffer.IsStandardError()) && AnsiConsole.Profile.Capabilities.Legacy)
|
||||
{
|
||||
legacyConsole = AnsiConsole.Profile.Capabilities.Legacy;
|
||||
}
|
||||
legacyConsole = AnsiConsole.Profile.Capabilities.Legacy;
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (buffer.IsStandardOut() || buffer.IsStandardError())
|
||||
{
|
||||
if (buffer.IsStandardOut() || buffer.IsStandardError())
|
||||
// Are we running on Windows?
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
// Are we running on Windows?
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
// Not the first console we're creating?
|
||||
if (AnsiConsole.Created)
|
||||
{
|
||||
// Not the first console we're creating?
|
||||
if (AnsiConsole.Created)
|
||||
{
|
||||
legacyConsole = AnsiConsole.Profile.Capabilities.Legacy;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try detecting whether or not this is a legacy console
|
||||
(_, legacyConsole) = AnsiDetector.Detect(buffer.IsStandardError(), false);
|
||||
}
|
||||
legacyConsole = AnsiConsole.Profile.Capabilities.Legacy;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try detecting whether or not this is a legacy console
|
||||
(_, legacyConsole) = AnsiDetector.Detect(buffer.IsStandardError(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (supportsAnsi, legacyConsole);
|
||||
}
|
||||
|
||||
return (supportsAnsi, legacyConsole);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,57 +2,56 @@ using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// Represents console output.
|
||||
/// </summary>
|
||||
public sealed class AnsiConsoleOutput : IAnsiConsoleOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents console output.
|
||||
/// </summary>
|
||||
public sealed class AnsiConsoleOutput : IAnsiConsoleOutput
|
||||
/// <inheritdoc/>
|
||||
public TextWriter Writer { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsTerminal
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public TextWriter Writer { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsTerminal
|
||||
get
|
||||
{
|
||||
get
|
||||
if (Writer.IsStandardOut())
|
||||
{
|
||||
if (Writer.IsStandardOut())
|
||||
{
|
||||
return !System.Console.IsOutputRedirected;
|
||||
}
|
||||
|
||||
if (Writer.IsStandardError())
|
||||
{
|
||||
return !System.Console.IsErrorRedirected;
|
||||
}
|
||||
|
||||
return false;
|
||||
return !System.Console.IsOutputRedirected;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int Width => ConsoleHelper.GetSafeWidth(Constants.DefaultTerminalWidth);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int Height => ConsoleHelper.GetSafeHeight(Constants.DefaultTerminalWidth);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AnsiConsoleOutput"/> class.
|
||||
/// </summary>
|
||||
/// <param name="writer">The output writer.</param>
|
||||
public AnsiConsoleOutput(TextWriter writer)
|
||||
{
|
||||
Writer = writer ?? throw new ArgumentNullException(nameof(writer));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void SetEncoding(Encoding encoding)
|
||||
{
|
||||
if (Writer.IsStandardOut() || Writer.IsStandardError())
|
||||
if (Writer.IsStandardError())
|
||||
{
|
||||
System.Console.OutputEncoding = encoding;
|
||||
return !System.Console.IsErrorRedirected;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int Width => ConsoleHelper.GetSafeWidth(Constants.DefaultTerminalWidth);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int Height => ConsoleHelper.GetSafeHeight(Constants.DefaultTerminalWidth);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AnsiConsoleOutput"/> class.
|
||||
/// </summary>
|
||||
/// <param name="writer">The output writer.</param>
|
||||
public AnsiConsoleOutput(TextWriter writer)
|
||||
{
|
||||
Writer = writer ?? throw new ArgumentNullException(nameof(writer));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void SetEncoding(Encoding encoding)
|
||||
{
|
||||
if (Writer.IsStandardOut() || Writer.IsStandardError())
|
||||
{
|
||||
System.Console.OutputEncoding = encoding;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,56 +1,55 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// Settings used when building a <see cref="IAnsiConsole"/>.
|
||||
/// </summary>
|
||||
public sealed class AnsiConsoleSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Settings used when building a <see cref="IAnsiConsole"/>.
|
||||
/// Gets or sets a value indicating whether or
|
||||
/// not ANSI escape sequences are supported.
|
||||
/// </summary>
|
||||
public sealed class AnsiConsoleSettings
|
||||
public AnsiSupport Ansi { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color system to use.
|
||||
/// </summary>
|
||||
public ColorSystemSupport ColorSystem { get; set; } = ColorSystemSupport.Detect;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the out buffer.
|
||||
/// </summary>
|
||||
public IAnsiConsoleOutput? Out { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not the
|
||||
/// terminal is interactive or not.
|
||||
/// </summary>
|
||||
public InteractionSupport Interactive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exclusivity mode.
|
||||
/// </summary>
|
||||
public IExclusivityMode? ExclusivityMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the profile enrichments settings.
|
||||
/// </summary>
|
||||
public ProfileEnrichment Enrichment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the environment variables.
|
||||
/// If not value is provided the default environment variables will be used.
|
||||
/// </summary>
|
||||
public Dictionary<string, string>? EnvironmentVariables { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AnsiConsoleSettings"/> class.
|
||||
/// </summary>
|
||||
public AnsiConsoleSettings()
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or
|
||||
/// not ANSI escape sequences are supported.
|
||||
/// </summary>
|
||||
public AnsiSupport Ansi { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color system to use.
|
||||
/// </summary>
|
||||
public ColorSystemSupport ColorSystem { get; set; } = ColorSystemSupport.Detect;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the out buffer.
|
||||
/// </summary>
|
||||
public IAnsiConsoleOutput? Out { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not the
|
||||
/// terminal is interactive or not.
|
||||
/// </summary>
|
||||
public InteractionSupport Interactive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exclusivity mode.
|
||||
/// </summary>
|
||||
public IExclusivityMode? ExclusivityMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the profile enrichments settings.
|
||||
/// </summary>
|
||||
public ProfileEnrichment Enrichment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the environment variables.
|
||||
/// If not value is provided the default environment variables will be used.
|
||||
/// </summary>
|
||||
public Dictionary<string, string>? EnvironmentVariables { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AnsiConsoleSettings"/> class.
|
||||
/// </summary>
|
||||
public AnsiConsoleSettings()
|
||||
{
|
||||
Enrichment = new ProfileEnrichment();
|
||||
}
|
||||
Enrichment = new ProfileEnrichment();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,24 +1,23 @@
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// Determines ANSI escape sequence support.
|
||||
/// </summary>
|
||||
public enum AnsiSupport
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines ANSI escape sequence support.
|
||||
/// ANSI escape sequence support should
|
||||
/// be detected by the system.
|
||||
/// </summary>
|
||||
public enum AnsiSupport
|
||||
{
|
||||
/// <summary>
|
||||
/// ANSI escape sequence support should
|
||||
/// be detected by the system.
|
||||
/// </summary>
|
||||
Detect = 0,
|
||||
Detect = 0,
|
||||
|
||||
/// <summary>
|
||||
/// ANSI escape sequences are supported.
|
||||
/// </summary>
|
||||
Yes = 1,
|
||||
/// <summary>
|
||||
/// ANSI escape sequences are supported.
|
||||
/// </summary>
|
||||
Yes = 1,
|
||||
|
||||
/// <summary>
|
||||
/// ANSI escape sequences are not supported.
|
||||
/// </summary>
|
||||
No = 2,
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// ANSI escape sequences are not supported.
|
||||
/// </summary>
|
||||
No = 2,
|
||||
}
|
@ -1,42 +1,41 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a border.
|
||||
/// </summary>
|
||||
public abstract partial class BoxBorder
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a border.
|
||||
/// Gets an invisible border.
|
||||
/// </summary>
|
||||
public abstract partial class BoxBorder
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an invisible border.
|
||||
/// </summary>
|
||||
public static BoxBorder None { get; } = new NoBoxBorder();
|
||||
public static BoxBorder None { get; } = new NoBoxBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ASCII border.
|
||||
/// </summary>
|
||||
public static BoxBorder Ascii { get; } = new AsciiBoxBorder();
|
||||
/// <summary>
|
||||
/// Gets an ASCII border.
|
||||
/// </summary>
|
||||
public static BoxBorder Ascii { get; } = new AsciiBoxBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a double border.
|
||||
/// </summary>
|
||||
[SuppressMessage("Naming", "CA1720:Identifier contains type name")]
|
||||
public static BoxBorder Double { get; } = new DoubleBoxBorder();
|
||||
/// <summary>
|
||||
/// Gets a double border.
|
||||
/// </summary>
|
||||
[SuppressMessage("Naming", "CA1720:Identifier contains type name")]
|
||||
public static BoxBorder Double { get; } = new DoubleBoxBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a heavy border.
|
||||
/// </summary>
|
||||
public static BoxBorder Heavy { get; } = new HeavyBoxBorder();
|
||||
/// <summary>
|
||||
/// Gets a heavy border.
|
||||
/// </summary>
|
||||
public static BoxBorder Heavy { get; } = new HeavyBoxBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a rounded border.
|
||||
/// </summary>
|
||||
public static BoxBorder Rounded { get; } = new RoundedBoxBorder();
|
||||
/// <summary>
|
||||
/// Gets a rounded border.
|
||||
/// </summary>
|
||||
public static BoxBorder Rounded { get; } = new RoundedBoxBorder();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a square border.
|
||||
/// </summary>
|
||||
public static BoxBorder Square { get; } = new SquareBoxBorder();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets a square border.
|
||||
/// </summary>
|
||||
public static BoxBorder Square { get; } = new SquareBoxBorder();
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user