Add analyzers and XML documentation
This commit is contained in:
Родитель
41757f1847
Коммит
ec6ec083c0
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 600 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 30 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 9.5 KiB |
|
@ -0,0 +1,95 @@
|
|||
root = false
|
||||
|
||||
[*.cs]
|
||||
# IDE0055: Fix formatting
|
||||
dotnet_diagnostic.IDE0055.severity = warning
|
||||
|
||||
# SA1101: Prefix local calls with this
|
||||
dotnet_diagnostic.SA1101.severity = none
|
||||
|
||||
# SA1633: File should have header
|
||||
dotnet_diagnostic.SA1633.severity = none
|
||||
|
||||
# SA1201: Elements should appear in the correct order
|
||||
dotnet_diagnostic.SA1201.severity = none
|
||||
|
||||
# SA1202: Public members should come before private members
|
||||
dotnet_diagnostic.SA1202.severity = none
|
||||
|
||||
# SA1309: Field names should not begin with underscore
|
||||
dotnet_diagnostic.SA1309.severity = none
|
||||
|
||||
# SA1404: Code analysis suppressions should have justification
|
||||
dotnet_diagnostic.SA1404.severity = none
|
||||
|
||||
# SA1516: Elements should be separated by a blank line
|
||||
dotnet_diagnostic.SA1516.severity = none
|
||||
|
||||
# CA1303: Do not pass literals as localized parameters
|
||||
dotnet_diagnostic.CA1303.severity = none
|
||||
|
||||
# CSA1204: Static members should appear before non-static members
|
||||
dotnet_diagnostic.SA1204.severity = none
|
||||
|
||||
# IDE0052: Remove unread private members
|
||||
dotnet_diagnostic.IDE0052.severity = warning
|
||||
|
||||
# IDE0063: Use simple 'using' statement
|
||||
csharp_prefer_simple_using_statement = false:suggestion
|
||||
|
||||
# IDE0018: Variable declaration can be inlined
|
||||
dotnet_diagnostic.IDE0018.severity = warning
|
||||
|
||||
# SA1625: Element documenation should not be copied and pasted
|
||||
dotnet_diagnostic.SA1625.severity = none
|
||||
|
||||
# IDE0005: Using directive is unnecessary
|
||||
dotnet_diagnostic.IDE0005.severity = warning
|
||||
|
||||
# SA1117: Parameters should be on same line or separate lines
|
||||
dotnet_diagnostic.SA1117.severity = none
|
||||
|
||||
# SA1404: Code analysis suppression should have justification
|
||||
dotnet_diagnostic.SA1404.severity = none
|
||||
|
||||
# SA1101: Prefix local calls with this
|
||||
dotnet_diagnostic.SA1101.severity = none
|
||||
|
||||
# SA1633: File should have header
|
||||
dotnet_diagnostic.SA1633.severity = none
|
||||
|
||||
# SA1649: File name should match first type name
|
||||
dotnet_diagnostic.SA1649.severity = none
|
||||
|
||||
# SA1402: File may only contain a single type
|
||||
dotnet_diagnostic.SA1402.severity = none
|
||||
|
||||
# CA1814: Prefer jagged arrays over multidimensional
|
||||
dotnet_diagnostic.CA1814.severity = none
|
||||
|
||||
# RCS1194: Implement exception constructors.
|
||||
dotnet_diagnostic.RCS1194.severity = none
|
||||
|
||||
# CA1032: Implement standard exception constructors
|
||||
dotnet_diagnostic.CA1032.severity = none
|
||||
|
||||
# CA1826: Do not use Enumerable methods on indexable collections. Instead use the collection directly
|
||||
dotnet_diagnostic.CA1826.severity = none
|
||||
|
||||
# RCS1079: Throwing of new NotImplementedException.
|
||||
dotnet_diagnostic.RCS1079.severity = warning
|
||||
|
||||
# RCS1057: Add empty line between declarations.
|
||||
dotnet_diagnostic.RCS1057.severity = none
|
||||
|
||||
# RCS1057: Validate arguments correctly
|
||||
dotnet_diagnostic.RCS1227.severity = none
|
||||
|
||||
# IDE0004: Remove Unnecessary Cast
|
||||
dotnet_diagnostic.IDE0004.severity = warning
|
||||
|
||||
# CA1810: Initialize reference type static fields inline
|
||||
dotnet_diagnostic.CA1810.severity = none
|
||||
|
||||
# IDE0044: Add readonly modifier
|
||||
dotnet_diagnostic.IDE0044.severity = warning
|
|
@ -0,0 +1,47 @@
|
|||
<Project>
|
||||
<PropertyGroup Label="Settings">
|
||||
<Deterministic>true</Deterministic>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>embedded</DebugType>
|
||||
<MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Deterministic Build" Condition="'$(GITHUB_ACTIONS)' == 'true'">
|
||||
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Package Information">
|
||||
<Description>A terminal abstraction with platform specific drivers.</Description>
|
||||
<Copyright>Patrik Svensson, Phil Scott</Copyright>
|
||||
<Authors>Patrik Svensson, Phil Scott</Authors>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/spectreconsole/terminal</RepositoryUrl>
|
||||
<PackageIcon>small-logo.png</PackageIcon>
|
||||
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
|
||||
<PackageProjectUrl>https://github.com/spectreconsole/terminal</PackageProjectUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Source Link">
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="MinVer" PrivateAssets="All" Version="2.4.0" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" Version="1.0.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.312">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Roslynator.Analyzers" Version="3.0.0">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,8 @@
|
|||
<Project>
|
||||
<Target Name="Versioning" BeforeTargets="MinVer">
|
||||
<PropertyGroup Label="Build">
|
||||
<MinVerDefaultPreReleasePhase>preview</MinVerDefaultPreReleasePhase>
|
||||
<MinVerVerbosity>normal</MinVerVerbosity>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,35 @@
|
|||
root = false
|
||||
[*.cs]
|
||||
|
||||
# Default severity for analyzer diagnostics with category 'StyleCop.CSharp.DocumentationRules'
|
||||
dotnet_analyzer_diagnostic.category-StyleCop.CSharp.DocumentationRules.severity = none
|
||||
|
||||
# CA1707: Identifiers should not contain underscores
|
||||
dotnet_diagnostic.CA1707.severity = none
|
||||
|
||||
# SA1600: Elements should be documented
|
||||
dotnet_diagnostic.SA1600.severity = none
|
||||
|
||||
# SA1601: Partial elements should be documented
|
||||
dotnet_diagnostic.SA1601.severity = none
|
||||
|
||||
# SA1200: Using directives should be placed correctly
|
||||
dotnet_diagnostic.SA1200.severity = none
|
||||
|
||||
# CS1591: Missing XML comment for publicly visible type or member
|
||||
dotnet_diagnostic.CS1591.severity = none
|
||||
|
||||
# SA1210: Using directives should be ordered alphabetically by namespace
|
||||
dotnet_diagnostic.SA1210.severity = none
|
||||
|
||||
# CA1034: Nested types should not be visible
|
||||
dotnet_diagnostic.CA1034.severity = none
|
||||
|
||||
# CA2000: Dispose objects before losing scope
|
||||
dotnet_diagnostic.CA2000.severity = none
|
||||
|
||||
# SA1118: Parameter should not span multiple lines
|
||||
dotnet_diagnostic.SA1118.severity = none
|
||||
|
||||
# CA1031: Do not catch general exception types
|
||||
dotnet_diagnostic.CA1031.severity = none
|
|
@ -50,12 +50,12 @@ namespace Spectre.Terminals.Tests
|
|||
|
||||
protected override void ShowCursor(ShowCursor instruction, StringBuilder state)
|
||||
{
|
||||
state.Append($"[ShowCursor]");
|
||||
state.Append("[ShowCursor]");
|
||||
}
|
||||
|
||||
protected override void HideCursor(HideCursor instruction, StringBuilder state)
|
||||
{
|
||||
state.Append($"[HideCursor]");
|
||||
state.Append("[HideCursor]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\stylecop.json" Link="Properties/stylecop.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||
<PackageReference Include="Shouldly" Version="4.0.3" />
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
root = false
|
||||
[*.cs]
|
||||
|
||||
# Default severity for analyzer diagnostics with category 'StyleCop.CSharp.DocumentationRules'
|
||||
dotnet_analyzer_diagnostic.category-StyleCop.CSharp.DocumentationRules.severity = none
|
||||
|
||||
# CA1707: Identifiers should not contain underscores
|
||||
dotnet_diagnostic.CA1707.severity = none
|
||||
|
||||
# SA1600: Elements should be documented
|
||||
dotnet_diagnostic.SA1600.severity = none
|
||||
|
||||
# SA1601: Partial elements should be documented
|
||||
dotnet_diagnostic.SA1601.severity = none
|
||||
|
||||
# SA1200: Using directives should be placed correctly
|
||||
dotnet_diagnostic.SA1200.severity = none
|
||||
|
||||
# CS1591: Missing XML comment for publicly visible type or member
|
||||
dotnet_diagnostic.CS1591.severity = none
|
|
@ -1,9 +1,3 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spectre.Terminals.Ansi
|
||||
{
|
||||
public sealed class EnableAlternativeBuffer : AnsiInstruction
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spectre.Terminals.Ansi
|
||||
{
|
||||
public sealed class HideCursor : AnsiInstruction
|
||||
|
|
|
@ -90,7 +90,7 @@ namespace Spectre.Terminals.Ansi
|
|||
{
|
||||
return new HideCursor();
|
||||
}
|
||||
else if(value == 1049)
|
||||
else if (value == 1049)
|
||||
{
|
||||
return new DisableAlternativeBuffer();
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Spectre.Terminals.Ansi
|
|||
{
|
||||
internal static class AnsiSequenceSplitter
|
||||
{
|
||||
public static List<(ReadOnlyMemory<char>, bool)> Split(ReadOnlyMemory<char> buffer)
|
||||
public static List<(ReadOnlyMemory<char> Text, bool IsSequence)> Split(ReadOnlyMemory<char> buffer)
|
||||
{
|
||||
var index = 0;
|
||||
var end = 0;
|
||||
|
|
|
@ -1,10 +1,29 @@
|
|||
namespace Spectre.Terminals
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents different ways of clearing a display.
|
||||
/// </summary>
|
||||
public enum ClearDisplay
|
||||
{
|
||||
/// <summary>
|
||||
/// Clears the whole display.
|
||||
/// </summary>
|
||||
Everything = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Clears the whole display, including the
|
||||
/// scrollback buffer.
|
||||
/// </summary>
|
||||
EverythingAndScrollbackBuffer = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Clears everything before the cursor.
|
||||
/// </summary>
|
||||
BeforeCursor = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Clears everything after the cursor.
|
||||
/// </summary>
|
||||
AfterCursor = 3,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,23 @@
|
|||
namespace Spectre.Terminals
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents different ways of clearing a line.
|
||||
/// </summary>
|
||||
public enum ClearLine
|
||||
{
|
||||
/// <summary>
|
||||
/// Clears the whole line.
|
||||
/// </summary>
|
||||
WholeLine = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Clears everything before the cursor.
|
||||
/// </summary>
|
||||
BeforeCursor = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Clears everything after the cursor.
|
||||
/// </summary>
|
||||
AfterCursor = 2,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,28 @@
|
|||
namespace Spectre.Terminals
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a cursor direction.
|
||||
/// </summary>
|
||||
public enum CursorDirection
|
||||
{
|
||||
/// <summary>
|
||||
/// Moves the cursor forward.
|
||||
/// </summary>
|
||||
Forward = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Moves the cursor backwards.
|
||||
/// </summary>
|
||||
Back = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Moves the cursor up.
|
||||
/// </summary>
|
||||
Up = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Moves the cursor down.
|
||||
/// </summary>
|
||||
Down = 3,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using Spectre.Terminals.Ansi;
|
||||
using Microsoft.Windows.Sdk;
|
||||
using System.Runtime.InteropServices;
|
||||
using Spectre.Terminals.Ansi;
|
||||
|
||||
namespace Spectre.Terminals.Windows
|
||||
{
|
||||
|
@ -94,13 +93,13 @@ namespace Spectre.Terminals.Windows
|
|||
{
|
||||
// Delete everything before the cursor
|
||||
var length = (info.dwCursorPosition.Y * info.dwSize.X) + info.dwCursorPosition.X;
|
||||
PInvoke.FillConsoleOutputCharacter(state.Handle, ' ', (uint)length, new COORD(), out _);
|
||||
PInvoke.FillConsoleOutputCharacter(state.Handle, ' ', (uint)length, default(COORD), out _);
|
||||
}
|
||||
else if (op.Mode == 2 || op.Mode == 3)
|
||||
{
|
||||
// Delete everything
|
||||
var terminalSize = info.dwSize.X * info.dwSize.Y;
|
||||
PInvoke.FillConsoleOutputCharacter(state.Handle, ' ', (uint)terminalSize, new COORD(), out _);
|
||||
PInvoke.FillConsoleOutputCharacter(state.Handle, ' ', (uint)terminalSize, default(COORD), out _);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,14 +116,14 @@ namespace Spectre.Terminals.Windows
|
|||
var length = info.dwSize.X - info.dwCursorPosition.X;
|
||||
PInvoke.FillConsoleOutputCharacter(state.Handle, ' ', (uint)length, info.dwCursorPosition, out _);
|
||||
}
|
||||
if (op.Mode == 1)
|
||||
else if (op.Mode == 1)
|
||||
{
|
||||
// Delete line before the cursor
|
||||
var length = info.dwCursorPosition.X;
|
||||
var pos = new COORD { X = 0, Y = info.dwCursorPosition.Y };
|
||||
PInvoke.FillConsoleOutputCharacter(state.Handle, ' ', (uint)length, pos, out _);
|
||||
}
|
||||
if (op.Mode == 2)
|
||||
else if (op.Mode == 2)
|
||||
{
|
||||
// Delete whole line
|
||||
var pos = new COORD { X = 0, Y = info.dwCursorPosition.Y };
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Windows.Sdk;
|
||||
|
||||
namespace Spectre.Terminals.Windows
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Windows writer.
|
||||
/// </summary>
|
||||
internal interface IWindowsTerminalWriter : ITerminalWriter, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the handle.
|
||||
/// </summary>
|
||||
SafeHandle Handle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified data to the specified handle.
|
||||
/// </summary>
|
||||
/// <param name="handle">The handle to write to.</param>
|
||||
/// <param name="buffer">The buffer to write.</param>
|
||||
void Write(SafeHandle handle, ReadOnlySpan<byte> buffer);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="CONSOLE_MODE"/> for the writer.
|
||||
/// </summary>
|
||||
/// <param name="mode">The resulting <see cref="CONSOLE_MODE"/>, or <c>null</c> if the operation failed.</param>
|
||||
/// <returns><c>true</c> if the operation succeeded, otherwise <c>false</c>.</returns>
|
||||
bool GetMode([NotNullWhen(true)] out CONSOLE_MODE? mode);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified <see cref="CONSOLE_MODE"/>.
|
||||
/// </summary>
|
||||
/// <param name="mode">The <see cref="CONSOLE_MODE"/> to add.</param>
|
||||
/// <returns><c>true</c> if the operation succeeded, otherwise <c>false</c>.</returns>
|
||||
bool AddMode(CONSOLE_MODE mode);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the specified <see cref="CONSOLE_MODE"/>.
|
||||
/// </summary>
|
||||
/// <param name="mode">The <see cref="CONSOLE_MODE"/> to remove.</param>
|
||||
/// <returns><c>true</c> if the operation succeeded, otherwise <c>false</c>.</returns>
|
||||
bool RemoveMode(CONSOLE_MODE mode);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Spectre.Terminals.Windows
|
||||
{
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore")]
|
||||
internal static class WindowsConstants
|
||||
{
|
||||
public const int ERROR_HANDLE_EOF = 38;
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.Windows.Sdk;
|
||||
|
||||
namespace Spectre.Terminals.Windows
|
||||
{
|
||||
public sealed class WindowsDriver : ITerminalDriver, IDisposable
|
||||
internal sealed class WindowsDriver : ITerminalDriver, IDisposable
|
||||
{
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore")]
|
||||
private const CONSOLE_MODE IN_MODE = CONSOLE_MODE.ENABLE_PROCESSED_INPUT | CONSOLE_MODE.ENABLE_LINE_INPUT | CONSOLE_MODE.ENABLE_ECHO_INPUT;
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore")]
|
||||
private const CONSOLE_MODE OUT_MODE = CONSOLE_MODE.DISABLE_NEWLINE_AUTO_RETURN;
|
||||
|
||||
private readonly WindowsTerminalReader _input;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using Microsoft.Windows.Sdk;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Windows.Sdk;
|
||||
|
||||
namespace Spectre.Terminals.Windows
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Microsoft.Windows.Sdk;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Spectre.Terminals.Windows
|
||||
{
|
||||
|
|
|
@ -1,22 +1,10 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Microsoft.Windows.Sdk;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Spectre.Terminals.Windows
|
||||
{
|
||||
internal interface IWindowsTerminalWriter : ITerminalWriter, IDisposable
|
||||
{
|
||||
SafeHandle Handle { get; }
|
||||
|
||||
void Write(SafeHandle handle, ReadOnlySpan<byte> buffer);
|
||||
|
||||
bool GetMode([NotNullWhen(true)] out CONSOLE_MODE? mode);
|
||||
bool AddMode(CONSOLE_MODE mode);
|
||||
bool RemoveMode(CONSOLE_MODE mode);
|
||||
}
|
||||
|
||||
internal sealed class WindowsTerminalWriter : WindowsTerminalHandle, IWindowsTerminalWriter
|
||||
{
|
||||
public Encoding Encoding { get; }
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spectre.Terminals
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="ITerminal"/>.
|
||||
/// </summary>
|
||||
public static partial class ITerminalExtensions
|
||||
{
|
||||
public static void MoveCursor(this ITerminal terminal, CursorDirection direction, int count)
|
||||
/// <summary>
|
||||
/// Moves the cursor.
|
||||
/// </summary>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
/// <param name="direction">The direction to move the cursor.</param>
|
||||
/// <param name="count">The number of steps to move the cursor.</param>
|
||||
public static void MoveCursor(this ITerminal terminal, CursorDirection direction, int count = 1)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
|
@ -32,6 +37,12 @@ namespace Spectre.Terminals
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the cursor position.
|
||||
/// </summary>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
/// <param name="row">The row.</param>
|
||||
/// <param name="column">The column.</param>
|
||||
public static void SetCursorProsition(this ITerminal terminal, int row, int column)
|
||||
{
|
||||
row = Math.Max(0, row);
|
||||
|
@ -40,6 +51,11 @@ namespace Spectre.Terminals
|
|||
terminal.Write($"\u001b[{row};{column}H");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves the cursor down and resets the column position.
|
||||
/// </summary>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
/// <param name="count">The number of lines to move down.</param>
|
||||
public static void MoveCursorToNextLine(this ITerminal terminal, int count)
|
||||
{
|
||||
if (count <= 0)
|
||||
|
@ -50,6 +66,11 @@ namespace Spectre.Terminals
|
|||
terminal.Write($"\u001b[{count}E");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves the cursor up and resets the column position.
|
||||
/// </summary>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
/// <param name="count">The number of lines to move up.</param>
|
||||
public static void MoveCursorToPreviousLine(this ITerminal terminal, int count)
|
||||
{
|
||||
if (count <= 0)
|
||||
|
@ -60,6 +81,11 @@ namespace Spectre.Terminals
|
|||
terminal.Write($"\u001b[{count}F");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves the cursor to the specified column.
|
||||
/// </summary>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
/// <param name="column">The column to move to.</param>
|
||||
public static void MoveCursorToColumn(this ITerminal terminal, int column)
|
||||
{
|
||||
if (column <= 0)
|
||||
|
@ -70,49 +96,67 @@ namespace Spectre.Terminals
|
|||
terminal.Write($"\u001b[{column}G");
|
||||
}
|
||||
|
||||
public static void Clear(this ITerminal terminal, ClearDisplay option)
|
||||
/// <summary>
|
||||
/// Clears the display.
|
||||
/// </summary>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
/// <param name="option">The clear options.</param>
|
||||
public static void Clear(this ITerminal terminal, ClearDisplay option = ClearDisplay.Everything)
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
case ClearDisplay.AfterCursor:
|
||||
terminal.Write($"\u001b[0J");
|
||||
terminal.Write("\u001b[0J");
|
||||
break;
|
||||
case ClearDisplay.BeforeCursor:
|
||||
terminal.Write($"\u001b[1J");
|
||||
terminal.Write("\u001b[1J");
|
||||
break;
|
||||
case ClearDisplay.Everything:
|
||||
terminal.Write($"\u001b[2J");
|
||||
terminal.Write("\u001b[2J");
|
||||
break;
|
||||
case ClearDisplay.EverythingAndScrollbackBuffer:
|
||||
terminal.Write($"\u001b[3J");
|
||||
terminal.Write("\u001b[3J");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the current line.
|
||||
/// </summary>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
/// <param name="option">The clear options.</param>
|
||||
public static void Clear(this ITerminal terminal, ClearLine option)
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
case ClearLine.AfterCursor:
|
||||
terminal.Write($"\u001b[0K");
|
||||
terminal.Write("\u001b[0K");
|
||||
break;
|
||||
case ClearLine.BeforeCursor:
|
||||
terminal.Write($"\u001b[1K");
|
||||
terminal.Write("\u001b[1K");
|
||||
break;
|
||||
case ClearLine.WholeLine:
|
||||
terminal.Write($"\u001b[2K");
|
||||
terminal.Write("\u001b[2K");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the cursor position.
|
||||
/// </summary>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
public static void SaveCursorPosition(this ITerminal terminal)
|
||||
{
|
||||
terminal.Write($"\u001b[s");
|
||||
terminal.Write("\u001b[s");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores the cursor position.
|
||||
/// </summary>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
public static void RestoreCursorPosition(this ITerminal terminal)
|
||||
{
|
||||
terminal.Write($"\u001b[u");
|
||||
terminal.Write("\u001b[u");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,17 @@ using System;
|
|||
|
||||
namespace Spectre.Terminals
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="ITerminal"/>.
|
||||
/// </summary>
|
||||
public static partial class ITerminalExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a single <see cref="byte"/> from the terminal's input handle.
|
||||
/// </summary>
|
||||
/// <remarks>Puts the terminal temporary in raw mode while reading occurs.</remarks>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
/// <returns>The read <see cref="byte"/>, or <c>null</c> if there was nothing to read.</returns>
|
||||
public static byte? ReadRaw(this ITerminal terminal)
|
||||
{
|
||||
try
|
||||
|
@ -18,26 +27,43 @@ namespace Spectre.Terminals
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified buffer to the terminal's output handle.
|
||||
/// </summary>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(this ITerminal terminal, ReadOnlySpan<char> value)
|
||||
{
|
||||
terminal.Output.Write(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified text to the terminal's output handle.
|
||||
/// </summary>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(this ITerminal terminal, string? value)
|
||||
{
|
||||
terminal.Output.Write(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an empty line to the terminal's output handle.
|
||||
/// </summary>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
public static void WriteLine(this ITerminal terminal)
|
||||
{
|
||||
terminal.Output.WriteLine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified text followed by a line break to the terminal's output handle.
|
||||
/// </summary>
|
||||
/// <param name="terminal">The terminal.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(this ITerminal terminal, string? value)
|
||||
{
|
||||
terminal.Output.WriteLine(value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,16 @@ using System.Buffers;
|
|||
|
||||
namespace Spectre.Terminals
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension methods for <see cref="ITerminalWriter"/>.
|
||||
/// </summary>
|
||||
public static class ITerminalWriterExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes the specified buffer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(this ITerminalWriter writer, ReadOnlySpan<char> value)
|
||||
{
|
||||
_ = writer ?? throw new ArgumentNullException(nameof(writer));
|
||||
|
@ -24,16 +32,30 @@ namespace Spectre.Terminals
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified text.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void Write(this ITerminalWriter writer, string? value)
|
||||
{
|
||||
Write(writer, value.AsSpan());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an empty line.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public static void WriteLine(this ITerminalWriter writer)
|
||||
{
|
||||
Write(writer, Environment.NewLine);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified text followed by a line break.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
public static void WriteLine(this ITerminalWriter writer, string? value)
|
||||
{
|
||||
Write(writer, value.AsSpan());
|
||||
|
|
|
@ -2,16 +2,46 @@ using System;
|
|||
|
||||
namespace Spectre.Terminals
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a terminal.
|
||||
/// </summary>
|
||||
public interface ITerminal : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the terminal driver.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the terminal is in raw mode.
|
||||
/// </summary>
|
||||
bool IsRawMode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="ITerminalWriter"/> for <c>STDIN</c>.
|
||||
/// </summary>
|
||||
ITerminalReader Input { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="ITerminalWriter"/> for <c>STDOUT</c>.
|
||||
/// </summary>
|
||||
ITerminalWriter Output { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="ITerminalWriter"/> for <c>STDERR</c>.
|
||||
/// </summary>
|
||||
ITerminalWriter Error { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables raw mode.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if the operation succeeded, otherwise <c>false</c>.</returns>
|
||||
bool EnableRawMode();
|
||||
|
||||
/// <summary>
|
||||
/// Disables raw mode.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if the operation succeeded, otherwise <c>false</c>.</returns>
|
||||
bool DisableRawMode();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,16 +2,46 @@ using System;
|
|||
|
||||
namespace Spectre.Terminals
|
||||
{
|
||||
/// <summary>
|
||||
/// Represent a terminal driver.
|
||||
/// </summary>
|
||||
public interface ITerminalDriver : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the terminal driver.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the terminal is in raw mode.
|
||||
/// </summary>
|
||||
bool IsRawMode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="ITerminalWriter"/> for <c>STDIN</c>.
|
||||
/// </summary>
|
||||
ITerminalReader Input { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="ITerminalWriter"/> for <c>STDOUT</c>.
|
||||
/// </summary>
|
||||
ITerminalWriter Output { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="ITerminalWriter"/> for <c>STDERR</c>.
|
||||
/// </summary>
|
||||
ITerminalWriter Error { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables raw mode.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if the operation succeeded, otherwise <c>false</c>.</returns>
|
||||
bool EnableRawMode();
|
||||
|
||||
/// <summary>
|
||||
/// Disables raw mode.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if the operation succeeded, otherwise <c>false</c>.</returns>
|
||||
bool DisableRawMode();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,34 @@ using System.Text;
|
|||
|
||||
namespace Spectre.Terminals
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a reader.
|
||||
/// </summary>
|
||||
public interface ITerminalReader
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the encoding.
|
||||
/// </summary>
|
||||
Encoding Encoding { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the reader has been redirected.
|
||||
/// </summary>
|
||||
bool IsRedirected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Reads a sequence of bytes from the current reader.
|
||||
/// </summary>
|
||||
/// <param name="buffer">
|
||||
/// A region of memory. When this method returns, the contents of this region are
|
||||
/// replaced by the bytes read from the current source.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The total number of bytes read into the buffer.
|
||||
/// This can be less than the number of bytes allocated in the buffer if
|
||||
/// that many bytes are not currently available, or zero (0) if the end
|
||||
/// of the stream has been reached.
|
||||
/// </returns>
|
||||
int Read(Span<byte> buffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,25 @@ using System.Text;
|
|||
|
||||
namespace Spectre.Terminals
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a writer.
|
||||
/// </summary>
|
||||
public interface ITerminalWriter
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the encoding.
|
||||
/// </summary>
|
||||
Encoding Encoding { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the writer has been redirected.
|
||||
/// </summary>
|
||||
bool IsRedirected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Writes a sequence of bytes to the current writer.
|
||||
/// </summary>
|
||||
/// <param name="buffer">A region of memory. This method copies the contents of this region to the writer.</param>
|
||||
void Write(ReadOnlySpan<byte> buffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
|
@ -7,6 +7,10 @@
|
|||
<NoWarn>$(NoWarn);NU5104</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\stylecop.json" Link="Properties/stylecop.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="6.0.0-preview.1.21102.12" />
|
||||
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.1.422-beta">
|
||||
|
|
|
@ -2,19 +2,34 @@ using System;
|
|||
|
||||
namespace Spectre.Terminals
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a terminal.
|
||||
/// </summary>
|
||||
public sealed class Terminal : ITerminal
|
||||
{
|
||||
private static readonly Lazy<ITerminal> _instance;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a lazily constructed, shared <see cref="ITerminal"/> instance.
|
||||
/// </summary>
|
||||
public static ITerminal Shared => _instance.Value;
|
||||
|
||||
private readonly ITerminalDriver _driver;
|
||||
private readonly object _lock;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Name => _driver.Name;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsRawMode { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ITerminalReader Input { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ITerminalWriter Output { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ITerminalWriter Error { get; }
|
||||
|
||||
static Terminal()
|
||||
|
@ -22,6 +37,10 @@ namespace Spectre.Terminals
|
|||
_instance = new Lazy<ITerminal>(() => TerminalFactory.Create());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Terminal"/> class.
|
||||
/// </summary>
|
||||
/// <param name="driver">The terminal driver.</param>
|
||||
public Terminal(ITerminalDriver driver)
|
||||
{
|
||||
_driver = driver ?? throw new ArgumentNullException(nameof(driver));
|
||||
|
@ -32,11 +51,15 @@ namespace Spectre.Terminals
|
|||
Error = new TerminalOutput(_driver.Error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="Terminal"/> class.
|
||||
/// </summary>
|
||||
~Terminal()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
|
@ -45,6 +68,7 @@ namespace Spectre.Terminals
|
|||
_driver.Dispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool EnableRawMode()
|
||||
{
|
||||
lock (_lock)
|
||||
|
@ -59,6 +83,7 @@ namespace Spectre.Terminals
|
|||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool DisableRawMode()
|
||||
{
|
||||
lock (_lock)
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
|
||||
"settings": {
|
||||
"documentationRules": {
|
||||
"documentExposedElements": true,
|
||||
"documentInternalElements": false,
|
||||
"documentPrivateElements": false,
|
||||
"documentPrivateFields": false
|
||||
},
|
||||
"layoutRules": {
|
||||
"newlineAtEndOfFile": "allow",
|
||||
"allowConsecutiveUsings": true
|
||||
},
|
||||
"orderingRules": {
|
||||
"usingDirectivesPlacement": "outsideNamespace",
|
||||
"systemUsingDirectivesFirst": true,
|
||||
"elementOrder": [
|
||||
"kind",
|
||||
"accessibility",
|
||||
"constant",
|
||||
"static",
|
||||
"readonly"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче