Skip to content

Instantly share code, notes, and snippets.

@jaredthirsk
Created September 10, 2022 08:19
Show Gist options
  • Save jaredthirsk/4bffdb3fdc3a71dae4515145420c43f2 to your computer and use it in GitHub Desktop.
Save jaredthirsk/4bffdb3fdc3a71dae4515145420c43f2 to your computer and use it in GitHub Desktop.
Spectre.Console: custom width (useful if detection is going to fail)
// Workaround for https://github.com/spectreconsole/spectre.console/issues/216
// Usage:
// var console = AnsiConsole.Create(new AnsiConsoleSettings()); // Replace this with below:
var console = SpectreFix.Create(s => s.Width = 110);
// -------------------------------------------
/// <summary>
///
/// </summary>
public static class SpectreFix
{
/// <summary>
///
/// </summary>
/// <returns></returns>
public static IAnsiConsole Create(Action<FixedAnsiConsoleOutput>? configure = null)
{
var @out = new FixedAnsiConsoleOutput(System.Console.Out);
configure?.Invoke(@out);
var settings = new AnsiConsoleSettings
{
Ansi = AnsiSupport.Detect,
ColorSystem = ColorSystemSupport.Detect,
Out = @out,
};
#pragma warning disable CS0618
return AnsiConsole.Console = new AnsiConsoleFactory().Create(settings);
#pragma warning restore CS0618
}
}
/// <summary>
/// Represents console output.
/// </summary>
public class FixedAnsiConsoleOutput : IAnsiConsoleOutput
{
/// <inheritdoc/>
public TextWriter Writer { get; }
/// <inheritdoc/>
public bool IsTerminal
{
get
{
if (TextWriterExtensions.IsStandardOut(Writer))
{
return !System.Console.IsOutputRedirected;
}
if (TextWriterExtensions.IsStandardError(Writer))
{
return !System.Console.IsErrorRedirected;
}
return false;
}
}
/// <inheritdoc/>
public int Width
{
get => width ?? ConsoleHelper.GetSafeWidth(Constants.DefaultTerminalWidth);
set => width = value;
}
private int? width;
/// <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 FixedAnsiConsoleOutput(TextWriter writer)
{
Writer = writer ?? throw new ArgumentNullException(nameof(writer));
}
/// <inheritdoc/>
public void SetEncoding(Encoding encoding)
{
if (TextWriterExtensions.IsStandardOut(Writer) || TextWriterExtensions.IsStandardError(Writer))
{
System.Console.OutputEncoding = encoding;
}
}
}
internal static class TextWriterExtensions
{
public static bool IsStandardOut(TextWriter writer)
{
try
{
return writer == System.Console.Out;
}
catch
{
return false;
}
}
public static bool IsStandardError(TextWriter writer)
{
try
{
return writer == System.Console.Error;
}
catch
{
return false;
}
}
}
internal static class ConsoleHelper
{
public static int GetSafeWidth(int defaultValue = Constants.DefaultTerminalWidth)
{
try
{
var width = System.Console.BufferWidth;
if (width == 0)
{
width = defaultValue;
}
return width;
}
catch (IOException)
{
return defaultValue;
}
}
public static int GetSafeHeight(int defaultValue = Constants.DefaultTerminalHeight)
{
try
{
var height = System.Console.WindowHeight;
if (height == 0)
{
height = defaultValue;
}
return height;
}
catch (IOException)
{
return defaultValue;
}
}
}
internal static class Constants
{
public const int DefaultTerminalWidth = 80;
public const int DefaultTerminalHeight = 24;
public const string EmptyLink = "https://emptylink";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment