mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-12-29 20:05:48 +08:00
Add support for moving the cursor
This commit is contained in:
committed by
Patrik Svensson
parent
93d1971f48
commit
a1d11e9d0c
82
src/Spectre.Console/Internal/Backends/Ansi/AnsiBackend.cs
Normal file
82
src/Spectre.Console/Internal/Backends/Ansi/AnsiBackend.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Internal
|
||||
{
|
||||
internal sealed class AnsiBackend : IAnsiConsole
|
||||
{
|
||||
private readonly TextWriter _out;
|
||||
private readonly AnsiBuilder _ansiBuilder;
|
||||
private readonly AnsiCursor _cursor;
|
||||
|
||||
public Capabilities Capabilities { get; }
|
||||
public Encoding Encoding { get; }
|
||||
public IAnsiConsoleCursor Cursor => _cursor;
|
||||
|
||||
public int Width
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_out.IsStandardOut())
|
||||
{
|
||||
return ConsoleHelper.GetSafeBufferWidth(Constants.DefaultBufferWidth);
|
||||
}
|
||||
|
||||
return Constants.DefaultBufferWidth;
|
||||
}
|
||||
}
|
||||
|
||||
public int Height
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_out.IsStandardOut())
|
||||
{
|
||||
return ConsoleHelper.GetSafeBufferHeight(Constants.DefaultBufferHeight);
|
||||
}
|
||||
|
||||
return Constants.DefaultBufferHeight;
|
||||
}
|
||||
}
|
||||
|
||||
public AnsiBackend(TextWriter @out, Capabilities capabilities, ILinkIdentityGenerator? linkHasher)
|
||||
{
|
||||
_out = @out ?? throw new ArgumentNullException(nameof(@out));
|
||||
|
||||
Capabilities = capabilities ?? throw new ArgumentNullException(nameof(capabilities));
|
||||
Encoding = _out.IsStandardOut() ? System.Console.OutputEncoding : Encoding.UTF8;
|
||||
|
||||
_ansiBuilder = new AnsiBuilder(Capabilities, linkHasher);
|
||||
_cursor = new AnsiCursor(this);
|
||||
}
|
||||
|
||||
public void Clear(bool home)
|
||||
{
|
||||
Write(Segment.Control("\u001b[2J"));
|
||||
|
||||
if (home)
|
||||
{
|
||||
Cursor.SetPosition(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(Segment segment)
|
||||
{
|
||||
var parts = segment.Text.NormalizeLineEndings().Split(new[] { '\n' });
|
||||
foreach (var (_, _, last, part) in parts.Enumerate())
|
||||
{
|
||||
if (!string.IsNullOrEmpty(part))
|
||||
{
|
||||
_out.Write(_ansiBuilder.GetAnsi(part, segment.Style));
|
||||
}
|
||||
|
||||
if (!last)
|
||||
{
|
||||
_out.Write(Environment.NewLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
56
src/Spectre.Console/Internal/Backends/Ansi/AnsiCursor.cs
Normal file
56
src/Spectre.Console/Internal/Backends/Ansi/AnsiCursor.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Internal
|
||||
{
|
||||
internal sealed class AnsiCursor : IAnsiConsoleCursor
|
||||
{
|
||||
private readonly AnsiBackend _renderer;
|
||||
|
||||
public AnsiCursor(AnsiBackend renderer)
|
||||
{
|
||||
_renderer = renderer ?? throw new ArgumentNullException(nameof(renderer));
|
||||
}
|
||||
|
||||
public void Show(bool show)
|
||||
{
|
||||
if (show)
|
||||
{
|
||||
_renderer.Write(Segment.Control("\u001b[?25h"));
|
||||
}
|
||||
else
|
||||
{
|
||||
_renderer.Write(Segment.Control("\u001b[?25l"));
|
||||
}
|
||||
}
|
||||
|
||||
public void Move(CursorDirection direction, int steps)
|
||||
{
|
||||
if (steps == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case CursorDirection.Up:
|
||||
_renderer.Write(Segment.Control($"\u001b[{steps}A"));
|
||||
break;
|
||||
case CursorDirection.Down:
|
||||
_renderer.Write(Segment.Control($"\u001b[{steps}B"));
|
||||
break;
|
||||
case CursorDirection.Right:
|
||||
_renderer.Write(Segment.Control($"\u001b[{steps}C"));
|
||||
break;
|
||||
case CursorDirection.Left:
|
||||
_renderer.Write(Segment.Control($"\u001b[{steps}D"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPosition(int column, int line)
|
||||
{
|
||||
_renderer.Write(Segment.Control($"\u001b[{line};{column}H"));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user