mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-06-19 13:28:16 +08:00
Add progress task list support
This commit is contained in:

committed by
Patrik Svensson

parent
c61e386440
commit
ae32785f21
@ -121,6 +121,8 @@ namespace Spectre.Console.Internal
|
||||
// Enabling failed.
|
||||
return false;
|
||||
}
|
||||
|
||||
isLegacy = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Spectre.Console.Rendering;
|
||||
@ -11,9 +12,11 @@ namespace Spectre.Console.Internal
|
||||
private readonly AnsiBuilder _ansiBuilder;
|
||||
private readonly AnsiCursor _cursor;
|
||||
private readonly ConsoleInput _input;
|
||||
private readonly object _lock;
|
||||
|
||||
public Capabilities Capabilities { get; }
|
||||
public Encoding Encoding { get; }
|
||||
public RenderPipeline Pipeline { get; }
|
||||
public IAnsiConsoleCursor Cursor => _cursor;
|
||||
public IAnsiConsoleInput Input => _input;
|
||||
|
||||
@ -49,35 +52,59 @@ namespace Spectre.Console.Internal
|
||||
|
||||
Capabilities = capabilities ?? throw new ArgumentNullException(nameof(capabilities));
|
||||
Encoding = _out.IsStandardOut() ? System.Console.OutputEncoding : Encoding.UTF8;
|
||||
Pipeline = new RenderPipeline();
|
||||
|
||||
_ansiBuilder = new AnsiBuilder(Capabilities, linkHasher);
|
||||
_cursor = new AnsiCursor(this);
|
||||
_input = new ConsoleInput();
|
||||
_lock = new object();
|
||||
}
|
||||
|
||||
public void Clear(bool home)
|
||||
{
|
||||
Write(Segment.Control("\u001b[2J"));
|
||||
|
||||
if (home)
|
||||
lock (_lock)
|
||||
{
|
||||
Cursor.SetPosition(0, 0);
|
||||
Write(new[] { Segment.Control("\u001b[2J") });
|
||||
|
||||
if (home)
|
||||
{
|
||||
Cursor.SetPosition(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(Segment segment)
|
||||
public void Write(IEnumerable<Segment> segments)
|
||||
{
|
||||
var parts = segment.Text.NormalizeLineEndings().Split(new[] { '\n' });
|
||||
foreach (var (_, _, last, part) in parts.Enumerate())
|
||||
lock (_lock)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(part))
|
||||
var builder = new StringBuilder();
|
||||
foreach (var segment in segments)
|
||||
{
|
||||
_out.Write(_ansiBuilder.GetAnsi(part, segment.Style));
|
||||
if (segment.IsControlCode)
|
||||
{
|
||||
builder.Append(segment.Text);
|
||||
continue;
|
||||
}
|
||||
|
||||
var parts = segment.Text.NormalizeNewLines().Split(new[] { '\n' });
|
||||
foreach (var (_, _, last, part) in parts.Enumerate())
|
||||
{
|
||||
if (!string.IsNullOrEmpty(part))
|
||||
{
|
||||
builder.Append(_ansiBuilder.GetAnsi(part, segment.Style));
|
||||
}
|
||||
|
||||
if (!last)
|
||||
{
|
||||
builder.Append(Environment.NewLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!last)
|
||||
if (builder.Length > 0)
|
||||
{
|
||||
_out.Write(Environment.NewLine);
|
||||
_out.Write(builder.ToString());
|
||||
_out.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,12 +50,18 @@ namespace Spectre.Console.Internal
|
||||
}
|
||||
}
|
||||
|
||||
var supportsInteraction = settings.Interactive == InteractionSupport.Yes;
|
||||
if (settings.Interactive == InteractionSupport.Detect)
|
||||
{
|
||||
supportsInteraction = InteractivityDetector.IsInteractive();
|
||||
}
|
||||
|
||||
var colorSystem = settings.ColorSystem == ColorSystemSupport.Detect
|
||||
? ColorSystemDetector.Detect(supportsAnsi)
|
||||
: (ColorSystem)settings.ColorSystem;
|
||||
|
||||
// Get the capabilities
|
||||
var capabilities = new Capabilities(supportsAnsi, colorSystem, legacyConsole);
|
||||
var capabilities = new Capabilities(supportsAnsi, colorSystem, legacyConsole, supportsInteraction);
|
||||
|
||||
// Create the renderer
|
||||
if (supportsAnsi)
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Spectre.Console.Rendering;
|
||||
@ -14,6 +15,7 @@ namespace Spectre.Console.Internal
|
||||
|
||||
public Capabilities Capabilities { get; }
|
||||
public Encoding Encoding { get; }
|
||||
public RenderPipeline Pipeline { get; }
|
||||
public IAnsiConsoleCursor Cursor => _cursor;
|
||||
public IAnsiConsoleInput Input => _input;
|
||||
|
||||
@ -43,8 +45,9 @@ namespace Spectre.Console.Internal
|
||||
System.Console.SetOut(@out ?? throw new ArgumentNullException(nameof(@out)));
|
||||
}
|
||||
|
||||
Encoding = System.Console.OutputEncoding;
|
||||
Capabilities = capabilities;
|
||||
Encoding = System.Console.OutputEncoding;
|
||||
Pipeline = new RenderPipeline();
|
||||
}
|
||||
|
||||
public void Clear(bool home)
|
||||
@ -60,14 +63,22 @@ namespace Spectre.Console.Internal
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(Segment segment)
|
||||
public void Write(IEnumerable<Segment> segments)
|
||||
{
|
||||
if (_lastStyle?.Equals(segment.Style) != true)
|
||||
foreach (var segment in segments)
|
||||
{
|
||||
SetStyle(segment.Style);
|
||||
}
|
||||
if (segment.IsControlCode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
System.Console.Write(segment.Text.NormalizeLineEndings(native: true));
|
||||
if (_lastStyle?.Equals(segment.Style) != true)
|
||||
{
|
||||
SetStyle(segment.Style);
|
||||
}
|
||||
|
||||
System.Console.Write(segment.Text.NormalizeNewLines(native: true));
|
||||
}
|
||||
}
|
||||
|
||||
private void SetStyle(Style style)
|
||||
|
@ -15,6 +15,11 @@ namespace Spectre.Console.Internal
|
||||
|
||||
foreach (var (_, first, _, segment) in segments.Enumerate())
|
||||
{
|
||||
if (segment.IsControlCode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (segment.Text == "\n" && !first)
|
||||
{
|
||||
builder.Append('\n');
|
||||
|
52
src/Spectre.Console/Internal/InteractivityDetector.cs
Normal file
52
src/Spectre.Console/Internal/InteractivityDetector.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console.Internal
|
||||
{
|
||||
internal static class InteractivityDetector
|
||||
{
|
||||
private static readonly Dictionary<string, Func<string, bool>> _environmentVariables;
|
||||
|
||||
static InteractivityDetector()
|
||||
{
|
||||
_environmentVariables = new Dictionary<string, Func<string, bool>>
|
||||
{
|
||||
{ "APPVEYOR", v => !string.IsNullOrWhiteSpace(v) },
|
||||
{ "bamboo_buildNumber", v => !string.IsNullOrWhiteSpace(v) },
|
||||
{ "BITBUCKET_REPO_OWNER", v => !string.IsNullOrWhiteSpace(v) },
|
||||
{ "BITBUCKET_REPO_SLUG", v => !string.IsNullOrWhiteSpace(v) },
|
||||
{ "BITBUCKET_COMMIT", v => !string.IsNullOrWhiteSpace(v) },
|
||||
{ "BITRISE_BUILD_URL", v => !string.IsNullOrWhiteSpace(v) },
|
||||
{ "ContinuaCI.Version", v => !string.IsNullOrWhiteSpace(v) },
|
||||
{ "CI_SERVER", v => v.Equals("yes", StringComparison.OrdinalIgnoreCase) }, // GitLab
|
||||
{ "GITHUB_ACTIONS", v => v.Equals("true", StringComparison.OrdinalIgnoreCase) },
|
||||
{ "GO_SERVER_URL", v => !string.IsNullOrWhiteSpace(v) },
|
||||
{ "JENKINS_URL", v => !string.IsNullOrWhiteSpace(v) },
|
||||
{ "BuildRunner", v => v.Equals("MyGet", StringComparison.OrdinalIgnoreCase) },
|
||||
{ "TEAMCITY_VERSION", v => !string.IsNullOrWhiteSpace(v) },
|
||||
{ "TF_BUILD", v => !string.IsNullOrWhiteSpace(v) }, // TFS and Azure
|
||||
{ "TRAVIS", v => !string.IsNullOrWhiteSpace(v) },
|
||||
};
|
||||
}
|
||||
|
||||
public static bool IsInteractive()
|
||||
{
|
||||
if (!Environment.UserInteractive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var variable in _environmentVariables)
|
||||
{
|
||||
var func = variable.Value;
|
||||
var value = Environment.GetEnvironmentVariable(variable.Key);
|
||||
if (!string.IsNullOrWhiteSpace(value) && variable.Value(value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ namespace Spectre.Console.Internal
|
||||
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
return reader.ReadToEnd().NormalizeLineEndings();
|
||||
return reader.ReadToEnd().NormalizeNewLines();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,11 @@ namespace Spectre.Console.Internal
|
||||
|
||||
foreach (var segment in Segment.Merge(segments))
|
||||
{
|
||||
if (segment.IsControlCode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.Append(segment.Text);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user