mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-16 08:52:50 +08:00
Add output abstraction and reorganize profile
* Moves ColorSystem from Profile to Capabilities * Renames Tty to IsTerminal * Adds IAnsiConsoleOutput to make output more flexible Closes #343 Closes #359 Closes #369
This commit is contained in:
parent
bc9f610258
commit
3e2eea730b
@ -7,7 +7,7 @@ namespace Spectre.Console.Examples
|
|||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
// No colors
|
// No colors
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
if (AnsiConsole.Profile.ColorSystem == ColorSystem.NoColors)
|
if (AnsiConsole.Profile.Capabilities.ColorSystem == ColorSystem.NoColors)
|
||||||
{
|
{
|
||||||
AnsiConsole.WriteLine("No colors are supported.");
|
AnsiConsole.WriteLine("No colors are supported.");
|
||||||
return;
|
return;
|
||||||
|
@ -8,13 +8,13 @@ namespace Spectre.Console.Examples
|
|||||||
.AddColumn(new GridColumn().NoWrap().PadRight(4))
|
.AddColumn(new GridColumn().NoWrap().PadRight(4))
|
||||||
.AddColumn()
|
.AddColumn()
|
||||||
.AddRow("[b]Enrichers[/]", string.Join(", ", AnsiConsole.Profile.Enrichers))
|
.AddRow("[b]Enrichers[/]", string.Join(", ", AnsiConsole.Profile.Enrichers))
|
||||||
.AddRow("[b]Color system[/]", $"{AnsiConsole.Profile.ColorSystem}")
|
.AddRow("[b]Color system[/]", $"{AnsiConsole.Profile.Capabilities.ColorSystem}")
|
||||||
.AddRow("[b]Unicode?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Unicode)}")
|
.AddRow("[b]Unicode?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Unicode)}")
|
||||||
.AddRow("[b]Supports ansi?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Ansi)}")
|
.AddRow("[b]Supports ansi?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Ansi)}")
|
||||||
.AddRow("[b]Supports links?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Links)}")
|
.AddRow("[b]Supports links?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Links)}")
|
||||||
.AddRow("[b]Legacy console?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Legacy)}")
|
.AddRow("[b]Legacy console?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Legacy)}")
|
||||||
.AddRow("[b]Interactive?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Interactive)}")
|
.AddRow("[b]Interactive?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Interactive)}")
|
||||||
.AddRow("[b]TTY?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Tty)}")
|
.AddRow("[b]Terminal?[/]", $"{YesNo(AnsiConsole.Profile.Out.IsTerminal)}")
|
||||||
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Profile.Width}")
|
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Profile.Width}")
|
||||||
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Profile.Height}")
|
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Profile.Height}")
|
||||||
.AddRow("[b]Encoding[/]", $"{AnsiConsole.Console.Profile.Encoding.EncodingName}");
|
.AddRow("[b]Encoding[/]", $"{AnsiConsole.Console.Profile.Encoding.EncodingName}");
|
||||||
|
@ -33,7 +33,7 @@ namespace Spectre.Console.Testing
|
|||||||
{
|
{
|
||||||
Ansi = ansi,
|
Ansi = ansi,
|
||||||
ColorSystem = (ColorSystemSupport)colors,
|
ColorSystem = (ColorSystemSupport)colors,
|
||||||
Out = _writer,
|
Out = new AnsiConsoleOutput(_writer),
|
||||||
Enrichment = new ProfileEnrichment
|
Enrichment = new ProfileEnrichment
|
||||||
{
|
{
|
||||||
UseDefaultEnrichers = false,
|
UseDefaultEnrichers = false,
|
||||||
|
@ -2,13 +2,15 @@ namespace Spectre.Console.Testing
|
|||||||
{
|
{
|
||||||
public sealed class FakeCapabilities : IReadOnlyCapabilities
|
public sealed class FakeCapabilities : IReadOnlyCapabilities
|
||||||
{
|
{
|
||||||
|
public ColorSystem ColorSystem { get; set; } = ColorSystem.TrueColor;
|
||||||
|
|
||||||
public bool Ansi { get; set; }
|
public bool Ansi { get; set; }
|
||||||
|
|
||||||
public bool Links { get; set; }
|
public bool Links { get; set; }
|
||||||
|
|
||||||
public bool Legacy { get; set; }
|
public bool Legacy { get; set; }
|
||||||
|
|
||||||
public bool Tty { get; set; }
|
public bool IsTerminal { get; set; }
|
||||||
|
|
||||||
public bool Interactive { get; set; }
|
public bool Interactive { get; set; }
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ namespace Spectre.Console.Testing
|
|||||||
public RenderPipeline Pipeline { get; }
|
public RenderPipeline Pipeline { get; }
|
||||||
|
|
||||||
public FakeConsoleInput Input { get; }
|
public FakeConsoleInput Input { get; }
|
||||||
public string Output => Profile.Out.ToString();
|
public string Output => Profile.Out.Writer.ToString();
|
||||||
public IReadOnlyList<string> Lines => Output.TrimEnd('\n').Split(new char[] { '\n' });
|
public IReadOnlyList<string> Lines => Output.TrimEnd('\n').Split(new char[] { '\n' });
|
||||||
|
|
||||||
public FakeConsole(
|
public FakeConsole(
|
||||||
@ -28,10 +28,10 @@ namespace Spectre.Console.Testing
|
|||||||
ExclusivityMode = new FakeExclusivityMode();
|
ExclusivityMode = new FakeExclusivityMode();
|
||||||
Pipeline = new RenderPipeline();
|
Pipeline = new RenderPipeline();
|
||||||
|
|
||||||
Profile = new Profile(new StringWriter(), encoding ?? Encoding.UTF8);
|
Profile = new Profile(new AnsiConsoleOutput(new StringWriter()), encoding ?? Encoding.UTF8);
|
||||||
Profile.Width = width;
|
Profile.Width = width;
|
||||||
Profile.Height = height;
|
Profile.Height = height;
|
||||||
Profile.ColorSystem = colorSystem;
|
Profile.Capabilities.ColorSystem = colorSystem;
|
||||||
Profile.Capabilities.Ansi = supportsAnsi;
|
Profile.Capabilities.Ansi = supportsAnsi;
|
||||||
Profile.Capabilities.Legacy = legacyConsole;
|
Profile.Capabilities.Legacy = legacyConsole;
|
||||||
Profile.Capabilities.Interactive = interactive;
|
Profile.Capabilities.Interactive = interactive;
|
||||||
@ -41,7 +41,7 @@ namespace Spectre.Console.Testing
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Profile.Out.Dispose();
|
Profile.Out.Writer.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear(bool home)
|
public void Clear(bool home)
|
||||||
@ -52,7 +52,7 @@ namespace Spectre.Console.Testing
|
|||||||
{
|
{
|
||||||
foreach (var segment in renderable.GetSegments(this))
|
foreach (var segment in renderable.GetSegments(this))
|
||||||
{
|
{
|
||||||
Profile.Out.Write(segment.Text);
|
Profile.Out.Writer.Write(segment.Text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,11 +19,11 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
var console = AnsiConsole.Create(new AnsiConsoleSettings
|
var console = AnsiConsole.Create(new AnsiConsoleSettings
|
||||||
{
|
{
|
||||||
ColorSystem = requested,
|
ColorSystem = requested,
|
||||||
Out = new StringWriter(),
|
Out = new AnsiConsoleOutput(new StringWriter()),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
console.Profile.ColorSystem.ShouldBe(expected);
|
console.Profile.Capabilities.ColorSystem.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class TrueColor
|
public sealed class TrueColor
|
||||||
|
@ -20,7 +20,7 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public string Render()
|
public string Render()
|
||||||
{
|
{
|
||||||
var console = new FakeConsole();
|
var console = new FakeConsole();
|
||||||
var context = new RenderContext(console.Profile.ColorSystem, console.Profile.Capabilities);
|
var context = new RenderContext(console.Profile.Capabilities);
|
||||||
console.Write(Column.Render(context, Task, TimeSpan.Zero));
|
console.Write(Column.Render(context, Task, TimeSpan.Zero));
|
||||||
return console.Output;
|
return console.Output;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,6 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(0, "Hello World Hello World Hello World Hello World Hello World", "")]
|
|
||||||
[InlineData(1, "Hello World Hello World Hello World Hello World Hello World", "─")]
|
[InlineData(1, "Hello World Hello World Hello World Hello World Hello World", "─")]
|
||||||
[InlineData(2, "Hello World Hello World Hello World Hello World Hello World", "──")]
|
[InlineData(2, "Hello World Hello World Hello World Hello World Hello World", "──")]
|
||||||
[InlineData(3, "Hello World Hello World Hello World Hello World Hello World", "───")]
|
[InlineData(3, "Hello World Hello World Hello World Hello World Hello World", "───")]
|
||||||
|
@ -15,7 +15,7 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
var text = new Text("Foo Bar Baz\nQux\nLol mobile");
|
var text = new Text("Foo Bar Baz\nQux\nLol mobile");
|
||||||
|
|
||||||
// When
|
// When
|
||||||
var result = ((IRenderable)text).Measure(new RenderContext(ColorSystem.TrueColor, caps), 80);
|
var result = ((IRenderable)text).Measure(new RenderContext(caps), 80);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
result.Min.ShouldBe(6);
|
result.Min.ShouldBe(6);
|
||||||
@ -29,7 +29,7 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
var text = new Text("Foo Bar Baz\nQux\nLol mobile");
|
var text = new Text("Foo Bar Baz\nQux\nLol mobile");
|
||||||
|
|
||||||
// When
|
// When
|
||||||
var result = ((IRenderable)text).Measure(new RenderContext(ColorSystem.TrueColor, caps), 80);
|
var result = ((IRenderable)text).Measure(new RenderContext(caps), 80);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
result.Max.ShouldBe(11);
|
result.Max.ShouldBe(11);
|
||||||
|
@ -15,7 +15,7 @@ namespace Spectre.Console
|
|||||||
{
|
{
|
||||||
Ansi = AnsiSupport.Detect,
|
Ansi = AnsiSupport.Detect,
|
||||||
ColorSystem = ColorSystemSupport.Detect,
|
ColorSystem = ColorSystemSupport.Detect,
|
||||||
Out = System.Console.Out,
|
Out = new AnsiConsoleOutput(System.Console.Out),
|
||||||
});
|
});
|
||||||
|
|
||||||
Created = true;
|
Created = true;
|
||||||
|
@ -22,13 +22,18 @@ namespace Spectre.Console
|
|||||||
throw new ArgumentNullException(nameof(settings));
|
throw new ArgumentNullException(nameof(settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer = settings.Out ?? System.Console.Out;
|
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
|
// Detect if the terminal support ANSI or not
|
||||||
var (supportsAnsi, legacyConsole) = DetectAnsi(settings, buffer);
|
var (supportsAnsi, legacyConsole) = DetectAnsi(settings, output.Writer);
|
||||||
|
|
||||||
// Use console encoding or fall back to provided encoding
|
// Use console encoding or fall back to provided encoding
|
||||||
var encoding = buffer.IsStandardOut() || buffer.IsStandardError() ? System.Console.OutputEncoding : buffer.Encoding;
|
var encoding = output.Writer.IsStandardOut() || output.Writer.IsStandardError()
|
||||||
|
? System.Console.OutputEncoding : output.Writer.Encoding;
|
||||||
|
|
||||||
// Get the color system
|
// Get the color system
|
||||||
var colorSystem = settings.ColorSystem == ColorSystemSupport.Detect
|
var colorSystem = settings.ColorSystem == ColorSystemSupport.Detect
|
||||||
@ -42,11 +47,9 @@ namespace Spectre.Console
|
|||||||
interactive = Environment.UserInteractive;
|
interactive = Environment.UserInteractive;
|
||||||
}
|
}
|
||||||
|
|
||||||
var profile = new Profile(buffer, encoding)
|
var profile = new Profile(output, encoding);
|
||||||
{
|
|
||||||
ColorSystem = colorSystem,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
profile.Capabilities.ColorSystem = colorSystem;
|
||||||
profile.Capabilities.Ansi = supportsAnsi;
|
profile.Capabilities.Ansi = supportsAnsi;
|
||||||
profile.Capabilities.Links = supportsAnsi && !legacyConsole;
|
profile.Capabilities.Links = supportsAnsi && !legacyConsole;
|
||||||
profile.Capabilities.Legacy = legacyConsole;
|
profile.Capabilities.Legacy = legacyConsole;
|
||||||
|
58
src/Spectre.Console/AnsiConsoleOutput.cs
Normal file
58
src/Spectre.Console/AnsiConsoleOutput.cs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Spectre.Console
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents console output.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class AnsiConsoleOutput : IAnsiConsoleOutput
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public TextWriter Writer { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool IsTerminal
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Writer.IsStandardOut())
|
||||||
|
{
|
||||||
|
return !System.Console.IsOutputRedirected;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Writer.IsStandardError())
|
||||||
|
{
|
||||||
|
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,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Spectre.Console
|
namespace Spectre.Console
|
||||||
{
|
{
|
||||||
@ -22,7 +21,7 @@ namespace Spectre.Console
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the out buffer.
|
/// Gets or sets the out buffer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TextWriter? Out { get; set; }
|
public IAnsiConsoleOutput? Out { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether or not the
|
/// Gets or sets a value indicating whether or not the
|
||||||
|
@ -7,7 +7,12 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class Capabilities : IReadOnlyCapabilities
|
public sealed class Capabilities : IReadOnlyCapabilities
|
||||||
{
|
{
|
||||||
private readonly Profile _profile;
|
private readonly IAnsiConsoleOutput _out;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the color system.
|
||||||
|
/// </summary>
|
||||||
|
public ColorSystem ColorSystem { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether or not
|
/// Gets or sets a value indicating whether or not
|
||||||
@ -33,26 +38,10 @@ namespace Spectre.Console
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether or not
|
/// Gets a value indicating whether or not
|
||||||
/// console output has been redirected.
|
/// the output is a terminal.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Tty
|
[Obsolete("Use Profile.Out.IsTerminal instead")]
|
||||||
{
|
public bool IsTerminal => _out.IsTerminal;
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_profile.Out.IsStandardOut())
|
|
||||||
{
|
|
||||||
return System.Console.IsOutputRedirected;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_profile.Out.IsStandardError())
|
|
||||||
{
|
|
||||||
return System.Console.IsErrorRedirected;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not stdout, so must be a TTY.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether
|
/// Gets or sets a value indicating whether
|
||||||
@ -67,11 +56,12 @@ namespace Spectre.Console
|
|||||||
public bool Unicode { get; set; }
|
public bool Unicode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Capabilities"/> class.
|
/// Initializes a new instance of the
|
||||||
|
/// <see cref="Capabilities"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal Capabilities(Profile profile)
|
internal Capabilities(IAnsiConsoleOutput @out)
|
||||||
{
|
{
|
||||||
_profile = profile ?? throw new ArgumentNullException(nameof(profile));
|
_out = @out ?? throw new ArgumentNullException(nameof(@out));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ namespace Spectre.Console
|
|||||||
throw new ArgumentNullException(nameof(renderable));
|
throw new ArgumentNullException(nameof(renderable));
|
||||||
}
|
}
|
||||||
|
|
||||||
var context = new RenderContext(console.Profile.ColorSystem, console.Profile.Capabilities);
|
var context = new RenderContext(console.Profile.Capabilities);
|
||||||
var renderables = console.Pipeline.Process(context, new[] { renderable });
|
var renderables = console.Pipeline.Process(context, new[] { renderable });
|
||||||
|
|
||||||
return GetSegments(console, context, renderables);
|
return GetSegments(console, context, renderables);
|
||||||
|
37
src/Spectre.Console/IAnsiConsoleOutput.cs
Normal file
37
src/Spectre.Console/IAnsiConsoleOutput.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Spectre.Console
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents console output.
|
||||||
|
/// </summary>
|
||||||
|
public interface IAnsiConsoleOutput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="TextWriter"/> used to write to the output.
|
||||||
|
/// </summary>
|
||||||
|
TextWriter Writer { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether or not the output is a terminal.
|
||||||
|
/// </summary>
|
||||||
|
bool IsTerminal { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the output width.
|
||||||
|
/// </summary>
|
||||||
|
int Width { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the output height.
|
||||||
|
/// </summary>
|
||||||
|
int Height { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the output encoding.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="encoding">The encoding.</param>
|
||||||
|
void SetEncoding(Encoding encoding);
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace Spectre.Console
|
namespace Spectre.Console
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -5,6 +7,11 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IReadOnlyCapabilities
|
public interface IReadOnlyCapabilities
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the color system.
|
||||||
|
/// </summary>
|
||||||
|
ColorSystem ColorSystem { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether or not
|
/// Gets a value indicating whether or not
|
||||||
/// the console supports Ansi.
|
/// the console supports Ansi.
|
||||||
@ -31,7 +38,8 @@ namespace Spectre.Console
|
|||||||
/// Gets a value indicating whether or not
|
/// Gets a value indicating whether or not
|
||||||
/// console output has been redirected.
|
/// console output has been redirected.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool Tty { get; }
|
[Obsolete("Use Profile.Out.IsTerminal instead")]
|
||||||
|
bool IsTerminal { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether
|
/// Gets a value indicating whether
|
||||||
|
@ -29,7 +29,7 @@ namespace Spectre.Console
|
|||||||
{
|
{
|
||||||
codes = codes.Concat(
|
codes = codes.Concat(
|
||||||
AnsiColorBuilder.GetAnsiCodes(
|
AnsiColorBuilder.GetAnsiCodes(
|
||||||
_profile.ColorSystem,
|
_profile.Capabilities.ColorSystem,
|
||||||
style.Foreground,
|
style.Foreground,
|
||||||
true));
|
true));
|
||||||
}
|
}
|
||||||
@ -39,7 +39,7 @@ namespace Spectre.Console
|
|||||||
{
|
{
|
||||||
codes = codes.Concat(
|
codes = codes.Concat(
|
||||||
AnsiColorBuilder.GetAnsiCodes(
|
AnsiColorBuilder.GetAnsiCodes(
|
||||||
_profile.ColorSystem,
|
_profile.Capabilities.ColorSystem,
|
||||||
style.Background,
|
style.Background,
|
||||||
false));
|
false));
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,8 @@ namespace Spectre.Console
|
|||||||
|
|
||||||
if (builder.Length > 0)
|
if (builder.Length > 0)
|
||||||
{
|
{
|
||||||
_console.Profile.Out.Write(builder.ToString());
|
_console.Profile.Out.Writer.Write(builder.ToString());
|
||||||
_console.Profile.Out.Flush();
|
_console.Profile.Out.Writer.Flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ namespace Spectre.Console
|
|||||||
SetStyle(segment.Style);
|
SetStyle(segment.Style);
|
||||||
}
|
}
|
||||||
|
|
||||||
_console.Profile.Out.Write(segment.Text.NormalizeNewLines(native: true));
|
_console.Profile.Out.Writer.Write(segment.Text.NormalizeNewLines(native: true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,13 +55,13 @@ namespace Spectre.Console
|
|||||||
System.Console.ResetColor();
|
System.Console.ResetColor();
|
||||||
|
|
||||||
var background = Color.ToConsoleColor(style.Background);
|
var background = Color.ToConsoleColor(style.Background);
|
||||||
if (_console.Profile.ColorSystem != ColorSystem.NoColors && (int)background != -1)
|
if (_console.Profile.Capabilities.ColorSystem != ColorSystem.NoColors && (int)background != -1)
|
||||||
{
|
{
|
||||||
System.Console.BackgroundColor = background;
|
System.Console.BackgroundColor = background;
|
||||||
}
|
}
|
||||||
|
|
||||||
var foreground = Color.ToConsoleColor(style.Foreground);
|
var foreground = Color.ToConsoleColor(style.Foreground);
|
||||||
if (_console.Profile.ColorSystem != ColorSystem.NoColors && (int)foreground != -1)
|
if (_console.Profile.Capabilities.ColorSystem != ColorSystem.NoColors && (int)foreground != -1)
|
||||||
{
|
{
|
||||||
System.Console.ForegroundColor = foreground;
|
System.Console.ForegroundColor = foreground;
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,6 @@ namespace Spectre.Console
|
|||||||
|
|
||||||
public ConsoleKeyInfo ReadKey(bool intercept)
|
public ConsoleKeyInfo ReadKey(bool intercept)
|
||||||
{
|
{
|
||||||
if (_profile.Capabilities.Tty)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Cannot read input from a TTY console.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_profile.Capabilities.Interactive)
|
if (!_profile.Capabilities.Interactive)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Failed to read input in non-interactive mode.");
|
throw new InvalidOperationException("Failed to read input in non-interactive mode.");
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
namespace Spectre.Console.Internal
|
||||||
|
{
|
||||||
|
internal sealed class EncoderCapabilities : IReadOnlyCapabilities
|
||||||
|
{
|
||||||
|
public ColorSystem ColorSystem { get; }
|
||||||
|
|
||||||
|
public bool Ansi => false;
|
||||||
|
public bool Links => false;
|
||||||
|
public bool Legacy => false;
|
||||||
|
public bool IsTerminal => false;
|
||||||
|
public bool Interactive => false;
|
||||||
|
public bool Unicode => true;
|
||||||
|
|
||||||
|
public EncoderCapabilities(ColorSystem colors)
|
||||||
|
{
|
||||||
|
ColorSystem = colors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ namespace Spectre.Console.Internal
|
|||||||
{
|
{
|
||||||
public string Encode(IAnsiConsole console, IEnumerable<IRenderable> renderables)
|
public string Encode(IAnsiConsole console, IEnumerable<IRenderable> renderables)
|
||||||
{
|
{
|
||||||
var context = new RenderContext(ColorSystem.TrueColor, EncoderCapabilities.Default);
|
var context = new RenderContext(new EncoderCapabilities(ColorSystem.TrueColor));
|
||||||
var builder = new StringBuilder();
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
builder.Append("<pre style=\"font-size:90%;font-family:consolas,'Courier New',monospace\">\n");
|
builder.Append("<pre style=\"font-size:90%;font-family:consolas,'Courier New',monospace\">\n");
|
||||||
|
@ -4,23 +4,11 @@ using Spectre.Console.Rendering;
|
|||||||
|
|
||||||
namespace Spectre.Console.Internal
|
namespace Spectre.Console.Internal
|
||||||
{
|
{
|
||||||
internal sealed class EncoderCapabilities : IReadOnlyCapabilities
|
|
||||||
{
|
|
||||||
public bool Ansi => false;
|
|
||||||
public bool Links => false;
|
|
||||||
public bool Legacy => false;
|
|
||||||
public bool Tty => false;
|
|
||||||
public bool Interactive => false;
|
|
||||||
public bool Unicode => true;
|
|
||||||
|
|
||||||
public static EncoderCapabilities Default { get; } = new EncoderCapabilities();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal sealed class TextEncoder : IAnsiConsoleEncoder
|
internal sealed class TextEncoder : IAnsiConsoleEncoder
|
||||||
{
|
{
|
||||||
public string Encode(IAnsiConsole console, IEnumerable<IRenderable> renderables)
|
public string Encode(IAnsiConsole console, IEnumerable<IRenderable> renderables)
|
||||||
{
|
{
|
||||||
var context = new RenderContext(ColorSystem.TrueColor, EncoderCapabilities.Default);
|
var context = new RenderContext(new EncoderCapabilities(ColorSystem.TrueColor));
|
||||||
var builder = new StringBuilder();
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
foreach (var renderable in renderables)
|
foreach (var renderable in renderables)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Spectre.Console
|
namespace Spectre.Console
|
||||||
@ -13,7 +12,7 @@ namespace Spectre.Console
|
|||||||
private readonly HashSet<string> _enrichers;
|
private readonly HashSet<string> _enrichers;
|
||||||
private static readonly string[] _defaultEnricher = new[] { "Default" };
|
private static readonly string[] _defaultEnricher = new[] { "Default" };
|
||||||
|
|
||||||
private TextWriter _out;
|
private IAnsiConsoleOutput _out;
|
||||||
private Encoding _encoding;
|
private Encoding _encoding;
|
||||||
private Capabilities _capabilities;
|
private Capabilities _capabilities;
|
||||||
private int? _width;
|
private int? _width;
|
||||||
@ -38,15 +37,15 @@ namespace Spectre.Console
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the out buffer.
|
/// Gets or sets the out buffer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TextWriter Out
|
public IAnsiConsoleOutput Out
|
||||||
{
|
{
|
||||||
get => _out;
|
get => _out;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_out = value ?? throw new InvalidOperationException("Output buffer cannot be null");
|
_out = value ?? throw new InvalidOperationException("Output buffer cannot be null");
|
||||||
|
|
||||||
// Reset the width and height if not a TTY.
|
// Reset the width and height if this is a terminal.
|
||||||
if (!Capabilities.Tty)
|
if (value.IsTerminal)
|
||||||
{
|
{
|
||||||
_width = null;
|
_width = null;
|
||||||
_height = null;
|
_height = null;
|
||||||
@ -67,12 +66,7 @@ namespace Spectre.Console
|
|||||||
throw new InvalidOperationException("Encoding cannot be null");
|
throw new InvalidOperationException("Encoding cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need to update the output encoding for stdout?
|
_out.SetEncoding(value);
|
||||||
if (_out.IsStandardOut() || _out.IsStandardError())
|
|
||||||
{
|
|
||||||
System.Console.OutputEncoding = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
_encoding = value;
|
_encoding = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,10 +76,10 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int Width
|
public int Width
|
||||||
{
|
{
|
||||||
get => GetWidth();
|
get => _width ?? _out.Width;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (_width <= 0)
|
if (value <= 0)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Console width must be greater than zero");
|
throw new InvalidOperationException("Console width must be greater than zero");
|
||||||
}
|
}
|
||||||
@ -99,10 +93,10 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int Height
|
public int Height
|
||||||
{
|
{
|
||||||
get => GetHeight();
|
get => _height ?? _out.Height;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (_height <= 0)
|
if (value <= 0)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Console height must be greater than zero");
|
throw new InvalidOperationException("Console height must be greater than zero");
|
||||||
}
|
}
|
||||||
@ -111,11 +105,6 @@ namespace Spectre.Console
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the color system.
|
|
||||||
/// </summary>
|
|
||||||
public ColorSystem ColorSystem { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the capabilities of the profile.
|
/// Gets or sets the capabilities of the profile.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -133,12 +122,12 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="out">The output buffer.</param>
|
/// <param name="out">The output buffer.</param>
|
||||||
/// <param name="encoding">The output encoding.</param>
|
/// <param name="encoding">The output encoding.</param>
|
||||||
public Profile(TextWriter @out, Encoding encoding)
|
public Profile(IAnsiConsoleOutput @out, Encoding encoding)
|
||||||
{
|
{
|
||||||
_enrichers = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
_enrichers = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
_out = @out ?? throw new ArgumentNullException(nameof(@out));
|
_out = @out ?? throw new ArgumentNullException(nameof(@out));
|
||||||
_encoding = encoding ?? throw new ArgumentNullException(nameof(encoding));
|
_encoding = encoding ?? throw new ArgumentNullException(nameof(encoding));
|
||||||
_capabilities = new Capabilities(this);
|
_capabilities = new Capabilities(_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -149,7 +138,7 @@ namespace Spectre.Console
|
|||||||
/// <returns><c>true</c> if the color system is supported, otherwise <c>false</c>.</returns>
|
/// <returns><c>true</c> if the color system is supported, otherwise <c>false</c>.</returns>
|
||||||
public bool Supports(ColorSystem colorSystem)
|
public bool Supports(ColorSystem colorSystem)
|
||||||
{
|
{
|
||||||
return (int)colorSystem <= (int)ColorSystem;
|
return (int)colorSystem <= (int)Capabilities.ColorSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddEnricher(string name)
|
internal void AddEnricher(string name)
|
||||||
@ -161,35 +150,5 @@ namespace Spectre.Console
|
|||||||
|
|
||||||
_enrichers.Add(name);
|
_enrichers.Add(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GetWidth()
|
|
||||||
{
|
|
||||||
if (_width != null)
|
|
||||||
{
|
|
||||||
return _width.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Capabilities.Tty)
|
|
||||||
{
|
|
||||||
return ConsoleHelper.GetSafeWidth(Constants.DefaultTerminalWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Constants.DefaultTerminalWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int GetHeight()
|
|
||||||
{
|
|
||||||
if (_height != null)
|
|
||||||
{
|
|
||||||
return _height.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Capabilities.Tty)
|
|
||||||
{
|
|
||||||
return ConsoleHelper.GetSafeHeight(Constants.DefaultTerminalHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Constants.DefaultTerminalHeight;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ namespace Spectre.Console.Rendering
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current color system.
|
/// Gets the current color system.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ColorSystem ColorSystem { get; }
|
public ColorSystem ColorSystem => _capabilities.ColorSystem;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether or not unicode is supported.
|
/// Gets a value indicating whether or not unicode is supported.
|
||||||
@ -33,19 +33,17 @@ namespace Spectre.Console.Rendering
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RenderContext"/> class.
|
/// Initializes a new instance of the <see cref="RenderContext"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="colorSystem">The color system.</param>
|
|
||||||
/// <param name="capabilities">The capabilities.</param>
|
/// <param name="capabilities">The capabilities.</param>
|
||||||
/// <param name="justification">The justification.</param>
|
/// <param name="justification">The justification.</param>
|
||||||
public RenderContext(ColorSystem colorSystem, IReadOnlyCapabilities capabilities, Justify? justification = null)
|
public RenderContext(IReadOnlyCapabilities capabilities, Justify? justification = null)
|
||||||
: this(colorSystem, capabilities, justification, false)
|
: this(capabilities, justification, false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private RenderContext(ColorSystem colorSystem, IReadOnlyCapabilities capabilities, Justify? justification = null, bool singleLine = false)
|
private RenderContext(IReadOnlyCapabilities capabilities, Justify? justification = null, bool singleLine = false)
|
||||||
{
|
{
|
||||||
_capabilities = capabilities ?? throw new ArgumentNullException(nameof(capabilities));
|
_capabilities = capabilities ?? throw new ArgumentNullException(nameof(capabilities));
|
||||||
|
|
||||||
ColorSystem = colorSystem;
|
|
||||||
Justification = justification;
|
Justification = justification;
|
||||||
SingleLine = singleLine;
|
SingleLine = singleLine;
|
||||||
}
|
}
|
||||||
@ -57,7 +55,7 @@ namespace Spectre.Console.Rendering
|
|||||||
/// <returns>A new <see cref="RenderContext"/> instance.</returns>
|
/// <returns>A new <see cref="RenderContext"/> instance.</returns>
|
||||||
public RenderContext WithJustification(Justify? justification)
|
public RenderContext WithJustification(Justify? justification)
|
||||||
{
|
{
|
||||||
return new RenderContext(ColorSystem, _capabilities, justification, SingleLine);
|
return new RenderContext(_capabilities, justification, SingleLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -72,7 +70,7 @@ namespace Spectre.Console.Rendering
|
|||||||
/// <returns>A new <see cref="RenderContext"/> instance.</returns>
|
/// <returns>A new <see cref="RenderContext"/> instance.</returns>
|
||||||
internal RenderContext WithSingleLine()
|
internal RenderContext WithSingleLine()
|
||||||
{
|
{
|
||||||
return new RenderContext(ColorSystem, _capabilities, Justification, true);
|
return new RenderContext(_capabilities, Justification, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ namespace Spectre.Console
|
|||||||
_stopwatch.Start();
|
_stopwatch.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
var renderContext = new RenderContext(_console.Profile.ColorSystem, _console.Profile.Capabilities);
|
var renderContext = new RenderContext(_console.Profile.Capabilities);
|
||||||
|
|
||||||
var delta = _stopwatch.Elapsed - _lastUpdate;
|
var delta = _stopwatch.Elapsed - _lastUpdate;
|
||||||
_lastUpdate = _stopwatch.Elapsed;
|
_lastUpdate = _stopwatch.Elapsed;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user