mirror of
https://github.com/spectreconsole/spectre.console.git
synced 2025-10-25 15:19:23 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e280b82679 | ||
|
|
6932c95731 | ||
|
|
ee305702e8 | ||
|
|
63abcc92ba |
28
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Information**
|
||||
- OS: [eg Windows/Linux/MacOS]
|
||||
- Version: [e.g. 0.33.0]
|
||||
- Terminal: [e.g Windows Terminal]
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior.
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -0,0 +1,7 @@
|
||||
┌──────────┐
|
||||
│ ┌──────┐ │
|
||||
│ │ 测试 │ │
|
||||
│ ├──────┤ │
|
||||
│ │ 测试 │ │
|
||||
│ └──────┘ │
|
||||
└──────────┘
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Shouldly;
|
||||
using Spectre.Console.Rendering;
|
||||
using VerifyXunit;
|
||||
using Xunit;
|
||||
@@ -267,5 +269,23 @@ namespace Spectre.Console.Tests.Unit
|
||||
// Then
|
||||
return Verifier.Verify(console.Output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task Should_Wrap_Table_With_CJK_Tables_In_Panel_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
|
||||
var table = new Table();
|
||||
table.AddColumn("测试");
|
||||
table.AddRow("测试");
|
||||
var panel = new Panel(table);
|
||||
|
||||
// When
|
||||
console.Render(panel);
|
||||
|
||||
// Then
|
||||
return Verifier.Verify(console.Output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task Foo()
|
||||
public Task Should_Reduce_Width_If_Needed()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 20);
|
||||
@@ -87,5 +87,29 @@ namespace Spectre.Console.Tests.Unit
|
||||
// Then
|
||||
return Verifier.Verify(console.Output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Setting_Max_Value_Should_Set_The_MaxValue_And_Cap_Value()
|
||||
{
|
||||
// Given
|
||||
var task = default(ProgressTask);
|
||||
var console = new PlainConsole();
|
||||
var progress = new Progress(console)
|
||||
.Columns(new[] { new ProgressBarColumn() })
|
||||
.AutoRefresh(false)
|
||||
.AutoClear(false);
|
||||
|
||||
// When
|
||||
progress.Start(ctx =>
|
||||
{
|
||||
task = ctx.AddTask("foo");
|
||||
task.Increment(100);
|
||||
task.MaxValue = 20;
|
||||
});
|
||||
|
||||
// Then
|
||||
task.MaxValue.ShouldBe(20);
|
||||
task.Value.ShouldBe(20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,18 +22,43 @@ namespace Spectre.Console.Tests.Unit
|
||||
[UsesVerify]
|
||||
public sealed class TheSplitMethod
|
||||
{
|
||||
[Fact]
|
||||
public Task Should_Split_Segment_Correctly()
|
||||
[Theory]
|
||||
[InlineData("Foo Bar", 0, "", "Foo Bar")]
|
||||
[InlineData("Foo Bar", 1, "F", "oo Bar")]
|
||||
[InlineData("Foo Bar", 2, "Fo", "o Bar")]
|
||||
[InlineData("Foo Bar", 3, "Foo", " Bar")]
|
||||
[InlineData("Foo Bar", 4, "Foo ", "Bar")]
|
||||
[InlineData("Foo Bar", 5, "Foo B", "ar")]
|
||||
[InlineData("Foo Bar", 6, "Foo Ba", "r")]
|
||||
[InlineData("Foo Bar", 7, "Foo Bar", null)]
|
||||
[InlineData("Foo 测试 Bar", 0, "", "Foo 测试 Bar")]
|
||||
[InlineData("Foo 测试 Bar", 1, "F", "oo 测试 Bar")]
|
||||
[InlineData("Foo 测试 Bar", 2, "Fo", "o 测试 Bar")]
|
||||
[InlineData("Foo 测试 Bar", 3, "Foo", " 测试 Bar")]
|
||||
[InlineData("Foo 测试 Bar", 4, "Foo ", "测试 Bar")]
|
||||
[InlineData("Foo 测试 Bar", 5, "Foo 测", "试 Bar")]
|
||||
[InlineData("Foo 测试 Bar", 6, "Foo 测", "试 Bar")]
|
||||
[InlineData("Foo 测试 Bar", 7, "Foo 测试", " Bar")]
|
||||
[InlineData("Foo 测试 Bar", 8, "Foo 测试", " Bar")]
|
||||
[InlineData("Foo 测试 Bar", 9, "Foo 测试 ", "Bar")]
|
||||
[InlineData("Foo 测试 Bar", 10, "Foo 测试 B", "ar")]
|
||||
[InlineData("Foo 测试 Bar", 11, "Foo 测试 Ba", "r")]
|
||||
[InlineData("Foo 测试 Bar", 12, "Foo 测试 Bar", null)]
|
||||
public void Should_Split_Segment_Correctly(string text, int offset, string expectedFirst, string expectedSecond)
|
||||
{
|
||||
// Given
|
||||
var style = new Style(Color.Red, Color.Green, Decoration.Bold);
|
||||
var segment = new Segment("Foo Bar", style);
|
||||
var context = new RenderContext(Encoding.UTF8, false);
|
||||
var segment = new Segment(text, style);
|
||||
|
||||
// When
|
||||
var result = segment.Split(3);
|
||||
var (first, second) = segment.Split(context, offset);
|
||||
|
||||
// Then
|
||||
return Verifier.Verify(result);
|
||||
first.Text.ShouldBe(expectedFirst);
|
||||
first.Style.ShouldBe(style);
|
||||
second?.Text?.ShouldBe(expectedSecond);
|
||||
second?.Style?.ShouldBe(style);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,10 @@ namespace Spectre.Console.Internal
|
||||
{
|
||||
public static int GetCellLength(RenderContext context, string text)
|
||||
{
|
||||
return text.Sum(rune =>
|
||||
return text.Sum(rune => GetCellLength(context, rune));
|
||||
}
|
||||
|
||||
public static int GetCellLength(RenderContext context, char rune)
|
||||
{
|
||||
if (context.LegacyConsole)
|
||||
{
|
||||
@@ -33,7 +36,6 @@ namespace Spectre.Console.Internal
|
||||
}
|
||||
|
||||
return UnicodeCalculator.GetWidth(rune);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace Spectre.Console
|
||||
|
||||
if (maxValue != null)
|
||||
{
|
||||
_maxValue += maxValue.Value;
|
||||
_maxValue = maxValue.Value;
|
||||
}
|
||||
|
||||
if (increment != null)
|
||||
@@ -175,6 +175,12 @@ namespace Spectre.Console
|
||||
Value += increment.Value;
|
||||
}
|
||||
|
||||
// Need to cap the max value?
|
||||
if (Value > _maxValue)
|
||||
{
|
||||
Value = _maxValue;
|
||||
}
|
||||
|
||||
var timestamp = DateTime.Now;
|
||||
var threshold = timestamp - TimeSpan.FromSeconds(30);
|
||||
|
||||
@@ -259,6 +265,14 @@ namespace Spectre.Console
|
||||
return null;
|
||||
}
|
||||
|
||||
// If the speed is zero, the estimate below
|
||||
// will return infinity (since it's a double),
|
||||
// so let's set the speed to 1 in that case.
|
||||
if (speed == 0)
|
||||
{
|
||||
speed = 1;
|
||||
}
|
||||
|
||||
var estimate = (MaxValue - Value) / speed.Value;
|
||||
return TimeSpan.FromSeconds(estimate);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Spectre.Console.Internal;
|
||||
|
||||
namespace Spectre.Console.Rendering
|
||||
{
|
||||
@@ -145,6 +146,7 @@ namespace Spectre.Console.Rendering
|
||||
/// </summary>
|
||||
/// <param name="offset">The offset where to split the segment.</param>
|
||||
/// <returns>One or two new segments representing the split.</returns>
|
||||
[Obsolete("Use Split(RenderContext, Int32) instead")]
|
||||
public (Segment First, Segment? Second) Split(int offset)
|
||||
{
|
||||
if (offset < 0)
|
||||
@@ -162,6 +164,44 @@ namespace Spectre.Console.Rendering
|
||||
new Segment(Text.Substring(offset, Text.Length - offset), Style));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Splits the segment at the offset.
|
||||
/// </summary>
|
||||
/// <param name="context">The render context.</param>
|
||||
/// <param name="offset">The offset where to split the segment.</param>
|
||||
/// <returns>One or two new segments representing the split.</returns>
|
||||
public (Segment First, Segment? Second) Split(RenderContext context, int offset)
|
||||
{
|
||||
if (offset < 0)
|
||||
{
|
||||
return (this, null);
|
||||
}
|
||||
|
||||
if (offset >= CellCount(context))
|
||||
{
|
||||
return (this, null);
|
||||
}
|
||||
|
||||
var index = 0;
|
||||
if (offset > 0)
|
||||
{
|
||||
var accumulated = 0;
|
||||
foreach (var character in Text)
|
||||
{
|
||||
index++;
|
||||
accumulated += Cell.GetCellLength(context, character);
|
||||
if (accumulated >= offset)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
new Segment(Text.Substring(0, index), Style),
|
||||
new Segment(Text.Substring(index, Text.Length - index), Style));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clones the segment.
|
||||
/// </summary>
|
||||
@@ -219,14 +259,16 @@ namespace Spectre.Console.Rendering
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
var segment = stack.Pop();
|
||||
var segmentLength = segment.CellCount(context);
|
||||
|
||||
// Does this segment make the line exceed the max width?
|
||||
if (line.CellCount(context) + segment.CellCount(context) > maxWidth)
|
||||
var lineLength = line.CellCount(context);
|
||||
if (lineLength + segmentLength > maxWidth)
|
||||
{
|
||||
var diff = -(maxWidth - (line.Length + segment.Text.Length));
|
||||
var diff = -(maxWidth - (lineLength + segmentLength));
|
||||
var offset = segment.Text.Length - diff;
|
||||
|
||||
var (first, second) = segment.Split(offset);
|
||||
var (first, second) = segment.Split(context, offset);
|
||||
|
||||
line.Add(first);
|
||||
lines.Add(line);
|
||||
|
||||
Reference in New Issue
Block a user