mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-07-06 20:48:15 +08:00
Compare commits
1 Commits
main
...
11cf298071
Author | SHA1 | Date | |
---|---|---|---|
11cf298071 |
1
.github/ISSUE_TEMPLATE/config.yml
vendored
1
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1 +0,0 @@
|
||||
blank_issues_enabled: false
|
3
.github/workflows/ci.yaml
vendored
3
.github/workflows/ci.yaml
vendored
@ -26,8 +26,9 @@ jobs:
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: |
|
||||
6.0.x
|
||||
7.0.x
|
||||
8.0.x
|
||||
9.0.x
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
|
3
.github/workflows/publish.yaml
vendored
3
.github/workflows/publish.yaml
vendored
@ -32,8 +32,9 @@ jobs:
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: |
|
||||
6.0.x
|
||||
7.0.x
|
||||
8.0.x
|
||||
9.0.x
|
||||
|
||||
- name: Publish
|
||||
shell: bash
|
||||
|
2
.github/workflows/top-issues-dashboard.yml
vendored
2
.github/workflows/top-issues-dashboard.yml
vendored
@ -9,7 +9,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Top Issues action
|
||||
uses: rickstaa/top-issues-action@v1.3.101
|
||||
uses: rickstaa/top-issues-action@v1.3.100
|
||||
env:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
|
23
README.fa.md
23
README.fa.md
@ -44,13 +44,30 @@ https://spectreconsole.net/
|
||||
|
||||
<h2 id="examples">مثالها</h2>
|
||||
|
||||
To see `Spectre.Console` in action, please see the
|
||||
[examples repository](https://github.com/spectreconsole/examples).
|
||||
برای بررسی `Spectre.Console` در عمل، ابزار سراسری
|
||||
[dotnet-example](https://github.com/patriksvensson/dotnet-example)
|
||||
را نصب کنید.
|
||||
|
||||
<pre dir="ltr">
|
||||
> dotnet tool restore
|
||||
</pre>
|
||||
|
||||
حالا شما میتوانید مثالهای موجود در این مخزن را لیست کنید:
|
||||
|
||||
<pre dir="ltr">
|
||||
> dotnet example
|
||||
</pre>
|
||||
|
||||
و برای اجرای مثال:
|
||||
|
||||
<pre dir="ltr">
|
||||
> dotnet example tables
|
||||
</pre>
|
||||
|
||||
<h2 id="license">مجوز</h2>
|
||||
|
||||
<div dir="ltr">
|
||||
Copyright © Patrik Svensson, Phil Scott, Nils Andresen, Cédric Luthi, Frank Ray
|
||||
Copyright © Patrik Svensson, Phil Scott
|
||||
</div>
|
||||
|
||||
همانطور که Spectre.Console تحت مجوز MIT ارائه شده است؛ برای کسب اطلاعات بیشتر به مجوز مراجعه کنید.
|
||||
|
23
README.md
23
README.md
@ -49,8 +49,25 @@ https://spectreconsole.net
|
||||
|
||||
## Examples
|
||||
|
||||
To see `Spectre.Console` in action, please see the
|
||||
[examples repository](https://github.com/spectreconsole/examples).
|
||||
To see `Spectre.Console` in action, install the
|
||||
[dotnet-example](https://github.com/patriksvensson/dotnet-example)
|
||||
global tool.
|
||||
|
||||
```
|
||||
> dotnet tool restore
|
||||
```
|
||||
|
||||
Now you can list available examples in this repository:
|
||||
|
||||
```
|
||||
> dotnet example
|
||||
```
|
||||
|
||||
And to run an example:
|
||||
|
||||
```
|
||||
> dotnet example tables
|
||||
```
|
||||
|
||||
## Sponsors
|
||||
|
||||
@ -83,7 +100,7 @@ This project is supported by the [.NET Foundation](https://dotnetfoundation.org)
|
||||
|
||||
## License
|
||||
|
||||
Copyright © Patrik Svensson, Phil Scott, Nils Andresen, Cédric Luthi, Frank Ray
|
||||
Copyright © Patrik Svensson, Phil Scott, Nils Andresen
|
||||
|
||||
`Spectre.Console` is provided as-is under the MIT license. For more information see LICENSE.
|
||||
|
||||
|
@ -43,8 +43,24 @@ https://spectreconsole.net/
|
||||
|
||||
## Exemplos
|
||||
|
||||
To see `Spectre.Console` in action, please see the
|
||||
[examples repository](https://github.com/spectreconsole/examples).
|
||||
Para ver o `Spectre.Console` em ação, instale a ferramenta global
|
||||
[dotnet-example](https://github.com/patriksvensson/dotnet-example).
|
||||
|
||||
```
|
||||
> dotnet tool restore
|
||||
```
|
||||
|
||||
Agora você pode listar os exemplos disponíveis neste repositório:
|
||||
|
||||
```
|
||||
> dotnet example
|
||||
```
|
||||
|
||||
E para executar um exemplo:
|
||||
|
||||
```
|
||||
> dotnet example tables
|
||||
```
|
||||
|
||||
## Patrocinadores
|
||||
|
||||
@ -67,7 +83,7 @@ Eu estou muito agradecido.
|
||||
|
||||
## Licença
|
||||
|
||||
Copyright © Patrik Svensson, Phil Scott, Nils Andresen, Cédric Luthi, Frank Ray
|
||||
Copyright © Patrik Svensson, Phil Scott, Nils Andresen
|
||||
|
||||
Spectre.Console é fornecido no estado em que se encontra sob a licença do MIT. Para obter mais informações, consulte o arquivo [LICENSE](LICENSE.md).
|
||||
|
||||
|
21
README.zh.md
21
README.zh.md
@ -39,8 +39,23 @@ https://spectreconsole.net/
|
||||
|
||||
## 例子
|
||||
|
||||
To see `Spectre.Console` in action, please see the
|
||||
[examples repository](https://github.com/spectreconsole/examples).
|
||||
如果想直接运行`Spectre.Console`的例子,则需要安装[dotnet-example](https://github.com/patriksvensson/dotnet-example)工具。
|
||||
|
||||
```
|
||||
> dotnet tool restore
|
||||
```
|
||||
|
||||
然后你可以列出仓库里的所有例子:
|
||||
|
||||
```
|
||||
> dotnet example
|
||||
```
|
||||
|
||||
跑一个看看效果:
|
||||
|
||||
```
|
||||
> dotnet example tables
|
||||
```
|
||||
|
||||
## Sponsors
|
||||
|
||||
@ -62,7 +77,7 @@ To see `Spectre.Console` in action, please see the
|
||||
|
||||
## 开源许可
|
||||
|
||||
版权所有 © Patrik Svensson, Phil Scott, Nils Andresen, Cédric Luthi, Frank Ray
|
||||
版权所有 © Patrik Svensson, Phil Scott, Nils Andresen
|
||||
|
||||
Spectre.Console 基于 MIT 协议提供。查看 LICENSE 文件了解更多信息。
|
||||
|
||||
|
57
build.cake
57
build.cake
@ -35,11 +35,41 @@ Task("Build")
|
||||
});
|
||||
});
|
||||
|
||||
Task("Test")
|
||||
Task("Build-Analyzer")
|
||||
.IsDependentOn("Build")
|
||||
.Does(context =>
|
||||
{
|
||||
DotNetTest("./src/Tests/Spectre.Console.Tests/Spectre.Console.Tests.csproj", new DotNetTestSettings {
|
||||
DotNetBuild("./src/Spectre.Console.Analyzer.sln", new DotNetBuildSettings {
|
||||
Configuration = configuration,
|
||||
Verbosity = DotNetVerbosity.Minimal,
|
||||
NoLogo = true,
|
||||
NoIncremental = context.HasArgument("rebuild"),
|
||||
MSBuildSettings = new DotNetMSBuildSettings()
|
||||
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
|
||||
});
|
||||
});
|
||||
|
||||
Task("Build-Examples")
|
||||
.IsDependentOn("Build")
|
||||
.Does(context =>
|
||||
{
|
||||
DotNetBuild("./examples/Examples.sln", new DotNetBuildSettings {
|
||||
Configuration = configuration,
|
||||
Verbosity = DotNetVerbosity.Minimal,
|
||||
NoLogo = true,
|
||||
NoIncremental = context.HasArgument("rebuild"),
|
||||
MSBuildSettings = new DotNetMSBuildSettings()
|
||||
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
|
||||
});
|
||||
});
|
||||
|
||||
Task("Test")
|
||||
.IsDependentOn("Build")
|
||||
.IsDependentOn("Build-Analyzer")
|
||||
.IsDependentOn("Build-Examples")
|
||||
.Does(context =>
|
||||
{
|
||||
DotNetTest("./test/Spectre.Console.Tests/Spectre.Console.Tests.csproj", new DotNetTestSettings {
|
||||
Configuration = configuration,
|
||||
Verbosity = DotNetVerbosity.Minimal,
|
||||
NoLogo = true,
|
||||
@ -47,7 +77,15 @@ Task("Test")
|
||||
NoBuild = true,
|
||||
});
|
||||
|
||||
DotNetTest("./src/Tests/Spectre.Console.Cli.Tests/Spectre.Console.Cli.Tests.csproj", new DotNetTestSettings {
|
||||
DotNetTest("./test/Spectre.Console.Cli.Tests/Spectre.Console.Cli.Tests.csproj", new DotNetTestSettings {
|
||||
Configuration = configuration,
|
||||
Verbosity = DotNetVerbosity.Minimal,
|
||||
NoLogo = true,
|
||||
NoRestore = true,
|
||||
NoBuild = true,
|
||||
});
|
||||
|
||||
DotNetTest("./test/Spectre.Console.Analyzer.Tests/Spectre.Console.Analyzer.Tests.csproj", new DotNetTestSettings {
|
||||
Configuration = configuration,
|
||||
Verbosity = DotNetVerbosity.Minimal,
|
||||
NoLogo = true,
|
||||
@ -70,6 +108,17 @@ Task("Package")
|
||||
MSBuildSettings = new DotNetMSBuildSettings()
|
||||
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
|
||||
});
|
||||
|
||||
// context.DotNetPack($"./src/Spectre.Console.Analyzer.sln", new DotNetPackSettings {
|
||||
// Configuration = configuration,
|
||||
// Verbosity = DotNetVerbosity.Minimal,
|
||||
// NoLogo = true,
|
||||
// NoRestore = true,
|
||||
// NoBuild = true,
|
||||
// OutputDirectory = "./.artifacts",
|
||||
// MSBuildSettings = new DotNetMSBuildSettings()
|
||||
// .TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
|
||||
// });
|
||||
});
|
||||
|
||||
Task("Publish-NuGet")
|
||||
@ -83,7 +132,7 @@ Task("Publish-NuGet")
|
||||
}
|
||||
|
||||
// Publish to GitHub Packages
|
||||
foreach(var file in context.GetFiles("./.artifacts/*.nupkg"))
|
||||
foreach(var file in context.GetFiles("./.artifacts/*.NS.*.nupkg"))
|
||||
{
|
||||
context.Information("Publishing {0}...", file.GetFilename().FullPath);
|
||||
DotNetNuGetPush(file.FullPath, new DotNetNuGetPushSettings
|
||||
|
@ -7,11 +7,6 @@
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);output\**;.gitignore</DefaultItemExcludes>
|
||||
<NoWarn>MVC1000</NoWarn>
|
||||
<MinVerSkip>true</MinVerSkip>
|
||||
<!--
|
||||
Disable NuGetAudit for now, there is an in progress PR with Statiq regarding these packages,
|
||||
but since since this is just a generator we are safe to ignore this for now.
|
||||
-->
|
||||
<NuGetAudit>false</NuGetAudit>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -38,13 +33,13 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Playwright" Version="1.52.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Statiq.CodeAnalysis" Version="1.0.0-beta.72" />
|
||||
<PackageReference Include="Statiq.Common" Version="1.0.0-beta.72" />
|
||||
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.60" />
|
||||
<PackageReference Include="MinVer" PrivateAssets="All" Version="6.0.0" />
|
||||
<PackageReference Include="Statiq.Web.Netlify" Version="1.0.0-beta.60" />
|
||||
<PackageReference Include="Microsoft.Playwright" Version="1.19.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Statiq.CodeAnalysis" Version="1.0.0-beta.58" />
|
||||
<PackageReference Include="Statiq.Common" Version="1.0.0-beta.58" />
|
||||
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.44" />
|
||||
<PackageReference Include="MinVer" PrivateAssets="All" Version="2.5.0" />
|
||||
<PackageReference Include="Statiq.Web.Netlify" Version="1.0.0-beta.44" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -23,9 +23,8 @@ namespace Docs
|
||||
{
|
||||
"../../src/Spectre.Console/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||
"../../src/Spectre.Console.Cli/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||
"../../src/Spectre.Console.Testing/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||
"../../src/Extensions/Spectre.Console.ImageSharp/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||
"../../src/Extensions/Spectre.Console.Json/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs"
|
||||
"../../src/Spectre.Console.ImageSharp/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||
"../../src/Spectre.Console.Json/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs"
|
||||
})
|
||||
.AddSetting(Constants.ExampleSourceFiles, new List<string>
|
||||
{
|
||||
|
@ -3,7 +3,7 @@
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"microsoft.playwright.cli": {
|
||||
"version": "1.2.3",
|
||||
"version": "1.2.2",
|
||||
"commands": [
|
||||
"playwright"
|
||||
]
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "9.0.202",
|
||||
"version": "8.0.100",
|
||||
"rollForward": "latestFeature"
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ For all available spinners, see https://jsfiddle.net/sindresorhus/2eLtsbey/embed
|
||||
|
||||
## Usage
|
||||
|
||||
Spinners can be used with [Progress](xref:live-progress) and [Status](xref:live-status).
|
||||
Spinners can be used with [Progress](xref:progress) and [Status](xref:status).
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Status()
|
||||
|
@ -6,7 +6,6 @@ Highlights:
|
||||
- Dim, Invert
|
||||
- Conceal, slowblink, rapidblink
|
||||
- Links
|
||||
Xref: appendix-styles
|
||||
---
|
||||
|
||||
Note that what styles that can be used is defined by the system or your terminal software, and may not appear as they should.
|
||||
@ -49,7 +48,7 @@ Note that what styles that can be used is defined by the system or your terminal
|
||||
<td>Shows text with a horizontal line through the center</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>link</code></td>
|
||||
<td><code>link</link></td>
|
||||
<td>Creates a clickable link within text</td>
|
||||
</tr>
|
||||
</table>
|
@ -1,2 +0,0 @@
|
||||
{"version": 2, "width": 40, "height": 3, "timestamp": 1667342769, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}}
|
||||
[0.0, "o", "\u001b[H\u001b[2B\u001b[38;5;9;48;5;0mSpectre!\u001b[0m"]
|
@ -1,332 +0,0 @@
|
||||
{"version": 2, "width": 42, "height": 4, "title": "await-spinner (plain)", "env": {"TERM": "Spectre.Console"}}
|
||||
[0, "o", "Loading the rocket ship "]
|
||||
[0, "o", "\u001B[?25l"]
|
||||
[0, "o", "\u280B"]
|
||||
[0, "o", "\u001B[1D"]
|
||||
[0.094, "o", "\u001B[?25l"]
|
||||
[0.094, "o", "\u2819"]
|
||||
[0.094, "o", "\u001B[1D"]
|
||||
[0.188, "o", "\u001B[?25l"]
|
||||
[0.188, "o", "\u2839"]
|
||||
[0.188, "o", "\u001B[1D"]
|
||||
[0.266, "o", "\u001B[?25l"]
|
||||
[0.266, "o", "\u2838"]
|
||||
[0.266, "o", "\u001B[1D"]
|
||||
[0.36, "o", "\u001B[?25l"]
|
||||
[0.36, "o", "\u283C"]
|
||||
[0.36, "o", "\u001B[1D"]
|
||||
[0.453, "o", "\u001B[?25l"]
|
||||
[0.453, "o", "\u2834"]
|
||||
[0.453, "o", "\u001B[1D"]
|
||||
[0.563, "o", "\u001B[?25l"]
|
||||
[0.563, "o", "\u2826"]
|
||||
[0.563, "o", "\u001B[1D"]
|
||||
[0.656, "o", "\u001B[?25l"]
|
||||
[0.656, "o", "\u2827"]
|
||||
[0.656, "o", "\u001B[1D"]
|
||||
[0.75, "o", "\u001B[?25l"]
|
||||
[0.75, "o", "\u2807"]
|
||||
[0.75, "o", "\u001B[1D"]
|
||||
[0.844, "o", "\u001B[?25l"]
|
||||
[0.844, "o", "\u280F"]
|
||||
[0.844, "o", "\u001B[1D"]
|
||||
[0.922, "o", "\u001B[?25l"]
|
||||
[0.922, "o", "\u280B"]
|
||||
[0.922, "o", "\u001B[1D"]
|
||||
[1.016, "o", "\u001B[?25l"]
|
||||
[1.016, "o", "\u2819"]
|
||||
[1.016, "o", "\u001B[1D"]
|
||||
[1.11, "o", "\u001B[?25l"]
|
||||
[1.11, "o", "\u2839"]
|
||||
[1.11, "o", "\u001B[1D"]
|
||||
[1.203, "o", "\u001B[?25l"]
|
||||
[1.203, "o", "\u2838"]
|
||||
[1.203, "o", "\u001B[1D"]
|
||||
[1.297, "o", "\u001B[?25l"]
|
||||
[1.297, "o", "\u283C"]
|
||||
[1.297, "o", "\u001B[1D"]
|
||||
[1.391, "o", "\u001B[?25l"]
|
||||
[1.391, "o", "\u2834"]
|
||||
[1.391, "o", "\u001B[1D"]
|
||||
[1.485, "o", "\u001B[?25l"]
|
||||
[1.485, "o", "\u2826"]
|
||||
[1.485, "o", "\u001B[1D"]
|
||||
[1.578, "o", "\u001B[?25l"]
|
||||
[1.578, "o", "\u2827"]
|
||||
[1.578, "o", "\u001B[1D"]
|
||||
[1.672, "o", "\u001B[?25l"]
|
||||
[1.672, "o", "\u2807"]
|
||||
[1.672, "o", "\u001B[1D"]
|
||||
[1.75, "o", "\u001B[?25l"]
|
||||
[1.75, "o", "\u280F"]
|
||||
[1.75, "o", "\u001B[1D"]
|
||||
[1.828, "o", "\u001B[?25l"]
|
||||
[1.828, "o", "\u280B"]
|
||||
[1.828, "o", "\u001B[1D"]
|
||||
[1.906, "o", "\u001B[?25l"]
|
||||
[1.906, "o", "\u2819"]
|
||||
[1.906, "o", "\u001B[1D"]
|
||||
[2, "o", "\u001B[?25l"]
|
||||
[2, "o", "\u2839"]
|
||||
[2, "o", "\u001B[1D"]
|
||||
[2.11, "o", "\u001B[?25l"]
|
||||
[2.11, "o", "\u2838"]
|
||||
[2.11, "o", "\u001B[1D"]
|
||||
[2.203, "o", "\u001B[?25l"]
|
||||
[2.203, "o", "\u283C"]
|
||||
[2.203, "o", "\u001B[1D"]
|
||||
[2.297, "o", "\u001B[?25l"]
|
||||
[2.297, "o", "\u2834"]
|
||||
[2.297, "o", "\u001B[1D"]
|
||||
[2.391, "o", "\u001B[?25l"]
|
||||
[2.391, "o", "\u2826"]
|
||||
[2.391, "o", "\u001B[1D"]
|
||||
[2.485, "o", "\u001B[?25l"]
|
||||
[2.485, "o", "\u2827"]
|
||||
[2.485, "o", "\u001B[1D"]
|
||||
[2.578, "o", "\u001B[?25l"]
|
||||
[2.578, "o", "\u2807"]
|
||||
[2.578, "o", "\u001B[1D"]
|
||||
[2.656, "o", "\u001B[?25l"]
|
||||
[2.656, "o", "\u280F"]
|
||||
[2.656, "o", "\u001B[1D"]
|
||||
[2.735, "o", "\u001B[?25l"]
|
||||
[2.735, "o", "\u280B"]
|
||||
[2.735, "o", "\u001B[1D"]
|
||||
[2.828, "o", "\u001B[?25l"]
|
||||
[2.828, "o", "\u2819"]
|
||||
[2.828, "o", "\u001B[1D"]
|
||||
[2.922, "o", "\u001B[?25l"]
|
||||
[2.922, "o", "\u2839"]
|
||||
[2.922, "o", "\u001B[1D"]
|
||||
[3.016, "o", "\u001B[?25l"]
|
||||
[3.016, "o", "\u2838"]
|
||||
[3.016, "o", "\u001B[1D"]
|
||||
[3.094, "o", "\u001B[?25l"]
|
||||
[3.094, "o", "\u283C"]
|
||||
[3.094, "o", "\u001B[1D"]
|
||||
[3.188, "o", "\u001B[?25l"]
|
||||
[3.188, "o", "\u2834"]
|
||||
[3.188, "o", "\u001B[1D"]
|
||||
[3.281, "o", "\u001B[?25l"]
|
||||
[3.281, "o", "\u2826"]
|
||||
[3.281, "o", "\u001B[1D"]
|
||||
[3.375, "o", "\u001B[?25l"]
|
||||
[3.375, "o", "\u2827"]
|
||||
[3.375, "o", "\u001B[1D"]
|
||||
[3.453, "o", "\u001B[?25l"]
|
||||
[3.453, "o", "\u2807"]
|
||||
[3.453, "o", "\u001B[1D"]
|
||||
[3.516, "o", " "]
|
||||
[3.516, "o", "\u001B[1D"]
|
||||
[3.516, "o", "\u001B[?25h"]
|
||||
[3.516, "o", "\u001B[32mDone\u001B[0m\r\n"]
|
||||
[3.516, "o", "Firing up the engines "]
|
||||
[3.516, "o", "\u001B[?25l"]
|
||||
[3.516, "o", "[ ]"]
|
||||
[3.516, "o", "\u001B[6D"]
|
||||
[3.61, "o", "\u001B[?25l"]
|
||||
[3.61, "o", "[= ]"]
|
||||
[3.61, "o", "\u001B[6D"]
|
||||
[3.703, "o", "\u001B[?25l"]
|
||||
[3.703, "o", "[== ]"]
|
||||
[3.703, "o", "\u001B[6D"]
|
||||
[3.797, "o", "\u001B[?25l"]
|
||||
[3.797, "o", "[=== ]"]
|
||||
[3.797, "o", "\u001B[6D"]
|
||||
[3.875, "o", "\u001B[?25l"]
|
||||
[3.875, "o", "[ ===]"]
|
||||
[3.875, "o", "\u001B[6D"]
|
||||
[3.953, "o", "\u001B[?25l"]
|
||||
[3.953, "o", "[ ==]"]
|
||||
[3.953, "o", "\u001B[6D"]
|
||||
[4.063, "o", "\u001B[?25l"]
|
||||
[4.063, "o", "[ =]"]
|
||||
[4.063, "o", "\u001B[6D"]
|
||||
[4.156, "o", "\u001B[?25l"]
|
||||
[4.156, "o", "[ ]"]
|
||||
[4.156, "o", "\u001B[6D"]
|
||||
[4.25, "o", "\u001B[?25l"]
|
||||
[4.25, "o", "[ =]"]
|
||||
[4.25, "o", "\u001B[6D"]
|
||||
[4.328, "o", "\u001B[?25l"]
|
||||
[4.328, "o", "[ ==]"]
|
||||
[4.328, "o", "\u001B[6D"]
|
||||
[4.406, "o", "\u001B[?25l"]
|
||||
[4.406, "o", "[ ===]"]
|
||||
[4.406, "o", "\u001B[6D"]
|
||||
[4.5, "o", "\u001B[?25l"]
|
||||
[4.5, "o", "[====]"]
|
||||
[4.5, "o", "\u001B[6D"]
|
||||
[4.594, "o", "\u001B[?25l"]
|
||||
[4.594, "o", "[=== ]"]
|
||||
[4.594, "o", "\u001B[6D"]
|
||||
[4.688, "o", "\u001B[?25l"]
|
||||
[4.688, "o", "[== ]"]
|
||||
[4.688, "o", "\u001B[6D"]
|
||||
[4.781, "o", "\u001B[?25l"]
|
||||
[4.781, "o", "[= ]"]
|
||||
[4.781, "o", "\u001B[6D"]
|
||||
[4.86, "o", "\u001B[?25l"]
|
||||
[4.86, "o", "[ ]"]
|
||||
[4.86, "o", "\u001B[6D"]
|
||||
[4.953, "o", "\u001B[?25l"]
|
||||
[4.953, "o", "[= ]"]
|
||||
[4.953, "o", "\u001B[6D"]
|
||||
[5.031, "o", "\u001B[?25l"]
|
||||
[5.031, "o", "[== ]"]
|
||||
[5.031, "o", "\u001B[6D"]
|
||||
[5.125, "o", "\u001B[?25l"]
|
||||
[5.125, "o", "[=== ]"]
|
||||
[5.125, "o", "\u001B[6D"]
|
||||
[5.219, "o", "\u001B[?25l"]
|
||||
[5.219, "o", "[ ===]"]
|
||||
[5.219, "o", "\u001B[6D"]
|
||||
[5.313, "o", "\u001B[?25l"]
|
||||
[5.313, "o", "[ ==]"]
|
||||
[5.313, "o", "\u001B[6D"]
|
||||
[5.422, "o", "\u001B[?25l"]
|
||||
[5.422, "o", "[ =]"]
|
||||
[5.422, "o", "\u001B[6D"]
|
||||
[5.5, "o", "\u001B[?25l"]
|
||||
[5.5, "o", "[ ]"]
|
||||
[5.5, "o", "\u001B[6D"]
|
||||
[5.594, "o", "\u001B[?25l"]
|
||||
[5.594, "o", "[ =]"]
|
||||
[5.594, "o", "\u001B[6D"]
|
||||
[5.672, "o", "\u001B[?25l"]
|
||||
[5.672, "o", "[ ==]"]
|
||||
[5.672, "o", "\u001B[6D"]
|
||||
[5.766, "o", "\u001B[?25l"]
|
||||
[5.766, "o", "[ ===]"]
|
||||
[5.766, "o", "\u001B[6D"]
|
||||
[5.86, "o", "\u001B[?25l"]
|
||||
[5.86, "o", "[====]"]
|
||||
[5.86, "o", "\u001B[6D"]
|
||||
[5.953, "o", "\u001B[?25l"]
|
||||
[5.969, "o", "[=== ]"]
|
||||
[5.969, "o", "\u001B[6D"]
|
||||
[6.063, "o", "\u001B[?25l"]
|
||||
[6.063, "o", "[== ]"]
|
||||
[6.063, "o", "\u001B[6D"]
|
||||
[6.156, "o", "\u001B[?25l"]
|
||||
[6.156, "o", "[= ]"]
|
||||
[6.156, "o", "\u001B[6D"]
|
||||
[6.25, "o", "\u001B[?25l"]
|
||||
[6.25, "o", "[ ]"]
|
||||
[6.25, "o", "\u001B[6D"]
|
||||
[6.328, "o", "\u001B[?25l"]
|
||||
[6.328, "o", "[= ]"]
|
||||
[6.328, "o", "\u001B[6D"]
|
||||
[6.422, "o", "\u001B[?25l"]
|
||||
[6.422, "o", "[== ]"]
|
||||
[6.422, "o", "\u001B[6D"]
|
||||
[6.516, "o", "\u001B[?25l"]
|
||||
[6.516, "o", "[=== ]"]
|
||||
[6.516, "o", "\u001B[6D"]
|
||||
[6.61, "o", "\u001B[?25l"]
|
||||
[6.61, "o", "[ ===]"]
|
||||
[6.61, "o", "\u001B[6D"]
|
||||
[6.703, "o", "\u001B[?25l"]
|
||||
[6.703, "o", "[ ==]"]
|
||||
[6.703, "o", "\u001B[6D"]
|
||||
[6.797, "o", "\u001B[?25l"]
|
||||
[6.797, "o", "[ =]"]
|
||||
[6.797, "o", "\u001B[6D"]
|
||||
[6.891, "o", "\u001B[?25l"]
|
||||
[6.891, "o", "[ ]"]
|
||||
[6.891, "o", "\u001B[6D"]
|
||||
[6.922, "o", " "]
|
||||
[6.922, "o", "\u001B[6D"]
|
||||
[6.922, "o", "\u001B[?25h"]
|
||||
[6.922, "o", "\u001B[32mDone\u001B[0m\r\n"]
|
||||
[6.922, "o", "Blasting into orbit "]
|
||||
[6.922, "o", "\u001B[?25l"]
|
||||
[6.922, "o", "\u2631"]
|
||||
[6.922, "o", "\u001B[1D"]
|
||||
[7.031, "o", "\u001B[?25l"]
|
||||
[7.031, "o", "\u2632"]
|
||||
[7.031, "o", "\u001B[1D"]
|
||||
[7.141, "o", "\u001B[?25l"]
|
||||
[7.141, "o", "\u2634"]
|
||||
[7.141, "o", "\u001B[1D"]
|
||||
[7.25, "o", "\u001B[?25l"]
|
||||
[7.25, "o", "\u2631"]
|
||||
[7.25, "o", "\u001B[1D"]
|
||||
[7.36, "o", "\u001B[?25l"]
|
||||
[7.36, "o", "\u2632"]
|
||||
[7.36, "o", "\u001B[1D"]
|
||||
[7.485, "o", "\u001B[?25l"]
|
||||
[7.485, "o", "\u2634"]
|
||||
[7.485, "o", "\u001B[1D"]
|
||||
[7.594, "o", "\u001B[?25l"]
|
||||
[7.594, "o", "\u2631"]
|
||||
[7.594, "o", "\u001B[1D"]
|
||||
[7.703, "o", "\u001B[?25l"]
|
||||
[7.703, "o", "\u2632"]
|
||||
[7.703, "o", "\u001B[1D"]
|
||||
[7.813, "o", "\u001B[?25l"]
|
||||
[7.813, "o", "\u2634"]
|
||||
[7.813, "o", "\u001B[1D"]
|
||||
[7.922, "o", "\u001B[?25l"]
|
||||
[7.922, "o", "\u2631"]
|
||||
[7.922, "o", "\u001B[1D"]
|
||||
[8.031, "o", "\u001B[?25l"]
|
||||
[8.031, "o", "\u2632"]
|
||||
[8.031, "o", "\u001B[1D"]
|
||||
[8.141, "o", "\u001B[?25l"]
|
||||
[8.141, "o", "\u2634"]
|
||||
[8.141, "o", "\u001B[1D"]
|
||||
[8.25, "o", "\u001B[?25l"]
|
||||
[8.25, "o", "\u2631"]
|
||||
[8.25, "o", "\u001B[1D"]
|
||||
[8.375, "o", "\u001B[?25l"]
|
||||
[8.375, "o", "\u2632"]
|
||||
[8.375, "o", "\u001B[1D"]
|
||||
[8.485, "o", "\u001B[?25l"]
|
||||
[8.485, "o", "\u2634"]
|
||||
[8.485, "o", "\u001B[1D"]
|
||||
[8.594, "o", "\u001B[?25l"]
|
||||
[8.594, "o", "\u2631"]
|
||||
[8.594, "o", "\u001B[1D"]
|
||||
[8.703, "o", "\u001B[?25l"]
|
||||
[8.703, "o", "\u2632"]
|
||||
[8.703, "o", "\u001B[1D"]
|
||||
[8.813, "o", "\u001B[?25l"]
|
||||
[8.813, "o", "\u2634"]
|
||||
[8.813, "o", "\u001B[1D"]
|
||||
[8.938, "o", "\u001B[?25l"]
|
||||
[8.938, "o", "\u2631"]
|
||||
[8.938, "o", "\u001B[1D"]
|
||||
[9.047, "o", "\u001B[?25l"]
|
||||
[9.047, "o", "\u2632"]
|
||||
[9.047, "o", "\u001B[1D"]
|
||||
[9.156, "o", "\u001B[?25l"]
|
||||
[9.156, "o", "\u2634"]
|
||||
[9.156, "o", "\u001B[1D"]
|
||||
[9.266, "o", "\u001B[?25l"]
|
||||
[9.266, "o", "\u2631"]
|
||||
[9.266, "o", "\u001B[1D"]
|
||||
[9.375, "o", "\u001B[?25l"]
|
||||
[9.375, "o", "\u2632"]
|
||||
[9.375, "o", "\u001B[1D"]
|
||||
[9.485, "o", "\u001B[?25l"]
|
||||
[9.485, "o", "\u2634"]
|
||||
[9.485, "o", "\u001B[1D"]
|
||||
[9.594, "o", "\u001B[?25l"]
|
||||
[9.594, "o", "\u2631"]
|
||||
[9.594, "o", "\u001B[1D"]
|
||||
[9.719, "o", "\u001B[?25l"]
|
||||
[9.719, "o", "\u2632"]
|
||||
[9.719, "o", "\u001B[1D"]
|
||||
[9.828, "o", "\u001B[?25l"]
|
||||
[9.828, "o", "\u2634"]
|
||||
[9.828, "o", "\u001B[1D"]
|
||||
[9.938, "o", "\u001B[?25l"]
|
||||
[9.938, "o", "\u2631"]
|
||||
[9.938, "o", "\u001B[1D"]
|
||||
[9.953, "o", " "]
|
||||
[9.953, "o", "\u001B[1D"]
|
||||
[9.953, "o", "\u001B[?25h"]
|
||||
[9.953, "o", "\u001B[31mOh no\u001B[0m\r\n"]
|
||||
|
@ -1,326 +0,0 @@
|
||||
{"version": 2, "width": 42, "height": 4, "title": "await-spinner (rich)", "env": {"TERM": "Spectre.Console"}}
|
||||
[0, "o", "Loading the rocket ship "]
|
||||
[0, "o", "\u001B[?25l"]
|
||||
[0, "o", "\u280B"]
|
||||
[0, "o", "\u001B[1D"]
|
||||
[0.094, "o", "\u001B[?25l"]
|
||||
[0.094, "o", "\u2819"]
|
||||
[0.094, "o", "\u001B[1D"]
|
||||
[0.172, "o", "\u001B[?25l"]
|
||||
[0.172, "o", "\u2839"]
|
||||
[0.172, "o", "\u001B[1D"]
|
||||
[0.266, "o", "\u001B[?25l"]
|
||||
[0.266, "o", "\u2838"]
|
||||
[0.266, "o", "\u001B[1D"]
|
||||
[0.36, "o", "\u001B[?25l"]
|
||||
[0.36, "o", "\u283C"]
|
||||
[0.36, "o", "\u001B[1D"]
|
||||
[0.453, "o", "\u001B[?25l"]
|
||||
[0.453, "o", "\u2834"]
|
||||
[0.453, "o", "\u001B[1D"]
|
||||
[0.547, "o", "\u001B[?25l"]
|
||||
[0.547, "o", "\u2826"]
|
||||
[0.547, "o", "\u001B[1D"]
|
||||
[0.641, "o", "\u001B[?25l"]
|
||||
[0.641, "o", "\u2827"]
|
||||
[0.641, "o", "\u001B[1D"]
|
||||
[0.719, "o", "\u001B[?25l"]
|
||||
[0.719, "o", "\u2807"]
|
||||
[0.719, "o", "\u001B[1D"]
|
||||
[0.797, "o", "\u001B[?25l"]
|
||||
[0.797, "o", "\u280F"]
|
||||
[0.797, "o", "\u001B[1D"]
|
||||
[0.891, "o", "\u001B[?25l"]
|
||||
[0.891, "o", "\u280B"]
|
||||
[0.891, "o", "\u001B[1D"]
|
||||
[0.969, "o", "\u001B[?25l"]
|
||||
[0.969, "o", "\u2819"]
|
||||
[0.969, "o", "\u001B[1D"]
|
||||
[1.078, "o", "\u001B[?25l"]
|
||||
[1.078, "o", "\u2839"]
|
||||
[1.094, "o", "\u001B[1D"]
|
||||
[1.25, "o", "\u001B[?25l"]
|
||||
[1.25, "o", "\u2838"]
|
||||
[1.266, "o", "\u001B[1D"]
|
||||
[1.407, "o", "\u001B[?25l"]
|
||||
[1.407, "o", "\u283C"]
|
||||
[1.422, "o", "\u001B[1D"]
|
||||
[1.532, "o", "\u001B[?25l"]
|
||||
[1.532, "o", "\u2834"]
|
||||
[1.532, "o", "\u001B[1D"]
|
||||
[1.61, "o", "\u001B[?25l"]
|
||||
[1.61, "o", "\u2826"]
|
||||
[1.61, "o", "\u001B[1D"]
|
||||
[1.703, "o", "\u001B[?25l"]
|
||||
[1.703, "o", "\u2827"]
|
||||
[1.703, "o", "\u001B[1D"]
|
||||
[1.782, "o", "\u001B[?25l"]
|
||||
[1.782, "o", "\u2807"]
|
||||
[1.782, "o", "\u001B[1D"]
|
||||
[1.86, "o", "\u001B[?25l"]
|
||||
[1.86, "o", "\u280F"]
|
||||
[1.86, "o", "\u001B[1D"]
|
||||
[1.953, "o", "\u001B[?25l"]
|
||||
[1.953, "o", "\u280B"]
|
||||
[1.953, "o", "\u001B[1D"]
|
||||
[2.047, "o", "\u001B[?25l"]
|
||||
[2.047, "o", "\u2819"]
|
||||
[2.047, "o", "\u001B[1D"]
|
||||
[2.125, "o", "\u001B[?25l"]
|
||||
[2.125, "o", "\u2839"]
|
||||
[2.125, "o", "\u001B[1D"]
|
||||
[2.219, "o", "\u001B[?25l"]
|
||||
[2.219, "o", "\u2838"]
|
||||
[2.219, "o", "\u001B[1D"]
|
||||
[2.313, "o", "\u001B[?25l"]
|
||||
[2.313, "o", "\u283C"]
|
||||
[2.313, "o", "\u001B[1D"]
|
||||
[2.407, "o", "\u001B[?25l"]
|
||||
[2.407, "o", "\u2834"]
|
||||
[2.407, "o", "\u001B[1D"]
|
||||
[2.5, "o", "\u001B[?25l"]
|
||||
[2.5, "o", "\u2826"]
|
||||
[2.5, "o", "\u001B[1D"]
|
||||
[2.594, "o", "\u001B[?25l"]
|
||||
[2.594, "o", "\u2827"]
|
||||
[2.594, "o", "\u001B[1D"]
|
||||
[2.688, "o", "\u001B[?25l"]
|
||||
[2.688, "o", "\u2807"]
|
||||
[2.688, "o", "\u001B[1D"]
|
||||
[2.782, "o", "\u001B[?25l"]
|
||||
[2.782, "o", "\u280F"]
|
||||
[2.782, "o", "\u001B[1D"]
|
||||
[2.875, "o", "\u001B[?25l"]
|
||||
[2.875, "o", "\u280B"]
|
||||
[2.875, "o", "\u001B[1D"]
|
||||
[2.969, "o", "\u001B[?25l"]
|
||||
[2.969, "o", "\u2819"]
|
||||
[2.969, "o", "\u001B[1D"]
|
||||
[3.063, "o", "\u001B[?25l"]
|
||||
[3.063, "o", "\u2839"]
|
||||
[3.063, "o", "\u001B[1D"]
|
||||
[3.157, "o", "\u001B[?25l"]
|
||||
[3.157, "o", "\u2838"]
|
||||
[3.157, "o", "\u001B[1D"]
|
||||
[3.25, "o", "\u001B[?25l"]
|
||||
[3.25, "o", "\u283C"]
|
||||
[3.25, "o", "\u001B[1D"]
|
||||
[3.344, "o", "\u001B[?25l"]
|
||||
[3.344, "o", "\u2834"]
|
||||
[3.344, "o", "\u001B[1D"]
|
||||
[3.469, "o", "\u001B[?25l"]
|
||||
[3.469, "o", "\u2826"]
|
||||
[3.469, "o", "\u001B[1D"]
|
||||
[3.563, "o", "\u001B[?25l"]
|
||||
[3.563, "o", "\u2827"]
|
||||
[3.563, "o", "\u001B[1D"]
|
||||
[3.563, "o", " "]
|
||||
[3.563, "o", "\u001B[1D"]
|
||||
[3.563, "o", "\u001B[?25h"]
|
||||
[3.563, "o", "\u001B[38;5;2mDone\u001B[0m\r\n"]
|
||||
[3.563, "o", "Firing up the engines "]
|
||||
[3.563, "o", "\u001B[?25l"]
|
||||
[3.563, "o", "[ ]"]
|
||||
[3.563, "o", "\u001B[6D"]
|
||||
[3.672, "o", "\u001B[?25l"]
|
||||
[3.672, "o", "[= ]"]
|
||||
[3.672, "o", "\u001B[6D"]
|
||||
[3.75, "o", "\u001B[?25l"]
|
||||
[3.75, "o", "[== ]"]
|
||||
[3.75, "o", "\u001B[6D"]
|
||||
[3.844, "o", "\u001B[?25l"]
|
||||
[3.844, "o", "[=== ]"]
|
||||
[3.844, "o", "\u001B[6D"]
|
||||
[3.953, "o", "\u001B[?25l"]
|
||||
[3.953, "o", "[ ===]"]
|
||||
[3.953, "o", "\u001B[6D"]
|
||||
[4.047, "o", "\u001B[?25l"]
|
||||
[4.047, "o", "[ ==]"]
|
||||
[4.047, "o", "\u001B[6D"]
|
||||
[4.157, "o", "\u001B[?25l"]
|
||||
[4.157, "o", "[ =]"]
|
||||
[4.157, "o", "\u001B[6D"]
|
||||
[4.25, "o", "\u001B[?25l"]
|
||||
[4.25, "o", "[ ]"]
|
||||
[4.25, "o", "\u001B[6D"]
|
||||
[4.344, "o", "\u001B[?25l"]
|
||||
[4.344, "o", "[ =]"]
|
||||
[4.344, "o", "\u001B[6D"]
|
||||
[4.438, "o", "\u001B[?25l"]
|
||||
[4.438, "o", "[ ==]"]
|
||||
[4.438, "o", "\u001B[6D"]
|
||||
[4.532, "o", "\u001B[?25l"]
|
||||
[4.532, "o", "[ ===]"]
|
||||
[4.532, "o", "\u001B[6D"]
|
||||
[4.625, "o", "\u001B[?25l"]
|
||||
[4.625, "o", "[====]"]
|
||||
[4.625, "o", "\u001B[6D"]
|
||||
[4.719, "o", "\u001B[?25l"]
|
||||
[4.719, "o", "[=== ]"]
|
||||
[4.719, "o", "\u001B[6D"]
|
||||
[4.828, "o", "\u001B[?25l"]
|
||||
[4.844, "o", "[== ]"]
|
||||
[4.86, "o", "\u001B[6D"]
|
||||
[4.953, "o", "\u001B[?25l"]
|
||||
[4.953, "o", "[= ]"]
|
||||
[4.953, "o", "\u001B[6D"]
|
||||
[5.047, "o", "\u001B[?25l"]
|
||||
[5.047, "o", "[ ]"]
|
||||
[5.047, "o", "\u001B[6D"]
|
||||
[5.141, "o", "\u001B[?25l"]
|
||||
[5.141, "o", "[= ]"]
|
||||
[5.141, "o", "\u001B[6D"]
|
||||
[5.235, "o", "\u001B[?25l"]
|
||||
[5.235, "o", "[== ]"]
|
||||
[5.235, "o", "\u001B[6D"]
|
||||
[5.328, "o", "\u001B[?25l"]
|
||||
[5.328, "o", "[=== ]"]
|
||||
[5.328, "o", "\u001B[6D"]
|
||||
[5.422, "o", "\u001B[?25l"]
|
||||
[5.422, "o", "[ ===]"]
|
||||
[5.422, "o", "\u001B[6D"]
|
||||
[5.532, "o", "\u001B[?25l"]
|
||||
[5.532, "o", "[ ==]"]
|
||||
[5.532, "o", "\u001B[6D"]
|
||||
[5.625, "o", "\u001B[?25l"]
|
||||
[5.625, "o", "[ =]"]
|
||||
[5.625, "o", "\u001B[6D"]
|
||||
[5.719, "o", "\u001B[?25l"]
|
||||
[5.719, "o", "[ ]"]
|
||||
[5.719, "o", "\u001B[6D"]
|
||||
[5.813, "o", "\u001B[?25l"]
|
||||
[5.813, "o", "[ =]"]
|
||||
[5.813, "o", "\u001B[6D"]
|
||||
[5.907, "o", "\u001B[?25l"]
|
||||
[5.907, "o", "[ ==]"]
|
||||
[5.907, "o", "\u001B[6D"]
|
||||
[6, "o", "\u001B[?25l"]
|
||||
[6, "o", "[ ===]"]
|
||||
[6, "o", "\u001B[6D"]
|
||||
[6.094, "o", "\u001B[?25l"]
|
||||
[6.094, "o", "[====]"]
|
||||
[6.094, "o", "\u001B[6D"]
|
||||
[6.188, "o", "\u001B[?25l"]
|
||||
[6.188, "o", "[=== ]"]
|
||||
[6.188, "o", "\u001B[6D"]
|
||||
[6.282, "o", "\u001B[?25l"]
|
||||
[6.282, "o", "[== ]"]
|
||||
[6.282, "o", "\u001B[6D"]
|
||||
[6.375, "o", "\u001B[?25l"]
|
||||
[6.375, "o", "[= ]"]
|
||||
[6.375, "o", "\u001B[6D"]
|
||||
[6.453, "o", "\u001B[?25l"]
|
||||
[6.453, "o", "[ ]"]
|
||||
[6.453, "o", "\u001B[6D"]
|
||||
[6.547, "o", "\u001B[?25l"]
|
||||
[6.547, "o", "[= ]"]
|
||||
[6.547, "o", "\u001B[6D"]
|
||||
[6.625, "o", "\u001B[?25l"]
|
||||
[6.625, "o", "[== ]"]
|
||||
[6.625, "o", "\u001B[6D"]
|
||||
[6.703, "o", "\u001B[?25l"]
|
||||
[6.703, "o", "[=== ]"]
|
||||
[6.703, "o", "\u001B[6D"]
|
||||
[6.797, "o", "\u001B[?25l"]
|
||||
[6.797, "o", "[ ===]"]
|
||||
[6.797, "o", "\u001B[6D"]
|
||||
[6.891, "o", "\u001B[?25l"]
|
||||
[6.891, "o", "[ ==]"]
|
||||
[6.891, "o", "\u001B[6D"]
|
||||
[6.969, "o", " "]
|
||||
[6.969, "o", "\u001B[6D"]
|
||||
[6.969, "o", "\u001B[?25h"]
|
||||
[6.969, "o", "\u001B[38;5;2mDone\u001B[0m\r\n"]
|
||||
[6.969, "o", "Blasting into orbit "]
|
||||
[6.969, "o", "\u001B[?25l"]
|
||||
[6.969, "o", "\u2631"]
|
||||
[6.969, "o", "\u001B[1D"]
|
||||
[7.078, "o", "\u001B[?25l"]
|
||||
[7.078, "o", "\u2632"]
|
||||
[7.078, "o", "\u001B[1D"]
|
||||
[7.172, "o", "\u001B[?25l"]
|
||||
[7.172, "o", "\u2634"]
|
||||
[7.172, "o", "\u001B[1D"]
|
||||
[7.282, "o", "\u001B[?25l"]
|
||||
[7.282, "o", "\u2631"]
|
||||
[7.282, "o", "\u001B[1D"]
|
||||
[7.375, "o", "\u001B[?25l"]
|
||||
[7.375, "o", "\u2632"]
|
||||
[7.375, "o", "\u001B[1D"]
|
||||
[7.485, "o", "\u001B[?25l"]
|
||||
[7.485, "o", "\u2634"]
|
||||
[7.485, "o", "\u001B[1D"]
|
||||
[7.594, "o", "\u001B[?25l"]
|
||||
[7.594, "o", "\u2631"]
|
||||
[7.594, "o", "\u001B[1D"]
|
||||
[7.703, "o", "\u001B[?25l"]
|
||||
[7.703, "o", "\u2632"]
|
||||
[7.703, "o", "\u001B[1D"]
|
||||
[7.813, "o", "\u001B[?25l"]
|
||||
[7.813, "o", "\u2634"]
|
||||
[7.813, "o", "\u001B[1D"]
|
||||
[7.922, "o", "\u001B[?25l"]
|
||||
[7.922, "o", "\u2631"]
|
||||
[7.922, "o", "\u001B[1D"]
|
||||
[8.032, "o", "\u001B[?25l"]
|
||||
[8.032, "o", "\u2632"]
|
||||
[8.032, "o", "\u001B[1D"]
|
||||
[8.125, "o", "\u001B[?25l"]
|
||||
[8.125, "o", "\u2634"]
|
||||
[8.125, "o", "\u001B[1D"]
|
||||
[8.235, "o", "\u001B[?25l"]
|
||||
[8.235, "o", "\u2631"]
|
||||
[8.235, "o", "\u001B[1D"]
|
||||
[8.344, "o", "\u001B[?25l"]
|
||||
[8.344, "o", "\u2632"]
|
||||
[8.344, "o", "\u001B[1D"]
|
||||
[8.453, "o", "\u001B[?25l"]
|
||||
[8.453, "o", "\u2634"]
|
||||
[8.453, "o", "\u001B[1D"]
|
||||
[8.563, "o", "\u001B[?25l"]
|
||||
[8.563, "o", "\u2631"]
|
||||
[8.563, "o", "\u001B[1D"]
|
||||
[8.657, "o", "\u001B[?25l"]
|
||||
[8.657, "o", "\u2632"]
|
||||
[8.657, "o", "\u001B[1D"]
|
||||
[8.766, "o", "\u001B[?25l"]
|
||||
[8.766, "o", "\u2634"]
|
||||
[8.766, "o", "\u001B[1D"]
|
||||
[8.86, "o", "\u001B[?25l"]
|
||||
[8.86, "o", "\u2631"]
|
||||
[8.86, "o", "\u001B[1D"]
|
||||
[8.969, "o", "\u001B[?25l"]
|
||||
[8.969, "o", "\u2632"]
|
||||
[8.969, "o", "\u001B[1D"]
|
||||
[9.078, "o", "\u001B[?25l"]
|
||||
[9.078, "o", "\u2634"]
|
||||
[9.078, "o", "\u001B[1D"]
|
||||
[9.203, "o", "\u001B[?25l"]
|
||||
[9.203, "o", "\u2631"]
|
||||
[9.203, "o", "\u001B[1D"]
|
||||
[9.313, "o", "\u001B[?25l"]
|
||||
[9.313, "o", "\u2632"]
|
||||
[9.313, "o", "\u001B[1D"]
|
||||
[9.407, "o", "\u001B[?25l"]
|
||||
[9.407, "o", "\u2634"]
|
||||
[9.407, "o", "\u001B[1D"]
|
||||
[9.516, "o", "\u001B[?25l"]
|
||||
[9.516, "o", "\u2631"]
|
||||
[9.516, "o", "\u001B[1D"]
|
||||
[9.625, "o", "\u001B[?25l"]
|
||||
[9.625, "o", "\u2632"]
|
||||
[9.625, "o", "\u001B[1D"]
|
||||
[9.719, "o", "\u001B[?25l"]
|
||||
[9.719, "o", "\u2634"]
|
||||
[9.735, "o", "\u001B[1D"]
|
||||
[9.828, "o", "\u001B[?25l"]
|
||||
[9.828, "o", "\u2631"]
|
||||
[9.828, "o", "\u001B[1D"]
|
||||
[9.938, "o", "\u001B[?25l"]
|
||||
[9.938, "o", "\u2632"]
|
||||
[9.938, "o", "\u001B[1D"]
|
||||
[10, "o", " "]
|
||||
[10, "o", "\u001B[1D"]
|
||||
[10, "o", "\u001B[?25h"]
|
||||
[10, "o", "\u001B[38;5;9mOh no\u001B[0m\r\n"]
|
||||
|
@ -85,8 +85,10 @@ on the main thread.
|
||||
### Unit Testing Best Practices
|
||||
|
||||
For testing of console output, Spectre.Console has [`IAnsiConsole`](xref:T:Spectre.Console.IAnsiConsole) that can be
|
||||
injected into your application. The [Spectre.Console.Test](https://www.nuget.org/packages/Spectre.Console.Testing/)
|
||||
NuGet package contains utilities for capturing the console output for verification. See the [Unit Testing](cli/unit-testing) page for further guidance.
|
||||
injected into your application.
|
||||
The [Spectre.Console.Test](https://www.nuget.org/packages/Spectre.Console.Testing/) contains a set of utilities for
|
||||
capturing the output for verification, either manually or via a tool such
|
||||
as [Verify](https://github.com/VerifyTests/Verify).
|
||||
|
||||
### Analyzer for Best Practices
|
||||
|
||||
@ -94,31 +96,6 @@ Spectre.Console has an [analyzer](https://www.nuget.org/packages/Spectre.Console
|
||||
common errors in writing console output from above such as using multiple live rendering widgets simultaneously,
|
||||
or using the static `AnsiConsole` class when `IAnsiConsole` is available.
|
||||
|
||||
### Native AOT Support
|
||||
|
||||
Publishing your app as Native AOT with Spectre.Console produces an app that's self-contained and has been ahead-of-time (AOT) compiled to native code. Native AOT apps have faster startup time and smaller memory footprints. These apps can run on machines that don't have the .NET runtime installed.
|
||||
|
||||
To enable AOT support on your application, Add `<PublishAot>true</PublishAot>` to your project file.
|
||||
|
||||
```xml
|
||||
<PropertyGroup>
|
||||
<PublishAot>true</PublishAot>
|
||||
</PropertyGroup>
|
||||
```
|
||||
|
||||
Current Spectre.Console support for AOT:
|
||||
|
||||
* ☑️ Spectre.Console
|
||||
* ❌ Spectre.Console.Cli
|
||||
* ☑️ Spectre.Console.Json
|
||||
* ☑️ Spectre.Console.ImageSharp
|
||||
|
||||
Spectre.Console.Cli relies on reflection and discovering types at runtime, preventing it from currently supporting AOT.
|
||||
|
||||
Spectre.Console supports AOT, but with the following limitations
|
||||
|
||||
* `WriteException` will output a simple stacktrace and ignore any `ExceptionFormats` set.
|
||||
|
||||
### Configuring the Windows Terminal For Unicode and Emoji Support
|
||||
|
||||
Windows Terminal supports Unicode and Emoji. However, the shells such as Powershell and cmd.exe do not.
|
||||
|
@ -26,9 +26,9 @@ New features have been added, such as the ability to show separators between tab
|
||||
## Rendering
|
||||
|
||||
* Add .NET 8 support by [@patriksvensson](https://github.com/patriksvensson) in [#1367](https://github.com/spectreconsole/spectre.console/pull/1367)
|
||||
* Fixed render issue where writeline inside status caused corrupt output #415 #694 by [@fredrikbentzen](https://github.com/fredrikbentzen) in [#1132](https://github.com/spectreconsole/spectre.console/pull/1132)
|
||||
* Relax the SDK requirements by rolling forward to the latest feature by [@0xced](https://github.com/0xced) in [#1237](https://github.com/spectreconsole/spectre.console/pull/1237)
|
||||
* Add fix to avoid exception on rows with no children by [@jeppevammenkristensen](https://github.com/jeppevammenkristensen) in [#1241](https://github.com/spectreconsole/spectre.console/pull/1241)
|
||||
* Fixed render issue where writeline inside status caused corrupt output #415 #694 by [@fredrikbentzen](https://github.com/fredrikbentzen) in [#1132]([#1132](https://github.com/spectreconsole/spectre.console/pull/1132))
|
||||
* Relax the SDK requirements by rolling forward to the latest feature by [@0xced](https://github.com/0xced) in [#1237]([#1237](https://github.com/spectreconsole/spectre.console/pull/1237))
|
||||
* Add fix to avoid exception on rows with no children by [@jeppevammenkristensen](https://github.com/jeppevammenkristensen) in [#1241]([#1241](https://github.com/spectreconsole/spectre.console/pull/1241))
|
||||
* Set `end_of_line` to `LF` instead of `CRLF` by [@0xced](https://github.com/0xced) in [#1256](https://github.com/spectreconsole/spectre.console/pull/1256)
|
||||
* Fix `Rule` widget docs by [@tomaszprasolek](https://github.com/tomaszprasolek) in [#1257](https://github.com/spectreconsole/spectre.console/pull/1257)
|
||||
* Added the missing columns-cast by [@nils](https://github.com/nils)-a in [#1294](https://github.com/spectreconsole/spectre.console/pull/1294)
|
||||
@ -46,7 +46,7 @@ New features have been added, such as the ability to show separators between tab
|
||||
|
||||
## CLI
|
||||
* Add async command unit tests by [@FrankRay78](https://github.com/FrankRay78) in [#1228](https://github.com/spectreconsole/spectre.console/pull/1228)
|
||||
* Add support for async delegate by [@icalvo](https://github.com/icalvo) in [#1215](https://github.com/spectreconsole/spectre.console/pull/1215)
|
||||
* Add support for async delegate by [@icalvo](https://github.com/icalvo) in [#1215]([#1215](https://github.com/spectreconsole/spectre.console/pull/1215))
|
||||
* Remove unnecessary `[NotNull]` attributes by [@0xced](https://github.com/0xced) in [#1255](https://github.com/spectreconsole/spectre.console/pull/1255)
|
||||
* Allow custom help providers by [@FrankRay78](https://github.com/FrankRay78) in [#1259](https://github.com/spectreconsole/spectre.console/pull/1259)
|
||||
* Specified details for settings for the argument vector by [@nils](https://github.com/nils)-a in [#1301](https://github.com/spectreconsole/spectre.console/pull/1301)
|
||||
|
@ -1,71 +0,0 @@
|
||||
Title: Spectre.Console 0.50 released!
|
||||
Description: Now with 25% less lead!
|
||||
Published: 2025-04-08
|
||||
Category: Release Notes
|
||||
Excluded: false
|
||||
---
|
||||
|
||||
Version 0.50 of Spectre.Console has been released!
|
||||
|
||||
## New Contributors
|
||||
|
||||
* [@Kissaki](https://github.com/Kissaki) made their first contribution in [#1575](https://github.com/spectreconsole/spectre.console/pull/1575)
|
||||
* [@z4ryy](https://github.com/z4ryy) made their first contribution in [#1590](https://github.com/spectreconsole/spectre.console/pull/1590)
|
||||
* [@TonWin618](https://github.com/TonWin618) made their first contribution in [#1595](https://github.com/spectreconsole/spectre.console/pull/1595)
|
||||
* [@KirillOsenkov](https://github.com/KirillOsenkov) made their first contribution in [#1623](https://github.com/spectreconsole/spectre.console/pull/1623)
|
||||
* [@davide-pi](https://github.com/davide-pi) made their first contribution in [#1246](https://github.com/spectreconsole/spectre.console/pull/1246)
|
||||
* [@armanossiloko](https://github.com/armanossiloko) made their first contribution in [#1668](https://github.com/spectreconsole/spectre.console/pull/1668)
|
||||
* [@PascalSenn](https://github.com/PascalSenn) made their first contribution in [#1687](https://github.com/spectreconsole/spectre.console/pull/1687)
|
||||
* [@tpill90](https://github.com/tpill90) made their first contribution in [#904](https://github.com/spectreconsole/spectre.console/pull/904)
|
||||
* [@tmds](https://github.com/tmds) made their first contribution in [#1194](https://github.com/spectreconsole/spectre.console/pull/1194)
|
||||
* [@TheMarteh](https://github.com/TheMarteh) made their first contribution in [#1708](https://github.com/spectreconsole/spectre.console/pull/1708)
|
||||
* [@Tolitech](https://github.com/Tolitech) made their first contribution in [#1717](https://github.com/spectreconsole/spectre.console/pull/1717)
|
||||
* [@TheTonttu](https://github.com/TheTonttu) made their first contribution in [#1740](https://github.com/spectreconsole/spectre.console/pull/1740)
|
||||
* [@byte2pixel](https://github.com/byte2pixel) made their first contribution in [#1762](https://github.com/spectreconsole/spectre.console/pull/1762)
|
||||
* [@Moustafaa91](https://github.com/Moustafaa91) made their first contribution in [#1779](https://github.com/spectreconsole/spectre.console/pull/1779)
|
||||
|
||||
### General
|
||||
|
||||
* Strong name the assemblies by [@KirillOsenkov](https://github.com/KirillOsenkov) in [#1623](https://github.com/spectreconsole/spectre.console/pull/1623)
|
||||
* Update MSDN link to learn.microsoft.com by [@Kissaki](https://github.com/Kissaki) in [#1575](https://github.com/spectreconsole/spectre.console/pull/1575)
|
||||
* Add spanish translation for help strings by [@kzu](https://github.com/kzu) in [#1597](https://github.com/spectreconsole/spectre.console/pull/1597)
|
||||
* Update documentation: add example for the Text Prompt usage by [@davide-pi](https://github.com/davide-pi) in [#1636](https://github.com/spectreconsole/spectre.console/pull/1636)
|
||||
* Fix typos xml docs by [@devlead](https://github.com/devlead) in [#1684](https://github.com/spectreconsole/spectre.console/pull/1684)
|
||||
* Upgrade SixLabors.ImageSharp to 3.1.7 by [@Moustafaa91](https://github.com/Moustafaa91) in [#1779](https://github.com/spectreconsole/spectre.console/pull/1779)
|
||||
|
||||
### Console
|
||||
|
||||
* AOT Support for Spectre.Console by [@phil-scott-78](https://github.com/phil-scott-78) in [#1690](https://github.com/spectreconsole/spectre.console/pull/1690)
|
||||
* Make method reference to Markup.Escape more obvious by [@Kissaki](https://github.com/Kissaki) in [#1574](https://github.com/spectreconsole/spectre.console/pull/1574)
|
||||
* Fix `HtmlEncoder` Incorrectly Applying Italics to Bold Text by [@z4ryy](https://github.com/z4ryy) in [#1590](https://github.com/spectreconsole/spectre.console/pull/1590)
|
||||
* Fix Console Display Issue with Deleting Wide Characters by [@TonWin618](https://github.com/TonWin618) in [#1595](https://github.com/spectreconsole/spectre.console/pull/1595)
|
||||
* Fix search bug in prompt related to custom item types by [@patriksvensson](https://github.com/patriksvensson) in [#1627](https://github.com/spectreconsole/spectre.console/pull/1627)
|
||||
* Cleanup the prompt tests by [@0xced](https://github.com/0xced) in [#1635](https://github.com/spectreconsole/spectre.console/pull/1635)
|
||||
* Add custom style for each calendar event by [@davide-pi](https://github.com/davide-pi) in [#1246](https://github.com/spectreconsole/spectre.console/pull/1246)
|
||||
* Fix tree expansion bug by [@davide-pi](https://github.com/davide-pi) in [#1245](https://github.com/spectreconsole/spectre.console/pull/1245)
|
||||
* Enhance the style of the checkboxes for multi-selection by [@davide-pi](https://github.com/davide-pi) in [#1244](https://github.com/spectreconsole/spectre.console/pull/1244)
|
||||
* Improve exception if a (multi)selection prompt is used incorrectly by [@0xced](https://github.com/0xced) in [#1637](https://github.com/spectreconsole/spectre.console/pull/1637)
|
||||
* Fix incorrect panel height calculation in complex layout by [@BlazeFace](https://github.com/BlazeFace) in [#1514](https://github.com/spectreconsole/spectre.console/pull/1514)
|
||||
* Adding Enricher for Azure Pipelines by [@BlazeFace](https://github.com/BlazeFace) in [#1675](https://github.com/spectreconsole/spectre.console/pull/1675)
|
||||
* Added hex color conversion by [@jsheely](https://github.com/jsheely) in [#1432](https://github.com/spectreconsole/spectre.console/pull/1432)
|
||||
* Fixed type in Segment description by [@PascalSenn](https://github.com/PascalSenn) in [#1687](https://github.com/spectreconsole/spectre.console/pull/1687)
|
||||
* Adding TransferSpeedColumn configuration to display bits/bytes + binary/decimal prefixes by [@tpill90](https://github.com/tpill90) in [#904](https://github.com/spectreconsole/spectre.console/pull/904)
|
||||
* Changes Emoji dictionary to OrdinalIgnoreCase for performance by [@phil-scott-78](https://github.com/phil-scott-78) in [#1691](https://github.com/spectreconsole/spectre.console/pull/1691)
|
||||
* ProgressTask.GetPercentage() returns 100 when max value is 0 by [@FrankRay78](https://github.com/FrankRay78) in [#1694](https://github.com/spectreconsole/spectre.console/pull/1694)
|
||||
* Async overloads for AnsiConsole Prompt/Ask/Confirm. by [@tmds](https://github.com/tmds) in [#1194](https://github.com/spectreconsole/spectre.console/pull/1194)
|
||||
* Support 3-digit hex codes in markup by [@TheMarteh](https://github.com/TheMarteh) in [#1708](https://github.com/spectreconsole/spectre.console/pull/1708)
|
||||
* Add async spinner extension methods and related documentation by [@phil-scott-78](https://github.com/phil-scott-78) in [#1747](https://github.com/spectreconsole/spectre.console/pull/1747)
|
||||
* Fix generic exception formatting by [@0xced](https://github.com/0xced) in [#1755](https://github.com/spectreconsole/spectre.console/pull/1755)
|
||||
|
||||
### CLI
|
||||
|
||||
* Remove redundant explain settings ctor by [@gitfool](https://github.com/gitfool) in [#1534](https://github.com/spectreconsole/spectre.console/pull/1534)
|
||||
* Trim trailing comma in settings by [@devlead](https://github.com/devlead) in [#1550](https://github.com/spectreconsole/spectre.console/pull/1550)
|
||||
* Consider -? as an alias to -h by [@kzu](https://github.com/kzu) in [#1552](https://github.com/spectreconsole/spectre.console/pull/1552)
|
||||
* Trimming of TestConsole output by CommandAppTester is user configurable. by [@FrankRay78](https://github.com/FrankRay78) in [#1739](https://github.com/spectreconsole/spectre.console/pull/1739)
|
||||
* Include resource files for additional cultures in HelpProvider. by [@Tolitech](https://github.com/Tolitech) in [#1717](https://github.com/spectreconsole/spectre.console/pull/1717)
|
||||
* Conditionally trim trailing periods of argument and option descriptions by [@TheTonttu](https://github.com/TheTonttu) in [#1740](https://github.com/spectreconsole/spectre.console/pull/1740)
|
||||
* Changed IConfigurator to return IConfigurator instead of void by [@byte2pixel](https://github.com/byte2pixel) in [#1762](https://github.com/spectreconsole/spectre.console/pull/1762)
|
||||
* Add parsed unknown flag to remaining arguments for a branch with a default command by [@FrankRay78](https://github.com/FrankRay78) in [#1660](https://github.com/spectreconsole/spectre.console/pull/1660)
|
||||
* Correctly show application version; execution of command with version option by [@FrankRay78](https://github.com/FrankRay78) in [#1663](https://github.com/spectreconsole/spectre.console/pull/1663)
|
||||
* Help output correctly decides when to show the version option by [@FrankRay78](https://github.com/FrankRay78) in [#1664](https://github.com/spectreconsole/spectre.console/pull/1664)
|
@ -1,3 +1,3 @@
|
||||
@{
|
||||
Layout = "_layout.cshtml";
|
||||
Layout = @$"_layout.cshtml";
|
||||
}
|
@ -41,7 +41,7 @@ Removing all styling from help text is also possible, a good choice for ensuring
|
||||
config.Settings.HelpProviderStyles = null;
|
||||
```
|
||||
|
||||
See [Markup](../markup) for information about the use of markup in Spectre.Console, and [Styles](xref:appendix-styles) for a listing of supported styles.
|
||||
See [Markup](../markup) for information about the use of markup in Spectre.Console, and [Styles](xref:styles) for a listing of supported styles.
|
||||
|
||||
## Custom help providers
|
||||
|
||||
@ -71,5 +71,5 @@ public static class Program
|
||||
}
|
||||
```
|
||||
|
||||
There is a working [example of a custom help provider](https://github.com/spectreconsole/examples/tree/main/examples/Cli/Help) demonstrating this.
|
||||
There is a working [example of a custom help provider](https://github.com/spectreconsole/spectre.console/tree/main/examples/Cli/Help) demonstrating this.
|
||||
|
||||
|
@ -67,7 +67,7 @@ registrations.AddSingleton<IGreeter, HelloWorldGreeter>();
|
||||
|
||||
// Create a type registrar and register any dependencies.
|
||||
// A type registrar is an adapter for a DI framework.
|
||||
var registrar = new MyTypeRegistrar(registrations);
|
||||
var registrar = new TypeRegistrar(registrations);
|
||||
|
||||
// Create a new command app with the registrar
|
||||
// and run it with the provided arguments.
|
||||
@ -75,13 +75,10 @@ var app = new CommandApp<DefaultCommand>(registrar);
|
||||
return app.Run(args);
|
||||
```
|
||||
|
||||
<?# Alert ?>
|
||||
`MyTypeRegistrar` is a custom class that implements [ITypeRegistrar](xref:T:Spectre.Console.Cli.ITypeRegistrar) and must be provided by the user.
|
||||
<?#/ Alert ?>
|
||||
`TypeRegistrar` is a custom class that must be created by the user. This [example using `Microsoft.Extensions.DependencyInjection` as the container](https://github.com/spectreconsole/spectre.console/tree/main/examples/Cli/Injection) provides an example `TypeRegistrar` and `TypeResolver` that can be added to your application with small adjustments for your DI container.
|
||||
|
||||
There is a working [example of dependency injection](https://github.com/spectreconsole/examples/tree/main/examples/Cli/Injection) that uses `Microsoft.Extensions.DependencyInjection` as the container. Example implementations of `ITypeRegistrar` and `ITypeResolver` are provided, which you can copy and paste to your application for dependency injection.
|
||||
|
||||
Unit testing your `ITypeRegistrar` and `ITypeResolver` implementations is done using the utility `TypeRegistrarBaseTests` included in `Spectre.Console.Testing`. Simply call `TypeRegistrarBaseTests.RunAllTests()` and expect no `TypeRegistrarBaseTests.TestFailedException` to be thrown.
|
||||
Hint: If you do write your own implementation of `TypeRegistrar` and `TypeResolver` and you have some form of unit tests in place for your project,
|
||||
there is a utility `TypeRegistrarBaseTests` available that can be used to ensure your implementations adhere to the required implementation. Simply call `TypeRegistrarBaseTests.RunAllTests()` and expect no `TypeRegistrarBaseTests.TestFailedException` to be thrown.
|
||||
|
||||
## Interception
|
||||
Interceptors can be registered with the `TypeRegistrar` (or with a custom DI-Container). Alternatively, `CommandApp` also provides a `SetInterceptor` configuration.
|
||||
@ -92,4 +89,4 @@ This provides an opportunity to modify the result and also to tear down any infr
|
||||
|
||||
The `Intercept`-Method of each interceptor is run before the command is executed and the `InterceptResult`-Method is run after it. These are typically used for configuring logging or other infrastructure concerns.
|
||||
|
||||
For an example of using the interceptor to configure logging, see the [Serilog demo](https://github.com/spectreconsole/examples/tree/main/examples/Cli/Logging)
|
||||
For an example of using the interceptor to configure logging, see the [Serilog demo](https://github.com/spectreconsole/spectre.console/tree/main/examples/Cli/Logging).
|
||||
|
@ -1,8 +1,8 @@
|
||||
Title: Composing Commands
|
||||
RedirectFrom: introduction
|
||||
Order: 8
|
||||
Description: The underlying philosophy behind *Spectre.Console.Cli* is
|
||||
to rely on the .NET type system to declare the commands, but tie everything together via composition.
|
||||
Description: "The underlying philosophy behind *Spectre.Console.Cli* is to rely on the .NET type system to
|
||||
declare the commands, but tie everything together via composition."
|
||||
---
|
||||
|
||||
The underlying philosophy behind `Spectre.Console.Cli` is to rely on the .NET type system to
|
||||
|
@ -1,8 +1,8 @@
|
||||
Title: Introduction
|
||||
Order: 1
|
||||
Description: "*Spectre.Console.Cli* is a modern library for parsing command line arguments. While it's extremely
|
||||
opinionated in what it does, it tries to follow established industry conventions, and draws
|
||||
its inspiration from applications you use everyday."
|
||||
opinionated in what it does, it tries to follow established industry conventions, and draws
|
||||
its inspiration from applications you use everyday."
|
||||
---
|
||||
|
||||
`Spectre.Console.Cli` is a modern library for parsing command line arguments. While it's extremely
|
||||
|
@ -1,199 +0,0 @@
|
||||
Title: Unit Testing
|
||||
Order: 14
|
||||
Description: Instructions for unit testing a Spectre.Console application.
|
||||
Reference:
|
||||
- T:Spectre.Console.Testing.CommandAppTester
|
||||
- T:Spectre.Console.Testing.TestConsole
|
||||
- T:Spectre.Console.Testing.TestConsoleInput
|
||||
---
|
||||
|
||||
`Spectre.Console` has a separate project that contains test harnesses for unit testing your own console applications.
|
||||
|
||||
The fastest way of getting started is to install the `Spectre.Console.Testing` NuGet package.
|
||||
|
||||
```text
|
||||
> dotnet add package Spectre.Console.Testing
|
||||
```
|
||||
|
||||
`Spectre.Console.Testing` is also the namespace containing the test classes.
|
||||
|
||||
## Testing a CommandApp
|
||||
|
||||
The `CommandAppTester` is a test implementation of `CommandApp` that's configured in a similar manner but designed for unit testing.
|
||||
|
||||
The following example validates the exit code and terminal output of a `Spectre.Console` command:
|
||||
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// A Spectre.Console Command
|
||||
/// </summary>
|
||||
public class HelloWorldCommand : Command
|
||||
{
|
||||
private readonly IAnsiConsole _console;
|
||||
|
||||
public HelloWorldCommand(IAnsiConsole console)
|
||||
{
|
||||
// nb. AnsiConsole should not be called directly by the command
|
||||
// since this doesn't play well with testing. Instead,
|
||||
// the command should inject a IAnsiConsole and use that.
|
||||
|
||||
_console = console;
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context)
|
||||
{
|
||||
_console.WriteLine("Hello world.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Should_Output_Hello_World()
|
||||
{
|
||||
// Given
|
||||
var app = new CommandAppTester();
|
||||
app.SetDefaultCommand<HelloWorldCommand>();
|
||||
|
||||
// When
|
||||
var result = app.Run();
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(result.ExitCode, 0);
|
||||
Assert.AreEqual(result.Output, "Hello world.");
|
||||
}
|
||||
```
|
||||
|
||||
The following example demonstrates how to mock user inputs for an interactive command.
|
||||
This test (InteractiveCommand_WithMockedUserInputs_ProducesExpectedOutput) simulates user interactions by pushing predefined inputs to the console, then verifies that the resulting output is as expected.
|
||||
|
||||
```csharp
|
||||
public sealed class InteractiveCommandTests
|
||||
{
|
||||
private sealed class InteractiveCommand : Command
|
||||
{
|
||||
private readonly IAnsiConsole _console;
|
||||
|
||||
public InteractiveCommand(IAnsiConsole console)
|
||||
{
|
||||
_console = console;
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context)
|
||||
{
|
||||
var fruits = _console.Prompt(
|
||||
new MultiSelectionPrompt<string>()
|
||||
.Title("What are your [green]favorite fruits[/]?")
|
||||
.NotRequired() // Not required to have a favorite fruit
|
||||
.PageSize(10)
|
||||
.MoreChoicesText("[grey](Move up and down to reveal more fruits)[/]")
|
||||
.InstructionsText(
|
||||
"[grey](Press [blue]<space>[/] to toggle a fruit, " +
|
||||
"[green]<enter>[/] to accept)[/]")
|
||||
.AddChoices(new[] {
|
||||
"Apple", "Apricot", "Avocado",
|
||||
"Banana", "Blackcurrant", "Blueberry",
|
||||
"Cherry", "Cloudberry", "Coconut",
|
||||
}));
|
||||
|
||||
var fruit = _console.Prompt(
|
||||
new SelectionPrompt<string>()
|
||||
.Title("What's your [green]favorite fruit[/]?")
|
||||
.PageSize(10)
|
||||
.MoreChoicesText("[grey](Move up and down to reveal more fruits)[/]")
|
||||
.AddChoices(new[] {
|
||||
"Apple", "Apricot", "Avocado",
|
||||
"Banana", "Blackcurrant", "Blueberry",
|
||||
"Cherry", "Cloudberry", "Cocunut",
|
||||
}));
|
||||
|
||||
var name = _console.Ask<string>("What's your name?");
|
||||
|
||||
_console.WriteLine($"[{string.Join(',', fruits)};{fruit};{name}]");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InteractiveCommand_WithMockedUserInputs_ProducesExpectedOutput()
|
||||
{
|
||||
// Given
|
||||
TestConsole console = new();
|
||||
console.Interactive();
|
||||
|
||||
// Your mocked inputs must always end with "Enter" for each prompt!
|
||||
|
||||
// Multi selection prompt: Choose first option
|
||||
console.Input.PushKey(ConsoleKey.Spacebar);
|
||||
console.Input.PushKey(ConsoleKey.Enter);
|
||||
|
||||
// Selection prompt: Choose second option
|
||||
console.Input.PushKey(ConsoleKey.DownArrow);
|
||||
console.Input.PushKey(ConsoleKey.Enter);
|
||||
|
||||
// Ask text prompt: Enter name
|
||||
console.Input.PushTextWithEnter("Spectre Console");
|
||||
|
||||
var app = new CommandAppTester(null, new CommandAppTesterSettings(), console);
|
||||
app.SetDefaultCommand<InteractiveCommand>();
|
||||
|
||||
// When
|
||||
var result = app.Run();
|
||||
|
||||
// Then
|
||||
result.ExitCode.ShouldBe(0);
|
||||
result.Output.EndsWith("[Apple;Apricot;Spectre Console]");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Testing console behaviour
|
||||
|
||||
`TestConsole` and `TestConsoleInput` are testable implementations of `IAnsiConsole` and `IAnsiConsoleInput`, allowing you fine-grain control over testing console output and interactivity.
|
||||
|
||||
The following example renders some widgets before then validating the console output:
|
||||
|
||||
```csharp
|
||||
[TestMethod]
|
||||
public void Should_Render_Panel()
|
||||
{
|
||||
// Given
|
||||
var console = new TestConsole();
|
||||
|
||||
// When
|
||||
console.Write(new Panel(new Text("Hello World")));
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(console.Output, """"
|
||||
┌─────────────┐
|
||||
│ Hello World │
|
||||
└─────────────┘
|
||||
|
||||
"""");
|
||||
}
|
||||
```
|
||||
|
||||
While `Assert` is fine for validating simple output, more complex output may benefit from a tool like [Verify](https://github.com/VerifyTests/Verify).
|
||||
|
||||
The following example prompts the user for input before then validating the expected choice was made:
|
||||
|
||||
```csharp
|
||||
[TestMethod]
|
||||
public void Should_Select_Orange()
|
||||
{
|
||||
// Given
|
||||
var console = new TestConsole();
|
||||
console.Input.PushTextWithEnter("Orange");
|
||||
|
||||
// When
|
||||
console.Prompt(
|
||||
new TextPrompt<string>("Favorite fruit?")
|
||||
.AddChoice("Banana")
|
||||
.AddChoice("Orange"));
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(console.Output, "Favorite fruit? [Banana/Orange]: Orange\n");
|
||||
}
|
||||
```
|
||||
|
||||
`CommandAppTester` uses `TestConsole` internally, which in turn uses `TestConsoleInput`, offering a fully testable harness for `Spectre.Console` widgets, prompts and commands.
|
@ -6,7 +6,7 @@ Order: 0
|
||||
Spectre.Console is a `.NET` library that makes it easier
|
||||
to create beautiful console applications.
|
||||
|
||||
## Spectre.Console.AnsiConsole
|
||||
## Spectre.Console.AnsiConsole Features
|
||||
|
||||
* Easily output text with different colors and even styles such as bold, italic and blinking with a Rich inspired [markup language](markup).
|
||||
* Supports `3`/`4`/`8`/`24`-bit colors in the terminal with auto-detection of the current terminal's capabilities.
|
||||
@ -14,19 +14,16 @@ to create beautiful console applications.
|
||||
* Display progress for long running tasks with live displays of [progress](live/progress) and [status](live/status) controls.
|
||||
* Prompt user input with strongly typed [text input](prompts/text) or via [single-item select](prompts/selection) and [multiple item select](prompts/multiselection) controls.
|
||||
* Format .NET [exceptions](exceptions) with custom color coded themes and styles.
|
||||
* Written with unit testing in mind.
|
||||
|
||||
Spectre.Console.AnsiConsole has been heavily inspired by the excellent [Rich](https://github.com/willmcgugan/rich) library for Python written by Will McGugan.
|
||||
Spectre.Console.AnsiConsole has been heavily inspired
|
||||
by the excellent [Rich](https://github.com/willmcgugan/rich) library
|
||||
for Python written by Will McGugan.
|
||||
|
||||
## Spectre.Console.Cli
|
||||
|
||||
* Create strongly typed settings and commands for parsing `args[]` to create complex command line applications like `git`, `gh`, or `dotnet`
|
||||
|
||||
## Spectre.Console.Testing
|
||||
|
||||
* Spectre.Console has been developed with unit testing in mind. The Spectre.Console library itself is covered by an extensive test suite, project maintainers require test coverage for all new commits, and the same extension points and test harnesses used internally for testing are available to you.
|
||||
|
||||
* The [Unit Testing](cli/unit-testing) page provides instructions for testing a Spectre.Console application.
|
||||
|
||||
## Examples
|
||||
|
||||

|
||||
@ -39,4 +36,3 @@ Spectre.Console.AnsiConsole has been heavily inspired by the excellent [Rich](ht
|
||||
Sorry, your browser doesn't support embedded videos.
|
||||
</video>
|
||||
|
||||
The Spectre.Console [examples repository](https://github.com/spectreconsole/examples) contains many other examples.
|
@ -1,73 +0,0 @@
|
||||
Title: Async Extensions
|
||||
Order: 11
|
||||
Description: "Async Extensions provides extension methods for running tasks with an inline animations."
|
||||
Highlights:
|
||||
- Extension methods for running tasks with spinner animations
|
||||
- Support for both void and generic Task types
|
||||
- Customizable spinner styles and console output
|
||||
Reference:
|
||||
- T:Spectre.Console.Extensions.SpinnerExtensions
|
||||
Xref: spinner-extensions
|
||||
---
|
||||
|
||||
The Async Spinner Extension provides convenient extension methods for running tasks with an inline spinner animations in the console.
|
||||
|
||||
<?# AsciiCast cast="await-spinner" /?>
|
||||
|
||||
<?# Alert ?>
|
||||
The spinner animation is not thread safe, and using it together with other interactive
|
||||
components such as prompts, progress displays or other status displays is not supported.
|
||||
<?#/ Alert ?>
|
||||
|
||||
## Usage
|
||||
|
||||
The extension methods allow you to easily add spinner animations to any Task execution:
|
||||
|
||||
```csharp
|
||||
// Basic usage with void Task
|
||||
await someTask.Spinner();
|
||||
|
||||
// With generic Task<T>
|
||||
var result = await someTaskWithResult.Spinner(
|
||||
Spinner.Known.Star,
|
||||
new Style(foreground: Color.Green));
|
||||
|
||||
// With custom console
|
||||
await someTask.Spinner(
|
||||
Spinner.Known.Dots,
|
||||
style: Style.Plain,
|
||||
ansiConsole: customConsole);
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
The spinner extensions provide:
|
||||
|
||||
- Support for both void Tasks and Tasks with return values
|
||||
- Customizable spinner animations using any Spectre.Console Spinner
|
||||
- Optional styling for the spinner animation
|
||||
- Ability to specify a custom IAnsiConsole instance
|
||||
|
||||
## Examples
|
||||
|
||||
Here's a more complete example showing different ways to use the spinner extensions:
|
||||
|
||||
```csharp
|
||||
// Basic spinner with default settings
|
||||
await Task.Delay(1000)
|
||||
.Spinner(Spinner.Known.Dots);
|
||||
|
||||
// Customized spinner with style
|
||||
var result = await CalculateSomething()
|
||||
.Spinner(
|
||||
Spinner.Known.Star,
|
||||
new Style(foreground: Color.Green));
|
||||
|
||||
// Using with a custom console
|
||||
await ProcessData()
|
||||
.Spinner(
|
||||
new Spinner(new[] { "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" }, 80),
|
||||
new Style(foreground: Color.Blue),
|
||||
customConsole);
|
||||
```
|
||||
|
@ -9,7 +9,6 @@ Highlights:
|
||||
Reference:
|
||||
- T:Spectre.Console.Progress
|
||||
- M:Spectre.Console.AnsiConsole.Progress
|
||||
Xref: live-progress
|
||||
---
|
||||
|
||||
Spectre.Console can display information about long running tasks in the console.
|
||||
@ -86,8 +85,6 @@ AnsiConsole.Progress()
|
||||
new PercentageColumn(), // Percentage
|
||||
new RemainingTimeColumn(), // Remaining time
|
||||
new SpinnerColumn(), // Spinner
|
||||
new DownloadedColumn(), // Downloaded
|
||||
new TransferSpeedColumn(), // Transfer speed
|
||||
})
|
||||
.Start(ctx =>
|
||||
{
|
||||
|
@ -8,7 +8,6 @@ Highlights:
|
||||
Reference:
|
||||
- T:Spectre.Console.Status
|
||||
- M:Spectre.Console.AnsiConsole.Status
|
||||
Xref: live-status
|
||||
---
|
||||
|
||||
Spectre.Console can display information about long running tasks in the console.
|
||||
|
@ -27,32 +27,6 @@ you can use the `Prompt<TResult>`.
|
||||
Run prompt example? [y/n] (y): _
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```csharp
|
||||
// Ask the user to confirm
|
||||
var confirmation = AnsiConsole.Prompt(
|
||||
new TextPrompt<bool>("Run prompt example?")
|
||||
.AddChoice(true)
|
||||
.AddChoice(false)
|
||||
.DefaultValue(true)
|
||||
.WithConverter(choice => choice ? "y" : "n"));
|
||||
|
||||
// Echo the confirmation back to the terminal
|
||||
Console.WriteLine(confirmation ? "Confirmed" : "Declined");
|
||||
```
|
||||
|
||||
Otherwise it is possible to use the `ConfirmationPrompt`
|
||||
|
||||
```csharp
|
||||
// Ask the user to confirm
|
||||
var confirmation = AnsiConsole.Prompt(
|
||||
new ConfirmationPrompt("Run prompt example?"));
|
||||
|
||||
// Echo the confirmation back to the terminal
|
||||
Console.WriteLine(confirmation ? "Confirmed" : "Declined");
|
||||
```
|
||||
|
||||
## Simple
|
||||
|
||||
<?# Example symbol="M:Prompt.Program.AskName" project="Prompt" /?>
|
||||
@ -62,30 +36,6 @@ What's your name? Patrik
|
||||
What's your age? 37
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```csharp
|
||||
// Ask the user a couple of simple questions
|
||||
var name = AnsiConsole.Prompt(
|
||||
new TextPrompt<string>("What's your name?"));
|
||||
var age = AnsiConsole.Prompt(
|
||||
new TextPrompt<int>("What's your age?"));
|
||||
|
||||
// Echo the name and age back to the terminal
|
||||
AnsiConsole.WriteLine($"So you're {name} and you're {age} years old");
|
||||
```
|
||||
|
||||
Otherwise it is possible to use the `Ask` method
|
||||
|
||||
```csharp
|
||||
// Ask the user a couple of simple questions
|
||||
var name = AnsiConsole.Ask<string>("What's your name?");
|
||||
var age = AnsiConsole.Ask<int>("What's your age?");
|
||||
|
||||
// Echo the name and age back to the terminal
|
||||
AnsiConsole.WriteLine($"So you're {name} and you're {age} years old");
|
||||
```
|
||||
|
||||
## Choices
|
||||
|
||||
<?# Example symbol="M:Prompt.Program.AskFruit" project="Prompt" /?>
|
||||
@ -94,19 +44,6 @@ AnsiConsole.WriteLine($"So you're {name} and you're {age} years old");
|
||||
What's your favorite fruit? [Apple/Banana/Orange] (Orange): _
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```csharp
|
||||
// Ask for the user's favorite fruit
|
||||
var fruit = AnsiConsole.Prompt(
|
||||
new TextPrompt<string>("What's your favorite fruit?")
|
||||
.AddChoices(["Apple", "Banana", "Orange"])
|
||||
.DefaultValue("Orange"));
|
||||
|
||||
// Echo the fruit back to the terminal
|
||||
Console.WriteLine($"I agree. {fruit} is tasty!");
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
<?# Example symbol="M:Prompt.Program.AskAge" project="Prompt" /?>
|
||||
@ -119,23 +56,6 @@ Too high
|
||||
What's the secret number? _
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```csharp
|
||||
// Ask the user to guess the secret number
|
||||
var number = AnsiConsole.Prompt(
|
||||
new TextPrompt<int>("What's the secret number?")
|
||||
.Validate((n) => n switch
|
||||
{
|
||||
< 50 => ValidationResult.Error("Too low"),
|
||||
50 => ValidationResult.Success(),
|
||||
> 50 => ValidationResult.Error("Too high"),
|
||||
}));
|
||||
|
||||
// Echo the user's success back to the terminal
|
||||
Console.WriteLine($"Correct! The secret number is {number}.");
|
||||
```
|
||||
|
||||
## Secrets
|
||||
|
||||
<?# Example symbol="M:Prompt.Program.AskPassword" project="Prompt" /?>
|
||||
@ -145,18 +65,6 @@ Console.WriteLine($"Correct! The secret number is {number}.");
|
||||
Enter password: ************_
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```csharp
|
||||
// Ask the user to enter the password
|
||||
var password = AnsiConsole.Prompt(
|
||||
new TextPrompt<string>("Enter password:")
|
||||
.Secret());
|
||||
|
||||
// Echo the password back to the terminal
|
||||
Console.WriteLine($"Your password is {password}");
|
||||
```
|
||||
|
||||
## Masks
|
||||
|
||||
<?# Example symbol="M:Prompt.Program.AskPasswordWithCustomMask" project="Prompt" /?>
|
||||
@ -174,36 +82,10 @@ You can utilize a null character to completely hide input.
|
||||
Enter password: _
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```csharp
|
||||
// Ask the user to enter the password
|
||||
var password = AnsiConsole.Prompt(
|
||||
new TextPrompt<string>("Enter password:")
|
||||
.Secret('-'));
|
||||
|
||||
// Echo the password back to the terminal
|
||||
Console.WriteLine($"Your password is {password}");
|
||||
```
|
||||
|
||||
## Optional
|
||||
|
||||
<?# Example symbol="M:Prompt.Program.AskColor" project="Prompt" /?>
|
||||
|
||||
```text
|
||||
[Optional] Favorite color? _
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```csharp
|
||||
// Ask the user to enter the password
|
||||
var color = AnsiConsole.Prompt(
|
||||
new TextPrompt<string>("[[Optional]] Favorite color?")
|
||||
.AllowEmpty());
|
||||
|
||||
// Echo the color back to the terminal
|
||||
Console.WriteLine(string.IsNullOrWhiteSpace(color)
|
||||
? "You're right, all colors are beautiful"
|
||||
: $"I agree. {color} is a very beautiful color");
|
||||
```
|
@ -17,7 +17,7 @@ and the ascii terminal player.
|
||||
/* temp styling for alerts */
|
||||
|
||||
.alert-warning {
|
||||
@apply p-4 border border-yellow-300 bg-yellow-100 text-yellow-800 dark:border-red-700/50 dark:bg-red-800/50 dark:text-red-100/90 rounded shadow-sm text-sm;
|
||||
@apply p-4 border border-yellow-300 bg-yellow-100 text-yellow-800 dark:border-orange-700/50 dark:bg-orange-800/50 dark:text-orange-300/90 rounded shadow-sm text-sm;
|
||||
}
|
||||
|
||||
.alert-warning p {
|
||||
|
@ -1,66 +0,0 @@
|
||||
Title: Align
|
||||
Description: "Use **Align** to render and position widgets in the console."
|
||||
Highlights:
|
||||
- Custom colors
|
||||
- Labels
|
||||
- Use your own data with a converter.
|
||||
Reference: T:Spectre.Console.Align
|
||||
|
||||
---
|
||||
|
||||
Use `Align` to render and position widgets in the console.
|
||||
|
||||
<?# AsciiCast cast="align" /?>
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic usage
|
||||
|
||||
```csharp
|
||||
// Render an item and align it in the bottom-left corner of the console
|
||||
AnsiConsole.Write(new Align(
|
||||
new Text("Spectre!"),
|
||||
HorizontalAlignment.Left,
|
||||
VerticalAlignment.Bottom
|
||||
));
|
||||
```
|
||||
|
||||
### Align items from an IEnumerable
|
||||
|
||||
```csharp
|
||||
// Create a list of items
|
||||
var alignItems = new List<Text>(){
|
||||
new Text("Spectre"),
|
||||
new Text("Console"),
|
||||
new Text("Is Awesome!")
|
||||
};
|
||||
|
||||
// Render the items in the middle-right of the console
|
||||
AnsiConsole.Write(new Align(
|
||||
alignItems,
|
||||
HorizontalAlignment.Right,
|
||||
VerticalAlignment.Middle
|
||||
));
|
||||
```
|
||||
|
||||
### Dynamically align with different widgets
|
||||
|
||||
```csharp
|
||||
// Create a table
|
||||
var table = new Table()
|
||||
.AddColumn("ID")
|
||||
.AddColumn("Methods")
|
||||
.AddColumn("Purpose")
|
||||
.AddRow("1", "Center()", "Initializes a new instance that is center aligned")
|
||||
.AddRow("2", "Measure()", "Measures the renderable object")
|
||||
.AddRow("3", "Right()", "Initializes a new instance that is right aligned.");
|
||||
|
||||
// Create a panel
|
||||
var panel = new Panel(table)
|
||||
.Header("Other Align Methods")
|
||||
.Border(BoxBorder.Double);
|
||||
|
||||
// Renders the panel in the top-center of the console
|
||||
AnsiConsole.Write(new Align(panel, HorizontalAlignment.Center, VerticalAlignment.Top));
|
||||
```
|
||||
|
@ -137,11 +137,4 @@ table.Columns[0].NoWrap();
|
||||
```csharp
|
||||
// Set the column width
|
||||
table.Columns[0].Width(15);
|
||||
```
|
||||
|
||||
### Show row separators
|
||||
|
||||
```csharp
|
||||
// Shows separator between each row
|
||||
table.ShowRowSeparators();
|
||||
```
|
282
docs/package-lock.json
generated
282
docs/package-lock.json
generated
@ -123,13 +123,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
|
||||
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.0.tgz",
|
||||
"integrity": "sha512-etcO/ohMNaNA2UBdaXBBSX/3aEzFMRrVfaPv8Ptc0k+cWpWW0QFiGZ2XnVqQZI1Cf734LbPGmqBKWESfW4x/dQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.14.0"
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -316,13 +315,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.1.1"
|
||||
"fill-range": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@ -477,11 +475,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
@ -503,13 +500,6 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/defined": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
|
||||
@ -597,11 +587,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
@ -748,7 +737,6 @@
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
@ -814,14 +802,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
||||
"integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
"braces": "^3.0.1",
|
||||
"picomatch": "^2.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
@ -837,27 +824,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
||||
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
@ -955,11 +931,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
@ -974,32 +949,21 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.3",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
|
||||
"integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
|
||||
"version": "8.4.6",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.6.tgz",
|
||||
"integrity": "sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.8",
|
||||
"picocolors": "^1.1.1",
|
||||
"source-map-js": "^1.2.1"
|
||||
"nanoid": "^3.2.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-js": {
|
||||
@ -1129,11 +1093,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/regenerator-runtime": {
|
||||
"version": "0.14.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
||||
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
"version": "0.13.9",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
||||
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.0",
|
||||
@ -1194,29 +1157,6 @@
|
||||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/seroval": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/seroval/-/seroval-1.2.1.tgz",
|
||||
"integrity": "sha512-yBxFFs3zmkvKNmR0pFSU//rIsYjuX418TnlDmc2weaq5XFDqDIV/NOMPBoLrbxjLH42p4UzRuXHryXh9dYcKcw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/seroval-plugins": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.2.1.tgz",
|
||||
"integrity": "sha512-H5vs53+39+x4Udwp4J5rNZfgFuA+Lt+uU+09w1gYBVWomtAl98B+E9w7yC05Xc81/HgLvJdlyqJbU0fJCKCmdw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"seroval": "^1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
@ -1239,23 +1179,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/solid-js": {
|
||||
"version": "1.9.5",
|
||||
"resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.5.tgz",
|
||||
"integrity": "sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"csstype": "^3.1.0",
|
||||
"seroval": "^1.1.0",
|
||||
"seroval-plugins": "^1.1.0"
|
||||
}
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.3.5.tgz",
|
||||
"integrity": "sha512-PUom2cCARfvvgxI7cwOhfXMrZZZxjp+vIrb5fzVNBFyICy8A30wTqExwfUv457eJYgKpii2D3qStW9ILtKnShw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@ -1341,7 +1274,6 @@
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
@ -1475,12 +1407,12 @@
|
||||
}
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
|
||||
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.0.tgz",
|
||||
"integrity": "sha512-etcO/ohMNaNA2UBdaXBBSX/3aEzFMRrVfaPv8Ptc0k+cWpWW0QFiGZ2XnVqQZI1Cf734LbPGmqBKWESfW4x/dQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.14.0"
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
}
|
||||
},
|
||||
"@nodelib/fs.scandir": {
|
||||
@ -1615,12 +1547,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"braces": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fill-range": "^7.1.1"
|
||||
"fill-range": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"browserslist": {
|
||||
@ -1720,9 +1652,9 @@
|
||||
}
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-key": "^3.1.0",
|
||||
@ -1736,12 +1668,6 @@
|
||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"dev": true
|
||||
},
|
||||
"defined": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
|
||||
@ -1817,9 +1743,9 @@
|
||||
}
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
@ -1979,13 +1905,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
||||
"integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
"braces": "^3.0.1",
|
||||
"picomatch": "^2.2.3"
|
||||
}
|
||||
},
|
||||
"mini-svg-data-uri": {
|
||||
@ -1995,15 +1921,15 @@
|
||||
"dev": true
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"dev": true
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
||||
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
|
||||
"dev": true
|
||||
},
|
||||
"node-releases": {
|
||||
@ -2072,9 +1998,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||
"dev": true
|
||||
},
|
||||
"picomatch": {
|
||||
@ -2084,14 +2010,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.5.3",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
|
||||
"integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
|
||||
"version": "8.4.6",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.6.tgz",
|
||||
"integrity": "sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"nanoid": "^3.3.8",
|
||||
"picocolors": "^1.1.1",
|
||||
"source-map-js": "^1.2.1"
|
||||
"nanoid": "^3.2.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"postcss-js": {
|
||||
@ -2160,9 +2086,9 @@
|
||||
}
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
"version": "0.14.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
||||
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
|
||||
"version": "0.13.9",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
||||
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
|
||||
"dev": true
|
||||
},
|
||||
"resolve": {
|
||||
@ -2197,19 +2123,6 @@
|
||||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"seroval": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/seroval/-/seroval-1.2.1.tgz",
|
||||
"integrity": "sha512-yBxFFs3zmkvKNmR0pFSU//rIsYjuX418TnlDmc2weaq5XFDqDIV/NOMPBoLrbxjLH42p4UzRuXHryXh9dYcKcw==",
|
||||
"dev": true
|
||||
},
|
||||
"seroval-plugins": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.2.1.tgz",
|
||||
"integrity": "sha512-H5vs53+39+x4Udwp4J5rNZfgFuA+Lt+uU+09w1gYBVWomtAl98B+E9w7yC05Xc81/HgLvJdlyqJbU0fJCKCmdw==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
@ -2226,20 +2139,15 @@
|
||||
"dev": true
|
||||
},
|
||||
"solid-js": {
|
||||
"version": "1.9.5",
|
||||
"resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.5.tgz",
|
||||
"integrity": "sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"csstype": "^3.1.0",
|
||||
"seroval": "^1.1.0",
|
||||
"seroval-plugins": "^1.1.0"
|
||||
}
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.3.5.tgz",
|
||||
"integrity": "sha512-PUom2cCARfvvgxI7cwOhfXMrZZZxjp+vIrb5fzVNBFyICy8A30wTqExwfUv457eJYgKpii2D3qStW9ILtKnShw==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
|
@ -99,7 +99,8 @@ public class Api : Pipeline
|
||||
new ConcatDocuments(nameof(Code)),
|
||||
new CacheDocuments(
|
||||
new AnalyzeCSharp()
|
||||
.WhereNamespaces(ns => ns.StartsWith("Spectre.Console") && !ns.Contains("Analyzer") && !ns.Contains("Examples"))
|
||||
.WhereNamespaces(ns => ns.StartsWith("Spectre.Console") && !ns.Contains("Analyzer") &&
|
||||
!ns.Contains("Testing") && !ns.Contains("Examples"))
|
||||
.WherePublic(true)
|
||||
.WithCssClasses("code", "cs")
|
||||
.WithDestinationPrefix("api")
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
<div id="container">
|
||||
<div id="console">
|
||||
<div class="line"><span style="color:var(--brightBlack)">╭─</span><span style="color:var(--folder)"></span><span style="background-color:var(--folder);color:var(--black)"> ~/spectre.console</span><span style="color:var(--folder);background-color:var(--dotnet)"></span><span style="background-color:var(--blue)"> .NET 9.0 </span><span style="color:var(--dotnet);background-color:var(--git)"></span><span style="background-color:var(--git);color:var(--background)">  main </span><span style="color:var(--git)"></span></div>
|
||||
<div class="line"><span style="color:var(--brightBlack)">╭─</span><span style="color:var(--folder)"></span><span style="background-color:var(--folder);color:var(--black)"> ~/spectre.console</span><span style="color:var(--folder);background-color:var(--dotnet)"></span><span style="background-color:var(--blue)"> .NET 8.0 </span><span style="color:var(--dotnet);background-color:var(--git)"></span><span style="background-color:var(--git);color:var(--background)">  main </span><span style="color:var(--git)"></span></div>
|
||||
<div class="line"><span style="color:var(--brightBlack)">╰─</span> dotnet run</div>
|
||||
<div class="line"></div>
|
||||
<div class="line">╭────────────────────────────────────────────────────────╮</div>
|
||||
|
@ -58,31 +58,21 @@ internal static class HighlightService
|
||||
}
|
||||
|
||||
var text = await syntaxReference.SyntaxTree.GetTextAsync();
|
||||
|
||||
// we need a document for the syntax highlighter, so create a temporary solution and project to hold it.
|
||||
var workspace = new AdhocWorkspace();
|
||||
var solution = workspace.CurrentSolution
|
||||
.AddProject("TempProject", "TempProject", "C#")
|
||||
.AddDocument("TempDocument", await syntaxReference.SyntaxTree.GetTextAsync());
|
||||
|
||||
var document = solution.Project.Documents.First();
|
||||
|
||||
var highlightElement = await HighlightElement(document, text, textSpan, indent);
|
||||
return highlightElement;
|
||||
// we need a workspace, but it seems it is only used to resolve a few services and nothing else so an empty one will suffice
|
||||
return HighlightElement(_emptyWorkspace, model, text, textSpan, indent);
|
||||
}
|
||||
|
||||
private static int GetIndent(SyntaxTriviaList leadingTrivia)
|
||||
{
|
||||
var whitespace = leadingTrivia.FirstOrDefault(i => i.IsKind(SyntaxKind.WhitespaceTrivia));
|
||||
var whitespace = leadingTrivia.FirstOrDefault(i => i.Kind() == SyntaxKind.WhitespaceTrivia);
|
||||
return whitespace == default ? 0 : whitespace.Span.Length;
|
||||
}
|
||||
|
||||
private static async Task<string> HighlightElement(Document document,
|
||||
SourceText fullSourceText,
|
||||
private static string HighlightElement(Workspace workspace, SemanticModel semanticModel, SourceText fullSourceText,
|
||||
TextSpan textSpan, int indent)
|
||||
{
|
||||
|
||||
var classifiedSpans = await Classifier.GetClassifiedSpansAsync(document, textSpan);
|
||||
var classifiedSpans = Classifier.GetClassifiedSpans(semanticModel, textSpan, workspace);
|
||||
return HighlightElement(classifiedSpans, fullSourceText, indent);
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,17 @@
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"cake.tool": {
|
||||
"version": "5.0.0",
|
||||
"version": "4.0.0",
|
||||
"commands": [
|
||||
"dotnet-cake"
|
||||
]
|
||||
},
|
||||
"dotnet-example": {
|
||||
"version": "3.1.0",
|
||||
"commands": [
|
||||
"dotnet-example"
|
||||
]
|
||||
},
|
||||
"verify.tool": {
|
||||
"version": "0.6.0",
|
||||
"commands": [
|
||||
|
15
examples/Cli/Delegates/BarSettings.cs
Normal file
15
examples/Cli/Delegates/BarSettings.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.ComponentModel;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Delegates;
|
||||
|
||||
public static partial class Program
|
||||
{
|
||||
public sealed class BarSettings : CommandSettings
|
||||
{
|
||||
[CommandOption("--count")]
|
||||
[Description("The number of bars to print")]
|
||||
[DefaultValue(3)]
|
||||
public int Count { get; set; }
|
||||
}
|
||||
}
|
17
examples/Cli/Delegates/Delegates.csproj
Normal file
17
examples/Cli/Delegates/Delegates.csproj
Normal file
@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<ExampleName>Delegates</ExampleName>
|
||||
<ExampleDescription>Demonstrates how to specify commands as delegates.</ExampleDescription>
|
||||
<ExampleGroup>Cli</ExampleGroup>
|
||||
<ExampleVisible>false</ExampleVisible>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
61
examples/Cli/Delegates/Program.cs
Normal file
61
examples/Cli/Delegates/Program.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using System.Threading.Tasks;
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Delegates;
|
||||
|
||||
public static partial class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
var app = new CommandApp();
|
||||
app.Configure(config =>
|
||||
{
|
||||
config.AddDelegate("foo", Foo)
|
||||
.WithDescription("Foos the bars");
|
||||
|
||||
config.AddDelegate<BarSettings>("bar", Bar)
|
||||
.WithDescription("Bars the foos");
|
||||
|
||||
config.AddAsyncDelegate("fooAsync", FooAsync)
|
||||
.WithDescription("Foos the bars asynchronously");
|
||||
|
||||
config.AddAsyncDelegate<BarSettings>("barAsync", BarAsync)
|
||||
.WithDescription("Bars the foos asynchronously");
|
||||
});
|
||||
|
||||
return app.Run(args);
|
||||
}
|
||||
|
||||
private static int Foo(CommandContext context)
|
||||
{
|
||||
AnsiConsole.WriteLine("Foo");
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int Bar(CommandContext context, BarSettings settings)
|
||||
{
|
||||
for (var index = 0; index < settings.Count; index++)
|
||||
{
|
||||
AnsiConsole.WriteLine("Bar");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static Task<int> FooAsync(CommandContext context)
|
||||
{
|
||||
AnsiConsole.WriteLine("Foo");
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
private static Task<int> BarAsync(CommandContext context, BarSettings settings)
|
||||
{
|
||||
for (var index = 0; index < settings.Count; index++)
|
||||
{
|
||||
AnsiConsole.WriteLine("Bar");
|
||||
}
|
||||
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
46
examples/Cli/Demo/Commands/Add/AddPackageCommand.cs
Normal file
46
examples/Cli/Demo/Commands/Add/AddPackageCommand.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using System.ComponentModel;
|
||||
using Demo.Utilities;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo.Commands.Add;
|
||||
|
||||
[Description("Add a NuGet package reference to the project.")]
|
||||
public sealed class AddPackageCommand : Command<AddPackageCommand.Settings>
|
||||
{
|
||||
public sealed class Settings : AddSettings
|
||||
{
|
||||
[CommandArgument(0, "<PACKAGENAME>")]
|
||||
[Description("The package reference to add.")]
|
||||
public string PackageName { get; set; }
|
||||
|
||||
[CommandOption("-v|--version <VERSION>")]
|
||||
[Description("The version of the package to add.")]
|
||||
public string Version { get; set; }
|
||||
|
||||
[CommandOption("-f|--framework <FRAMEWORK>")]
|
||||
[Description("Add the reference only when targeting a specific framework.")]
|
||||
public string Framework { get; set; }
|
||||
|
||||
[CommandOption("--no-restore")]
|
||||
[Description("Add the reference without performing restore preview and compatibility check.")]
|
||||
public bool NoRestore { get; set; }
|
||||
|
||||
[CommandOption("--source <SOURCE>")]
|
||||
[Description("The NuGet package source to use during the restore.")]
|
||||
public string Source { get; set; }
|
||||
|
||||
[CommandOption("--package-directory <PACKAGEDIR>")]
|
||||
[Description("The directory to restore packages to.")]
|
||||
public string PackageDirectory { get; set; }
|
||||
|
||||
[CommandOption("--interactive")]
|
||||
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
||||
public bool Interactive { get; set; }
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
SettingsDumper.Dump(settings);
|
||||
return 0;
|
||||
}
|
||||
}
|
29
examples/Cli/Demo/Commands/Add/AddReferenceCommand.cs
Normal file
29
examples/Cli/Demo/Commands/Add/AddReferenceCommand.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System.ComponentModel;
|
||||
using Demo.Utilities;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo.Commands.Add;
|
||||
|
||||
public sealed class AddReferenceCommand : Command<AddReferenceCommand.Settings>
|
||||
{
|
||||
public sealed class Settings : AddSettings
|
||||
{
|
||||
[CommandArgument(0, "<PROJECTPATH>")]
|
||||
[Description("The package reference to add.")]
|
||||
public string ProjectPath { get; set; }
|
||||
|
||||
[CommandOption("-f|--framework <FRAMEWORK>")]
|
||||
[Description("Add the reference only when targeting a specific framework.")]
|
||||
public string Framework { get; set; }
|
||||
|
||||
[CommandOption("--interactive")]
|
||||
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
||||
public bool Interactive { get; set; }
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
SettingsDumper.Dump(settings);
|
||||
return 0;
|
||||
}
|
||||
}
|
11
examples/Cli/Demo/Commands/Add/AddSettings.cs
Normal file
11
examples/Cli/Demo/Commands/Add/AddSettings.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System.ComponentModel;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo.Commands.Add;
|
||||
|
||||
public abstract class AddSettings : CommandSettings
|
||||
{
|
||||
[CommandArgument(0, "<PROJECT>")]
|
||||
[Description("The project file to operate on. If a file is not specified, the command will search the current directory for one.")]
|
||||
public string Project { get; set; }
|
||||
}
|
69
examples/Cli/Demo/Commands/Run/RunCommand.cs
Normal file
69
examples/Cli/Demo/Commands/Run/RunCommand.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using System.ComponentModel;
|
||||
using Demo.Utilities;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo.Commands.Run;
|
||||
|
||||
[Description("Build and run a .NET project output.")]
|
||||
public sealed class RunCommand : Command<RunCommand.Settings>
|
||||
{
|
||||
public sealed class Settings : CommandSettings
|
||||
{
|
||||
[CommandOption("-c|--configuration <CONFIGURATION>")]
|
||||
[Description("The configuration to run for. The default for most projects is '[grey]Debug[/]'.")]
|
||||
[DefaultValue("Debug")]
|
||||
public string Configuration { get; set; }
|
||||
|
||||
[CommandOption("-f|--framework <FRAMEWORK>")]
|
||||
[Description("The target framework to run for. The target framework must also be specified in the project file.")]
|
||||
public string Framework { get; set; }
|
||||
|
||||
[CommandOption("-r|--runtime <RUNTIMEIDENTIFIER>")]
|
||||
[Description("The target runtime to run for.")]
|
||||
public string RuntimeIdentifier { get; set; }
|
||||
|
||||
[CommandOption("-p|--project <PROJECTPATH>")]
|
||||
[Description("The path to the project file to run (defaults to the current directory if there is only one project).")]
|
||||
public string ProjectPath { get; set; }
|
||||
|
||||
[CommandOption("--launch-profile <LAUNCHPROFILE>")]
|
||||
[Description("The name of the launch profile (if any) to use when launching the application.")]
|
||||
public string LaunchProfile { get; set; }
|
||||
|
||||
[CommandOption("--no-launch-profile")]
|
||||
[Description("Do not attempt to use [grey]launchSettings.json[/] to configure the application.")]
|
||||
public bool NoLaunchProfile { get; set; }
|
||||
|
||||
[CommandOption("--no-build")]
|
||||
[Description("Do not build the project before running. Implies [grey]--no-restore[/].")]
|
||||
public bool NoBuild { get; set; }
|
||||
|
||||
[CommandOption("--interactive")]
|
||||
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
||||
public string Interactive { get; set; }
|
||||
|
||||
[CommandOption("--no-restore")]
|
||||
[Description("Do not restore the project before building.")]
|
||||
public bool NoRestore { get; set; }
|
||||
|
||||
[CommandOption("--verbosity <VERBOSITY>")]
|
||||
[Description("Set the MSBuild verbosity level. Allowed values are q[grey]uiet[/], m[grey]inimal[/], n[grey]ormal[/], d[grey]etailed[/], and diag[grey]nostic[/].")]
|
||||
[TypeConverter(typeof(VerbosityConverter))]
|
||||
[DefaultValue(Verbosity.Normal)]
|
||||
public Verbosity Verbosity { get; set; }
|
||||
|
||||
[CommandOption("--no-dependencies")]
|
||||
[Description("Do not restore project-to-project references and only restore the specified project.")]
|
||||
public bool NoDependencies { get; set; }
|
||||
|
||||
[CommandOption("--force")]
|
||||
[Description("Force all dependencies to be resolved even if the last restore was successful. This is equivalent to deleting [grey]project.assets.json[/].")]
|
||||
public bool Force { get; set; }
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
SettingsDumper.Dump(settings);
|
||||
return 0;
|
||||
}
|
||||
}
|
40
examples/Cli/Demo/Commands/Serve/ServeCommand.cs
Normal file
40
examples/Cli/Demo/Commands/Serve/ServeCommand.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using Demo.Utilities;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo.Commands.Serve;
|
||||
|
||||
[Description("Launches a web server in the current working directory and serves all files in it.")]
|
||||
public sealed class ServeCommand : Command<ServeCommand.Settings>
|
||||
{
|
||||
public sealed class Settings : CommandSettings
|
||||
{
|
||||
[CommandOption("-p|--port <PORT>")]
|
||||
[Description("Port to use. Defaults to [grey]8080[/]. Use [grey]0[/] for a dynamic port.")]
|
||||
public int Port { get; set; }
|
||||
|
||||
[CommandOption("-o|--open-browser [BROWSER]")]
|
||||
[Description("Open a web browser when the server starts. You can also specify which browser to use. If none is specified, the default one will be used.")]
|
||||
public FlagValue<string> OpenBrowser { get; set; }
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
if (settings.OpenBrowser.IsSet)
|
||||
{
|
||||
var browser = settings.OpenBrowser.Value;
|
||||
if (browser != null)
|
||||
{
|
||||
Console.WriteLine($"Open in {browser}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Open in default browser.");
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDumper.Dump(settings);
|
||||
return 0;
|
||||
}
|
||||
}
|
17
examples/Cli/Demo/Demo.csproj
Normal file
17
examples/Cli/Demo/Demo.csproj
Normal file
@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<ExampleName>Demo</ExampleName>
|
||||
<ExampleDescription>Demonstrates the most common use cases of Spectre.Cli.</ExampleDescription>
|
||||
<ExampleGroup>Cli</ExampleGroup>
|
||||
<ExampleVisible>false</ExampleVisible>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\Spectre.Console.Cli\Spectre.Console.Cli.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
39
examples/Cli/Demo/Program.cs
Normal file
39
examples/Cli/Demo/Program.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using Demo.Commands;
|
||||
using Demo.Commands.Add;
|
||||
using Demo.Commands.Run;
|
||||
using Demo.Commands.Serve;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
var app = new CommandApp();
|
||||
app.Configure(config =>
|
||||
{
|
||||
config.SetApplicationName("fake-dotnet");
|
||||
config.ValidateExamples();
|
||||
config.AddExample("run", "--no-build");
|
||||
|
||||
// Run
|
||||
config.AddCommand<RunCommand>("run");
|
||||
|
||||
// Add
|
||||
config.AddBranch<AddSettings>("add", add =>
|
||||
{
|
||||
add.SetDescription("Add a package or reference to a .NET project");
|
||||
add.AddCommand<AddPackageCommand>("package");
|
||||
add.AddCommand<AddReferenceCommand>("reference");
|
||||
});
|
||||
|
||||
// Serve
|
||||
config.AddCommand<ServeCommand>("serve")
|
||||
.WithExample("serve", "-o", "firefox")
|
||||
.WithExample("serve", "--port", "80", "-o", "firefox");
|
||||
});
|
||||
|
||||
return app.Run(args);
|
||||
}
|
||||
}
|
28
examples/Cli/Demo/Utilities/SettingsDumper.cs
Normal file
28
examples/Cli/Demo/Utilities/SettingsDumper.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Demo.Utilities;
|
||||
|
||||
public static class SettingsDumper
|
||||
{
|
||||
public static void Dump(CommandSettings settings)
|
||||
{
|
||||
var table = new Table().RoundedBorder();
|
||||
table.AddColumn("[grey]Name[/]");
|
||||
table.AddColumn("[grey]Value[/]");
|
||||
|
||||
var properties = settings.GetType().GetProperties();
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var value = property.GetValue(settings)
|
||||
?.ToString()
|
||||
?.Replace("[", "[[");
|
||||
|
||||
table.AddRow(
|
||||
property.Name,
|
||||
value ?? "[grey]null[/]");
|
||||
}
|
||||
|
||||
AnsiConsole.Write(table);
|
||||
}
|
||||
}
|
53
examples/Cli/Demo/Verbosity.cs
Normal file
53
examples/Cli/Demo/Verbosity.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Demo;
|
||||
|
||||
public enum Verbosity
|
||||
{
|
||||
Quiet,
|
||||
Minimal,
|
||||
Normal,
|
||||
Detailed,
|
||||
Diagnostic
|
||||
}
|
||||
|
||||
public sealed class VerbosityConverter : TypeConverter
|
||||
{
|
||||
private readonly Dictionary<string, Verbosity> _lookup;
|
||||
|
||||
public VerbosityConverter()
|
||||
{
|
||||
_lookup = new Dictionary<string, Verbosity>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "q", Verbosity.Quiet },
|
||||
{ "quiet", Verbosity.Quiet },
|
||||
{ "m", Verbosity.Minimal },
|
||||
{ "minimal", Verbosity.Minimal },
|
||||
{ "n", Verbosity.Normal },
|
||||
{ "normal", Verbosity.Normal },
|
||||
{ "d", Verbosity.Detailed },
|
||||
{ "detailed", Verbosity.Detailed },
|
||||
{ "diag", Verbosity.Diagnostic },
|
||||
{ "diagnostic", Verbosity.Diagnostic }
|
||||
};
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
if (value is string stringValue)
|
||||
{
|
||||
var result = _lookup.TryGetValue(stringValue, out var verbosity);
|
||||
if (!result)
|
||||
{
|
||||
const string format = "The value '{0}' is not a valid verbosity.";
|
||||
var message = string.Format(CultureInfo.InvariantCulture, format, value);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
return verbosity;
|
||||
}
|
||||
throw new NotSupportedException("Can't convert value to verbosity.");
|
||||
}
|
||||
}
|
17
examples/Cli/Dynamic/Dynamic.csproj
Normal file
17
examples/Cli/Dynamic/Dynamic.csproj
Normal file
@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<ExampleName>Dynamic</ExampleName>
|
||||
<ExampleDescription>Demonstrates how to define dynamic commands.</ExampleDescription>
|
||||
<ExampleGroup>Cli</ExampleGroup>
|
||||
<ExampleVisible>false</ExampleVisible>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
20
examples/Cli/Dynamic/MyCommand.cs
Normal file
20
examples/Cli/Dynamic/MyCommand.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Dynamic;
|
||||
|
||||
public sealed class MyCommand : Command
|
||||
{
|
||||
public override int Execute(CommandContext context)
|
||||
{
|
||||
if (!(context.Data is int data))
|
||||
{
|
||||
throw new InvalidOperationException("Command has no associated data.");
|
||||
|
||||
}
|
||||
|
||||
AnsiConsole.WriteLine("Value = {0}", data);
|
||||
return 0;
|
||||
}
|
||||
}
|
23
examples/Cli/Dynamic/Program.cs
Normal file
23
examples/Cli/Dynamic/Program.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System.Linq;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Dynamic;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
var app = new CommandApp();
|
||||
app.Configure(config =>
|
||||
{
|
||||
foreach (var index in Enumerable.Range(1, 10))
|
||||
{
|
||||
config.AddCommand<MyCommand>($"c{index}")
|
||||
.WithDescription($"Prints the number {index}")
|
||||
.WithData(index);
|
||||
}
|
||||
});
|
||||
|
||||
return app.Run(args);
|
||||
}
|
||||
}
|
30
examples/Cli/Help/CustomHelpProvider.cs
Normal file
30
examples/Cli/Help/CustomHelpProvider.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System.Linq;
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Cli;
|
||||
using Spectre.Console.Cli.Help;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Help;
|
||||
|
||||
/// <summary>
|
||||
/// Example showing how to extend the built-in Spectre.Console help provider
|
||||
/// by rendering a custom banner at the top of the help information
|
||||
/// </summary>
|
||||
internal class CustomHelpProvider : HelpProvider
|
||||
{
|
||||
public CustomHelpProvider(ICommandAppSettings settings)
|
||||
: base(settings)
|
||||
{
|
||||
}
|
||||
|
||||
public override IEnumerable<IRenderable> GetHeader(ICommandModel model, ICommandInfo? command)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new Text("--------------------------------------"), Text.NewLine,
|
||||
new Text("--- CUSTOM HELP PROVIDER ---"), Text.NewLine,
|
||||
new Text("--------------------------------------"), Text.NewLine,
|
||||
Text.NewLine,
|
||||
};
|
||||
}
|
||||
}
|
20
examples/Cli/Help/DefaultCommand.cs
Normal file
20
examples/Cli/Help/DefaultCommand.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Help;
|
||||
|
||||
public sealed class DefaultCommand : Command
|
||||
{
|
||||
private IAnsiConsole _console;
|
||||
|
||||
public DefaultCommand(IAnsiConsole console)
|
||||
{
|
||||
_console = console;
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context)
|
||||
{
|
||||
_console.WriteLine("Hello world");
|
||||
return 0;
|
||||
}
|
||||
}
|
18
examples/Cli/Help/Help.csproj
Normal file
18
examples/Cli/Help/Help.csproj
Normal file
@ -0,0 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<ExampleName>Help</ExampleName>
|
||||
<ExampleDescription>Demonstrates how to extend the built-in Spectre.Console help provider to render a custom banner at the top of the help information.</ExampleDescription>
|
||||
<ExampleGroup>Cli</ExampleGroup>
|
||||
<ExampleVisible>false</ExampleVisible>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
23
examples/Cli/Help/Program.cs
Normal file
23
examples/Cli/Help/Program.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using Spectre.Console.Cli;
|
||||
using Spectre.Console.Cli.Help;
|
||||
|
||||
namespace Help;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
var app = new CommandApp<DefaultCommand>();
|
||||
|
||||
app.Configure(config =>
|
||||
{
|
||||
// Register the custom help provider
|
||||
config.SetHelpProvider(new CustomHelpProvider(config.Settings));
|
||||
|
||||
// Render an unstyled help text for maximum accessibility
|
||||
config.Settings.HelpProviderStyles = null;
|
||||
});
|
||||
|
||||
return app.Run(args);
|
||||
}
|
||||
}
|
29
examples/Cli/Injection/Commands/DefaultCommand.cs
Normal file
29
examples/Cli/Injection/Commands/DefaultCommand.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Injection.Commands;
|
||||
|
||||
public sealed class DefaultCommand : Command<DefaultCommand.Settings>
|
||||
{
|
||||
private readonly IGreeter _greeter;
|
||||
|
||||
public sealed class Settings : CommandSettings
|
||||
{
|
||||
[CommandOption("-n|--name <NAME>")]
|
||||
[Description("The person or thing to greet.")]
|
||||
[DefaultValue("World")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public DefaultCommand(IGreeter greeter)
|
||||
{
|
||||
_greeter = greeter ?? throw new ArgumentNullException(nameof(greeter));
|
||||
}
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
_greeter.Greet(settings.Name);
|
||||
return 0;
|
||||
}
|
||||
}
|
16
examples/Cli/Injection/IGreeter.cs
Normal file
16
examples/Cli/Injection/IGreeter.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Injection;
|
||||
|
||||
public interface IGreeter
|
||||
{
|
||||
void Greet(string name);
|
||||
}
|
||||
|
||||
public sealed class HelloWorldGreeter : IGreeter
|
||||
{
|
||||
public void Greet(string name)
|
||||
{
|
||||
AnsiConsole.WriteLine($"Hello {name}!");
|
||||
}
|
||||
}
|
40
examples/Cli/Injection/Infrastructure/TypeRegistrar.cs
Normal file
40
examples/Cli/Injection/Infrastructure/TypeRegistrar.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Injection.Infrastructure;
|
||||
|
||||
public sealed class TypeRegistrar : ITypeRegistrar
|
||||
{
|
||||
private readonly IServiceCollection _builder;
|
||||
|
||||
public TypeRegistrar(IServiceCollection builder)
|
||||
{
|
||||
_builder = builder;
|
||||
}
|
||||
|
||||
public ITypeResolver Build()
|
||||
{
|
||||
return new TypeResolver(_builder.BuildServiceProvider());
|
||||
}
|
||||
|
||||
public void Register(Type service, Type implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterInstance(Type service, object implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterLazy(Type service, Func<object> func)
|
||||
{
|
||||
if (func is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(func));
|
||||
}
|
||||
|
||||
_builder.AddSingleton(service, (provider) => func());
|
||||
}
|
||||
}
|
32
examples/Cli/Injection/Infrastructure/TypeResolver.cs
Normal file
32
examples/Cli/Injection/Infrastructure/TypeResolver.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Injection.Infrastructure;
|
||||
|
||||
public sealed class TypeResolver : ITypeResolver, IDisposable
|
||||
{
|
||||
private readonly IServiceProvider _provider;
|
||||
|
||||
public TypeResolver(IServiceProvider provider)
|
||||
{
|
||||
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||
}
|
||||
|
||||
public object Resolve(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _provider.GetService(type);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_provider is IDisposable disposable)
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
21
examples/Cli/Injection/Injection.csproj
Normal file
21
examples/Cli/Injection/Injection.csproj
Normal file
@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<ExampleName>Injection</ExampleName>
|
||||
<ExampleDescription>Demonstrates how to use dependency injection with Spectre.Cli.</ExampleDescription>
|
||||
<ExampleGroup>Cli</ExampleGroup>
|
||||
<ExampleVisible>false</ExampleVisible>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
23
examples/Cli/Injection/Program.cs
Normal file
23
examples/Cli/Injection/Program.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using Injection.Commands;
|
||||
using Injection.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Injection;
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
// Create a type registrar and register any dependencies.
|
||||
// A type registrar is an adapter for a DI framework.
|
||||
var registrations = new ServiceCollection();
|
||||
registrations.AddSingleton<IGreeter, HelloWorldGreeter>();
|
||||
var registrar = new TypeRegistrar(registrations);
|
||||
|
||||
// Create a new command app with the registrar
|
||||
// and run it with the provided arguments.
|
||||
var app = new CommandApp<DefaultCommand>(registrar);
|
||||
return app.Run(args);
|
||||
}
|
||||
}
|
34
examples/Cli/Logging/Commands/HelloCommand.cs
Normal file
34
examples/Cli/Logging/Commands/HelloCommand.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Logging.Commands;
|
||||
|
||||
public class HelloCommand : Command<HelloCommand.Settings>
|
||||
{
|
||||
private ILogger<HelloCommand> _logger;
|
||||
private IAnsiConsole _console;
|
||||
|
||||
public HelloCommand(IAnsiConsole console, ILogger<HelloCommand> logger)
|
||||
{
|
||||
_console = console;
|
||||
_logger = logger;
|
||||
_logger.LogDebug("{0} initialized", nameof(HelloCommand));
|
||||
}
|
||||
|
||||
public class Settings : LogCommandSettings
|
||||
{
|
||||
[CommandArgument(0, "[Name]")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
_logger.LogInformation("Starting my command");
|
||||
AnsiConsole.MarkupLine($"Hello, [blue]{settings.Name}[/]");
|
||||
_logger.LogInformation("Completed my command");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
55
examples/Cli/Logging/Commands/LogCommandSettings.cs
Normal file
55
examples/Cli/Logging/Commands/LogCommandSettings.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using Serilog.Events;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Logging.Commands;
|
||||
|
||||
public class LogCommandSettings : CommandSettings
|
||||
{
|
||||
[CommandOption("--logFile")]
|
||||
[Description("Path and file name for logging")]
|
||||
public string LogFile { get; set; }
|
||||
|
||||
[CommandOption("--logLevel")]
|
||||
[Description("Minimum level for logging")]
|
||||
[TypeConverter(typeof(VerbosityConverter))]
|
||||
[DefaultValue(LogEventLevel.Information)]
|
||||
public LogEventLevel LogLevel { get; set; }
|
||||
}
|
||||
|
||||
public sealed class VerbosityConverter : TypeConverter
|
||||
{
|
||||
private readonly Dictionary<string, LogEventLevel> _lookup;
|
||||
|
||||
public VerbosityConverter()
|
||||
{
|
||||
_lookup = new Dictionary<string, LogEventLevel>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{"d", LogEventLevel.Debug},
|
||||
{"v", LogEventLevel.Verbose},
|
||||
{"i", LogEventLevel.Information},
|
||||
{"w", LogEventLevel.Warning},
|
||||
{"e", LogEventLevel.Error},
|
||||
{"f", LogEventLevel.Fatal}
|
||||
};
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
if (value is string stringValue)
|
||||
{
|
||||
var result = _lookup.TryGetValue(stringValue, out var verbosity);
|
||||
if (!result)
|
||||
{
|
||||
const string format = "The value '{0}' is not a valid verbosity.";
|
||||
var message = string.Format(CultureInfo.InvariantCulture, format, value);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
return verbosity;
|
||||
}
|
||||
throw new NotSupportedException("Can't convert value to verbosity.");
|
||||
}
|
||||
}
|
19
examples/Cli/Logging/Infrastructure/LogInterceptor.cs
Normal file
19
examples/Cli/Logging/Infrastructure/LogInterceptor.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using Logging.Commands;
|
||||
using Serilog.Core;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Logging.Infrastructure;
|
||||
|
||||
public class LogInterceptor : ICommandInterceptor
|
||||
{
|
||||
public static readonly LoggingLevelSwitch LogLevel = new();
|
||||
|
||||
public void Intercept(CommandContext context, CommandSettings settings)
|
||||
{
|
||||
if (settings is LogCommandSettings logSettings)
|
||||
{
|
||||
LoggingEnricher.Path = logSettings.LogFile ?? "application.log";
|
||||
LogLevel.MinimumLevel = logSettings.LogLevel;
|
||||
}
|
||||
}
|
||||
}
|
37
examples/Cli/Logging/Infrastructure/LoggingEnricher.cs
Normal file
37
examples/Cli/Logging/Infrastructure/LoggingEnricher.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace Logging.Infrastructure;
|
||||
|
||||
internal class LoggingEnricher : ILogEventEnricher
|
||||
{
|
||||
private string _cachedLogFilePath;
|
||||
private LogEventProperty _cachedLogFilePathProperty;
|
||||
|
||||
// this path and level will be set by the LogInterceptor.cs after parsing the settings
|
||||
public static string Path = string.Empty;
|
||||
|
||||
public const string LogFilePathPropertyName = "LogFilePath";
|
||||
|
||||
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
|
||||
{
|
||||
// the settings might not have a path or we might not be within a command in which case
|
||||
// we won't have the setting so a default value for the log file will be required
|
||||
LogEventProperty logFilePathProperty;
|
||||
|
||||
if (_cachedLogFilePathProperty != null && Path.Equals(_cachedLogFilePath))
|
||||
{
|
||||
// Path hasn't changed, so let's use the cached property
|
||||
logFilePathProperty = _cachedLogFilePathProperty;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We've got a new path for the log. Let's create a new property
|
||||
// and cache it for future log events to use
|
||||
_cachedLogFilePath = Path;
|
||||
_cachedLogFilePathProperty = logFilePathProperty = propertyFactory.CreateProperty(LogFilePathPropertyName, Path);
|
||||
}
|
||||
|
||||
logEvent.AddPropertyIfAbsent(logFilePathProperty);
|
||||
}
|
||||
}
|
40
examples/Cli/Logging/Infrastructure/TypeRegistrar.cs
Normal file
40
examples/Cli/Logging/Infrastructure/TypeRegistrar.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Logging.Infrastructure;
|
||||
|
||||
public sealed class TypeRegistrar : ITypeRegistrar
|
||||
{
|
||||
private readonly IServiceCollection _builder;
|
||||
|
||||
public TypeRegistrar(IServiceCollection builder)
|
||||
{
|
||||
_builder = builder;
|
||||
}
|
||||
|
||||
public ITypeResolver Build()
|
||||
{
|
||||
return new TypeResolver(_builder.BuildServiceProvider());
|
||||
}
|
||||
|
||||
public void Register(Type service, Type implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterInstance(Type service, object implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterLazy(Type service, Func<object> func)
|
||||
{
|
||||
if (func is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(func));
|
||||
}
|
||||
|
||||
_builder.AddSingleton(service, _ => func());
|
||||
}
|
||||
}
|
24
examples/Cli/Logging/Infrastructure/TypeResolver.cs
Normal file
24
examples/Cli/Logging/Infrastructure/TypeResolver.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Logging.Infrastructure;
|
||||
|
||||
public sealed class TypeResolver : ITypeResolver
|
||||
{
|
||||
private readonly IServiceProvider _provider;
|
||||
|
||||
public TypeResolver(IServiceProvider provider)
|
||||
{
|
||||
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||
}
|
||||
|
||||
public object Resolve(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _provider.GetService(type);
|
||||
}
|
||||
}
|
26
examples/Cli/Logging/Logging.csproj
Normal file
26
examples/Cli/Logging/Logging.csproj
Normal file
@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<ExampleName>Logging</ExampleName>
|
||||
<ExampleDescription>Demonstrates how to dynamically configure Serilog for logging using parameters from a command.</ExampleDescription>
|
||||
<ExampleGroup>Cli</ExampleGroup>
|
||||
<ExampleVisible>false</ExampleVisible>
|
||||
<Nullable>disable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="Serilog" Version="3.1.1" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Map" Version="1.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
54
examples/Cli/Logging/Program.cs
Normal file
54
examples/Cli/Logging/Program.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using Logging.Commands;
|
||||
using Logging.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
/*
|
||||
* Dynamically control serilog configuration via command line parameters
|
||||
*
|
||||
* This works around the chicken and egg situation with configuring serilog via the command line.
|
||||
* The logger needs to be configured prior to executing the parser, but the logger needs the parsed values
|
||||
* to be configured. By using serilog.sinks.map we can defer configuration. We use a LogLevelSwitch to control the
|
||||
* logging levels dynamically, and then we use a serilog enricher that has its state populated via a
|
||||
* Spectre.Console CommandInterceptor
|
||||
*/
|
||||
|
||||
namespace Logging;
|
||||
|
||||
public class Program
|
||||
{
|
||||
static int Main(string[] args)
|
||||
{
|
||||
// to retrieve the log file name, we must first parse the command settings
|
||||
// this will require us to delay setting the file path for the file writer.
|
||||
// With serilog we can use an enricher and Serilog.Sinks.Map to dynamically
|
||||
// pull this setting.
|
||||
var serviceCollection = new ServiceCollection()
|
||||
.AddLogging(configure =>
|
||||
configure.AddSerilog(new LoggerConfiguration()
|
||||
// log level will be dynamically be controlled by our log interceptor upon running
|
||||
.MinimumLevel.ControlledBy(LogInterceptor.LogLevel)
|
||||
// the log enricher will add a new property with the log file path from the settings
|
||||
// that we can use to set the path dynamically
|
||||
.Enrich.With<LoggingEnricher>()
|
||||
// serilog.sinks.map will defer the configuration of the sink to be ondemand
|
||||
// allowing us to look at the properties set by the enricher to set the path appropriately
|
||||
.WriteTo.Map(LoggingEnricher.LogFilePathPropertyName,
|
||||
(logFilePath, wt) => wt.File($"{logFilePath}"), 1)
|
||||
.CreateLogger()
|
||||
)
|
||||
);
|
||||
|
||||
var registrar = new TypeRegistrar(serviceCollection);
|
||||
var app = new CommandApp(registrar);
|
||||
|
||||
app.Configure(config =>
|
||||
{
|
||||
config.SetInterceptor(new LogInterceptor()); // add the interceptor
|
||||
config.AddCommand<HelloCommand>("hello");
|
||||
});
|
||||
|
||||
return app.Run(args);
|
||||
}
|
||||
}
|
15
examples/Console/AlternateScreen/AlternateScreen.csproj
Normal file
15
examples/Console/AlternateScreen/AlternateScreen.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ExampleTitle>Screens</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to use alternate screens.</ExampleDescription>
|
||||
<ExampleGroup>Widgets</ExampleGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
26
examples/Console/AlternateScreen/Program.cs
Normal file
26
examples/Console/AlternateScreen/Program.cs
Normal file
@ -0,0 +1,26 @@
|
||||
// Check if we can use alternate screen buffers
|
||||
using Spectre.Console;
|
||||
|
||||
if (!AnsiConsole.Profile.Capabilities.AlternateBuffer)
|
||||
{
|
||||
AnsiConsole.MarkupLine(
|
||||
"[red]Alternate screen buffers are not supported " +
|
||||
"by your terminal[/] [yellow]:([/]");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Write to the terminal
|
||||
AnsiConsole.Write(new Rule("[yellow]Normal universe[/]"));
|
||||
AnsiConsole.Write(new Panel("Hello World!"));
|
||||
AnsiConsole.MarkupLine("[grey]Press a key to continue[/]");
|
||||
AnsiConsole.Console.Input.ReadKey(true);
|
||||
|
||||
AnsiConsole.AlternateScreen(() =>
|
||||
{
|
||||
// Now we're in another terminal screen buffer
|
||||
AnsiConsole.Write(new Rule("[red]Mirror universe[/]"));
|
||||
AnsiConsole.Write(new Panel("[red]Welcome to the upside down![/]"));
|
||||
AnsiConsole.MarkupLine("[grey]Press a key to return[/]");
|
||||
AnsiConsole.Console.Input.ReadKey(true);
|
||||
});
|
15
examples/Console/Borders/Borders.csproj
Normal file
15
examples/Console/Borders/Borders.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ExampleTitle>Borders</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates the different kind of borders.</ExampleDescription>
|
||||
<ExampleGroup>Widgets</ExampleGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
86
examples/Console/Borders/Program.cs
Normal file
86
examples/Console/Borders/Program.cs
Normal file
@ -0,0 +1,86 @@
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Borders;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
// Render panel borders
|
||||
HorizontalRule("PANEL BORDERS");
|
||||
PanelBorders();
|
||||
|
||||
// Render table borders
|
||||
HorizontalRule("TABLE BORDERS");
|
||||
TableBorders();
|
||||
}
|
||||
|
||||
private static void PanelBorders()
|
||||
{
|
||||
static IRenderable CreatePanel(string name, BoxBorder border)
|
||||
{
|
||||
return
|
||||
new Panel($"This is a panel with\nthe [yellow]{name}[/] border.")
|
||||
.Header($" [blue]{name}[/] ", Justify.Center)
|
||||
.Border(border)
|
||||
.BorderStyle(Style.Parse("grey"));
|
||||
}
|
||||
|
||||
var items = new[]
|
||||
{
|
||||
CreatePanel("Ascii", BoxBorder.Ascii),
|
||||
CreatePanel("Square", BoxBorder.Square),
|
||||
CreatePanel("Rounded", BoxBorder.Rounded),
|
||||
CreatePanel("Heavy", BoxBorder.Heavy),
|
||||
CreatePanel("Double", BoxBorder.Double),
|
||||
CreatePanel("None", BoxBorder.None),
|
||||
};
|
||||
|
||||
AnsiConsole.Write(
|
||||
new Padder(
|
||||
new Columns(items).PadRight(2),
|
||||
new Padding(2, 0, 0, 0)));
|
||||
}
|
||||
|
||||
private static void TableBorders()
|
||||
{
|
||||
static IRenderable CreateTable(string name, TableBorder border)
|
||||
{
|
||||
var table = new Table().Border(border);
|
||||
table.ShowRowSeparators();
|
||||
table.AddColumn("[yellow]Header 1[/]", c => c.Footer("[grey]Footer 1[/]"));
|
||||
table.AddColumn("[yellow]Header 2[/]", col => col.Footer("[grey]Footer 2[/]").RightAligned());
|
||||
table.AddRow("Cell", "Cell");
|
||||
table.AddRow("Cell", "Cell");
|
||||
|
||||
return new Panel(table)
|
||||
.Header($" [blue]{name}[/] ", Justify.Center)
|
||||
.PadBottom(1)
|
||||
.NoBorder();
|
||||
}
|
||||
|
||||
var items = new[]
|
||||
{
|
||||
CreateTable("Ascii", TableBorder.Ascii), CreateTable("Ascii2", TableBorder.Ascii2),
|
||||
CreateTable("AsciiDoubleHead", TableBorder.AsciiDoubleHead),
|
||||
CreateTable("Horizontal", TableBorder.Horizontal), CreateTable("Simple", TableBorder.Simple),
|
||||
CreateTable("SimpleHeavy", TableBorder.SimpleHeavy), CreateTable("Minimal", TableBorder.Minimal),
|
||||
CreateTable("MinimalHeavyHead", TableBorder.MinimalHeavyHead),
|
||||
CreateTable("MinimalDoubleHead", TableBorder.MinimalDoubleHead),
|
||||
CreateTable("Square", TableBorder.Square), CreateTable("Rounded", TableBorder.Rounded),
|
||||
CreateTable("Heavy", TableBorder.Heavy), CreateTable("HeavyEdge", TableBorder.HeavyEdge),
|
||||
CreateTable("HeavyHead", TableBorder.HeavyHead), CreateTable("Double", TableBorder.Double),
|
||||
CreateTable("DoubleEdge", TableBorder.DoubleEdge), CreateTable("Markdown", TableBorder.Markdown),
|
||||
};
|
||||
|
||||
AnsiConsole.Write(new Columns(items).Collapse());
|
||||
}
|
||||
|
||||
private static void HorizontalRule(string title)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule($"[white bold]{title}[/]").RuleStyle("grey").LeftJustified());
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
}
|
15
examples/Console/Calendars/Calendars.csproj
Normal file
15
examples/Console/Calendars/Calendars.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ExampleTitle>Calendars</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to render calendars.</ExampleDescription>
|
||||
<ExampleGroup>Widgets</ExampleGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
18
examples/Console/Calendars/Program.cs
Normal file
18
examples/Console/Calendars/Program.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Calendars;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Calendar(2020, 10)
|
||||
.RoundedBorder()
|
||||
.HighlightStyle(Style.Parse("red"))
|
||||
.HeaderStyle(Style.Parse("yellow"))
|
||||
.AddCalendarEvent("An event", 2020, 9, 22)
|
||||
.AddCalendarEvent("Another event", 2020, 10, 2)
|
||||
.AddCalendarEvent("A third event", 2020, 10, 13));
|
||||
}
|
||||
}
|
22
examples/Console/Canvas/Canvas.csproj
Normal file
22
examples/Console/Canvas/Canvas.csproj
Normal file
@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ExampleTitle>Canvas</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to render pixels and images.</ExampleDescription>
|
||||
<ExampleGroup>Widgets</ExampleGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
<ProjectReference Include="..\..\..\src\Spectre.Console.ImageSharp\Spectre.Console.ImageSharp.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="cake.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
43
examples/Console/Canvas/Program.cs
Normal file
43
examples/Console/Canvas/Program.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Canvas;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
// Draw an image using CanvasImage powered by ImageSharp.
|
||||
// This requires the "Spectre.Console.ImageSharp" NuGet package.
|
||||
var image = new CanvasImage("cake.png");
|
||||
image.BilinearResampler();
|
||||
image.MaxWidth(16);
|
||||
Render(image, "Image from file (16 wide)");
|
||||
|
||||
// Draw image again, but without max width
|
||||
image.NoMaxWidth();
|
||||
image.Mutate(ctx => ctx.Grayscale().Rotate(-45).EntropyCrop());
|
||||
Render(image, "Image from file (fit, greyscale, rotated)");
|
||||
|
||||
// Draw image again, but load from embedded resource rather than file
|
||||
using (var fileStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Canvas.cake.png"))
|
||||
{
|
||||
Debug.Assert(fileStream != null);
|
||||
var embeddedImage = new CanvasImage(fileStream);
|
||||
embeddedImage.BilinearResampler();
|
||||
embeddedImage.MaxWidth(16);
|
||||
Render(embeddedImage, "Image from embedded resource (16 wide)");
|
||||
}
|
||||
}
|
||||
|
||||
private static void Render(IRenderable canvas, string title)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule($"[yellow]{title}[/]").LeftJustified().RuleStyle("grey"));
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(canvas);
|
||||
}
|
||||
}
|
BIN
examples/Console/Canvas/cake.png
Normal file
BIN
examples/Console/Canvas/cake.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
15
examples/Console/Charts/Charts.csproj
Normal file
15
examples/Console/Charts/Charts.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ExampleTitle>Charts</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to render charts in a console.</ExampleDescription>
|
||||
<ExampleGroup>Widgets</ExampleGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
42
examples/Console/Charts/Program.cs
Normal file
42
examples/Console/Charts/Program.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Charts;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
// Render a bar chart
|
||||
AnsiConsole.WriteLine();
|
||||
Render("Fruits per month", new BarChart()
|
||||
.Width(60)
|
||||
.Label("[green bold underline]Number of fruits[/]")
|
||||
.CenterLabel()
|
||||
.AddItem("Apple", 12, Color.Yellow)
|
||||
.AddItem("Orange", 54, Color.Green)
|
||||
.AddItem("Banana", 33, Color.Red));
|
||||
|
||||
// Render a breakdown chart
|
||||
AnsiConsole.WriteLine();
|
||||
Render("Languages used", new BreakdownChart()
|
||||
.FullSize()
|
||||
.Width(60)
|
||||
.ShowPercentage()
|
||||
.WithValueColor(Color.Orange1)
|
||||
.AddItem("SCSS", 37, Color.Red)
|
||||
.AddItem("HTML", 28.3, Color.Blue)
|
||||
.AddItem("C#", 22.6, Color.Green)
|
||||
.AddItem("JavaScript", 6, Color.Yellow)
|
||||
.AddItem("Ruby", 6, Color.LightGreen)
|
||||
.AddItem("Shell", 0.1, Color.Aqua));
|
||||
}
|
||||
|
||||
private static void Render(string title, IRenderable chart)
|
||||
{
|
||||
AnsiConsole.Write(
|
||||
new Panel(chart)
|
||||
.Padding(1, 1)
|
||||
.Header(title));
|
||||
}
|
||||
}
|
15
examples/Console/Colors/Colors.csproj
Normal file
15
examples/Console/Colors/Colors.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ExampleTitle>Colors</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to use [yellow]c[/][red]o[/][green]l[/][blue]o[/][aqua]r[/][lime]s[/] in the console.</ExampleDescription>
|
||||
<ExampleGroup>Misc</ExampleGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
105
examples/Console/Colors/Program.cs
Normal file
105
examples/Console/Colors/Program.cs
Normal file
@ -0,0 +1,105 @@
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Examples;
|
||||
|
||||
namespace Colors;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// No colors
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Capabilities.ColorSystem == ColorSystem.NoColors)
|
||||
{
|
||||
AnsiConsole.WriteLine("No colors are supported.");
|
||||
return;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 3-BIT
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.Legacy))
|
||||
{
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("[yellow bold underline]3-bit Colors[/]").RuleStyle("grey").LeftJustified());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
AnsiConsole.Background = Color.FromInt32(i);
|
||||
AnsiConsole.Foreground = AnsiConsole.Background.GetInvertedColor();
|
||||
AnsiConsole.Write(string.Format(" {0,-9}", AnsiConsole.Background.ToString()));
|
||||
AnsiConsole.ResetColors();
|
||||
if ((i + 1) % 8 == 0)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 4-BIT
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.Standard))
|
||||
{
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("[yellow bold underline]4-bit Colors[/]").RuleStyle("grey").LeftJustified());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
for (var i = 0; i < 16; i++)
|
||||
{
|
||||
AnsiConsole.Background = Color.FromInt32(i);
|
||||
AnsiConsole.Foreground = AnsiConsole.Background.GetInvertedColor();
|
||||
AnsiConsole.Write(string.Format(" {0,-9}", AnsiConsole.Background.ToString()));
|
||||
AnsiConsole.ResetColors();
|
||||
if ((i + 1) % 8 == 0)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 8-BIT
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.EightBit))
|
||||
{
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("[yellow bold underline]8-bit Colors[/]").RuleStyle("grey").LeftJustified());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
for (var i = 0; i < 16; i++)
|
||||
{
|
||||
for (var j = 0; j < 16; j++)
|
||||
{
|
||||
var number = i * 16 + j;
|
||||
AnsiConsole.Background = Color.FromInt32(number);
|
||||
AnsiConsole.Foreground = AnsiConsole.Background.GetInvertedColor();
|
||||
AnsiConsole.Write(string.Format(" {0,-4}", number));
|
||||
AnsiConsole.ResetColors();
|
||||
if ((number + 1) % 16 == 0)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 24-BIT
|
||||
/////////////////////////////////////////////////////////////////
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.TrueColor))
|
||||
{
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("[yellow bold underline]24-bit Colors[/]").RuleStyle("grey").LeftJustified());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
AnsiConsole.Write(new ColorBox(width: 80, height: 15));
|
||||
}
|
||||
}
|
||||
}
|
19
examples/Console/Columns/Columns.csproj
Normal file
19
examples/Console/Columns/Columns.csproj
Normal file
@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ExampleTitle>Columns</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to render data into columns.</ExampleDescription>
|
||||
<ExampleGroup>Widgets</ExampleGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
30
examples/Console/Columns/Program.cs
Normal file
30
examples/Console/Columns/Program.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Columns;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
var cards = new List<Panel>();
|
||||
foreach (var user in User.LoadUsers())
|
||||
{
|
||||
cards.Add(
|
||||
new Panel(GetCardContent(user))
|
||||
.Header($"{user.Country}")
|
||||
.RoundedBorder().Expand());
|
||||
}
|
||||
|
||||
// Render all cards in columns
|
||||
AnsiConsole.Write(new Spectre.Console.Columns(cards));
|
||||
}
|
||||
|
||||
private static string GetCardContent(User user)
|
||||
{
|
||||
var name = $"{user.FirstName} {user.LastName}";
|
||||
var city = $"{user.City}";
|
||||
|
||||
return $"[b]{name}[/]\n[yellow]{city}[/]";
|
||||
}
|
||||
}
|
88
examples/Console/Columns/User.cs
Normal file
88
examples/Console/Columns/User.cs
Normal file
@ -0,0 +1,88 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Columns;
|
||||
|
||||
public sealed class User
|
||||
{
|
||||
public string FirstName { get; set; }
|
||||
public string LastName { get; set; }
|
||||
public string City { get; set; }
|
||||
public string Country { get; set; }
|
||||
|
||||
public static List<User> LoadUsers()
|
||||
{
|
||||
return new List<User>
|
||||
{
|
||||
new User
|
||||
{
|
||||
FirstName = "Andrea",
|
||||
LastName = "Johansen",
|
||||
City = "Hornbæk",
|
||||
Country = "Denmark",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Phil",
|
||||
LastName = "Scott",
|
||||
City = "Dayton",
|
||||
Country = "United States",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Patrik",
|
||||
LastName = "Svensson",
|
||||
City = "Stockholm",
|
||||
Country = "Sweden",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Freya",
|
||||
LastName = "Thompson",
|
||||
City = "Rotorua",
|
||||
Country = "New Zealand",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "طاها",
|
||||
LastName = "رضایی",
|
||||
City = "اهواز",
|
||||
Country = "Iran",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Yara",
|
||||
LastName = "Simon",
|
||||
City = "Develier",
|
||||
Country = "Switzerland",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Giray",
|
||||
LastName = "Erbay",
|
||||
City = "Karabük",
|
||||
Country = "Turkey",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Miodrag",
|
||||
LastName = "Schaffer",
|
||||
City = "Möckern",
|
||||
Country = "Germany",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Carmela",
|
||||
LastName = "Lo Castro",
|
||||
City = "Firenze",
|
||||
Country = "Italy",
|
||||
},
|
||||
new User
|
||||
{
|
||||
FirstName = "Roberto",
|
||||
LastName = "Sims",
|
||||
City = "Mallow",
|
||||
Country = "Ireland",
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
15
examples/Console/Cursor/Cursor.csproj
Normal file
15
examples/Console/Cursor/Cursor.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ExampleTitle>Cursor</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to move the cursor.</ExampleDescription>
|
||||
<ExampleGroup>Misc</ExampleGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
19
examples/Console/Cursor/Program.cs
Normal file
19
examples/Console/Cursor/Program.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Cursor;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
AnsiConsole.Write("Hello");
|
||||
|
||||
// Move the cursor 3 cells to the right
|
||||
AnsiConsole.Cursor.Move(CursorDirection.Right, 3);
|
||||
AnsiConsole.Write("World");
|
||||
|
||||
// Move the cursor 5 cells to the left.
|
||||
AnsiConsole.Cursor.Move(CursorDirection.Left, 5);
|
||||
AnsiConsole.WriteLine("Universe");
|
||||
}
|
||||
}
|
15
examples/Console/Decorations/Decorations.csproj
Normal file
15
examples/Console/Decorations/Decorations.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ExampleTitle>Decorations</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to [italic]use[/] [bold]decorations[/] [dim]in[/] the console.</ExampleDescription>
|
||||
<ExampleGroup>Misc</ExampleGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
29
examples/Console/Decorations/Program.cs
Normal file
29
examples/Console/Decorations/Program.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Colors;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
AnsiConsole.ResetDecoration();
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
if (AnsiConsole.Profile.Capabilities.Ansi)
|
||||
{
|
||||
AnsiConsole.Write(new Rule("[bold green]ANSI Decorations[/]"));
|
||||
}
|
||||
else
|
||||
{
|
||||
AnsiConsole.Write(new Rule("[bold red]Legacy Decorations (unsupported)[/]"));
|
||||
}
|
||||
|
||||
var decorations = System.Enum.GetValues(typeof(Decoration));
|
||||
foreach (var decoration in decorations)
|
||||
{
|
||||
var name = System.Enum.GetName(typeof(Decoration),decoration);
|
||||
AnsiConsole.Write(name + ": ");
|
||||
AnsiConsole.Write(new Markup(name+"\n", new Style(decoration: (Decoration)decoration)));
|
||||
}
|
||||
}
|
||||
}
|
15
examples/Console/Emojis/Emojis.csproj
Normal file
15
examples/Console/Emojis/Emojis.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ExampleTitle>Emojis</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to render emojis.</ExampleDescription>
|
||||
<ExampleGroup>Misc</ExampleGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
23
examples/Console/Emojis/Program.cs
Normal file
23
examples/Console/Emojis/Program.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Emojis;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// Show a known emoji
|
||||
RenderEmoji();
|
||||
|
||||
// Show a remapped emoji
|
||||
Emoji.Remap("globe_showing_europe_africa", Emoji.Known.GrinningFaceWithSmilingEyes);
|
||||
RenderEmoji();
|
||||
}
|
||||
|
||||
private static void RenderEmoji()
|
||||
{
|
||||
AnsiConsole.Write(
|
||||
new Panel("[yellow]Hello :globe_showing_europe_africa:![/]")
|
||||
.RoundedBorder());
|
||||
}
|
||||
}
|
15
examples/Console/Exceptions/Exceptions.csproj
Normal file
15
examples/Console/Exceptions/Exceptions.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ExampleTitle>Exceptions</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to render formatted exceptions.</ExampleDescription>
|
||||
<ExampleGroup>Misc</ExampleGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
101
examples/Console/Exceptions/Program.cs
Normal file
101
examples/Console/Exceptions/Program.cs
Normal file
@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Authentication;
|
||||
using System.Threading.Tasks;
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Exceptions;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
var foo = new List<string>();
|
||||
DoMagic(42, null, ref foo);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("Default").LeftJustified());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex);
|
||||
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("Compact").LeftJustified());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks);
|
||||
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("Compact + Custom colors").LeftJustified());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex, new ExceptionSettings
|
||||
{
|
||||
Format = ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks,
|
||||
Style = new ExceptionStyle
|
||||
{
|
||||
Exception = new Style().Foreground(Color.Grey),
|
||||
Message = new Style().Foreground(Color.White),
|
||||
NonEmphasized = new Style().Foreground(Color.Cornsilk1),
|
||||
Parenthesis = new Style().Foreground(Color.Cornsilk1),
|
||||
Method = new Style().Foreground(Color.Red),
|
||||
ParameterName = new Style().Foreground(Color.Cornsilk1),
|
||||
ParameterType = new Style().Foreground(Color.Red),
|
||||
Path = new Style().Foreground(Color.Red),
|
||||
LineNumber = new Style().Foreground(Color.Cornsilk1),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await DoMagicAsync<int>(42, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Write(new Rule("Async").LeftJustified());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenPaths);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DoMagic(int foo, string[,] bar, ref List<string> result)
|
||||
{
|
||||
try
|
||||
{
|
||||
CheckCredentials(foo, bar);
|
||||
result = new List<string>();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException("Whaaat?", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CheckCredentials(int? qux, string[,] corgi)
|
||||
{
|
||||
throw new InvalidCredentialException("The credentials are invalid.");
|
||||
}
|
||||
|
||||
private static async Task DoMagicAsync<T>(T foo, string[,] bar)
|
||||
{
|
||||
try
|
||||
{
|
||||
await CheckCredentialsAsync(new[] { foo }.ToList(), new []{ foo }, bar);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException("Whaaat?", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<bool> CheckCredentialsAsync<T>(List<T> qux, T[] otherArray, string[,] corgi)
|
||||
{
|
||||
await Task.Delay(0);
|
||||
throw new InvalidCredentialException("The credentials are invalid.");
|
||||
}
|
||||
}
|
||||
|
15
examples/Console/Figlet/Figlet.csproj
Normal file
15
examples/Console/Figlet/Figlet.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ExampleTitle>Figlet</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to render FIGlet text.</ExampleDescription>
|
||||
<ExampleGroup>Widgets</ExampleGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
13
examples/Console/Figlet/Program.cs
Normal file
13
examples/Console/Figlet/Program.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Figlet;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
AnsiConsole.Write(new FigletText("Left aligned").LeftJustified().Color(Color.Red));
|
||||
AnsiConsole.Write(new FigletText("Centered").Centered().Color(Color.Green));
|
||||
AnsiConsole.Write(new FigletText("Right aligned").RightJustified().Color(Color.Blue));
|
||||
}
|
||||
}
|
15
examples/Console/Grids/Grids.csproj
Normal file
15
examples/Console/Grids/Grids.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ExampleTitle>Grids</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to render grids in a console.</ExampleDescription>
|
||||
<ExampleGroup>Widgets</ExampleGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user