mirror of
https://github.com/spectreconsole/spectre.console.git
synced 2025-10-25 15:19:23 +00:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d70ad661fc | ||
|
|
0d209d8f18 | ||
|
|
380c6aca45 | ||
|
|
b1da5e7ba8 | ||
|
|
be3350a411 | ||
|
|
a1d11e9d0c | ||
|
|
93d1971f48 | ||
|
|
bca1c889d1 | ||
|
|
9915a0d6a8 | ||
|
|
f34fc43d00 | ||
|
|
e7f497050c | ||
|
|
3e5e22d6c2 | ||
|
|
10daf727e9 | ||
|
|
03334f693d | ||
|
|
c9c0ad733f | ||
|
|
041bd016a2 | ||
|
|
037a215a78 | ||
|
|
9afc1ea721 | ||
|
|
b52056ee49 | ||
|
|
3941fd81ab | ||
|
|
5a1b8a1710 | ||
|
|
1410cba6c5 | ||
|
|
70fc14e9cd | ||
|
|
0b4359a52a | ||
|
|
cb2924a609 | ||
|
|
5c119ee0c3 | ||
|
|
b9d182b6e3 | ||
|
|
bfffef630f | ||
|
|
a2f507e58f | ||
|
|
d1d06d6a6b | ||
|
|
52718c499c | ||
|
|
7ef1ac483a | ||
|
|
c0875c912a | ||
|
|
3f2ca49071 | ||
|
|
0a0380ae0a | ||
|
|
ae92c606bb | ||
|
|
68e92f3365 | ||
|
|
39a8588dc3 | ||
|
|
3c3afe7439 | ||
|
|
971f9032ba | ||
|
|
5149557560 | ||
|
|
e0947708c9 | ||
|
|
b1db8a9403 | ||
|
|
a2f8652575 | ||
|
|
672faa131f |
13
.github/workflows/ci.yaml
vendored
13
.github/workflows/ci.yaml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '3.1.301' # SDK Version to use.
|
||||
dotnet-version: 5.0.100
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
@@ -55,10 +55,15 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup dotnet
|
||||
- name: Setup dotnet 3.1.402
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 3.1.301
|
||||
dotnet-version: 3.1.402
|
||||
|
||||
- name: Setup dotnet 5.0.100
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.100
|
||||
|
||||
- name: Integration Tests
|
||||
shell: bash
|
||||
@@ -70,6 +75,8 @@ jobs:
|
||||
dotnet example panels
|
||||
dotnet example colors
|
||||
dotnet example emojis
|
||||
dotnet example exceptions
|
||||
dotnet example calendars
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
|
||||
2
.github/workflows/docs.yaml
vendored
2
.github/workflows/docs.yaml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '3.1.301' # SDK Version to use.
|
||||
dotnet-version: 5.0.100
|
||||
|
||||
- name: Publish
|
||||
shell: bash
|
||||
|
||||
20
.github/workflows/publish.yaml
vendored
20
.github/workflows/publish.yaml
vendored
@@ -29,7 +29,7 @@ jobs:
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '3.1.301' # SDK Version to use.
|
||||
dotnet-version: 5.0.100
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
@@ -64,10 +64,15 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup dotnet
|
||||
- name: Setup dotnet 3.1.402
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 3.1.301
|
||||
dotnet-version: 3.1.402
|
||||
|
||||
- name: Setup dotnet 5.0.100
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.100
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
@@ -90,10 +95,15 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup dotnet
|
||||
- name: Setup dotnet 3.1.402
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 3.1.301
|
||||
dotnet-version: 3.1.402
|
||||
|
||||
- name: Setup dotnet 5.0.100
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.100
|
||||
|
||||
- name: Publish
|
||||
shell: bash
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,6 +5,7 @@
|
||||
[Pp]ackages/
|
||||
/.artifacts/
|
||||
/[Tt]ools/
|
||||
.idea
|
||||
.DS_Store
|
||||
|
||||
# Cakeup
|
||||
|
||||
413
README.jp.md
Normal file
413
README.jp.md
Normal file
@@ -0,0 +1,413 @@
|
||||
# `Spectre.Console`
|
||||
|
||||
_[](https://www.nuget.org/packages/spectre.console)_
|
||||
|
||||
綺麗なコンソールアプリケーションを簡単に作成するための.NET Standard 2.0ライブラリです。
|
||||
Python用の素晴らしい[Rich ライブラリ](https://github.com/willmcgugan/rich)に強く影響を受けています。
|
||||
|
||||
## 目次
|
||||
|
||||
1. [特徴](#特徴)
|
||||
2. [例](#例)
|
||||
3. [使用方法](#使用方法)
|
||||
3.1. [Static APIの利用](#static-apiの利用)
|
||||
3.2. [コンソールの作成](#コンソールの作成)
|
||||
4. [例の実行](#例の実行)
|
||||
5. [クイックスタート](#クイックスタート)
|
||||
6. [マークアップ](#マークアップ)
|
||||
7. [絵文字](#絵文字)
|
||||
8. [テーブル](#テーブル)
|
||||
9. [例外](#例外)
|
||||
|
||||
## 特徴
|
||||
|
||||
* ユニットテストを意識して書いています。
|
||||
* table、grid、panel、マークアップ言語に影響を受けた [rich](https://github.com/willmcgugan/rich) に対応しています。
|
||||
* 太字、薄字、斜字、下線、斜線、点滅などの一般的なSGR parameters に対応しています。
|
||||
* ターミナルで 3/4/8/24ビットカラーに対応しています。
|
||||
ライブラリは現在のターミナルの性能を検知し、必要なカラーにダウングレードします
|
||||
|
||||
## 例
|
||||
|
||||

|
||||
|
||||
## 使用方法
|
||||
|
||||
`Spectre.Console` APIはステートフルで、スレッドセーフではありません。
|
||||
異なるスレッドからコンソールに書く必要がある場合、通常の`System.Console` APIを使用するときと同様、適切な注意を払ってください。
|
||||
|
||||
現在の端末がANSIエスケープシーケンスに対応していない場合、
|
||||
`Spectre.Console`は、`System.Console` APIの利用に切り替わります。
|
||||
|
||||
_メモ: このライブラリは現在開発中で、APIは1.0のリリースまでの間に変更されたり、
|
||||
削除されたりする可能性があります。_
|
||||
|
||||
### Static APIの利用
|
||||
|
||||
|
||||
`System.Console` APIでするように、テキストを出力したいだけの時にはstatic APIが最適ですが、綺麗です。
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Foreground = Color.CornflowerBlue;
|
||||
AnsiConsole.Decoration = Decoration.Underline | Decoration.Bold;
|
||||
AnsiConsole.WriteLine("Hello World!");
|
||||
|
||||
AnsiConsole.Reset();
|
||||
AnsiConsole.MarkupLine("[bold yellow on red]{0}[/] [underline]world[/]!", "Goodbye");
|
||||
```
|
||||
|
||||
もし、デフォルトの`IAnsiConsole`への参照を取得したい場合、
|
||||
`AnsiConsole.Console`経由でアクセスできます。
|
||||
|
||||
### コンソールの作成
|
||||
|
||||
単体テスト中にコードの実行環境を制御したい場合など、
|
||||
特定の機能をもつコンソールを明示的に作成すると便利なことがあります。
|
||||
|
||||
単体テストの一部としてコードで `AnsiConsole`を使わないことを推奨します。
|
||||
|
||||
```csharp
|
||||
IAnsiConsole console = AnsiConsole.Create(
|
||||
new AnsiConsoleSettings()
|
||||
{
|
||||
Ansi = AnsiSupport.Yes,
|
||||
ColorSystem = ColorSystemSupport.TrueColor,
|
||||
Out = new StringWriter(),
|
||||
});
|
||||
```
|
||||
|
||||
_メモ: 主導でコンソールを作成しているときに特定のカラーシステムを指定できたとしても、
|
||||
ユーザーのターミナルでは使えないかもしれないことを覚えておいてください。
|
||||
テスト用にIAnsiConsoleを作成していない限り、
|
||||
常に`ColorSystemSupport.Detect` と `AnsiSupport.Detect`を使用してください。_
|
||||
|
||||
## 例の実行
|
||||
|
||||
Spectre.Consoleでできることを見るために、
|
||||
[dotnet-example](https://github.com/patriksvensson/dotnet-example)グローバルツールをインストールします。
|
||||
|
||||
|
||||
```
|
||||
> dotnet tool restore
|
||||
```
|
||||
|
||||
このリポジトリで提供している例が一覧表示されます
|
||||
|
||||
```
|
||||
> dotnet example
|
||||
|
||||
╭────────────┬───────────────────────────────────────┬──────────────────────────────────────────────────────╮
|
||||
│ Name │ Path │ Description │
|
||||
├────────────┼───────────────────────────────────────┼──────────────────────────────────────────────────────┤
|
||||
│ Borders │ examples/Borders/Borders.csproj │ Demonstrates the different kind of borders. │
|
||||
│ Calendars │ examples/Calendars/Calendars.csproj │ Demonstrates how to render calendars. │
|
||||
│ Colors │ examples/Colors/Colors.csproj │ Demonstrates how to use colors in the console. │
|
||||
│ Columns │ examples/Columns/Columns.csproj │ Demonstrates how to render data into columns. │
|
||||
│ Emojis │ examples/Emojis/Emojis.csproj │ Demonstrates how to render emojis. │
|
||||
│ Exceptions │ examples/Exceptions/Exceptions.csproj │ Demonstrates how to render formatted exceptions. │
|
||||
│ Grids │ examples/Grids/Grids.csproj │ Demonstrates how to render grids in a console. │
|
||||
│ Info │ examples/Info/Info.csproj │ Displays the capabilities of the current console. │
|
||||
│ Links │ examples/Links/Links.csproj │ Demonstrates how to render links in a console. │
|
||||
│ Panels │ examples/Panels/Panels.csproj │ Demonstrates how to render items in panels. │
|
||||
│ Rules │ examples/Rules/Rules.csproj │ Demonstrates how to render horizontal rules (lines). │
|
||||
│ Tables │ examples/Tables/Tables.csproj │ Demonstrates how to render tables in a console. │
|
||||
╰────────────┴───────────────────────────────────────┴──────────────────────────────────────────────────────╯
|
||||
```
|
||||
|
||||
そして、例を実行します
|
||||
|
||||
```
|
||||
> dotnet example tables
|
||||
┌──────────┬──────────┬────────┐
|
||||
│ Foo │ Bar │ Baz │
|
||||
├──────────┼──────────┼────────┤
|
||||
│ Hello │ World! │ │
|
||||
│ Bonjour │ le │ monde! │
|
||||
│ Hej │ Världen! │ │
|
||||
└──────────┴──────────┴────────┘
|
||||
```
|
||||
|
||||
## クイックスタート
|
||||
pectre.Consoleの利用を開始する最初の方法は、Nugetパッケージをインストールすることです。
|
||||
|
||||
```shell
|
||||
> dotnet add package Spectre.Console
|
||||
```
|
||||
|
||||
その後、`Spectre.Console`名前空間を参照する必要があります。一度参照したら、提供されている全ての機能を使用できます。
|
||||
|
||||
```csharp
|
||||
using Spectre.Console
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
AnsiConsole.Markup("[underline red]Hello[/] World!");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## マークアップ
|
||||
`Markup`クラスは、コンソールにリッチなテキストを出力することができます。
|
||||
|
||||
### 文法
|
||||
|
||||
コンソールマークアップはbbcodeに影響を受けた文法を利用します。角括弧でスタイルを書いたら(スタイルを参照)、例えば、`[bold red]`
|
||||
は、`[/]`で閉じるまでスタイルが適用されます。
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Render(new Markup("[bold yellow]Hello[/] [red]World![/]"));
|
||||
```
|
||||
|
||||
`Markup` クラスは`IRenderable`を実装しており、table、grid、Panelを使用できることを意味します。
|
||||
`IRenderable`のレンダリングに対応している多くのクラスは、リッチテキストの描画を上書きます。
|
||||
|
||||
```csharp
|
||||
var table = new Table();
|
||||
table.AddColumn(new TableColumn(new Markup("[yellow]Foo[/]")));
|
||||
table.AddColumn(new TableColumn("[blue]Bar[/]"));
|
||||
```
|
||||
|
||||
### 便利なメソッド
|
||||
|
||||
`AnsiConsole`には、新しい`Markup`インスタンスをインスタンス化することなく、コンソールにマークアップテキストを書き込める便利なメソッドがあります。
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Markup("[underline green]Hello[/] ");
|
||||
AnsiConsole.MarkupLine("[bold]World[/]");
|
||||
```
|
||||
|
||||
### エスケープ文字列
|
||||
|
||||
`[`を出力するために、 `[[`を利用し、`]`を出力するために`]]`を利用します。
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Markup("[[Hello]] "); // [Hello]
|
||||
AnsiConsole.Markup("[red][[World]][/]"); // [World]
|
||||
```
|
||||
|
||||
`SafeMarkup`拡張メソッドを使用することもできます。
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Markup("[red]{0}[/]", "Hello [World]".SafeMarkup());
|
||||
```
|
||||
|
||||
### カラー
|
||||
|
||||
`new Style(foreground: Color.Maroon)`のようなコード、または、`AnsiConsole.Markup("[maroon on blue]Hello[/]")`のようなマークアップテキストで色を使用できます。
|
||||
|
||||
### 背景色の設定
|
||||
|
||||
カラー指定の際に、`on`を付けることで、マークアップで背景色を設定できます。
|
||||
|
||||
```
|
||||
[bold yellow on blue]Hello[/]
|
||||
[default on blue]World[/]
|
||||
```
|
||||
|
||||
### 絵文字の描画
|
||||
|
||||
マークアップの一部として絵文字を出力するために、emojiショートコードが使用できます。
|
||||
|
||||
```csharp
|
||||
AnsiConsole.MarkupLine("Hello :globe_showing_europe_africa:!");
|
||||
```
|
||||
|
||||
emojiのスタイルについては、付録の[Emoji](./appendix/emojis) を参照してください。
|
||||
|
||||
### カラー
|
||||
|
||||
上の例では、全ての色は名前で参照されています。
|
||||
しかし、16進数やRGB表現をマークダウンで色指定に使用できます。
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Markup("[red]Foo[/] ");
|
||||
AnsiConsole.Markup("[#ff0000]Bar[/] ");
|
||||
AnsiConsole.Markup("[rgb(255,0,0)]Baz[/] ");
|
||||
```
|
||||
|
||||
## 絵文字
|
||||
|
||||
どのような絵文字が使用できるかは、使用しているOSやターミナルに依存し、どのように表示されるかは保証されません。絵文字の幅計算は正確ではないため、表、パネル、グリッドで使用する場合は表示がずれるかもしれません。
|
||||
|
||||
完全な互換性を確保するために、Unicode 13.0 より以前の`Emoji_Presentation`カテゴリにあるものだけを使用することを検討してください。
|
||||
公式の絵文字一覧
|
||||
https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt
|
||||
|
||||
|
||||
```csharp
|
||||
// Markup
|
||||
AnsiConsole.MarkupLine("Hello :globe_showing_europe_africa:!");
|
||||
|
||||
// Constant
|
||||
var hello = "Hello " + Emoji.Known.GlobeShowingEuropeAfrica;
|
||||
```
|
||||
|
||||
テキスト内の絵文字を置き換えることができます。
|
||||
|
||||
```csharp
|
||||
var phrase = "Mmmm :birthday_cake:";
|
||||
var rendered
|
||||
```
|
||||
|
||||
既存の絵文字を別のものにしたり、完全に新しい物を追加したいことがあります。このために、`Emoji.Remap`メソッドを使用できます。
|
||||
この方法は、マークアップ文字と`Emoji.Replace`の両方で動作します。
|
||||
|
||||
```csharp
|
||||
// Remap the emoji
|
||||
Emoji.Remap("globe_showing_europe_africa", "😄");
|
||||
|
||||
// Render markup
|
||||
AnsiConsole.MarkupLine("Hello :globe_showing_europe_africa:!");
|
||||
|
||||
// Replace emojis in string
|
||||
var phrase = "Hello :globe_showing_europe_africa:!";
|
||||
var rendered = Emoji.Replace(phrase);
|
||||
```
|
||||
|
||||
## テーブル
|
||||
|
||||
テーブルはターミナルで表データを表示するのに完璧な方法です。
|
||||
`Spectre.Console` は、テーブルの描画にとても優れていて、全てのカラムは中に合わせて調整してくれます。
|
||||
`IRenderable`を実装しているものは、列ヘッダやセル、別のテーブルとして使用できます。
|
||||
|
||||
### 使い方
|
||||
|
||||
テーブルを描画するために、`Table`インスタンスを作成し、必要な数の列を追加し、行を追加します。
|
||||
テーブルをコンソールの`Render`メソッドに渡して終わりです。
|
||||
|
||||
```csharp
|
||||
// テーブルの作成
|
||||
var table = new Table();
|
||||
|
||||
// 列の追加
|
||||
table.AddColumn("Foo");
|
||||
table.AddColumn(new TableColumn("Bar").Centered());
|
||||
|
||||
// 行の追加
|
||||
table.AddRow("Baz", "[green]Qux[/]");
|
||||
table.AddRow(new Markup("[blue]Corgi[/]"), new Panel("Waldo"));
|
||||
|
||||
// コンソールにテーブルの描画
|
||||
AnsiConsole.Render(table);
|
||||
```
|
||||
|
||||
これは次のように出力を描画します。
|
||||
|
||||

|
||||
|
||||
### 罫線
|
||||
|
||||
|
||||
```csharp
|
||||
// 罫線を設定します
|
||||
table.SetBorder(Border.None);
|
||||
table.SetBorder(Border.Ascii);
|
||||
table.SetBorder(Border.Square);
|
||||
table.SetBorder(Border.Rounded);
|
||||
```
|
||||
|
||||
### 拡大 / 縮小
|
||||
|
||||
```csharp
|
||||
// テーブル幅を最大に設定します
|
||||
table.Expand();
|
||||
|
||||
// テーブル幅を最小に設定します
|
||||
table.Collapse();
|
||||
```
|
||||
|
||||
### ヘッダーを隠す
|
||||
|
||||
```csharp
|
||||
// 全ての列のヘッダーを隠します
|
||||
table.HideHeaders();
|
||||
```
|
||||
|
||||
### テーブル幅の設定
|
||||
|
||||
```csharp
|
||||
// テーブル幅50セルに設定します
|
||||
table.SetWidth(50);
|
||||
```
|
||||
|
||||
### 整列(アライメント)
|
||||
|
||||
```csharp
|
||||
// 整列を明示的に設定する
|
||||
column.SetAlignment(Justify.Right);
|
||||
```
|
||||
|
||||
### パディング
|
||||
|
||||
```csharp
|
||||
// 左と右のパディングを設定する
|
||||
column.SetPadding(left: 3, right: 5);
|
||||
|
||||
// 個別にパディングを設定する
|
||||
column.PadLeft(3);
|
||||
column.PadRight(5);
|
||||
```
|
||||
|
||||
### 列改行の無効化
|
||||
|
||||
```csharp
|
||||
// 列改行の無効化
|
||||
column.NoWrap();
|
||||
```
|
||||
|
||||
### 列幅の設定
|
||||
|
||||
```csharp
|
||||
// 列幅の設定(これはまだ柔軟な拡張メソッドがありません)
|
||||
column.Width = 15;
|
||||
```
|
||||
|
||||
## 例外
|
||||
例外はターミナルで見たときに読みやすいとは限りません。
|
||||
`WriteException`メソッドを使用することで、例外をもう少し読みやすくすることができます。
|
||||
|
||||
```csharp
|
||||
AnsiConsole.WriteException(ex);
|
||||
```
|
||||
|
||||

|
||||
### 例外の省略表示
|
||||
|
||||
例外の特定部分を短くして、さらに読みやすくしたり、パスをクリック可能なハイパーリンクにすることもできます。
|
||||
ハイパーリンクがクリックできるかはターミナル次第です。
|
||||
|
||||
|
||||
```csharp
|
||||
AnsiConsole.WriteException(ex,
|
||||
ExceptionFormats.ShortenPaths | ExceptionFormats.ShortenTypes |
|
||||
ExceptionFormats.ShortenMethods | ExceptionFormats.ShowLinks);
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 例外出力のカスタマイズ
|
||||
|
||||
例外の特定部分を短縮するだけでなく、デフォルトのスタイルを上書きすることもできます。
|
||||
|
||||
```csharp
|
||||
AnsiConsole.WriteException(ex, new ExceptionSettings
|
||||
{
|
||||
Format = ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks,
|
||||
Style = new ExceptionStyle
|
||||
{
|
||||
Exception = Style.WithForeground(Color.Grey),
|
||||
Message = Style.WithForeground(Color.White),
|
||||
NonEmphasized = Style.WithForeground(Color.Cornsilk1),
|
||||
Parenthesis = Style.WithForeground(Color.Cornsilk1),
|
||||
Method = Style.WithForeground(Color.Red),
|
||||
ParameterName = Style.WithForeground(Color.Cornsilk1),
|
||||
ParameterType = Style.WithForeground(Color.Red),
|
||||
Path = Style.WithForeground(Color.Red),
|
||||
LineNumber = Style.WithForeground(Color.Cornsilk1),
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||

|
||||
47
README.md
47
README.md
@@ -10,10 +10,11 @@ for Python.
|
||||
|
||||
1. [Features](#features)
|
||||
2. [Example](#example)
|
||||
3. [Usage](#usage)
|
||||
3.1. [Using the static API](#using-the-static-api)
|
||||
3.2. [Creating a console](#creating-a-console)
|
||||
4. [Running examples](#running-examples)
|
||||
3. [Installing](#installing)
|
||||
4. [Usage](#usage)
|
||||
4.1. [Using the static API](#using-the-static-api)
|
||||
4.2. [Creating a console](#creating-a-console)
|
||||
5. [Running examples](#running-examples)
|
||||
|
||||
## Features
|
||||
|
||||
@@ -30,6 +31,14 @@ for Python.
|
||||
|
||||

|
||||
|
||||
## Installing
|
||||
|
||||
The fastest way of getting started using Spectre.Console is to install the NuGet package.
|
||||
|
||||
```csharp
|
||||
dotnet add package Spectre.Console
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
The `Spectre.Console` API is stateful and is not thread-safe.
|
||||
@@ -40,7 +49,7 @@ regular `System.Console` API.
|
||||
If the current terminal does not support ANSI escape sequences,
|
||||
`Spectre.Console` will fallback to using the `System.Console` API.
|
||||
|
||||
_NOTE: This library is currently under development and API's
|
||||
_NOTE: This library is currently under development and APIs
|
||||
might change or get removed at any point up until a 1.0 release._
|
||||
|
||||
### Using the static API
|
||||
@@ -91,7 +100,7 @@ To see Spectre.Console in action, install the
|
||||
global tool.
|
||||
|
||||
```
|
||||
> dotnet tool install -g dotnet-example
|
||||
> dotnet tool restore
|
||||
```
|
||||
|
||||
Now you can list available examples in this repository:
|
||||
@@ -99,20 +108,28 @@ Now you can list available examples in this repository:
|
||||
```
|
||||
> dotnet example
|
||||
|
||||
╭────────┬───────────────────────────────┬─────────────────────────────────────────────────╮
|
||||
│ Name │ Path │ Description │
|
||||
├────────┼───────────────────────────────┼─────────────────────────────────────────────────┤
|
||||
│ Colors │ examples/Colors/Colors.csproj │ Demonstrates how to use colors in the console. │
|
||||
│ Grid │ examples/Grid/Grid.csproj │ Demonstrates how to render grids in a console. │
|
||||
│ Panel │ examples/Panel/Panel.csproj │ Demonstrates how to render items in panels. │
|
||||
│ Table │ examples/Table/Table.csproj │ Demonstrates how to render tables in a console. │
|
||||
╰────────┴───────────────────────────────┴─────────────────────────────────────────────────╯
|
||||
╭────────────┬───────────────────────────────────────┬──────────────────────────────────────────────────────╮
|
||||
│ Name │ Path │ Description │
|
||||
├────────────┼───────────────────────────────────────┼──────────────────────────────────────────────────────┤
|
||||
│ Borders │ examples/Borders/Borders.csproj │ Demonstrates the different kind of borders. │
|
||||
│ Calendars │ examples/Calendars/Calendars.csproj │ Demonstrates how to render calendars. │
|
||||
│ Colors │ examples/Colors/Colors.csproj │ Demonstrates how to use colors in the console. │
|
||||
│ Columns │ examples/Columns/Columns.csproj │ Demonstrates how to render data into columns. │
|
||||
│ Emojis │ examples/Emojis/Emojis.csproj │ Demonstrates how to render emojis. │
|
||||
│ Exceptions │ examples/Exceptions/Exceptions.csproj │ Demonstrates how to render formatted exceptions. │
|
||||
│ Grids │ examples/Grids/Grids.csproj │ Demonstrates how to render grids in a console. │
|
||||
│ Info │ examples/Info/Info.csproj │ Displays the capabilities of the current console. │
|
||||
│ Links │ examples/Links/Links.csproj │ Demonstrates how to render links in a console. │
|
||||
│ Panels │ examples/Panels/Panels.csproj │ Demonstrates how to render items in panels. │
|
||||
│ Rules │ examples/Rules/Rules.csproj │ Demonstrates how to render horizontal rules (lines). │
|
||||
│ Tables │ examples/Tables/Tables.csproj │ Demonstrates how to render tables in a console. │
|
||||
╰────────────┴───────────────────────────────────────┴──────────────────────────────────────────────────────╯
|
||||
```
|
||||
|
||||
And to run an example:
|
||||
|
||||
```
|
||||
> dotnet example table
|
||||
> dotnet example tables
|
||||
┌──────────┬──────────┬────────┐
|
||||
│ Foo │ Bar │ Baz │
|
||||
├──────────┼──────────┼────────┤
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);output\**;.gitignore</DefaultItemExcludes>
|
||||
<MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip>
|
||||
@@ -31,8 +31,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.5" />
|
||||
<PackageReference Include="MinVer" PrivateAssets="All" Version="2.3.0" />
|
||||
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.13" />
|
||||
<PackageReference Include="MinVer" PrivateAssets="All" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,8 +1,50 @@
|
||||
# Documentation
|
||||
|
||||
Preview the documentation locally by running the following
|
||||
from your favourite shell:
|
||||
To start contributing to the [Spectre.Console](https://github.com/spectresystems/spectre.console) documentation, you will need the [.NET Core SDK](https://dot.net) 3.1 or higher.
|
||||
|
||||
## Running Preview Site
|
||||
|
||||
The documentation site uses [Statiq](https://statiq.dev), a static site generator. To build the documentation site run the following in a command-line terminal.
|
||||
|
||||
```
|
||||
> dotnet run -- preview --virtual-dir "spectre.console"
|
||||
```
|
||||
> dotnet run preview --virtual-dir "spectre.console"
|
||||
```
|
||||
|
||||
After the build is complete, you can navigate to [http://localhost:5080/spectre.console](http://localhost:5080/spectre.console).
|
||||
|
||||
**Note that the site runs under a virtual directory.**
|
||||
|
||||
## Editing Content
|
||||
|
||||
The documentation is written using [Markdown](https://www.markdownguide.org/basic-syntax/).
|
||||
|
||||
Markdown files can be found under the following directories:
|
||||
|
||||
- [/input](./input)
|
||||
- [/appendix](./input/appendix)
|
||||
|
||||
## Editing Layout
|
||||
|
||||
Layout and styling can also be found in the [input](./input) directory. Look for Sass, Css, and Images under the [assets](./input/assets) directory.
|
||||
|
||||
## Custom Build Features
|
||||
|
||||
The documentation site has custom enhancements to Statiq located under the [./src](./src) directory. Enhancements to the build process include:
|
||||
|
||||
- [Extension Methods](./src/Extensions)
|
||||
- [Models](./src/Models)
|
||||
- [Pipelines](./src/Pipelines)
|
||||
- [Shortcodes](./src/Shortcodes)
|
||||
- [Utilities](./src/Utilities)
|
||||
|
||||
## License
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Spectre Systems AB
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -5,8 +5,8 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link href="/spectre.console/assets/bootstrap/bootstrap.css" rel="stylesheet" />
|
||||
<link href="/spectre.console/assets/css/styles.css" rel="stylesheet" />
|
||||
<link href="@Context.GetLink("/assets/bootstrap/bootstrap.css")" rel="stylesheet" />
|
||||
<link href="@Context.GetLink("/assets/css/styles.css")" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&family=Roboto+Slab:wght@400;700&family=Roboto:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&display=swap" rel="stylesheet" data-no-mirror>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.19.0/themes/prism.css">
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
<nav id="topnav" class="navbar navbar-expand-lg navbar-light">
|
||||
<div class="container py-3">
|
||||
<a class="navbar-brand" href="/spectre.console"><img id="logo" src="/spectre.console/assets/logo.svg" alt="Spectre.Console"> Spectre.Console</a>
|
||||
<a class="navbar-brand" href="@Context.GetLink("/")"><img id="logo" src="@Context.GetLink("/assets/logo.svg")" alt="Spectre.Console"> Spectre.Console</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
@@ -130,16 +130,21 @@
|
||||
<div class="sidebar-nav-item @(Document.IdEquals(root) ? "active" : null)">
|
||||
@if(root.ShowLink())
|
||||
{
|
||||
@Html.DocumentLink(root)
|
||||
@Html.DocumentLink(root)
|
||||
}
|
||||
else
|
||||
{
|
||||
@root.GetTitle()
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
||||
@foreach (IDocument document in OutputPages.GetChildrenOf(root).OnlyVisible())
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(document.GetTitle()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
DocumentList<IDocument> documentChildren = OutputPages.GetChildrenOf(document);
|
||||
<div class="sidebar-nav-item @(Document.IdEquals(document) ? "active" : null) @(documentChildren.Any() ? "has-children" : null)">
|
||||
@if(document.ShowLink())
|
||||
@@ -149,7 +154,7 @@
|
||||
else
|
||||
{
|
||||
@document.GetTitle()
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (documentChildren.OnlyVisible().Any())
|
||||
|
||||
@@ -13,4 +13,19 @@ in markup text such as `AnsiConsole.Markup("[maroon on blue]Hello[/]")`.
|
||||
|
||||
# Standard colors
|
||||
|
||||
<?# ColorTable /?>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="basic-addon1">
|
||||
<i class="fas fa-search" aria-hidden="true"></i>
|
||||
</span>
|
||||
</div>
|
||||
<input
|
||||
class="form-control w-100 filter"
|
||||
data-table="color-results"
|
||||
type="text" placeholder="Search Colors..." autocomplete="off"
|
||||
aria-label="Search Colors">
|
||||
</div>
|
||||
|
||||
<?# ColorTable /?>
|
||||
|
||||
<script type="text/javascript" src="../assets/js/table-search.js"></script>
|
||||
@@ -30,9 +30,43 @@ var phrase = "Mmmm :birthday_cake:";
|
||||
var rendered = Emoji.Replace(phrase);
|
||||
```
|
||||
|
||||
# Remapping or adding an emoji
|
||||
|
||||
Sometimes you want to remap an existing emoji, or
|
||||
add a completely new one. For this you can use the
|
||||
`Emoji.Remap` method. This approach works both with
|
||||
markup strings and `Emoji.Replace`.
|
||||
|
||||
```csharp
|
||||
// Remap the emoji
|
||||
Emoji.Remap("globe_showing_europe_africa", "😄");
|
||||
|
||||
// Render markup
|
||||
AnsiConsole.MarkupLine("Hello :globe_showing_europe_africa:!");
|
||||
|
||||
// Replace emojis in string
|
||||
var phrase = "Hello :globe_showing_europe_africa:!";
|
||||
var rendered = Emoji.Replace(phrase);
|
||||
```
|
||||
|
||||
# Emojis
|
||||
|
||||
_The images in the table below might not render correctly in your
|
||||
browser for the same reasons mentioned in the `Compatibility` section._
|
||||
|
||||
<?# EmojiTable /?>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="basic-addon1">
|
||||
<i class="fas fa-search" aria-hidden="true"></i>
|
||||
</span>
|
||||
</div>
|
||||
<input
|
||||
class="form-control w-100 filter"
|
||||
data-table="emoji-results"
|
||||
type="text" placeholder="Search Emojis..." autocomplete="off"
|
||||
aria-label="Search Emojis">
|
||||
</div>
|
||||
|
||||
<?# EmojiTable /?>
|
||||
|
||||
<script type="text/javascript" src="../assets/js/table-search.js"></script>
|
||||
12
docs/input/appendix/index.cshtml
Normal file
12
docs/input/appendix/index.cshtml
Normal file
@@ -0,0 +1,12 @@
|
||||
Title: Appendix
|
||||
Order: 10
|
||||
---
|
||||
|
||||
<h1>Sections</h1>
|
||||
|
||||
<ul>
|
||||
@foreach (IDocument child in OutputPages.GetChildrenOf(Document))
|
||||
{
|
||||
<li>@Html.DocumentLink(child)</li>
|
||||
}
|
||||
</ul>
|
||||
@@ -1,10 +0,0 @@
|
||||
Title: Appendix
|
||||
Order: 10
|
||||
---
|
||||
|
||||
# Sections
|
||||
|
||||
* [Styles](xref:styles)
|
||||
* [Colors](xref:colors)
|
||||
* [Borders](xref:borders)
|
||||
* [Emojis](xref:emojis)
|
||||
BIN
docs/input/assets/images/compact_exception.png
Normal file
BIN
docs/input/assets/images/compact_exception.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 163 KiB |
BIN
docs/input/assets/images/custom_exception.png
Normal file
BIN
docs/input/assets/images/custom_exception.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 159 KiB |
BIN
docs/input/assets/images/exception.png
Normal file
BIN
docs/input/assets/images/exception.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 421 KiB |
BIN
docs/input/assets/images/rule.png
Normal file
BIN
docs/input/assets/images/rule.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
docs/input/assets/images/table.gif
Normal file
BIN
docs/input/assets/images/table.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
35
docs/input/assets/js/table-search.js
Normal file
35
docs/input/assets/js/table-search.js
Normal file
@@ -0,0 +1,35 @@
|
||||
$(document).ready(function () {
|
||||
|
||||
$('.filter').each(function () {
|
||||
let input = this;
|
||||
let table = document.getElementById(input.dataset.table);
|
||||
|
||||
input.onkeyup = function (event) {
|
||||
|
||||
if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
|
||||
let value = input.value.toUpperCase();
|
||||
let rows = table.getElementsByClassName('search-row');
|
||||
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let row = rows[i];
|
||||
|
||||
let match =
|
||||
new RegExp(value, "i").test(row.textContent) ||
|
||||
value === '';
|
||||
|
||||
if (match) {
|
||||
row.style.display = 'table-row';
|
||||
} else {
|
||||
row.style.display = 'none';
|
||||
}
|
||||
}
|
||||
}; // keyup
|
||||
})
|
||||
|
||||
|
||||
}); // ready
|
||||
52
docs/input/exceptions.md
Normal file
52
docs/input/exceptions.md
Normal file
@@ -0,0 +1,52 @@
|
||||
Title: Exceptions
|
||||
Order: 3
|
||||
---
|
||||
|
||||
Exceptions isn't always readable when viewed in the terminal.
|
||||
You can make exception a bit more readable by using the `WriteException` method.
|
||||
|
||||
```csharp
|
||||
AnsiConsole.WriteException(ex);
|
||||
```
|
||||
|
||||
<img src="assets/images/exception.png" style="max-width: 100%;">
|
||||
|
||||
## Shortening parts
|
||||
|
||||
You can also shorten specific parts of the exception to make it even
|
||||
more readable, and make paths clickable hyperlinks. Whether or not
|
||||
the hyperlinks are clickable is up to the terminal.
|
||||
|
||||
```csharp
|
||||
AnsiConsole.WriteException(ex,
|
||||
ExceptionFormats.ShortenPaths | ExceptionFormats.ShortenTypes |
|
||||
ExceptionFormats.ShortenMethods | ExceptionFormats.ShowLinks);
|
||||
```
|
||||
|
||||
<img src="assets/images/compact_exception.png" style="max-width: 100%;">
|
||||
|
||||
## Customizing exception output
|
||||
|
||||
In addition to shorten specific part of the exception, you can
|
||||
also override the default styling.
|
||||
|
||||
```csharp
|
||||
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),
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
<img src="assets/images/custom_exception.png" style="max-width: 100%;">
|
||||
@@ -1,4 +1,4 @@
|
||||
Title: Welcome
|
||||
Title: Welcome
|
||||
Order: 0
|
||||
---
|
||||
|
||||
@@ -20,7 +20,7 @@ for Python written by Will McGugan.
|
||||
The library will detect the capabilities of the current terminal
|
||||
and downgrade colors as needed.
|
||||
|
||||
## Example
|
||||
## Examples
|
||||
|
||||
<img width="100%"
|
||||
src="https://github.com/spectresystems/spectre.console/raw/main/resources/gfx/screenshots/example.png" />
|
||||
<img src="assets/images/table.gif" style="max-width: 100%; margin-top: 15px; margin-bottom: 25px;" />
|
||||
<img src="https://github.com/spectresystems/spectre.console/raw/main/resources/gfx/screenshots/example.png" style="max-width: 100%;" />
|
||||
@@ -6,7 +6,7 @@ The class `Markup` allows you to output rich text to the console.
|
||||
|
||||
# Syntax
|
||||
|
||||
Console markup uses a syntax inspired by bbcode. If you write the style (see Styles)
|
||||
Console markup uses a syntax inspired by bbcode. If you write the style (see [Styles](xref:styles))
|
||||
in square brackets, e.g. `[bold red]`, that style will apply until it is closed with a `[/]`.
|
||||
|
||||
```csharp
|
||||
@@ -21,6 +21,7 @@ rendering of `IRenderable` also have overloads for rendering rich text.
|
||||
var table = new Table();
|
||||
table.AddColumn(new TableColumn(new Markup("[yellow]Foo[/]")));
|
||||
table.AddColumn(new TableColumn("[blue]Bar[/]"));
|
||||
AnsiConsole.Render(table);
|
||||
```
|
||||
|
||||
# Convenience methods
|
||||
@@ -43,14 +44,24 @@ AnsiConsole.Markup("[[Hello]] "); // [Hello]
|
||||
AnsiConsole.Markup("[red][[World]][/]"); // [World]
|
||||
```
|
||||
|
||||
You can also use the `EscapeMarkup` extension method.
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Markup("[red]{0}[/]", "Hello [World]".EscapeMarkup());
|
||||
```
|
||||
You can also use the `Markup.Escape` method.
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Markup("[red]{0}[/]", Markup.Escape("Hello [World]"));
|
||||
```
|
||||
# Setting background color
|
||||
|
||||
You can set the background color in markup by prefixing the color with
|
||||
`on`.
|
||||
|
||||
```
|
||||
[bold yellow on blue]Hello[/]
|
||||
[default on blue]World[/]
|
||||
```csharp
|
||||
AnsiConsole.Markup("[bold yellow on blue]Hello[/]");
|
||||
AnsiConsole.Markup("[default on blue]World[/]");
|
||||
```
|
||||
|
||||
# Rendering emojis
|
||||
@@ -58,13 +69,22 @@ You can set the background color in markup by prefixing the color with
|
||||
To output an emoji as part of markup, you can use emoji shortcodes.
|
||||
|
||||
```csharp
|
||||
AnsiConsole.MarkupLine("Hello :globe_showing_europe_africa:!");
|
||||
AnsiConsole.Markup("Hello :globe_showing_europe_africa:!");
|
||||
```
|
||||
|
||||
For a list of emoji, see the [Emojis](xref:styles) appendix section.
|
||||
For a list of emoji, see the [Emojis](xref:emojis) appendix section.
|
||||
|
||||
# Colors
|
||||
|
||||
In the examples above, all colors was referenced by their name,
|
||||
but you can also use the hex or rgb representation for colors in markdown.
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Markup("[red]Foo[/] ");
|
||||
AnsiConsole.Markup("[#ff0000]Bar[/] ");
|
||||
AnsiConsole.Markup("[rgb(255,0,0)]Baz[/] ");
|
||||
```
|
||||
|
||||
For a list of colors, see the [Colors](xref:colors) appendix section.
|
||||
|
||||
# Styles
|
||||
|
||||
99
docs/input/prompt.md
Normal file
99
docs/input/prompt.md
Normal file
@@ -0,0 +1,99 @@
|
||||
Title: Prompt
|
||||
Order: 4
|
||||
---
|
||||
|
||||
Sometimes you want to get some input from the user, and for this
|
||||
you can use the `Prompt<TResult>`.
|
||||
|
||||
# Confirmation
|
||||
|
||||
```csharp
|
||||
if (!AnsiConsole.Confirm("Run example?"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
```text
|
||||
Run example? [y/n] (y): _
|
||||
```
|
||||
|
||||
# Simple
|
||||
|
||||
```csharp
|
||||
// Ask for the user's name
|
||||
string name = AnsiConsole.Ask<string>("What's your [green]name[/]?");
|
||||
|
||||
// Ask for the user's age
|
||||
int age = AnsiConsole.Ask<int>("What's your [green]age[/]?");
|
||||
```
|
||||
|
||||
```text
|
||||
What's your name? Patrik
|
||||
What's your age? 37
|
||||
```
|
||||
|
||||
# Choices
|
||||
|
||||
```csharp
|
||||
var fruit = AnsiConsole.Prompt(
|
||||
new TextPrompt<string>("What's your [green]favorite fruit[/]?")
|
||||
.InvalidChoiceMessage("[red]That's not a valid fruit[/]")
|
||||
.DefaultValue("Orange")
|
||||
.AddChoice("Apple")
|
||||
.AddChoice("Banana")
|
||||
.AddChoice("Orange"));
|
||||
```
|
||||
|
||||
```text
|
||||
What's your favorite fruit? [Apple/Banana/Orange] (Orange): _
|
||||
```
|
||||
|
||||
# Validation
|
||||
|
||||
```csharp
|
||||
var age = AnsiConsole.Prompt(
|
||||
new TextPrompt<int>("What's the secret number?")
|
||||
.Validate(age =>
|
||||
{
|
||||
return age switch
|
||||
{
|
||||
<= 99 => ValidationResult.Error("[red]Too low[/]"),
|
||||
>= 99 => ValidationResult.Error("[red]Too high[/]"),
|
||||
_ => ValidationResult.Success(),
|
||||
};
|
||||
}));
|
||||
```
|
||||
|
||||
```text
|
||||
What's the secret number? 32
|
||||
Too low
|
||||
What's the secret number? 102
|
||||
Too high
|
||||
What's the secret number? _
|
||||
```
|
||||
|
||||
# Secrets
|
||||
|
||||
```csharp
|
||||
var password = AnsiConsole.Prompt(
|
||||
new TextPrompt<string>("Enter [green]password[/]")
|
||||
.PromptStyle("red")
|
||||
.Secret());
|
||||
```
|
||||
|
||||
```text
|
||||
Enter password: ************_
|
||||
```
|
||||
|
||||
# Optional
|
||||
|
||||
```csharp
|
||||
var color = AnsiConsole.Prompt(
|
||||
new TextPrompt<string>("[grey][[Optional]][/] [green]Favorite color[/]?")
|
||||
.AllowEmpty());
|
||||
```
|
||||
|
||||
```text
|
||||
[Optional] Favorite color? _
|
||||
```
|
||||
121
docs/input/widgets/calendar.md
Normal file
121
docs/input/widgets/calendar.md
Normal file
@@ -0,0 +1,121 @@
|
||||
Title: Calendar
|
||||
Order: 4
|
||||
RedirectFrom: calendar
|
||||
---
|
||||
|
||||
The `Calendar` is used to render a calendar to the terminal.
|
||||
|
||||
# Usage
|
||||
|
||||
To render a calendar, create a `Calendar` instance with a target date.
|
||||
|
||||
```csharp
|
||||
var calendar = new Calendar(2020,10);
|
||||
AnsiConsole.Render(calendar);
|
||||
```
|
||||
|
||||
```text
|
||||
2020 October
|
||||
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
|
||||
│ Sun │ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │
|
||||
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
|
||||
│ │ │ │ │ 1 │ 2 │ 3 │
|
||||
│ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │
|
||||
│ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │
|
||||
│ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │
|
||||
│ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │
|
||||
│ │ │ │ │ │ │ │
|
||||
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
|
||||
```
|
||||
|
||||
## Culture
|
||||
|
||||
You can set the calendar's culture to show localized weekdays.
|
||||
|
||||
```csharp
|
||||
var calendar = new Calendar(2020,10);
|
||||
calendar.Culture("ja-JP");
|
||||
AnsiConsole.Render(calendar);
|
||||
```
|
||||
|
||||
```text
|
||||
Oktober 2020
|
||||
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
|
||||
│ Mån │ Tis │ Ons │ Tor │ Fre │ Lör │ Sön │
|
||||
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
|
||||
│ │ │ │ 1 │ 2 │ 3 │ 4 │
|
||||
│ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11* │
|
||||
│ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │ 18 │
|
||||
│ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │
|
||||
│ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
|
||||
```
|
||||
|
||||
## Header
|
||||
|
||||
You can hide the calendar header.
|
||||
|
||||
```csharp
|
||||
var calendar = new Calendar(2020,10);
|
||||
calendar.ShowHeader();
|
||||
AnsiConsole.Render(calendar);
|
||||
```
|
||||
|
||||
```text
|
||||
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
|
||||
│ Sun │ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │
|
||||
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
|
||||
│ │ │ │ │ 1 │ 2 │ 3 │
|
||||
│ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │
|
||||
│ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │
|
||||
│ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │
|
||||
│ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │
|
||||
│ │ │ │ │ │ │ │
|
||||
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
|
||||
```
|
||||
|
||||
You can set the header style of the calendar.
|
||||
|
||||
```csharp
|
||||
var calendar = new Calendar(2020, 10);
|
||||
calendar.HeaderStyle(Style.Parse("blue bold"));
|
||||
AnsiConsole.Render(calendar);
|
||||
```
|
||||
|
||||
|
||||
## Calendar Events
|
||||
|
||||
You can add an event to the calendar.
|
||||
If a date has an event associated with it, the date gets highlighted in the calendar.
|
||||
|
||||
```csharp
|
||||
var calendar = new Calendar(2020,10);
|
||||
calendar.AddCalendarEvent(2020, 10, 11);
|
||||
AnsiConsole.Render(calendar);
|
||||
```
|
||||
|
||||
```text
|
||||
2020 October
|
||||
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
|
||||
│ Sun │ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │
|
||||
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
|
||||
│ │ │ │ │ 1 │ 2 │ 3 │
|
||||
│ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │
|
||||
│ 11* │ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │
|
||||
│ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │
|
||||
│ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │
|
||||
│ │ │ │ │ │ │ │
|
||||
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
|
||||
```
|
||||
|
||||
### Highlight style
|
||||
|
||||
You can set the highlight style for a calendar event via `SetHighlightStyle`.
|
||||
|
||||
```csharp
|
||||
var calendar = new Calendar(2020, 10);
|
||||
calendar.AddCalendarEvent(2020, 10, 11);
|
||||
calendar.HighlightStyle(Style.Parse("yellow bold"));
|
||||
AnsiConsole.Render(calendar);
|
||||
```
|
||||
3
docs/input/widgets/index.md
Normal file
3
docs/input/widgets/index.md
Normal file
@@ -0,0 +1,3 @@
|
||||
Title: Widgets
|
||||
Order: 9
|
||||
---
|
||||
72
docs/input/widgets/rule.md
Normal file
72
docs/input/widgets/rule.md
Normal file
@@ -0,0 +1,72 @@
|
||||
Title: Rule
|
||||
Order: 5
|
||||
RedirectFrom: rule
|
||||
---
|
||||
|
||||
The `Rule` class is used to render a horizontal rule (line) to the terminal.
|
||||
|
||||
<img src="../assets/images/rule.png" style="width: 100%;" />
|
||||
|
||||
# Usage
|
||||
|
||||
To render a rule without a title:
|
||||
|
||||
```csharp
|
||||
var rule = new Rule();
|
||||
AnsiConsole.Render(rule);
|
||||
```
|
||||
|
||||
## Title
|
||||
|
||||
You can set the rule title markup text.
|
||||
|
||||
```csharp
|
||||
var rule = new Rule("[red]Hello[/]");
|
||||
AnsiConsole.Render(rule);
|
||||
```
|
||||
|
||||
```text
|
||||
───────────────────────────────── Hello ─────────────────────────────────
|
||||
```
|
||||
|
||||
### Title alignment
|
||||
|
||||
You can set the rule's title alignment.
|
||||
|
||||
```csharp
|
||||
var rule = new Rule("[red]Hello[/]");
|
||||
rule.Alignment = Justify.Left;
|
||||
AnsiConsole.Render(rule);
|
||||
```
|
||||
|
||||
```text
|
||||
── Hello ────────────────────────────────────────────────────────────────
|
||||
```
|
||||
|
||||
You can also specify it via an extension method:
|
||||
|
||||
```csharp
|
||||
var rule = new Rule("[red]Hello[/]");
|
||||
rule.LeftAligned();
|
||||
AnsiConsole.Render(rule);
|
||||
```
|
||||
|
||||
```text
|
||||
── Hello ────────────────────────────────────────────────────────────────
|
||||
```
|
||||
|
||||
|
||||
## Styling
|
||||
|
||||
```csharp
|
||||
var rule = new Rule("[red]Hello[/]");
|
||||
rule.Style = Style.Parse("red dim");
|
||||
AnsiConsole.Render(rule);
|
||||
```
|
||||
You can also specify it via an extension method
|
||||
|
||||
```csharp
|
||||
var rule = new Rule("[red]Hello[/]");
|
||||
rule.RuleStyle("red dim");
|
||||
AnsiConsole.Render(rule);
|
||||
```
|
||||
@@ -1,5 +1,6 @@
|
||||
Title: Tables
|
||||
Title: Table
|
||||
Order: 3
|
||||
RedirectFrom: tables
|
||||
---
|
||||
|
||||
Tables are a perfect way of displaying tabular data in a terminal.
|
||||
@@ -36,7 +37,7 @@ AnsiConsole.Render(table);
|
||||
|
||||
This will render the following output:
|
||||
|
||||

|
||||

|
||||
|
||||
# Table appearance
|
||||
|
||||
@@ -50,10 +51,10 @@ For a list of borders, see the [Borders](xref:borders) appendix section.
|
||||
|
||||
```csharp
|
||||
// Sets the border
|
||||
table.SetBorder(Border.None);
|
||||
table.SetBorder(Border.Ascii);
|
||||
table.SetBorder(Border.Square);
|
||||
table.SetBorder(Border.Rounded);
|
||||
table.Border(TableBorder.None);
|
||||
table.Border(TableBorder.Ascii);
|
||||
table.Border(TableBorder.Square);
|
||||
table.Border(TableBorder.Rounded);
|
||||
```
|
||||
|
||||
## Expand / Collapse
|
||||
@@ -78,7 +79,16 @@ table.HideHeaders();
|
||||
|
||||
```csharp
|
||||
// Sets the table width to 50 cells
|
||||
table.SetWidth(50);
|
||||
table.Width(50);
|
||||
```
|
||||
|
||||
## Alignment
|
||||
|
||||
```csharp
|
||||
table.Alignment(Justify.Right);
|
||||
table.RightAligned();
|
||||
table.Centered();
|
||||
table.LeftAligned();
|
||||
```
|
||||
|
||||
# Column appearance
|
||||
@@ -90,31 +100,37 @@ table.SetWidth(50);
|
||||
## Alignment
|
||||
|
||||
```csharp
|
||||
// Set the alignment explicitly
|
||||
column.SetAlignment(Justify.Right);
|
||||
table.Columns[0].Alignment(Justify.Right);
|
||||
table.Columns[0].LeftAligned();
|
||||
table.Columns[0].Centered();
|
||||
table.Columns[0].RightAligned();
|
||||
```
|
||||
|
||||
## Padding
|
||||
|
||||
```csharp
|
||||
// Set left and right padding
|
||||
column.SetPadding(left: 3, right: 5);
|
||||
// Set padding individually
|
||||
table.Columns[0].PadLeft(3);
|
||||
table.Columns[0].PadRight(5);
|
||||
|
||||
// Set padding individually.
|
||||
column.PadLeft(3);
|
||||
column.PadRight(5);
|
||||
// Or chained together
|
||||
table.Columns[0].PadLeft(3).PadRight(5);
|
||||
|
||||
// Or with the shorthand method if the left and right
|
||||
// padding are identical. Vertical padding is ignored.
|
||||
table.Columns[0].Padding(4, 0);
|
||||
```
|
||||
|
||||
## Disable column wrapping
|
||||
|
||||
```csharp
|
||||
// Disable column wrapping
|
||||
column.NoWrap();
|
||||
table.Columns[0].NoWrap();
|
||||
```
|
||||
|
||||
## Set column width
|
||||
|
||||
```csharp
|
||||
// Set the column width (no fluent extension method for this yet)
|
||||
column.Width = 15;
|
||||
// Set the column width
|
||||
table.Columns[0].Width(15);
|
||||
```
|
||||
@@ -20,10 +20,7 @@ namespace Docs
|
||||
|
||||
public static Bootstrapper ConfigureDeployment(this Bootstrapper bootstrapper, string deployBranch)
|
||||
{
|
||||
if (bootstrapper != null)
|
||||
{
|
||||
bootstrapper.AddSetting(Constants.Deployment.TargetBranch, deployBranch);
|
||||
}
|
||||
bootstrapper?.AddSetting(Constants.Deployment.TargetBranch, deployBranch);
|
||||
return bootstrapper;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,15 +9,13 @@ namespace Docs.Pipelines
|
||||
{
|
||||
public class ColorsPipeline : Pipeline
|
||||
{
|
||||
public const string Url = "https://raw.githubusercontent.com/spectresystems/spectre.console/main/resources/scripts/Generator/Data/colors.json";
|
||||
|
||||
public ColorsPipeline()
|
||||
{
|
||||
InputModules = new ModuleList
|
||||
{
|
||||
new ExecuteConfig(
|
||||
Config.FromContext(ctx => {
|
||||
return new ReadWeb(Url);
|
||||
return new ReadWeb(Constants.Colors.Url);
|
||||
}))
|
||||
};
|
||||
|
||||
@@ -32,4 +30,4 @@ namespace Docs.Pipelines
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Docs.Shortcodes
|
||||
.First().Object;
|
||||
|
||||
// Headers
|
||||
var table = new XElement("table", new XAttribute("class", "table"));
|
||||
var table = new XElement("table", new XAttribute("class", "table"), new XAttribute("id", "color-results"));
|
||||
var header = new XElement("tr", new XAttribute("class", "color-row"));
|
||||
header.Add(new XElement("th", ""));
|
||||
header.Add(new XElement("th", "#"));
|
||||
@@ -33,8 +33,8 @@ namespace Docs.Shortcodes
|
||||
|
||||
foreach (var color in colors)
|
||||
{
|
||||
var rep = new XElement("td",
|
||||
new XElement("span",
|
||||
var rep = new XElement("td",
|
||||
new XElement("span",
|
||||
new XAttribute("class", "color-representation"),
|
||||
new XAttribute("style", $"background-color:{color.Hex};")));
|
||||
var name = new XElement("td", new XElement("code", color.Number.ToString()));
|
||||
@@ -44,7 +44,7 @@ namespace Docs.Shortcodes
|
||||
var clr = new XElement("td", new XElement("code", color.ClrName));
|
||||
|
||||
// Create row
|
||||
var row = new XElement("tr");
|
||||
var row = new XElement("tr", new XAttribute("class", "search-row"));
|
||||
row.Add(rep);
|
||||
row.Add(name);
|
||||
row.Add(number);
|
||||
|
||||
@@ -18,8 +18,8 @@ namespace Docs.Shortcodes
|
||||
.First().Object;
|
||||
|
||||
// Headers
|
||||
var table = new XElement("table", new XAttribute("class", "table"));
|
||||
var header = new XElement("tr", new XAttribute("class", "emoji-row"));
|
||||
var table = new XElement("table", new XAttribute("class", "table"), new XAttribute("id", "emoji-results"));
|
||||
var header = new XElement("tr", new XAttribute("class", "emoji-row-header"));
|
||||
header.Add(new XElement("th", ""));
|
||||
header.Add(new XElement("th", "Markup"));
|
||||
header.Add(new XElement("th", "Constant"));
|
||||
@@ -28,9 +28,9 @@ namespace Docs.Shortcodes
|
||||
foreach (var emoji in emojis)
|
||||
{
|
||||
var code = emoji.Code.Replace("U+0000", "U+").Replace("U+000", "U+");
|
||||
var icon = string.Format("&#x{0};", emoji.Code.Replace("U+", string.Empty));
|
||||
var icon = $"&#x{emoji.Code.Replace("U+", string.Empty)};";
|
||||
|
||||
var row = new XElement("tr");
|
||||
var row = new XElement("tr", new XAttribute("class", "search-row"));
|
||||
row.Add(new XElement("td", icon));
|
||||
row.Add(new XElement("td", new XElement("code", $":{emoji.Id}:")));
|
||||
row.Add(new XElement("td", new XElement("code", emoji.Name)));
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"cake.tool": {
|
||||
"version": "0.38.4",
|
||||
"version": "1.0.0-rc0001",
|
||||
"commands": [
|
||||
"dotnet-cake"
|
||||
]
|
||||
@@ -15,7 +15,7 @@
|
||||
]
|
||||
},
|
||||
"dotnet-example": {
|
||||
"version": "0.8.0",
|
||||
"version": "1.1.0",
|
||||
"commands": [
|
||||
"dotnet-example"
|
||||
]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Borders</Title>
|
||||
<Description>Demonstrates the different kind of borders.</Description>
|
||||
|
||||
@@ -8,26 +8,22 @@ namespace BordersExample
|
||||
public static void Main()
|
||||
{
|
||||
// Render panel borders
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.MarkupLine("[white bold underline]PANEL BORDERS[/]");
|
||||
AnsiConsole.WriteLine();
|
||||
RenderPanelBorders();
|
||||
HorizontalRule("PANEL BORDERS");
|
||||
PanelBorders();
|
||||
|
||||
// Render table borders
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.MarkupLine("[white bold underline]TABLE BORDERS[/]");
|
||||
AnsiConsole.WriteLine();
|
||||
RenderTableBorders();
|
||||
HorizontalRule("TABLE BORDERS");
|
||||
TableBorders();
|
||||
}
|
||||
|
||||
private static void RenderPanelBorders()
|
||||
private static void PanelBorders()
|
||||
{
|
||||
static IRenderable CreatePanel(string name, BoxBorder border)
|
||||
{
|
||||
return new Panel($"This is a panel with\nthe [yellow]{name}[/] border.")
|
||||
.SetHeader($" {name} ", Style.Parse("blue"), Justify.Center)
|
||||
.SetBorderStyle(Style.Parse("grey"))
|
||||
.SetBorder(border);
|
||||
.Header($" [blue]{name}[/] ", Justify.Center)
|
||||
.Border(border)
|
||||
.BorderStyle(Style.Parse("grey"));
|
||||
}
|
||||
|
||||
var items = new[]
|
||||
@@ -46,19 +42,18 @@ namespace BordersExample
|
||||
new Padding(2,0,0,0)));
|
||||
}
|
||||
|
||||
private static void RenderTableBorders()
|
||||
private static void TableBorders()
|
||||
{
|
||||
static IRenderable CreateTable(string name, TableBorder border)
|
||||
{
|
||||
var table = new Table().SetBorder(border);
|
||||
table.AddColumn("[yellow]Header 1[/]");
|
||||
table.AddColumn("[yellow]Header 2[/]", col => col.RightAligned());
|
||||
var table = new Table().Border(border);
|
||||
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)
|
||||
.SetHeader($" {name} ", Style.Parse("blue"), Justify.Center)
|
||||
.SetBorderStyle(Style.Parse("grey"))
|
||||
.Header($" [blue]{name}[/] ", Justify.Center)
|
||||
.NoBorder();
|
||||
}
|
||||
|
||||
@@ -85,5 +80,12 @@ namespace BordersExample
|
||||
|
||||
AnsiConsole.Render(new Columns(items).Collapse());
|
||||
}
|
||||
|
||||
private static void HorizontalRule(string title)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Rule($"[white bold]{title}[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
examples/Calendars/Calendars.csproj
Normal file
15
examples/Calendars/Calendars.csproj
Normal file
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Calendars</Title>
|
||||
<Description>Demonstrates how to render calendars.</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
19
examples/Calendars/Program.cs
Normal file
19
examples/Calendars/Program.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Calendars
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Colors</Title>
|
||||
<Description>Demonstrates how to use [yellow]c[/][red]o[/][green]l[/][blue]o[/][aqua]r[/][lime]s[/] in the console.</Description>
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace ColorExample
|
||||
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.MarkupLine("[bold underline]3-bit Colors[/]");
|
||||
AnsiConsole.Render(new Rule("[yellow bold underline]3-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
for (var i = 0; i < 8; i++)
|
||||
@@ -47,7 +47,7 @@ namespace ColorExample
|
||||
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.MarkupLine("[bold underline]4-bit Colors[/]");
|
||||
AnsiConsole.Render(new Rule("[yellow bold underline]4-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
for (var i = 0; i < 16; i++)
|
||||
@@ -70,7 +70,7 @@ namespace ColorExample
|
||||
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.MarkupLine("[bold underline]8-bit Colors[/]");
|
||||
AnsiConsole.Render(new Rule("[yellow bold underline]8-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
for (var i = 0; i < 16; i++)
|
||||
@@ -97,7 +97,7 @@ namespace ColorExample
|
||||
|
||||
AnsiConsole.ResetColors();
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.MarkupLine("[bold underline]24-bit Colors[/]");
|
||||
AnsiConsole.Render(new Rule("[yellow bold underline]24-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
var index = 0;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Columns</Title>
|
||||
<Description>Demonstrates how to render data into columns.</Description>
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace ColumnsExample
|
||||
var cards = new List<Panel>();
|
||||
foreach(var user in users.results)
|
||||
{
|
||||
cards.Add(new Panel(GetCard(user))
|
||||
.SetHeader($"{user.location.country}")
|
||||
cards.Add(new Panel(GetCardContent(user))
|
||||
.Header($"{user.location.country}")
|
||||
.RoundedBorder().Expand());
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace ColumnsExample
|
||||
AnsiConsole.Render(new Columns(cards));
|
||||
}
|
||||
|
||||
private static string GetCard(dynamic user)
|
||||
private static string GetCardContent(dynamic user)
|
||||
{
|
||||
var name = $"{user.name.first} {user.name.last}";
|
||||
var country = $"{user.location.city}";
|
||||
|
||||
15
examples/Cursor/Cursor.csproj
Normal file
15
examples/Cursor/Cursor.csproj
Normal file
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Cursor</Title>
|
||||
<Description>Demonstrates how to move the cursor.</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
20
examples/Cursor/Program.cs
Normal file
20
examples/Cursor/Program.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Emojis</Title>
|
||||
<Description>Demonstrates how to render emojis.</Description>
|
||||
|
||||
@@ -6,11 +6,19 @@ namespace EmojiExample
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// Markup
|
||||
// Show a known emoji
|
||||
RenderEmoji();
|
||||
|
||||
// Show a remapped emoji
|
||||
Emoji.Remap("globe_showing_europe_africa", Emoji.Known.GrinningFaceWithSmilingEyes);
|
||||
RenderEmoji();
|
||||
}
|
||||
|
||||
private static void RenderEmoji()
|
||||
{
|
||||
AnsiConsole.Render(
|
||||
new Panel("[yellow]Hello :globe_showing_europe_africa:![/]")
|
||||
.RoundedBorder()
|
||||
.SetHeader("Markup"));
|
||||
.RoundedBorder());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
examples/Exceptions/Exceptions.csproj
Normal file
15
examples/Exceptions/Exceptions.csproj
Normal file
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Exceptions</Title>
|
||||
<Description>Demonstrates how to render formatted exceptions.</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
66
examples/Exceptions/Program.cs
Normal file
66
examples/Exceptions/Program.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Security.Authentication;
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Exceptions
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
DoMagic(42, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Rule("Default").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex);
|
||||
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Rule("Compact").LeftAligned());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks);
|
||||
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Rule("Compact + Custom colors").LeftAligned());
|
||||
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),
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static void DoMagic(int foo, string[,] bar)
|
||||
{
|
||||
try
|
||||
{
|
||||
CheckCredentials(foo, bar);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException("Whaaat?", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckCredentials(int qux, string[,] corgi)
|
||||
{
|
||||
throw new InvalidCredentialException("The credentials are invalid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Grids</Title>
|
||||
<Description>Demonstrates how to render grids in a console.</Description>
|
||||
|
||||
@@ -11,13 +11,12 @@ namespace GridExample
|
||||
AnsiConsole.WriteLine();
|
||||
|
||||
var grid = new Grid();
|
||||
grid.AddColumn(new GridColumn { NoWrap = true });
|
||||
grid.AddColumn(new GridColumn { NoWrap = true, Width = 2 });
|
||||
grid.AddColumn();
|
||||
grid.AddRow("Options:", "", "");
|
||||
grid.AddRow(" [blue]-h[/], [blue]--help[/]", "", "Show command line help.");
|
||||
grid.AddRow(" [blue]-c[/], [blue]--configuration[/] <CONFIGURATION>", "", "The configuration to run for.");
|
||||
grid.AddRow(" [blue]-v[/], [blue]--verbosity[/] <LEVEL>", "", "Set the [grey]MSBuild[/] verbosity level.");
|
||||
grid.AddColumn(new GridColumn().NoWrap());
|
||||
grid.AddColumn(new GridColumn().PadLeft(2));
|
||||
grid.AddRow("Options:");
|
||||
grid.AddRow(" [blue]-h[/], [blue]--help[/]", "Show command line help.");
|
||||
grid.AddRow(" [blue]-c[/], [blue]--configuration[/] <CONFIGURATION>", "The configuration to run for.");
|
||||
grid.AddRow(" [blue]-v[/], [blue]--verbosity[/] <LEVEL>", "Set the [grey]MSBuild[/] verbosity level.");
|
||||
|
||||
AnsiConsole.Render(grid);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Info</Title>
|
||||
<Description>Displays the capabilities of the current console.</Description>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using Spectre.Console;
|
||||
|
||||
namespace InfoExample
|
||||
@@ -12,12 +13,13 @@ namespace InfoExample
|
||||
.AddRow("[b]Color system[/]", $"{AnsiConsole.Capabilities.ColorSystem}")
|
||||
.AddRow("[b]Supports ansi?[/]", $"{YesNo(AnsiConsole.Capabilities.SupportsAnsi)}")
|
||||
.AddRow("[b]Legacy console?[/]", $"{YesNo(AnsiConsole.Capabilities.LegacyConsole)}")
|
||||
.AddRow("[b]Interactive?[/]", $"{YesNo(Environment.UserInteractive)}")
|
||||
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Width}")
|
||||
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Height}");
|
||||
|
||||
AnsiConsole.Render(
|
||||
new Panel(grid)
|
||||
.SetHeader("Information"));
|
||||
.Header("Information"));
|
||||
}
|
||||
|
||||
private static string YesNo(bool value)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Links</Title>
|
||||
<Description>Demonstrates how to render links in a console.</Description>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Panels</Title>
|
||||
<Description>Demonstrates how to render items in panels.</Description>
|
||||
|
||||
@@ -13,28 +13,30 @@ namespace PanelExample
|
||||
AnsiConsole.Render(
|
||||
new Panel(
|
||||
new Panel(content)
|
||||
.SetBorder(BoxBorder.Rounded)));
|
||||
.Border(BoxBorder.Rounded)));
|
||||
|
||||
// Left adjusted panel with text
|
||||
AnsiConsole.Render(
|
||||
new Panel(new Text("Left adjusted\nLeft").LeftAligned())
|
||||
.Expand()
|
||||
.SquareBorder()
|
||||
.SetHeader("Left", Style.WithForeground(Color.Red)));
|
||||
.Header("[red]Left[/]"));
|
||||
|
||||
// Centered ASCII panel with text
|
||||
AnsiConsole.Render(
|
||||
new Panel(new Text("Centered\nCenter").Centered())
|
||||
.Expand()
|
||||
.AsciiBorder()
|
||||
.SetHeader("Center", Style.WithForeground(Color.Green), Justify.Center));
|
||||
.Header("[green]Center[/]")
|
||||
.HeaderAlignment(Justify.Center));
|
||||
|
||||
// Right adjusted, rounded panel with text
|
||||
AnsiConsole.Render(
|
||||
new Panel(new Text("Right adjusted\nRight").RightAligned())
|
||||
.Expand()
|
||||
.RoundedBorder()
|
||||
.SetHeader("Right", Style.WithForeground(Color.Blue), Justify.Right));
|
||||
.Header("[blue]Right[/]")
|
||||
.HeaderAlignment(Justify.Right));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
77
examples/Prompt/Program.cs
Normal file
77
examples/Prompt/Program.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using Spectre.Console;
|
||||
|
||||
namespace Cursor
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// Confirmation
|
||||
if (!AnsiConsole.Confirm("Run prompt example?"))
|
||||
{
|
||||
AnsiConsole.MarkupLine("Ok... :(");
|
||||
return;
|
||||
}
|
||||
|
||||
// String
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Rule("[yellow]Strings[/]").RuleStyle("grey").LeftAligned());
|
||||
var name = AnsiConsole.Ask<string>("What's your [green]name[/]?");
|
||||
|
||||
// String with choices
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Rule("[yellow]Choices[/]").RuleStyle("grey").LeftAligned());
|
||||
var fruit = AnsiConsole.Prompt(
|
||||
new TextPrompt<string>("What's your [green]favorite fruit[/]?")
|
||||
.InvalidChoiceMessage("[red]That's not a valid fruit[/]")
|
||||
.DefaultValue("Orange")
|
||||
.AddChoice("Apple")
|
||||
.AddChoice("Banana")
|
||||
.AddChoice("Orange"));
|
||||
|
||||
// Integer
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Rule("[yellow]Integers[/]").RuleStyle("grey").LeftAligned());
|
||||
var age = AnsiConsole.Prompt(
|
||||
new TextPrompt<int>("How [green]old[/] are you?")
|
||||
.PromptStyle("green")
|
||||
.ValidationErrorMessage("[red]That's not a valid age[/]")
|
||||
.Validate(age =>
|
||||
{
|
||||
return age switch
|
||||
{
|
||||
<= 0 => ValidationResult.Error("[red]You must at least be 1 years old[/]"),
|
||||
>= 123 => ValidationResult.Error("[red]You must be younger than the oldest person alive[/]"),
|
||||
_ => ValidationResult.Success(),
|
||||
};
|
||||
}));
|
||||
|
||||
// Secret
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Rule("[yellow]Secrets[/]").RuleStyle("grey").LeftAligned());
|
||||
var password = AnsiConsole.Prompt(
|
||||
new TextPrompt<string>("Enter [green]password[/]?")
|
||||
.PromptStyle("red")
|
||||
.Secret());
|
||||
|
||||
// Optional
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Rule("[yellow]Optional[/]").RuleStyle("grey").LeftAligned());
|
||||
var color = AnsiConsole.Prompt(
|
||||
new TextPrompt<string>("[grey][[Optional]][/] What is your [green]favorite color[/]?")
|
||||
.AllowEmpty());
|
||||
|
||||
// Summary
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Rule("[yellow]Results[/]").RuleStyle("grey").LeftAligned());
|
||||
AnsiConsole.Render(new Table().AddColumns("[grey]Question[/]", "[grey]Answer[/]")
|
||||
.RoundedBorder()
|
||||
.BorderColor(Color.Grey)
|
||||
.AddRow("[grey]Name[/]", name)
|
||||
.AddRow("[grey]Favorite fruit[/]", fruit)
|
||||
.AddRow("[grey]Age[/]", age.ToString())
|
||||
.AddRow("[grey]Password[/]", password)
|
||||
.AddRow("[grey]Favorite color[/]", string.IsNullOrEmpty(color) ? "Unknown" : color));
|
||||
}
|
||||
}
|
||||
}
|
||||
16
examples/Prompt/Prompt.csproj
Normal file
16
examples/Prompt/Prompt.csproj
Normal file
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<LangVersion>9</LangVersion>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Prompt</Title>
|
||||
<Description>Demonstrates how to get input from a user.</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
43
examples/Rules/Program.cs
Normal file
43
examples/Rules/Program.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Spectre.Console;
|
||||
|
||||
namespace EmojiExample
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// No title
|
||||
WrapInPanel(
|
||||
new Rule()
|
||||
.RuleStyle(Style.Parse("yellow"))
|
||||
.AsciiBorder()
|
||||
.LeftAligned());
|
||||
|
||||
// Left aligned title
|
||||
WrapInPanel(
|
||||
new Rule("[blue]Left aligned[/]")
|
||||
.RuleStyle(Style.Parse("red"))
|
||||
.DoubleBorder()
|
||||
.LeftAligned());
|
||||
|
||||
// Centered title
|
||||
WrapInPanel(
|
||||
new Rule("[green]Centered[/]")
|
||||
.RuleStyle(Style.Parse("green"))
|
||||
.HeavyBorder()
|
||||
.Centered());
|
||||
|
||||
// Right aligned title
|
||||
WrapInPanel(
|
||||
new Rule("[red]Right aligned[/]")
|
||||
.RuleStyle(Style.Parse("blue"))
|
||||
.RightAligned());
|
||||
}
|
||||
|
||||
private static void WrapInPanel(Rule rule)
|
||||
{
|
||||
AnsiConsole.Render(rule);
|
||||
AnsiConsole.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
15
examples/Rules/Rules.csproj
Normal file
15
examples/Rules/Rules.csproj
Normal file
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Rules</Title>
|
||||
<Description>Demonstrates how to render horizontal rules (lines).</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -5,86 +5,47 @@ namespace TableExample
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
// A simple table
|
||||
RenderSimpleTable();
|
||||
|
||||
// A big table
|
||||
RenderBigTable();
|
||||
|
||||
// A nested table
|
||||
RenderNestedTable();
|
||||
}
|
||||
|
||||
private static void RenderSimpleTable()
|
||||
{
|
||||
// Create the table.
|
||||
var table = new Table();
|
||||
table.AddColumn(new TableColumn("[u]Foo[/]"));
|
||||
table.AddColumn(new TableColumn("[u]Bar[/]"));
|
||||
table.AddColumn(new TableColumn("[u]Baz[/]"));
|
||||
|
||||
// Add some rows
|
||||
table.AddRow("Hello", "[red]World![/]", "");
|
||||
table.AddRow("[blue]Bonjour[/]", "[white]le[/]", "[red]monde![/]");
|
||||
table.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
||||
var table = CreateTable();
|
||||
|
||||
// Render the table.
|
||||
AnsiConsole.Render(table);
|
||||
}
|
||||
|
||||
private static void RenderBigTable()
|
||||
private static Table CreateTable()
|
||||
{
|
||||
// Create the table.
|
||||
var table = new Table().SetBorder(TableBorder.Rounded);
|
||||
table.AddColumn("[red underline]Foo[/]");
|
||||
table.AddColumn(new TableColumn("[blue]Bar[/]") { Alignment = Justify.Right, NoWrap = true });
|
||||
var simple = new Table()
|
||||
.Border(TableBorder.Square)
|
||||
.BorderColor(Color.Red)
|
||||
.AddColumn(new TableColumn("[u]CDE[/]").Footer("EDC").Centered())
|
||||
.AddColumn(new TableColumn("[u]FED[/]").Footer("DEF"))
|
||||
.AddColumn(new TableColumn("[u]IHG[/]").Footer("GHI"))
|
||||
.AddRow("Hello", "[red]World![/]", "")
|
||||
.AddRow("[blue]Bonjour[/]", "[white]le[/]", "[red]monde![/]")
|
||||
.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
||||
|
||||
// Add some rows
|
||||
table.AddRow("[blue][underline]Hell[/]o[/]", "World");
|
||||
table.AddRow("[yellow]Patrik [green]\"Hello World\"[/] Svensson[/]", "Was [underline]here[/]!");
|
||||
table.AddEmptyRow();
|
||||
table.AddRow(
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
|
||||
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
|
||||
"dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat " +
|
||||
"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum", "<- Strange language");
|
||||
table.AddEmptyRow();
|
||||
table.AddRow("Hej", "[green]Världen[/]");
|
||||
var second = new Table()
|
||||
.Border(TableBorder.Rounded)
|
||||
.BorderColor(Color.Green)
|
||||
.AddColumn(new TableColumn("[u]Foo[/]"))
|
||||
.AddColumn(new TableColumn("[u]Bar[/]"))
|
||||
.AddColumn(new TableColumn("[u]Baz[/]"))
|
||||
.AddRow("Hello", "[red]World![/]", "")
|
||||
.AddRow(simple, new Text("Whaaat"), new Text("Lolz"))
|
||||
.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
||||
|
||||
AnsiConsole.Render(table);
|
||||
}
|
||||
|
||||
private static void RenderNestedTable()
|
||||
{
|
||||
// Create simple table.
|
||||
var simple = new Table().SetBorder(TableBorder.Rounded).SetBorderColor(Color.Red);
|
||||
simple.AddColumn(new TableColumn("[u]Foo[/]").Centered());
|
||||
simple.AddColumn(new TableColumn("[u]Bar[/]"));
|
||||
simple.AddColumn(new TableColumn("[u]Baz[/]"));
|
||||
simple.AddRow("Hello", "[red]World![/]", "");
|
||||
simple.AddRow("[blue]Bonjour[/]", "[white]le[/]", "[red]monde![/]");
|
||||
simple.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
||||
|
||||
// Create other table.
|
||||
var second = new Table().SetBorder(TableBorder.Square).SetBorderColor(Color.Green);
|
||||
second.AddColumn(new TableColumn("[u]Foo[/]"));
|
||||
second.AddColumn(new TableColumn("[u]Bar[/]"));
|
||||
second.AddColumn(new TableColumn("[u]Baz[/]"));
|
||||
second.AddRow("Hello", "[red]World![/]", "");
|
||||
second.AddRow(simple, new Text("Whaaat"), new Text("Lolz"));
|
||||
second.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
||||
|
||||
var table = new Table().SetBorder(TableBorder.Rounded);
|
||||
table.AddColumn(new TableColumn(new Panel("[u]Foo[/]").SetBorderColor(Color.Red)));
|
||||
table.AddColumn(new TableColumn(new Panel("[u]Bar[/]").SetBorderColor(Color.Green)));
|
||||
table.AddColumn(new TableColumn(new Panel("[u]Baz[/]").SetBorderColor(Color.Blue)));
|
||||
|
||||
// Add some rows
|
||||
table.AddRow(new Text("Hello").Centered(), new Markup("[red]World![/]"), Text.Empty);
|
||||
table.AddRow(second, new Text("Whaaat"), new Text("Lol"));
|
||||
table.AddRow(new Markup("[blue]Hej[/]").Centered(), new Markup("[yellow]Världen![/]"), Text.Empty);
|
||||
|
||||
AnsiConsole.Render(table);
|
||||
return new Table()
|
||||
.Centered()
|
||||
.Border(TableBorder.DoubleEdge)
|
||||
.Title("TABLE [yellow]TITLE[/]")
|
||||
.Caption("TABLE [yellow]CAPTION[/]")
|
||||
.AddColumn(new TableColumn(new Panel("[u]ABC[/]").BorderColor(Color.Red)).Footer("[u]FOOTER 1[/]"))
|
||||
.AddColumn(new TableColumn(new Panel("[u]DEF[/]").BorderColor(Color.Green)).Footer("[u]FOOTER 2[/]"))
|
||||
.AddColumn(new TableColumn(new Panel("[u]GHI[/]").BorderColor(Color.Blue)).Footer("[u]FOOTER 3[/]"))
|
||||
.AddRow(new Text("Hello").Centered(), new Markup("[red]World![/]"), Text.Empty)
|
||||
.AddRow(second, new Text("Whaaat"), new Text("Lol"))
|
||||
.AddRow(new Markup("[blue]Hej[/]").Centered(), new Markup("[yellow]Världen![/]"), Text.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Title>Tables</Title>
|
||||
<Description>Demonstrates how to render tables in a console.</Description>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"projects": [ "src" ],
|
||||
"sdk": {
|
||||
"version": "3.1.301",
|
||||
"version": "5.0.100",
|
||||
"rollForward": "latestPatch"
|
||||
}
|
||||
}
|
||||
@@ -86,4 +86,7 @@ dotnet_diagnostic.RCS1057.severity = none
|
||||
dotnet_diagnostic.RCS1227.severity = none
|
||||
|
||||
# IDE0004: Remove Unnecessary Cast
|
||||
dotnet_diagnostic.IDE0004.severity = warning
|
||||
dotnet_diagnostic.IDE0004.severity = warning
|
||||
|
||||
# CA1810: Initialize reference type static fields inline
|
||||
dotnet_diagnostic.CA1810.severity = none
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project>
|
||||
<PropertyGroup Label="Settings">
|
||||
<Deterministic>true</Deterministic>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>embedded</DebugType>
|
||||
<MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip>
|
||||
|
||||
@@ -24,3 +24,6 @@ dotnet_diagnostic.CA2000.severity = none
|
||||
|
||||
# SA1118: Parameter should not span multiple lines
|
||||
dotnet_diagnostic.SA1118.severity = none
|
||||
|
||||
# CA1031: Do not catch general exception types
|
||||
dotnet_diagnostic.CA1031.severity = none
|
||||
|
||||
23
src/Spectre.Console.Tests/Data/Exceptions.cs
Normal file
23
src/Spectre.Console.Tests/Data/Exceptions.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Spectre.Console.Tests.Data
|
||||
{
|
||||
public static class TestExceptions
|
||||
{
|
||||
[SuppressMessage("Usage", "CA1801:Review unused parameters", Justification = "<Pending>")]
|
||||
public static bool MethodThatThrows(int? number) => throw new InvalidOperationException("Throwing!");
|
||||
|
||||
public static void ThrowWithInnerException()
|
||||
{
|
||||
try
|
||||
{
|
||||
MethodThatThrows(null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException("Something threw!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,34 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Spectre.Console.Tests
|
||||
{
|
||||
public static class StringExtensions
|
||||
{
|
||||
private static readonly Regex _lineNumberRegex = new Regex(":\\d+", RegexOptions.Singleline);
|
||||
private static readonly Regex _filenameRegex = new Regex("\\sin\\s.*cs:nn", RegexOptions.Multiline);
|
||||
|
||||
public static string NormalizeLineEndings(this string text)
|
||||
{
|
||||
return text?.Replace("\r\n", "\n", StringComparison.OrdinalIgnoreCase)
|
||||
?.Replace("\r", string.Empty, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static string NormalizeStackTrace(this string text)
|
||||
{
|
||||
text = _lineNumberRegex.Replace(text, match =>
|
||||
{
|
||||
return ":nn";
|
||||
});
|
||||
|
||||
return _filenameRegex.Replace(text, match =>
|
||||
{
|
||||
var value = match.Value;
|
||||
var index = value.LastIndexOfAny(new[] { '\\', '/' });
|
||||
var filename = value.Substring(index + 1, value.Length - index - 1);
|
||||
|
||||
return $" in /xyz/{filename}";
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ namespace Spectre.Console.Tests
|
||||
{
|
||||
if (foreground)
|
||||
{
|
||||
return style.WithForeground(color);
|
||||
return style.Foreground(color);
|
||||
}
|
||||
|
||||
return style.WithBackground(color);
|
||||
return style.Background(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFrameworks>net5.0;netcoreapp3.1</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
@@ -10,10 +11,14 @@ namespace Spectre.Console.Tests
|
||||
{
|
||||
public Capabilities Capabilities { get; }
|
||||
public Encoding Encoding { get; }
|
||||
public IAnsiConsoleCursor Cursor => throw new NotSupportedException();
|
||||
public TestableConsoleInput Input { get; }
|
||||
|
||||
public int Width { get; }
|
||||
public int Height { get; }
|
||||
|
||||
IAnsiConsoleInput IAnsiConsole.Input => Input;
|
||||
|
||||
public Decoration Decoration { get; set; }
|
||||
public Color Foreground { get; set; }
|
||||
public Color Background { get; set; }
|
||||
@@ -34,6 +39,7 @@ namespace Spectre.Console.Tests
|
||||
Width = width;
|
||||
Height = height;
|
||||
Writer = new StringWriter();
|
||||
Input = new TestableConsoleInput();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@@ -41,6 +47,10 @@ namespace Spectre.Console.Tests
|
||||
Writer.Dispose();
|
||||
}
|
||||
|
||||
public void Clear(bool home)
|
||||
{
|
||||
}
|
||||
|
||||
public void Write(Segment segment)
|
||||
{
|
||||
if (segment is null)
|
||||
@@ -50,5 +60,16 @@ namespace Spectre.Console.Tests
|
||||
|
||||
Writer.Write(segment.Text);
|
||||
}
|
||||
|
||||
public string[] WriteExceptionAndGetLines(Exception ex, ExceptionFormats formats = ExceptionFormats.Default)
|
||||
{
|
||||
this.WriteException(ex, formats);
|
||||
|
||||
return Output.NormalizeStackTrace()
|
||||
.NormalizeLineEndings()
|
||||
.Split(new char[] { '\n' })
|
||||
.Select(line => line.TrimEnd())
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,10 @@ namespace Spectre.Console.Tests
|
||||
public Encoding Encoding => _console.Encoding;
|
||||
public int Width { get; }
|
||||
public int Height => _console.Height;
|
||||
public IAnsiConsoleCursor Cursor => _console.Cursor;
|
||||
public TestableConsoleInput Input { get; }
|
||||
|
||||
IAnsiConsoleInput IAnsiConsole.Input => Input;
|
||||
|
||||
public TestableAnsiConsole(ColorSystem system, AnsiSupport ansi = AnsiSupport.Yes, int width = 80)
|
||||
{
|
||||
@@ -30,6 +34,7 @@ namespace Spectre.Console.Tests
|
||||
});
|
||||
|
||||
Width = width;
|
||||
Input = new TestableConsoleInput();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@@ -37,6 +42,11 @@ namespace Spectre.Console.Tests
|
||||
_writer?.Dispose();
|
||||
}
|
||||
|
||||
public void Clear(bool home)
|
||||
{
|
||||
_console.Clear(home);
|
||||
}
|
||||
|
||||
public void Write(Segment segment)
|
||||
{
|
||||
_console.Write(segment);
|
||||
51
src/Spectre.Console.Tests/Tools/TestableConsoleInput.cs
Normal file
51
src/Spectre.Console.Tests/Tools/TestableConsoleInput.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console.Tests
|
||||
{
|
||||
public sealed class TestableConsoleInput : IAnsiConsoleInput
|
||||
{
|
||||
private readonly Queue<ConsoleKeyInfo> _input;
|
||||
|
||||
public TestableConsoleInput()
|
||||
{
|
||||
_input = new Queue<ConsoleKeyInfo>();
|
||||
}
|
||||
|
||||
public void PushText(string input)
|
||||
{
|
||||
if (input is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(input));
|
||||
}
|
||||
|
||||
foreach (var character in input)
|
||||
{
|
||||
PushCharacter(character);
|
||||
}
|
||||
|
||||
PushKey(ConsoleKey.Enter);
|
||||
}
|
||||
|
||||
public void PushCharacter(char character)
|
||||
{
|
||||
var control = char.IsUpper(character);
|
||||
_input.Enqueue(new ConsoleKeyInfo(character, (ConsoleKey)character, false, false, control));
|
||||
}
|
||||
|
||||
public void PushKey(ConsoleKey key)
|
||||
{
|
||||
_input.Enqueue(new ConsoleKeyInfo((char)key, key, false, false, false));
|
||||
}
|
||||
|
||||
public ConsoleKeyInfo ReadKey(bool intercept)
|
||||
{
|
||||
if (_input.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("No input available.");
|
||||
}
|
||||
|
||||
return _input.Dequeue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
var console = new TestableAnsiConsole(ColorSystem.TrueColor);
|
||||
|
||||
// When
|
||||
console.Write("Hello World", Style.WithDecoration(decoration));
|
||||
console.Write("Hello World", new Style().Decoration(decoration));
|
||||
|
||||
// Then
|
||||
console.Output.ShouldBe(expected);
|
||||
@@ -36,7 +36,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
var console = new TestableAnsiConsole(ColorSystem.TrueColor);
|
||||
|
||||
// When
|
||||
console.Write("Hello World", Style.WithDecoration(decoration));
|
||||
console.Write("Hello World", new Style().Decoration(decoration));
|
||||
|
||||
// Then
|
||||
console.Output.ShouldBe(expected);
|
||||
|
||||
@@ -15,9 +15,10 @@ namespace Spectre.Console.Tests.Unit
|
||||
// When
|
||||
console.Write(
|
||||
"Hello",
|
||||
Style.WithForeground(Color.RoyalBlue1)
|
||||
.WithBackground(Color.NavajoWhite1)
|
||||
.WithDecoration(Decoration.Italic));
|
||||
new Style()
|
||||
.Foreground(Color.RoyalBlue1)
|
||||
.Background(Color.NavajoWhite1)
|
||||
.Decoration(Decoration.Italic));
|
||||
|
||||
// Then
|
||||
console.Output.ShouldBe("\u001b[3;90;47mHello\u001b[0m");
|
||||
@@ -32,9 +33,10 @@ namespace Spectre.Console.Tests.Unit
|
||||
// When
|
||||
console.Write(
|
||||
"Hello",
|
||||
Style.WithForeground(Color.Default)
|
||||
.WithBackground(Color.NavajoWhite1)
|
||||
.WithDecoration(Decoration.Italic));
|
||||
new Style()
|
||||
.Foreground(Color.Default)
|
||||
.Background(Color.NavajoWhite1)
|
||||
.Decoration(Decoration.Italic));
|
||||
|
||||
// Then
|
||||
console.Output.ShouldBe("\u001b[3;47mHello\u001b[0m");
|
||||
@@ -49,9 +51,10 @@ namespace Spectre.Console.Tests.Unit
|
||||
// When
|
||||
console.Write(
|
||||
"Hello",
|
||||
Style.WithForeground(Color.RoyalBlue1)
|
||||
.WithBackground(Color.Default)
|
||||
.WithDecoration(Decoration.Italic));
|
||||
new Style()
|
||||
.Foreground(Color.RoyalBlue1)
|
||||
.Background(Color.Default)
|
||||
.Decoration(Decoration.Italic));
|
||||
|
||||
// Then
|
||||
console.Output.ShouldBe("\u001b[3;90mHello\u001b[0m");
|
||||
@@ -66,9 +69,10 @@ namespace Spectre.Console.Tests.Unit
|
||||
// When
|
||||
console.Write(
|
||||
"Hello",
|
||||
Style.WithForeground(Color.RoyalBlue1)
|
||||
.WithBackground(Color.NavajoWhite1)
|
||||
.WithDecoration(Decoration.None));
|
||||
new Style()
|
||||
.Foreground(Color.RoyalBlue1)
|
||||
.Background(Color.NavajoWhite1)
|
||||
.Decoration(Decoration.None));
|
||||
|
||||
// Then
|
||||
console.Output.ShouldBe("\u001b[90;47mHello\u001b[0m");
|
||||
@@ -83,8 +87,8 @@ namespace Spectre.Console.Tests.Unit
|
||||
var console = new TestableAnsiConsole(ColorSystem.Standard, AnsiSupport.Yes);
|
||||
|
||||
// When
|
||||
console.WriteLine("Hello", Style.WithBackground(ConsoleColor.Red));
|
||||
console.WriteLine("World", Style.WithBackground(ConsoleColor.Green));
|
||||
console.WriteLine("Hello", new Style().Background(ConsoleColor.Red));
|
||||
console.WriteLine("World", new Style().Background(ConsoleColor.Green));
|
||||
|
||||
// Then
|
||||
console.Output.NormalizeLineEndings()
|
||||
@@ -98,7 +102,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
var console = new TestableAnsiConsole(ColorSystem.Standard, AnsiSupport.Yes);
|
||||
|
||||
// When
|
||||
console.WriteLine("Hello\nWorld", Style.WithBackground(ConsoleColor.Red));
|
||||
console.WriteLine("Hello\nWorld", new Style().Background(ConsoleColor.Red));
|
||||
|
||||
// Then
|
||||
console.Output.NormalizeLineEndings()
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
public void Should_Return_Safe_Border()
|
||||
{
|
||||
// Given, When
|
||||
var border = BoxBorder.None.GetSafeBorder(safe: true);
|
||||
var border = BoxExtensions.GetSafeBorder(BoxBorder.None, safe: true);
|
||||
|
||||
// Then
|
||||
border.ShouldBeSameAs(BoxBorder.None);
|
||||
@@ -47,7 +47,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
public void Should_Return_Safe_Border()
|
||||
{
|
||||
// Given, When
|
||||
var border = BoxBorder.Ascii.GetSafeBorder(safe: true);
|
||||
var border = BoxExtensions.GetSafeBorder(BoxBorder.Ascii, safe: true);
|
||||
|
||||
// Then
|
||||
border.ShouldBeSameAs(BoxBorder.Ascii);
|
||||
@@ -80,7 +80,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
public void Should_Return_Safe_Border()
|
||||
{
|
||||
// Given, When
|
||||
var border = BoxBorder.Double.GetSafeBorder(safe: true);
|
||||
var border = BoxExtensions.GetSafeBorder(BoxBorder.Double, safe: true);
|
||||
|
||||
// Then
|
||||
border.ShouldBeSameAs(BoxBorder.Double);
|
||||
@@ -113,7 +113,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
public void Should_Return_Safe_Border()
|
||||
{
|
||||
// Given, When
|
||||
var border = BoxBorder.Heavy.GetSafeBorder(safe: true);
|
||||
var border = BoxExtensions.GetSafeBorder(BoxBorder.Heavy, safe: true);
|
||||
|
||||
// Then
|
||||
border.ShouldBeSameAs(BoxBorder.Square);
|
||||
@@ -144,7 +144,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
public void Should_Return_Safe_Border()
|
||||
{
|
||||
// Given, When
|
||||
var border = BoxBorder.Rounded.GetSafeBorder(safe: true);
|
||||
var border = BoxExtensions.GetSafeBorder(BoxBorder.Rounded, safe: true);
|
||||
|
||||
// Then
|
||||
border.ShouldBeSameAs(BoxBorder.Square);
|
||||
@@ -174,7 +174,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
public void Should_Return_Safe_Border()
|
||||
{
|
||||
// Given, When
|
||||
var border = BoxBorder.Square.GetSafeBorder(safe: true);
|
||||
var border = BoxExtensions.GetSafeBorder(BoxBorder.Square, safe: true);
|
||||
|
||||
// Then
|
||||
border.ShouldBeSameAs(BoxBorder.Square);
|
||||
@@ -203,7 +203,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
public static Panel GetPanel()
|
||||
{
|
||||
return new Panel("Hello World")
|
||||
.SetHeader("Greeting");
|
||||
.Header("Greeting");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
153
src/Spectre.Console.Tests/Unit/CalendarTests.cs
Normal file
153
src/Spectre.Console.Tests/Unit/CalendarTests.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
using System;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace Spectre.Console.Tests.Unit
|
||||
{
|
||||
public sealed class CalendarTests
|
||||
{
|
||||
[Fact]
|
||||
public void Should_Render_Calendar_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var calendar = new Calendar(2020, 10)
|
||||
.AddCalendarEvent(new DateTime(2020, 9, 1))
|
||||
.AddCalendarEvent(new DateTime(2020, 10, 3))
|
||||
.AddCalendarEvent(new DateTime(2020, 10, 12));
|
||||
|
||||
// When
|
||||
console.Render(calendar);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(11);
|
||||
console.Lines[00].ShouldBe(" 2020 October ");
|
||||
console.Lines[01].ShouldBe("┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐");
|
||||
console.Lines[02].ShouldBe("│ Sun │ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │");
|
||||
console.Lines[03].ShouldBe("├─────┼─────┼─────┼─────┼─────┼─────┼─────┤");
|
||||
console.Lines[04].ShouldBe("│ │ │ │ │ 1 │ 2 │ 3* │");
|
||||
console.Lines[05].ShouldBe("│ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │");
|
||||
console.Lines[06].ShouldBe("│ 11 │ 12* │ 13 │ 14 │ 15 │ 16 │ 17 │");
|
||||
console.Lines[07].ShouldBe("│ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │");
|
||||
console.Lines[08].ShouldBe("│ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │");
|
||||
console.Lines[09].ShouldBe("│ │ │ │ │ │ │ │");
|
||||
console.Lines[10].ShouldBe("└─────┴─────┴─────┴─────┴─────┴─────┴─────┘");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Center_Calendar_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var calendar = new Calendar(2020, 10)
|
||||
.Centered()
|
||||
.AddCalendarEvent(new DateTime(2020, 9, 1))
|
||||
.AddCalendarEvent(new DateTime(2020, 10, 3))
|
||||
.AddCalendarEvent(new DateTime(2020, 10, 12));
|
||||
|
||||
// When
|
||||
console.Render(calendar);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(11);
|
||||
console.Lines[00].ShouldBe(" 2020 October ");
|
||||
console.Lines[01].ShouldBe(" ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐ ");
|
||||
console.Lines[02].ShouldBe(" │ Sun │ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │ ");
|
||||
console.Lines[03].ShouldBe(" ├─────┼─────┼─────┼─────┼─────┼─────┼─────┤ ");
|
||||
console.Lines[04].ShouldBe(" │ │ │ │ │ 1 │ 2 │ 3* │ ");
|
||||
console.Lines[05].ShouldBe(" │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ ");
|
||||
console.Lines[06].ShouldBe(" │ 11 │ 12* │ 13 │ 14 │ 15 │ 16 │ 17 │ ");
|
||||
console.Lines[07].ShouldBe(" │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │ ");
|
||||
console.Lines[08].ShouldBe(" │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │ ");
|
||||
console.Lines[09].ShouldBe(" │ │ │ │ │ │ │ │ ");
|
||||
console.Lines[10].ShouldBe(" └─────┴─────┴─────┴─────┴─────┴─────┴─────┘ ");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Left_Align_Calendar_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var calendar = new Calendar(2020, 10)
|
||||
.LeftAligned()
|
||||
.AddCalendarEvent(new DateTime(2020, 9, 1))
|
||||
.AddCalendarEvent(new DateTime(2020, 10, 3))
|
||||
.AddCalendarEvent(new DateTime(2020, 10, 12));
|
||||
|
||||
// When
|
||||
console.Render(calendar);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(11);
|
||||
console.Lines[00].ShouldBe(" 2020 October ");
|
||||
console.Lines[01].ShouldBe("┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐");
|
||||
console.Lines[02].ShouldBe("│ Sun │ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │");
|
||||
console.Lines[03].ShouldBe("├─────┼─────┼─────┼─────┼─────┼─────┼─────┤");
|
||||
console.Lines[04].ShouldBe("│ │ │ │ │ 1 │ 2 │ 3* │");
|
||||
console.Lines[05].ShouldBe("│ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │");
|
||||
console.Lines[06].ShouldBe("│ 11 │ 12* │ 13 │ 14 │ 15 │ 16 │ 17 │");
|
||||
console.Lines[07].ShouldBe("│ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │");
|
||||
console.Lines[08].ShouldBe("│ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │");
|
||||
console.Lines[09].ShouldBe("│ │ │ │ │ │ │ │");
|
||||
console.Lines[10].ShouldBe("└─────┴─────┴─────┴─────┴─────┴─────┴─────┘");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Right_Align_Calendar_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var calendar = new Calendar(2020, 10)
|
||||
.RightAligned()
|
||||
.AddCalendarEvent(new DateTime(2020, 9, 1))
|
||||
.AddCalendarEvent(new DateTime(2020, 10, 3))
|
||||
.AddCalendarEvent(new DateTime(2020, 10, 12));
|
||||
|
||||
// When
|
||||
console.Render(calendar);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(11);
|
||||
console.Lines[00].ShouldBe(" 2020 October ");
|
||||
console.Lines[01].ShouldBe(" ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐");
|
||||
console.Lines[02].ShouldBe(" │ Sun │ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │");
|
||||
console.Lines[03].ShouldBe(" ├─────┼─────┼─────┼─────┼─────┼─────┼─────┤");
|
||||
console.Lines[04].ShouldBe(" │ │ │ │ │ 1 │ 2 │ 3* │");
|
||||
console.Lines[05].ShouldBe(" │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │");
|
||||
console.Lines[06].ShouldBe(" │ 11 │ 12* │ 13 │ 14 │ 15 │ 16 │ 17 │");
|
||||
console.Lines[07].ShouldBe(" │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │");
|
||||
console.Lines[08].ShouldBe(" │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │");
|
||||
console.Lines[09].ShouldBe(" │ │ │ │ │ │ │ │");
|
||||
console.Lines[10].ShouldBe(" └─────┴─────┴─────┴─────┴─────┴─────┴─────┘");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Render_Calendar_Correctly_For_Specific_Culture()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var calendar = new Calendar(2020, 10, 15)
|
||||
.Culture("de-DE")
|
||||
.AddCalendarEvent(new DateTime(2020, 9, 1))
|
||||
.AddCalendarEvent(new DateTime(2020, 10, 3))
|
||||
.AddCalendarEvent(new DateTime(2020, 10, 12));
|
||||
|
||||
// When
|
||||
console.Render(calendar);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(11);
|
||||
console.Lines[00].ShouldBe(" Oktober 2020 ");
|
||||
console.Lines[01].ShouldBe("┌─────┬────┬────┬────┬────┬────┬────┐");
|
||||
console.Lines[02].ShouldBe("│ Mo │ Di │ Mi │ Do │ Fr │ Sa │ So │");
|
||||
console.Lines[03].ShouldBe("├─────┼────┼────┼────┼────┼────┼────┤");
|
||||
console.Lines[04].ShouldBe("│ │ │ │ 1 │ 2 │ 3* │ 4 │");
|
||||
console.Lines[05].ShouldBe("│ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │");
|
||||
console.Lines[06].ShouldBe("│ 12* │ 13 │ 14 │ 15 │ 16 │ 17 │ 18 │");
|
||||
console.Lines[07].ShouldBe("│ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │");
|
||||
console.Lines[08].ShouldBe("│ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │ │");
|
||||
console.Lines[09].ShouldBe("│ │ │ │ │ │ │ │");
|
||||
console.Lines[10].ShouldBe("└─────┴────┴────┴────┴────┴────┴────┘");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,6 +228,39 @@ namespace Spectre.Console.Tests.Unit
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class TheToMarkupMethod
|
||||
{
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Default_Color()
|
||||
{
|
||||
// Given, When
|
||||
var result = Color.Default.ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("default");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Known_Color()
|
||||
{
|
||||
// Given, When
|
||||
var result = Color.Red.ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("red");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Custom_Color()
|
||||
{
|
||||
// Given, When
|
||||
var result = new Color(255, 1, 12).ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("#FF010C");
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class TheToStringMethod
|
||||
{
|
||||
[Fact]
|
||||
|
||||
99
src/Spectre.Console.Tests/Unit/ExceptionTests.cs
Normal file
99
src/Spectre.Console.Tests/Unit/ExceptionTests.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using Shouldly;
|
||||
using Spectre.Console.Tests.Data;
|
||||
using Xunit;
|
||||
|
||||
namespace Spectre.Console.Tests.Unit
|
||||
{
|
||||
public sealed class ExceptionTests
|
||||
{
|
||||
[Fact]
|
||||
public void Should_Write_Exception()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 1024);
|
||||
var dex = GetException(() => TestExceptions.MethodThatThrows(null));
|
||||
|
||||
// When
|
||||
var result = console.WriteExceptionAndGetLines(dex);
|
||||
|
||||
// Then
|
||||
result.Length.ShouldBe(4);
|
||||
result[0].ShouldBe("System.InvalidOperationException: Throwing!");
|
||||
result[1].ShouldBe(" at Spectre.Console.Tests.Data.TestExceptions.MethodThatThrows(Nullable`1 number) in /xyz/Exceptions.cs:nn");
|
||||
result[2].ShouldBe(" at Spectre.Console.Tests.Unit.ExceptionTests.<>c.<Should_Write_Exception>b__0_0() in /xyz/ExceptionTests.cs:nn");
|
||||
result[3].ShouldBe(" at Spectre.Console.Tests.Unit.ExceptionTests.GetException(Action action) in /xyz/ExceptionTests.cs:nn");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Write_Exception_With_Shortened_Types()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 1024);
|
||||
var dex = GetException(() => TestExceptions.MethodThatThrows(null));
|
||||
|
||||
// When
|
||||
var result = console.WriteExceptionAndGetLines(dex, ExceptionFormats.ShortenTypes);
|
||||
|
||||
// Then
|
||||
result.Length.ShouldBe(4);
|
||||
result[0].ShouldBe("InvalidOperationException: Throwing!");
|
||||
result[1].ShouldBe(" at Spectre.Console.Tests.Data.TestExceptions.MethodThatThrows(Nullable`1 number) in /xyz/Exceptions.cs:nn");
|
||||
result[2].ShouldBe(" at Spectre.Console.Tests.Unit.ExceptionTests.<>c.<Should_Write_Exception_With_Shortened_Types>b__1_0() in /xyz/ExceptionTests.cs:nn");
|
||||
result[3].ShouldBe(" at Spectre.Console.Tests.Unit.ExceptionTests.GetException(Action action) in /xyz/ExceptionTests.cs:nn");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Write_Exception_With_Shortened_Methods()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 1024);
|
||||
var dex = GetException(() => TestExceptions.MethodThatThrows(null));
|
||||
|
||||
// When
|
||||
var result = console.WriteExceptionAndGetLines(dex, ExceptionFormats.ShortenMethods);
|
||||
|
||||
// Then
|
||||
result.Length.ShouldBe(4);
|
||||
result[0].ShouldBe("System.InvalidOperationException: Throwing!");
|
||||
result[1].ShouldBe(" at MethodThatThrows(Nullable`1 number) in /xyz/Exceptions.cs:nn");
|
||||
result[2].ShouldBe(" at <Should_Write_Exception_With_Shortened_Methods>b__2_0() in /xyz/ExceptionTests.cs:nn");
|
||||
result[3].ShouldBe(" at GetException(Action action) in /xyz/ExceptionTests.cs:nn");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Write_Exception_With_Inner_Exception()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 1024);
|
||||
var dex = GetException(() => TestExceptions.ThrowWithInnerException());
|
||||
|
||||
// When
|
||||
var result = console.WriteExceptionAndGetLines(dex);
|
||||
|
||||
// Then
|
||||
result.Length.ShouldBe(7);
|
||||
result[0].ShouldBe("System.InvalidOperationException: Something threw!");
|
||||
result[1].ShouldBe(" System.InvalidOperationException: Throwing!");
|
||||
result[2].ShouldBe(" at Spectre.Console.Tests.Data.TestExceptions.MethodThatThrows(Nullable`1 number) in /xyz/Exceptions.cs:nn");
|
||||
result[3].ShouldBe(" at Spectre.Console.Tests.Data.TestExceptions.ThrowWithInnerException() in /xyz/Exceptions.cs:nn");
|
||||
result[4].ShouldBe(" at Spectre.Console.Tests.Data.TestExceptions.ThrowWithInnerException() in /xyz/Exceptions.cs:nn");
|
||||
result[5].ShouldBe(" at Spectre.Console.Tests.Unit.ExceptionTests.<>c.<Should_Write_Exception_With_Inner_Exception>b__3_0() in /xyz/ExceptionTests.cs:nn");
|
||||
result[6].ShouldBe(" at Spectre.Console.Tests.Unit.ExceptionTests.GetException(Action action) in /xyz/ExceptionTests.cs:nn");
|
||||
}
|
||||
|
||||
public static Exception GetException(Action action)
|
||||
{
|
||||
try
|
||||
{
|
||||
action?.Invoke();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException("Exception harness failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
grid.AddRow("Foo");
|
||||
|
||||
// Then
|
||||
grid.RowCount.ShouldBe(1);
|
||||
grid.Rows.Count.ShouldBe(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -6,6 +6,24 @@ namespace Spectre.Console.Tests.Unit
|
||||
{
|
||||
public sealed class MarkupTests
|
||||
{
|
||||
public sealed class TheEscapeMethod
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("Hello World", "Hello World")]
|
||||
[InlineData("Hello World [", "Hello World [[")]
|
||||
[InlineData("Hello World ]", "Hello World ]]")]
|
||||
[InlineData("Hello [World]", "Hello [[World]]")]
|
||||
[InlineData("Hello [[World]]", "Hello [[[[World]]]]")]
|
||||
public void Should_Escape_Markup_As_Expected(string input, string expected)
|
||||
{
|
||||
// Given, When
|
||||
var result = Markup.Escape(input);
|
||||
|
||||
// Then
|
||||
result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Hello [[ World ]")]
|
||||
[InlineData("Hello [[ World ] !")]
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
table.AddRow("Corgi", "Waldo");
|
||||
|
||||
// When
|
||||
console.Render(new Padder(table).SetPadding(1, 2, 3, 4));
|
||||
console.Render(new Padder(table).Padding(1, 2, 3, 4));
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(12);
|
||||
@@ -48,7 +48,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
|
||||
// When
|
||||
console.Render(new Padder(table)
|
||||
.SetPadding(1, 2, 3, 4)
|
||||
.Padding(1, 2, 3, 4)
|
||||
.Expand());
|
||||
|
||||
// Then
|
||||
@@ -77,11 +77,11 @@ namespace Spectre.Console.Tests.Unit
|
||||
table.AddColumn("Bar", c => c.PadLeft(0).PadRight(0));
|
||||
table.AddRow("Baz", "Qux");
|
||||
table.AddRow(new Text("Corgi"), new Padder(new Panel("Waldo"))
|
||||
.SetPadding(2, 1, 2, 1));
|
||||
.Padding(2, 1));
|
||||
|
||||
// When
|
||||
console.Render(new Padder(table)
|
||||
.SetPadding(1, 2, 3, 4)
|
||||
.Padding(1, 2, 3, 4)
|
||||
.Expand());
|
||||
|
||||
// Then
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Shouldly;
|
||||
using Spectre.Console.Rendering;
|
||||
using Xunit;
|
||||
|
||||
namespace Spectre.Console.Tests.Unit
|
||||
@@ -242,7 +244,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Justify_Child_To_Right()
|
||||
public void Should_Justify_Child_To_Right_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 25);
|
||||
@@ -262,7 +264,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Justify_Child_To_Center()
|
||||
public void Should_Center_Child_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 25);
|
||||
@@ -298,5 +300,33 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Lines[3].ShouldBe("│ └─────────────┘ │");
|
||||
console.Lines[4].ShouldBe("└─────────────────┘");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Wrap_Content_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 84);
|
||||
var rows = new List<IRenderable>();
|
||||
var grid = new Grid();
|
||||
grid.AddColumn(new GridColumn().PadLeft(2).PadRight(0));
|
||||
grid.AddColumn(new GridColumn().PadLeft(1).PadRight(0));
|
||||
grid.AddRow("at", "[grey]System.Runtime.CompilerServices.TaskAwaiter.[/][yellow]HandleNonSuccessAndDebuggerNotification[/]([blue]Task[/] task)");
|
||||
rows.Add(grid);
|
||||
|
||||
var panel = new Panel(grid)
|
||||
.Expand().RoundedBorder()
|
||||
.BorderStyle(new Style().Foreground(Color.Grey))
|
||||
.Header("[grey]Short paths[/]");
|
||||
|
||||
// When
|
||||
console.Render(panel);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(4);
|
||||
console.Lines[0].ShouldBe("╭─Short paths──────────────────────────────────────────────────────────────────────╮");
|
||||
console.Lines[1].ShouldBe("│ at System.Runtime.CompilerServices.TaskAwaiter. │");
|
||||
console.Lines[2].ShouldBe("│ HandleNonSuccessAndDebuggerNotification(Task task) │");
|
||||
console.Lines[3].ShouldBe("╰──────────────────────────────────────────────────────────────────────────────────╯");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
126
src/Spectre.Console.Tests/Unit/PromptTests.cs
Normal file
126
src/Spectre.Console.Tests/Unit/PromptTests.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace Spectre.Console.Tests.Unit
|
||||
{
|
||||
public sealed class PromptTests
|
||||
{
|
||||
[Fact]
|
||||
public void Should_Return_Validation_Error_If_Value_Cannot_Be_Converted()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole();
|
||||
console.Input.PushText("ninety-nine");
|
||||
console.Input.PushText("99");
|
||||
|
||||
// When
|
||||
console.Prompt(new TextPrompt<int>("Age?"));
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(3);
|
||||
console.Lines[0].ShouldBe("Age? ninety-nine");
|
||||
console.Lines[1].ShouldBe("Invalid input");
|
||||
console.Lines[2].ShouldBe("Age? 99");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Chose_Default_Value_If_Nothing_Is_Entered()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole();
|
||||
console.Input.PushKey(ConsoleKey.Enter);
|
||||
|
||||
// When
|
||||
console.Prompt(
|
||||
new TextPrompt<string>("Favorite fruit?")
|
||||
.AddChoice("Banana")
|
||||
.AddChoice("Orange")
|
||||
.DefaultValue("Banana"));
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(1);
|
||||
console.Lines[0].ShouldBe("Favorite fruit? [Banana/Orange] (Banana): Banana");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Error_If_An_Invalid_Choice_Is_Made()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole();
|
||||
console.Input.PushText("Apple");
|
||||
console.Input.PushText("Banana");
|
||||
|
||||
// When
|
||||
console.Prompt(
|
||||
new TextPrompt<string>("Favorite fruit?")
|
||||
.AddChoice("Banana")
|
||||
.AddChoice("Orange")
|
||||
.DefaultValue("Banana"));
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(3);
|
||||
console.Lines[0].ShouldBe("Favorite fruit? [Banana/Orange] (Banana): Apple");
|
||||
console.Lines[1].ShouldBe("Please select one of the available options");
|
||||
console.Lines[2].ShouldBe("Favorite fruit? [Banana/Orange] (Banana): Banana");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Accept_Choice_In_List()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole();
|
||||
console.Input.PushText("Orange");
|
||||
|
||||
// When
|
||||
console.Prompt(
|
||||
new TextPrompt<string>("Favorite fruit?")
|
||||
.AddChoice("Banana")
|
||||
.AddChoice("Orange")
|
||||
.DefaultValue("Banana"));
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(1);
|
||||
console.Lines[0].ShouldBe("Favorite fruit? [Banana/Orange] (Banana): Orange");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Error_If_Custom_Validation_Fails()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole();
|
||||
console.Input.PushText("22");
|
||||
console.Input.PushText("102");
|
||||
console.Input.PushText("ABC");
|
||||
console.Input.PushText("99");
|
||||
|
||||
// When
|
||||
console.Prompt(
|
||||
new TextPrompt<int>("Guess number:")
|
||||
.ValidationErrorMessage("Invalid input")
|
||||
.Validate(age =>
|
||||
{
|
||||
if (age < 99)
|
||||
{
|
||||
return ValidationResult.Error("Too low");
|
||||
}
|
||||
else if (age > 99)
|
||||
{
|
||||
return ValidationResult.Error("Too high");
|
||||
}
|
||||
|
||||
return ValidationResult.Success();
|
||||
}));
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(7);
|
||||
console.Lines[0].ShouldBe("Guess number: 22");
|
||||
console.Lines[1].ShouldBe("Too low");
|
||||
console.Lines[2].ShouldBe("Guess number: 102");
|
||||
console.Lines[3].ShouldBe("Too high");
|
||||
console.Lines[4].ShouldBe("Guess number: ABC");
|
||||
console.Lines[5].ShouldBe("Invalid input");
|
||||
console.Lines[6].ShouldBe("Guess number: 99");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
.AddColumns("[red on black]Foo[/]", "[green bold]Bar[/]", "[blue italic]Qux[/]")
|
||||
.AddRow("[invert underline]Corgi[/]", "[bold strikethrough]Waldo[/]", "[dim]Zap[/]")
|
||||
.AddRow(new Panel("[blue]Hello World[/]")
|
||||
.SetBorderColor(Color.Red).RoundedBorder()));
|
||||
.BorderColor(Color.Red).RoundedBorder()));
|
||||
|
||||
// When
|
||||
var html = recorder.ExportHtml();
|
||||
|
||||
153
src/Spectre.Console.Tests/Unit/RuleTests.cs
Normal file
153
src/Spectre.Console.Tests/Unit/RuleTests.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace Spectre.Console.Tests.Unit
|
||||
{
|
||||
public sealed class RuleTests
|
||||
{
|
||||
[Fact]
|
||||
public void Should_Render_Default_Rule_Without_Title()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 40);
|
||||
|
||||
// When
|
||||
console.Render(new Rule());
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(1);
|
||||
console.Lines[0].ShouldBe("────────────────────────────────────────");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Render_Default_Rule_With_Specified_Box()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 40);
|
||||
|
||||
// When
|
||||
console.Render(new Rule().DoubleBorder());
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(1);
|
||||
console.Lines[0].ShouldBe("════════════════════════════════════════");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Render_With_Specified_Box()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 40);
|
||||
|
||||
// When
|
||||
console.Render(new Rule("Hello World").DoubleBorder());
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(1);
|
||||
console.Lines[0].ShouldBe("═════════════ Hello World ══════════════");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Render_Default_Rule_With_Title_Centered_By_Default()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 40);
|
||||
|
||||
// When
|
||||
console.Render(new Rule("Hello World"));
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(1);
|
||||
console.Lines[0].ShouldBe("───────────── Hello World ──────────────");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Render_Default_Rule_With_Title_Left_Aligned()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 40);
|
||||
|
||||
// When
|
||||
console.Render(new Rule("Hello World")
|
||||
{
|
||||
Alignment = Justify.Left,
|
||||
});
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(1);
|
||||
console.Lines[0].ShouldBe("── Hello World ─────────────────────────");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Render_Default_Rule_With_Title_Right_Aligned()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 40);
|
||||
|
||||
// When
|
||||
console.Render(new Rule("Hello World")
|
||||
{
|
||||
Alignment = Justify.Right,
|
||||
});
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(1);
|
||||
console.Lines[0].ShouldBe("───────────────────────── Hello World ──");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Convert_Line_Breaks_In_Title_To_Spaces()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 40);
|
||||
|
||||
// When
|
||||
console.Render(new Rule("Hello\nWorld\r\n!"));
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(1);
|
||||
console.Lines[0].ShouldBe("──────────── Hello World ! ─────────────");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Truncate_Title()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 40);
|
||||
|
||||
// When
|
||||
console.Render(new Rule(" Hello World "));
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(1);
|
||||
console.Lines[0].ShouldBe("───────────── Hello World ──────────────");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0, "Hello World Hello World Hello World Hello World Hello World", "")]
|
||||
[InlineData(1, "Hello World Hello World Hello World Hello World Hello World", "─")]
|
||||
[InlineData(2, "Hello World Hello World Hello World Hello World Hello World", "──")]
|
||||
[InlineData(3, "Hello World Hello World Hello World Hello World Hello World", "───")]
|
||||
[InlineData(4, "Hello World Hello World Hello World Hello World Hello World", "────")]
|
||||
[InlineData(5, "Hello World Hello World Hello World Hello World Hello World", "─────")]
|
||||
[InlineData(6, "Hello World Hello World Hello World Hello World Hello World", "──────")]
|
||||
[InlineData(7, "Hello World Hello World Hello World Hello World Hello World", "───────")]
|
||||
[InlineData(8, "Hello World Hello World Hello World Hello World Hello World", "── H… ──")]
|
||||
[InlineData(8, "A", "── A ───")]
|
||||
[InlineData(8, "AB", "── AB ──")]
|
||||
[InlineData(8, "ABC", "── A… ──")]
|
||||
[InlineData(40, "Hello World Hello World Hello World Hello World Hello World", "──── Hello World Hello World Hello… ────")]
|
||||
public void Should_Truncate_Too_Long_Title(int width, string input, string expected)
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width);
|
||||
|
||||
// When
|
||||
console.Render(new Rule(input));
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(1);
|
||||
console.Lines[0].ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Text;
|
||||
using Shouldly;
|
||||
using Spectre.Console.Rendering;
|
||||
using Xunit;
|
||||
@@ -6,6 +7,16 @@ namespace Spectre.Console.Tests.Unit
|
||||
{
|
||||
public sealed class SegmentTests
|
||||
{
|
||||
[Fact]
|
||||
public void Lol()
|
||||
{
|
||||
var context = new RenderContext(Encoding.UTF8, false);
|
||||
|
||||
var result = new Segment(" ").CellCount(context);
|
||||
|
||||
result.ShouldBe(4);
|
||||
}
|
||||
|
||||
public sealed class TheSplitMethod
|
||||
{
|
||||
[Fact]
|
||||
@@ -31,7 +42,10 @@ namespace Spectre.Console.Tests.Unit
|
||||
[Fact]
|
||||
public void Should_Split_Segment()
|
||||
{
|
||||
var context = new RenderContext(Encoding.UTF8, false);
|
||||
|
||||
var lines = Segment.SplitLines(
|
||||
context,
|
||||
new[]
|
||||
{
|
||||
new Segment("Foo"),
|
||||
@@ -61,7 +75,9 @@ namespace Spectre.Console.Tests.Unit
|
||||
[Fact]
|
||||
public void Should_Split_Segments_With_Linebreak_In_Text()
|
||||
{
|
||||
var context = new RenderContext(Encoding.UTF8, false);
|
||||
var lines = Segment.SplitLines(
|
||||
context,
|
||||
new[]
|
||||
{
|
||||
new Segment("Foo\n"),
|
||||
|
||||
@@ -317,5 +317,60 @@ namespace Spectre.Console.Tests.Unit
|
||||
result.ShouldBeFalse();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class TheToMarkupMethod
|
||||
{
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Style_With_Foreground_Color()
|
||||
{
|
||||
// Given
|
||||
var style = new Style(Color.Red);
|
||||
|
||||
// When
|
||||
var result = style.ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("red");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Style_With_Foreground_And_Background_Color()
|
||||
{
|
||||
// Given
|
||||
var style = new Style(Color.Red, Color.Green);
|
||||
|
||||
// When
|
||||
var result = style.ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("red on green");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Style_With_Foreground_And_Background_Color_And_Decoration()
|
||||
{
|
||||
// Given
|
||||
var style = new Style(Color.Red, Color.Green, Decoration.Bold | Decoration.Underline);
|
||||
|
||||
// When
|
||||
var result = style.ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("bold underline red on green");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Style_With_Only_Background_Color()
|
||||
{
|
||||
// Given
|
||||
var style = new Style(background: Color.Green);
|
||||
|
||||
// When
|
||||
var result = style.ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("default on green");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,10 +42,11 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(3);
|
||||
console.Lines.Count.ShouldBe(4);
|
||||
console.Lines[0].ShouldBe("Header 1 Header 2");
|
||||
console.Lines[1].ShouldBe("Cell Cell ");
|
||||
console.Lines[2].ShouldBe("Cell Cell ");
|
||||
console.Lines[3].ShouldBe("Footer 1 Footer 2");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,13 +86,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe("+---------------------+");
|
||||
console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
|
||||
console.Lines[2].ShouldBe("|----------+----------|");
|
||||
console.Lines[3].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[4].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[5].ShouldBe("+---------------------+");
|
||||
console.Lines[5].ShouldBe("|----------+----------|");
|
||||
console.Lines[6].ShouldBe("| Footer 1 | Footer 2 |");
|
||||
console.Lines[7].ShouldBe("+---------------------+");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,13 +134,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe("+----------+----------+");
|
||||
console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
|
||||
console.Lines[2].ShouldBe("|----------+----------|");
|
||||
console.Lines[3].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[4].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[5].ShouldBe("+----------+----------+");
|
||||
console.Lines[5].ShouldBe("|----------+----------|");
|
||||
console.Lines[6].ShouldBe("| Footer 1 | Footer 2 |");
|
||||
console.Lines[7].ShouldBe("+----------+----------+");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,13 +182,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe("+----------+----------+");
|
||||
console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
|
||||
console.Lines[2].ShouldBe("|==========+==========|");
|
||||
console.Lines[3].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[4].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[5].ShouldBe("+----------+----------+");
|
||||
console.Lines[6].ShouldBe("| Footer 1 | Footer 2 |");
|
||||
console.Lines[7].ShouldBe("+----------+----------+");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,13 +230,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe("┌──────────┬──────────┐");
|
||||
console.Lines[1].ShouldBe("│ Header 1 │ Header 2 │");
|
||||
console.Lines[2].ShouldBe("├──────────┼──────────┤");
|
||||
console.Lines[3].ShouldBe("│ Cell │ Cell │");
|
||||
console.Lines[4].ShouldBe("│ Cell │ Cell │");
|
||||
console.Lines[5].ShouldBe("└──────────┴──────────┘");
|
||||
console.Lines[5].ShouldBe("├──────────┼──────────┤");
|
||||
console.Lines[6].ShouldBe("│ Footer 1 │ Footer 2 │");
|
||||
console.Lines[7].ShouldBe("└──────────┴──────────┘");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,13 +278,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe("╭──────────┬──────────╮");
|
||||
console.Lines[1].ShouldBe("│ Header 1 │ Header 2 │");
|
||||
console.Lines[2].ShouldBe("├──────────┼──────────┤");
|
||||
console.Lines[3].ShouldBe("│ Cell │ Cell │");
|
||||
console.Lines[4].ShouldBe("│ Cell │ Cell │");
|
||||
console.Lines[5].ShouldBe("╰──────────┴──────────╯");
|
||||
console.Lines[5].ShouldBe("├──────────┼──────────┤");
|
||||
console.Lines[6].ShouldBe("│ Footer 1 │ Footer 2 │");
|
||||
console.Lines[7].ShouldBe("╰──────────┴──────────╯");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,13 +326,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe(" ");
|
||||
console.Lines[1].ShouldBe(" Header 1 │ Header 2 ");
|
||||
console.Lines[2].ShouldBe(" ──────────┼────────── ");
|
||||
console.Lines[3].ShouldBe(" Cell │ Cell ");
|
||||
console.Lines[4].ShouldBe(" Cell │ Cell ");
|
||||
console.Lines[5].ShouldBe(" ");
|
||||
console.Lines[5].ShouldBe(" ──────────┼────────── ");
|
||||
console.Lines[6].ShouldBe(" Footer 1 │ Footer 2 ");
|
||||
console.Lines[7].ShouldBe(" ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,13 +374,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe(" ");
|
||||
console.Lines[1].ShouldBe(" Header 1 │ Header 2 ");
|
||||
console.Lines[2].ShouldBe(" ━━━━━━━━━━┿━━━━━━━━━━ ");
|
||||
console.Lines[3].ShouldBe(" Cell │ Cell ");
|
||||
console.Lines[4].ShouldBe(" Cell │ Cell ");
|
||||
console.Lines[5].ShouldBe(" ");
|
||||
console.Lines[5].ShouldBe(" ━━━━━━━━━━┿━━━━━━━━━━ ");
|
||||
console.Lines[6].ShouldBe(" Footer 1 │ Footer 2 ");
|
||||
console.Lines[7].ShouldBe(" ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,13 +422,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe(" ");
|
||||
console.Lines[1].ShouldBe(" Header 1 │ Header 2 ");
|
||||
console.Lines[2].ShouldBe(" ══════════╪══════════ ");
|
||||
console.Lines[3].ShouldBe(" Cell │ Cell ");
|
||||
console.Lines[4].ShouldBe(" Cell │ Cell ");
|
||||
console.Lines[5].ShouldBe(" ");
|
||||
console.Lines[5].ShouldBe(" ══════════╪══════════ ");
|
||||
console.Lines[6].ShouldBe(" Footer 1 │ Footer 2 ");
|
||||
console.Lines[7].ShouldBe(" ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,13 +470,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe(" ");
|
||||
console.Lines[1].ShouldBe(" Header 1 Header 2 ");
|
||||
console.Lines[2].ShouldBe("───────────────────────");
|
||||
console.Lines[3].ShouldBe(" Cell Cell ");
|
||||
console.Lines[4].ShouldBe(" Cell Cell ");
|
||||
console.Lines[5].ShouldBe(" ");
|
||||
console.Lines[5].ShouldBe("───────────────────────");
|
||||
console.Lines[6].ShouldBe(" Footer 1 Footer 2 ");
|
||||
console.Lines[7].ShouldBe(" ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,13 +518,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe("───────────────────────");
|
||||
console.Lines[1].ShouldBe(" Header 1 Header 2 ");
|
||||
console.Lines[2].ShouldBe("───────────────────────");
|
||||
console.Lines[3].ShouldBe(" Cell Cell ");
|
||||
console.Lines[4].ShouldBe(" Cell Cell ");
|
||||
console.Lines[5].ShouldBe("───────────────────────");
|
||||
console.Lines[6].ShouldBe(" Footer 1 Footer 2 ");
|
||||
console.Lines[7].ShouldBe("───────────────────────");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,13 +566,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe(" ");
|
||||
console.Lines[1].ShouldBe(" Header 1 Header 2 ");
|
||||
console.Lines[2].ShouldBe("━━━━━━━━━━━━━━━━━━━━━━━");
|
||||
console.Lines[3].ShouldBe(" Cell Cell ");
|
||||
console.Lines[4].ShouldBe(" Cell Cell ");
|
||||
console.Lines[5].ShouldBe(" ");
|
||||
console.Lines[5].ShouldBe("━━━━━━━━━━━━━━━━━━━━━━━");
|
||||
console.Lines[6].ShouldBe(" Footer 1 Footer 2 ");
|
||||
console.Lines[7].ShouldBe(" ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -591,13 +614,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe("┏━━━━━━━━━━┳━━━━━━━━━━┓");
|
||||
console.Lines[1].ShouldBe("┃ Header 1 ┃ Header 2 ┃");
|
||||
console.Lines[2].ShouldBe("┣━━━━━━━━━━╋━━━━━━━━━━┫");
|
||||
console.Lines[3].ShouldBe("┃ Cell ┃ Cell ┃");
|
||||
console.Lines[4].ShouldBe("┃ Cell ┃ Cell ┃");
|
||||
console.Lines[5].ShouldBe("┗━━━━━━━━━━┻━━━━━━━━━━┛");
|
||||
console.Lines[5].ShouldBe("┣━━━━━━━━━━╋━━━━━━━━━━┫");
|
||||
console.Lines[6].ShouldBe("┃ Footer 1 ┃ Footer 2 ┃");
|
||||
console.Lines[7].ShouldBe("┗━━━━━━━━━━┻━━━━━━━━━━┛");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,13 +662,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe("┏━━━━━━━━━━┯━━━━━━━━━━┓");
|
||||
console.Lines[1].ShouldBe("┃ Header 1 │ Header 2 ┃");
|
||||
console.Lines[2].ShouldBe("┠──────────┼──────────┨");
|
||||
console.Lines[3].ShouldBe("┃ Cell │ Cell ┃");
|
||||
console.Lines[4].ShouldBe("┃ Cell │ Cell ┃");
|
||||
console.Lines[5].ShouldBe("┗━━━━━━━━━━┷━━━━━━━━━━┛");
|
||||
console.Lines[5].ShouldBe("┠──────────┼──────────┨");
|
||||
console.Lines[6].ShouldBe("┃ Footer 1 │ Footer 2 ┃");
|
||||
console.Lines[7].ShouldBe("┗━━━━━━━━━━┷━━━━━━━━━━┛");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,13 +710,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe("┏━━━━━━━━━━┳━━━━━━━━━━┓");
|
||||
console.Lines[1].ShouldBe("┃ Header 1 ┃ Header 2 ┃");
|
||||
console.Lines[2].ShouldBe("┡━━━━━━━━━━╇━━━━━━━━━━┩");
|
||||
console.Lines[3].ShouldBe("│ Cell │ Cell │");
|
||||
console.Lines[4].ShouldBe("│ Cell │ Cell │");
|
||||
console.Lines[5].ShouldBe("└──────────┴──────────┘");
|
||||
console.Lines[5].ShouldBe("├──────────┼──────────┤");
|
||||
console.Lines[6].ShouldBe("│ Footer 1 │ Footer 2 │");
|
||||
console.Lines[7].ShouldBe("└──────────┴──────────┘");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -729,13 +758,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe("╔══════════╦══════════╗");
|
||||
console.Lines[1].ShouldBe("║ Header 1 ║ Header 2 ║");
|
||||
console.Lines[2].ShouldBe("╠══════════╬══════════╣");
|
||||
console.Lines[3].ShouldBe("║ Cell ║ Cell ║");
|
||||
console.Lines[4].ShouldBe("║ Cell ║ Cell ║");
|
||||
console.Lines[5].ShouldBe("╚══════════╩══════════╝");
|
||||
console.Lines[5].ShouldBe("╠══════════╬══════════╣");
|
||||
console.Lines[6].ShouldBe("║ Footer 1 ║ Footer 2 ║");
|
||||
console.Lines[7].ShouldBe("╚══════════╩══════════╝");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -775,13 +806,15 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe("╔══════════╤══════════╗");
|
||||
console.Lines[1].ShouldBe("║ Header 1 │ Header 2 ║");
|
||||
console.Lines[2].ShouldBe("╟──────────┼──────────╢");
|
||||
console.Lines[3].ShouldBe("║ Cell │ Cell ║");
|
||||
console.Lines[4].ShouldBe("║ Cell │ Cell ║");
|
||||
console.Lines[5].ShouldBe("╚══════════╧══════════╝");
|
||||
console.Lines[5].ShouldBe("╟──────────┼──────────╢");
|
||||
console.Lines[6].ShouldBe("║ Footer 1 │ Footer 2 ║");
|
||||
console.Lines[7].ShouldBe("╚══════════╧══════════╝");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -821,13 +854,14 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(7);
|
||||
console.Lines[0].ShouldBe(" ");
|
||||
console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
|
||||
console.Lines[2].ShouldBe("| -------- | -------- |");
|
||||
console.Lines[3].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[4].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[5].ShouldBe(" ");
|
||||
console.Lines[5].ShouldBe("| Footer 1 | Footer 2 |");
|
||||
console.Lines[6].ShouldBe(" ");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -841,13 +875,14 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(7);
|
||||
console.Lines[0].ShouldBe(" ");
|
||||
console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
|
||||
console.Lines[2].ShouldBe("| -------- | :------- |");
|
||||
console.Lines[3].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[4].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[5].ShouldBe(" ");
|
||||
console.Lines[5].ShouldBe("| Footer 1 | Footer 2 |");
|
||||
console.Lines[6].ShouldBe(" ");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -861,13 +896,14 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(7);
|
||||
console.Lines[0].ShouldBe(" ");
|
||||
console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
|
||||
console.Lines[2].ShouldBe("| -------- | :------: |");
|
||||
console.Lines[3].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[4].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[5].ShouldBe(" ");
|
||||
console.Lines[5].ShouldBe("| Footer 1 | Footer 2 |");
|
||||
console.Lines[6].ShouldBe(" ");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -881,13 +917,14 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines.Count.ShouldBe(7);
|
||||
console.Lines[0].ShouldBe(" ");
|
||||
console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
|
||||
console.Lines[2].ShouldBe("| -------- | -------: |");
|
||||
console.Lines[3].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[4].ShouldBe("| Cell | Cell |");
|
||||
console.Lines[5].ShouldBe(" ");
|
||||
console.Lines[5].ShouldBe("| Footer 1 | Footer 2 |");
|
||||
console.Lines[6].ShouldBe(" ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -896,8 +933,8 @@ namespace Spectre.Console.Tests.Unit
|
||||
public static Table GetTable(Justify? header1 = null, Justify? header2 = null)
|
||||
{
|
||||
var table = new Table();
|
||||
table.AddColumn("Header 1", c => c.Alignment = header1);
|
||||
table.AddColumn("Header 2", c => c.Alignment = header2);
|
||||
table.AddColumn("Header 1", c => c.Alignment(header1).Footer("Footer 1"));
|
||||
table.AddColumn("Header 2", c => c.Alignment(header2).Footer("Footer 2"));
|
||||
table.AddRow("Cell", "Cell");
|
||||
table.AddRow("Cell", "Cell");
|
||||
return table;
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
table.AddRow("Foo");
|
||||
|
||||
// Then
|
||||
table.RowCount.ShouldBe(1);
|
||||
table.Rows.Count.ShouldBe(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -168,6 +168,105 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Lines[5].ShouldBe("└────────┴────────┴───────┘");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Render_Table_With_Footers_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var table = new Table();
|
||||
table.AddColumn(new TableColumn("Foo").Footer("Oof").RightAligned());
|
||||
table.AddColumn("Bar");
|
||||
table.AddColumns(new TableColumn("Baz").Footer("Zab"));
|
||||
table.AddRow("Qux", "Corgi", "Waldo");
|
||||
table.AddRow("Grault", "Garply", "Fred");
|
||||
|
||||
// When
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe("┌────────┬────────┬───────┐");
|
||||
console.Lines[1].ShouldBe("│ Foo │ Bar │ Baz │");
|
||||
console.Lines[2].ShouldBe("├────────┼────────┼───────┤");
|
||||
console.Lines[3].ShouldBe("│ Qux │ Corgi │ Waldo │");
|
||||
console.Lines[4].ShouldBe("│ Grault │ Garply │ Fred │");
|
||||
console.Lines[5].ShouldBe("├────────┼────────┼───────┤");
|
||||
console.Lines[6].ShouldBe("│ Oof │ │ Zab │");
|
||||
console.Lines[7].ShouldBe("└────────┴────────┴───────┘");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Left_Align_Table_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var table = new Table();
|
||||
table.Alignment = Justify.Left;
|
||||
table.AddColumns("Foo", "Bar", "Baz");
|
||||
table.AddRow("Qux", "Corgi", "Waldo");
|
||||
table.AddRow("Grault", "Garply", "Fred");
|
||||
|
||||
// When
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines[0].ShouldBe("┌────────┬────────┬───────┐");
|
||||
console.Lines[1].ShouldBe("│ Foo │ Bar │ Baz │");
|
||||
console.Lines[2].ShouldBe("├────────┼────────┼───────┤");
|
||||
console.Lines[3].ShouldBe("│ Qux │ Corgi │ Waldo │");
|
||||
console.Lines[4].ShouldBe("│ Grault │ Garply │ Fred │");
|
||||
console.Lines[5].ShouldBe("└────────┴────────┴───────┘");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Center_Table_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var table = new Table();
|
||||
table.Alignment = Justify.Center;
|
||||
table.AddColumns("Foo", "Bar", "Baz");
|
||||
table.AddRow("Qux", "Corgi", "Waldo");
|
||||
table.AddRow("Grault", "Garply", "Fred");
|
||||
|
||||
// When
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines[0].ShouldBe(" ┌────────┬────────┬───────┐ ");
|
||||
console.Lines[1].ShouldBe(" │ Foo │ Bar │ Baz │ ");
|
||||
console.Lines[2].ShouldBe(" ├────────┼────────┼───────┤ ");
|
||||
console.Lines[3].ShouldBe(" │ Qux │ Corgi │ Waldo │ ");
|
||||
console.Lines[4].ShouldBe(" │ Grault │ Garply │ Fred │ ");
|
||||
console.Lines[5].ShouldBe(" └────────┴────────┴───────┘ ");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Right_Align_Table_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var table = new Table();
|
||||
table.Alignment = Justify.Right;
|
||||
table.AddColumns("Foo", "Bar", "Baz");
|
||||
table.AddRow("Qux", "Corgi", "Waldo");
|
||||
table.AddRow("Grault", "Garply", "Fred");
|
||||
|
||||
// When
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines[0].ShouldBe(" ┌────────┬────────┬───────┐");
|
||||
console.Lines[1].ShouldBe(" │ Foo │ Bar │ Baz │");
|
||||
console.Lines[2].ShouldBe(" ├────────┼────────┼───────┤");
|
||||
console.Lines[3].ShouldBe(" │ Qux │ Corgi │ Waldo │");
|
||||
console.Lines[4].ShouldBe(" │ Grault │ Garply │ Fred │");
|
||||
console.Lines[5].ShouldBe(" └────────┴────────┴───────┘");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Render_Table_Nested_In_Panels_Correctly()
|
||||
{
|
||||
@@ -250,52 +349,6 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Lines[5].ShouldBe("└───────────────────────────┴───────────────────────────┴──────────────────────┘");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Render_Table_With_Ascii_Border_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var table = new Table { Border = TableBorder.Ascii };
|
||||
table.AddColumns("Foo", "Bar", "Baz");
|
||||
table.AddRow("Qux", "Corgi", "Waldo");
|
||||
table.AddRow("Grault", "Garply", "Fred");
|
||||
|
||||
// When
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines[0].ShouldBe("+-------------------------+");
|
||||
console.Lines[1].ShouldBe("| Foo | Bar | Baz |");
|
||||
console.Lines[2].ShouldBe("|--------+--------+-------|");
|
||||
console.Lines[3].ShouldBe("| Qux | Corgi | Waldo |");
|
||||
console.Lines[4].ShouldBe("| Grault | Garply | Fred |");
|
||||
console.Lines[5].ShouldBe("+-------------------------+");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Render_Table_With_Rounded_Border_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var table = new Table { Border = TableBorder.Rounded };
|
||||
table.AddColumns("Foo", "Bar", "Baz");
|
||||
table.AddRow("Qux", "Corgi", "Waldo");
|
||||
table.AddRow("Grault", "Garply", "Fred");
|
||||
|
||||
// When
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(6);
|
||||
console.Lines[0].ShouldBe("╭────────┬────────┬───────╮");
|
||||
console.Lines[1].ShouldBe("│ Foo │ Bar │ Baz │");
|
||||
console.Lines[2].ShouldBe("├────────┼────────┼───────┤");
|
||||
console.Lines[3].ShouldBe("│ Qux │ Corgi │ Waldo │");
|
||||
console.Lines[4].ShouldBe("│ Grault │ Garply │ Fred │");
|
||||
console.Lines[5].ShouldBe("╰────────┴────────┴───────╯");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Render_Table_With_No_Border_Correctly()
|
||||
{
|
||||
@@ -383,5 +436,165 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Lines[1].ShouldBe("│ Foo │ Bar │ Baz │");
|
||||
console.Lines[2].ShouldBe("└─────┴─────┴────────┘");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Not_Draw_Tables_That_Are_Impossible_To_Draw()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 25);
|
||||
|
||||
var first = new Table().Border(TableBorder.Rounded).BorderColor(Color.Red);
|
||||
first.AddColumn(new TableColumn("[u]PS1[/]").Centered());
|
||||
first.AddColumn(new TableColumn("[u]PS2[/]"));
|
||||
first.AddColumn(new TableColumn("[u]PS3[/]"));
|
||||
first.AddRow("Hello", "[red]World[/]", string.Empty);
|
||||
first.AddRow("[blue]Bonjour[/]", "[white]le[/]", "[red]monde![/]");
|
||||
first.AddRow("[blue]Hej[/]", "[yellow]Världen[/]", string.Empty);
|
||||
|
||||
var second = new Table().Border(TableBorder.Square).BorderColor(Color.Green);
|
||||
second.AddColumn(new TableColumn("[u]Foo[/]"));
|
||||
second.AddColumn(new TableColumn("[u]Bar[/]"));
|
||||
second.AddColumn(new TableColumn("[u]Baz[/]"));
|
||||
second.AddRow("Hello", "[red]World[/]", string.Empty);
|
||||
second.AddRow(first, new Text("Whaaat"), new Text("Lolz"));
|
||||
second.AddRow("[blue]Hej[/]", "[yellow]Världen[/]", string.Empty);
|
||||
|
||||
var table = new Table().Border(TableBorder.Rounded);
|
||||
table.AddColumn(new TableColumn(new Panel("[u]ABC[/]").BorderColor(Color.Red)));
|
||||
table.AddColumn(new TableColumn(new Panel("[u]DEF[/]").BorderColor(Color.Green)));
|
||||
table.AddColumn(new TableColumn(new Panel("[u]GHI[/]").BorderColor(Color.Blue)));
|
||||
table.AddRow(new Text("Hello").Centered(), new Markup("[red]World[/]"), Text.Empty);
|
||||
table.AddRow(second, new Text("Whaat"), new Text("Lol").RightAligned());
|
||||
table.AddRow(new Markup("[blue]Hej[/]"), new Markup("[yellow]Världen[/]"), Text.Empty);
|
||||
|
||||
// When
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(12);
|
||||
console.Lines[00].ShouldBe("╭───────┬───────┬───────╮");
|
||||
console.Lines[01].ShouldBe("│ ┌───┐ │ ┌───┐ │ ┌───┐ │");
|
||||
console.Lines[02].ShouldBe("│ │ A │ │ │ D │ │ │ G │ │");
|
||||
console.Lines[03].ShouldBe("│ │ B │ │ │ E │ │ │ H │ │");
|
||||
console.Lines[04].ShouldBe("│ │ C │ │ │ F │ │ │ I │ │");
|
||||
console.Lines[05].ShouldBe("│ └───┘ │ └───┘ │ └───┘ │");
|
||||
console.Lines[06].ShouldBe("├───────┼───────┼───────┤");
|
||||
console.Lines[07].ShouldBe("│ Hello │ World │ │");
|
||||
console.Lines[08].ShouldBe("│ … │ Whaat │ Lol │");
|
||||
console.Lines[09].ShouldBe("│ Hej │ Värld │ │");
|
||||
console.Lines[10].ShouldBe("│ │ en │ │");
|
||||
console.Lines[11].ShouldBe("╰───────┴───────┴───────╯");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Render_Table_With_Title_And_Caption_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var table = new Table { Border = TableBorder.Rounded };
|
||||
table.Title = new TableTitle("Hello World");
|
||||
table.Caption = new TableTitle("Goodbye World");
|
||||
table.AddColumns("Foo", "Bar", "Baz");
|
||||
table.AddRow("Qux", "Corgi", "Waldo");
|
||||
table.AddRow("Grault", "Garply", "Fred");
|
||||
|
||||
// When
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe(" Hello World ");
|
||||
console.Lines[1].ShouldBe("╭────────┬────────┬───────╮");
|
||||
console.Lines[2].ShouldBe("│ Foo │ Bar │ Baz │");
|
||||
console.Lines[3].ShouldBe("├────────┼────────┼───────┤");
|
||||
console.Lines[4].ShouldBe("│ Qux │ Corgi │ Waldo │");
|
||||
console.Lines[5].ShouldBe("│ Grault │ Garply │ Fred │");
|
||||
console.Lines[6].ShouldBe("╰────────┴────────┴───────╯");
|
||||
console.Lines[7].ShouldBe(" Goodbye World ");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Left_Align_Table_With_Title_And_Caption_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var table = new Table { Border = TableBorder.Rounded };
|
||||
table.LeftAligned();
|
||||
table.Title = new TableTitle("Hello World");
|
||||
table.Caption = new TableTitle("Goodbye World");
|
||||
table.AddColumns("Foo", "Bar", "Baz");
|
||||
table.AddRow("Qux", "Corgi", "Waldo");
|
||||
table.AddRow("Grault", "Garply", "Fred");
|
||||
|
||||
// When
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe(" Hello World ");
|
||||
console.Lines[1].ShouldBe("╭────────┬────────┬───────╮");
|
||||
console.Lines[2].ShouldBe("│ Foo │ Bar │ Baz │");
|
||||
console.Lines[3].ShouldBe("├────────┼────────┼───────┤");
|
||||
console.Lines[4].ShouldBe("│ Qux │ Corgi │ Waldo │");
|
||||
console.Lines[5].ShouldBe("│ Grault │ Garply │ Fred │");
|
||||
console.Lines[6].ShouldBe("╰────────┴────────┴───────╯");
|
||||
console.Lines[7].ShouldBe(" Goodbye World ");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Center_Table_With_Title_And_Caption_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var table = new Table { Border = TableBorder.Rounded };
|
||||
table.Centered();
|
||||
table.Title = new TableTitle("Hello World");
|
||||
table.Caption = new TableTitle("Goodbye World");
|
||||
table.AddColumns("Foo", "Bar", "Baz");
|
||||
table.AddRow("Qux", "Corgi", "Waldo");
|
||||
table.AddRow("Grault", "Garply", "Fred");
|
||||
|
||||
// When
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe(" Hello World ");
|
||||
console.Lines[1].ShouldBe(" ╭────────┬────────┬───────╮ ");
|
||||
console.Lines[2].ShouldBe(" │ Foo │ Bar │ Baz │ ");
|
||||
console.Lines[3].ShouldBe(" ├────────┼────────┼───────┤ ");
|
||||
console.Lines[4].ShouldBe(" │ Qux │ Corgi │ Waldo │ ");
|
||||
console.Lines[5].ShouldBe(" │ Grault │ Garply │ Fred │ ");
|
||||
console.Lines[6].ShouldBe(" ╰────────┴────────┴───────╯ ");
|
||||
console.Lines[7].ShouldBe(" Goodbye World ");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Right_Align_Table_With_Title_And_Caption_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new PlainConsole(width: 80);
|
||||
var table = new Table { Border = TableBorder.Rounded };
|
||||
table.RightAligned();
|
||||
table.Title = new TableTitle("Hello World");
|
||||
table.Caption = new TableTitle("Goodbye World");
|
||||
table.AddColumns("Foo", "Bar", "Baz");
|
||||
table.AddRow("Qux", "Corgi", "Waldo");
|
||||
table.AddRow("Grault", "Garply", "Fred");
|
||||
|
||||
// When
|
||||
console.Render(table);
|
||||
|
||||
// Then
|
||||
console.Lines.Count.ShouldBe(8);
|
||||
console.Lines[0].ShouldBe(" Hello World ");
|
||||
console.Lines[1].ShouldBe(" ╭────────┬────────┬───────╮");
|
||||
console.Lines[2].ShouldBe(" │ Foo │ Bar │ Baz │");
|
||||
console.Lines[3].ShouldBe(" ├────────┼────────┼───────┤");
|
||||
console.Lines[4].ShouldBe(" │ Qux │ Corgi │ Waldo │");
|
||||
console.Lines[5].ShouldBe(" │ Grault │ Garply │ Fred │");
|
||||
console.Lines[6].ShouldBe(" ╰────────┴────────┴───────╯");
|
||||
console.Lines[7].ShouldBe(" Goodbye World ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace Spectre.Console.Tests.Unit
|
||||
// Given
|
||||
var console = new PlainConsole(14);
|
||||
var text = new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar qux")
|
||||
.SetOverflow(overflow);
|
||||
.Overflow(overflow);
|
||||
|
||||
// When
|
||||
console.Render(text);
|
||||
|
||||
@@ -35,6 +35,23 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Links", "..\examples\Links\
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Emojis", "..\examples\Emojis\Emojis.csproj", "{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exceptions", "..\examples\Exceptions\Exceptions.csproj", "{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub", "GitHub", "{C3E2CB5C-1517-4C75-B59A-93D4E22BEC8D}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\.github\workflows\ci.yaml = ..\.github\workflows\ci.yaml
|
||||
..\.github\workflows\docs.yaml = ..\.github\workflows\docs.yaml
|
||||
..\.github\workflows\publish.yaml = ..\.github\workflows\publish.yaml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Calendars", "..\examples\Calendars\Calendars.csproj", "{57691C7D-683D-46E6-AA4F-57A8C5F65D25}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rules", "..\examples\Rules\Rules.csproj", "{8622A261-02C6-40CA-9797-E3F01ED87D6B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cursor", "..\examples\Cursor\Cursor.csproj", "{75C608C3-ABB4-4168-A229-7F8250B946D1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Prompt", "..\examples\Prompt\Prompt.csproj", "{6351C70F-F368-46DB-BAED-9B87CCD69353}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -177,6 +194,66 @@ Global
|
||||
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|x64.Build.0 = Release|Any CPU
|
||||
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|x86.Build.0 = Release|Any CPU
|
||||
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Release|x64.Build.0 = Release|Any CPU
|
||||
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32}.Release|x86.Build.0 = Release|Any CPU
|
||||
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Release|x64.Build.0 = Release|Any CPU
|
||||
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{57691C7D-683D-46E6-AA4F-57A8C5F65D25}.Release|x86.Build.0 = Release|Any CPU
|
||||
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8622A261-02C6-40CA-9797-E3F01ED87D6B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Release|x64.Build.0 = Release|Any CPU
|
||||
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{75C608C3-ABB4-4168-A229-7F8250B946D1}.Release|x86.Build.0 = Release|Any CPU
|
||||
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|x64.Build.0 = Release|Any CPU
|
||||
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{6351C70F-F368-46DB-BAED-9B87CCD69353}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -191,6 +268,12 @@ Global
|
||||
{094245E6-4C94-485D-B5AC-3153E878B112} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||
{6AF8C93B-AA41-4F44-8B1B-B8D166576174} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||
{90C081A7-7C1D-4A4A-82B6-8FF473C3EA32} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||
{C3E2CB5C-1517-4C75-B59A-93D4E22BEC8D} = {20595AD4-8D75-4AF8-B6BC-9C38C160423F}
|
||||
{57691C7D-683D-46E6-AA4F-57A8C5F65D25} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||
{8622A261-02C6-40CA-9797-E3F01ED87D6B} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||
{75C608C3-ABB4-4168-A229-7F8250B946D1} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||
{6351C70F-F368-46DB-BAED-9B87CCD69353} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {5729B071-67A0-48FB-8B1B-275E6822086C}
|
||||
|
||||
30
src/Spectre.Console/AnsiConsole.Exceptions.cs
Normal file
30
src/Spectre.Console/AnsiConsole.Exceptions.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes an exception to the console.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to write to the console.</param>
|
||||
/// <param name="format">The exception format options.</param>
|
||||
public static void WriteException(Exception exception, ExceptionFormats format = ExceptionFormats.Default)
|
||||
{
|
||||
Console.WriteException(exception, format);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an exception to the console.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to write to the console.</param>
|
||||
/// <param name="settings">The exception settings.</param>
|
||||
public static void WriteException(Exception exception, ExceptionSettings settings)
|
||||
{
|
||||
Console.WriteException(exception, settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/Spectre.Console/AnsiConsole.Prompt.cs
Normal file
47
src/Spectre.Console/AnsiConsole.Prompt.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// A console capable of writing ANSI escape sequences.
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays a prompt to the user.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The prompt result type.</typeparam>
|
||||
/// <param name="prompt">The prompt to display.</param>
|
||||
/// <returns>The prompt input result.</returns>
|
||||
public static T Prompt<T>(IPrompt<T> prompt)
|
||||
{
|
||||
if (prompt is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(prompt));
|
||||
}
|
||||
|
||||
return prompt.Show(Console);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a prompt to the user.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The prompt result type.</typeparam>
|
||||
/// <param name="prompt">The prompt markup text.</param>
|
||||
/// <returns>The prompt input result.</returns>
|
||||
public static T Ask<T>(string prompt)
|
||||
{
|
||||
return new TextPrompt<T>(prompt).Show(Console);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a prompt with two choices, yes or no.
|
||||
/// </summary>
|
||||
/// <param name="prompt">The prompt markup text.</param>
|
||||
/// <returns><c>true</c> if the user selected "yes", otherwise <c>false</c>.</returns>
|
||||
public static bool Confirm(string prompt)
|
||||
{
|
||||
return new ConfirmationPrompt(prompt).Show(Console);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,3 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Spectre.Console.Internal;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
@@ -9,9 +5,6 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
private static ConsoleColor _defaultForeground;
|
||||
private static ConsoleColor _defaultBackground;
|
||||
|
||||
internal static Style CurrentStyle { get; private set; } = Style.Plain;
|
||||
internal static bool Created { get; private set; }
|
||||
|
||||
@@ -21,7 +14,7 @@ namespace Spectre.Console
|
||||
public static Color Foreground
|
||||
{
|
||||
get => CurrentStyle.Foreground;
|
||||
set => CurrentStyle = CurrentStyle.WithForeground(value);
|
||||
set => CurrentStyle = CurrentStyle.Foreground(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -30,7 +23,7 @@ namespace Spectre.Console
|
||||
public static Color Background
|
||||
{
|
||||
get => CurrentStyle.Background;
|
||||
set => CurrentStyle = CurrentStyle.WithBackground(value);
|
||||
set => CurrentStyle = CurrentStyle.Background(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -39,21 +32,7 @@ namespace Spectre.Console
|
||||
public static Decoration Decoration
|
||||
{
|
||||
get => CurrentStyle.Decoration;
|
||||
set => CurrentStyle = CurrentStyle.WithDecoration(value);
|
||||
}
|
||||
|
||||
internal static void Initialize(TextWriter? @out)
|
||||
{
|
||||
if (@out?.IsStandardOut() ?? false)
|
||||
{
|
||||
Foreground = _defaultForeground = System.Console.ForegroundColor;
|
||||
Background = _defaultBackground = System.Console.BackgroundColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
Foreground = _defaultForeground = Color.Silver;
|
||||
Background = _defaultBackground = Color.Black;
|
||||
}
|
||||
set => CurrentStyle = CurrentStyle.Decoration(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -78,8 +57,7 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public static void ResetColors()
|
||||
{
|
||||
Foreground = _defaultForeground;
|
||||
Background = _defaultBackground;
|
||||
CurrentStyle = Style.Plain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace Spectre.Console
|
||||
ColorSystem = ColorSystemSupport.Detect,
|
||||
Out = System.Console.Out,
|
||||
});
|
||||
Initialize(System.Console.Out);
|
||||
Created = true;
|
||||
return console;
|
||||
});
|
||||
@@ -28,6 +27,11 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public static IAnsiConsole Console => _recorder ?? _console.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IAnsiConsoleCursor"/>.
|
||||
/// </summary>
|
||||
public static IAnsiConsoleCursor Cursor => _recorder?.Cursor ?? _console.Value.Cursor;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the console's capabilities.
|
||||
/// </summary>
|
||||
@@ -57,7 +61,7 @@ namespace Spectre.Console
|
||||
/// <returns>An <see cref="IAnsiConsole"/> instance.</returns>
|
||||
public static IAnsiConsole Create(AnsiConsoleSettings settings)
|
||||
{
|
||||
return AnsiConsoleBuilder.Build(settings);
|
||||
return BackendBuilder.Build(settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console
|
||||
@@ -11,70 +7,16 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public abstract partial class BoxBorder
|
||||
{
|
||||
private readonly Dictionary<BoxBorderPart, string> _lookup;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the safe border for this border or <c>null</c> if none exist.
|
||||
/// </summary>
|
||||
public virtual BoxBorder? SafeBorder { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BoxBorder"/> class.
|
||||
/// </summary>
|
||||
protected BoxBorder()
|
||||
{
|
||||
_lookup = Initialize();
|
||||
}
|
||||
|
||||
private Dictionary<BoxBorderPart, string> Initialize()
|
||||
{
|
||||
var lookup = new Dictionary<BoxBorderPart, string>();
|
||||
foreach (BoxBorderPart? part in Enum.GetValues(typeof(BoxBorderPart)))
|
||||
{
|
||||
if (part == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var text = GetBorderPart(part.Value);
|
||||
if (text.Length > 1)
|
||||
{
|
||||
throw new InvalidOperationException("A box part cannot contain more than one character.");
|
||||
}
|
||||
|
||||
lookup.Add(part.Value, GetBorderPart(part.Value));
|
||||
}
|
||||
|
||||
return lookup;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the string representation of a specific border part.
|
||||
/// </summary>
|
||||
/// <param name="part">The part to get a string representation for.</param>
|
||||
/// <param name="count">The number of repetitions.</param>
|
||||
/// <returns>A string representation of the specified border part.</returns>
|
||||
public string GetPart(BoxBorderPart part, int count)
|
||||
{
|
||||
// TODO: This need some optimization...
|
||||
return string.Join(string.Empty, Enumerable.Repeat(GetBorderPart(part)[0], count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the string representation of a specific border part.
|
||||
/// </summary>
|
||||
/// <param name="part">The part to get a string representation for.</param>
|
||||
/// <returns>A string representation of the specified border part.</returns>
|
||||
public string GetPart(BoxBorderPart part)
|
||||
{
|
||||
return _lookup[part].ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the character representing the specified border part.
|
||||
/// Gets the string representation of the specified border part.
|
||||
/// </summary>
|
||||
/// <param name="part">The part to get the character representation for.</param>
|
||||
/// <returns>A character representation of the specified border part.</returns>
|
||||
protected abstract string GetBorderPart(BoxBorderPart part);
|
||||
public abstract string GetPart(BoxBorderPart part);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,9 +245,37 @@ namespace Spectre.Console
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the color to a markup string.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="string"/> representing the color as markup.</returns>
|
||||
public string ToMarkup()
|
||||
{
|
||||
if (IsDefault)
|
||||
{
|
||||
return "default";
|
||||
}
|
||||
|
||||
if (Number != null)
|
||||
{
|
||||
var name = ColorTable.GetName(Number.Value);
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return string.Format(CultureInfo.InvariantCulture, "#{0:X2}{1:X2}{2:X2}", R, G, B);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
if (IsDefault)
|
||||
{
|
||||
return "default";
|
||||
}
|
||||
|
||||
if (Number != null)
|
||||
{
|
||||
var name = ColorTable.GetName(Number.Value);
|
||||
|
||||
62
src/Spectre.Console/ConfirmationPrompt.cs
Normal file
62
src/Spectre.Console/ConfirmationPrompt.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// A prompt that is answered with a yes or no.
|
||||
/// </summary>
|
||||
public sealed class ConfirmationPrompt : IPrompt<bool>
|
||||
{
|
||||
private readonly string _prompt;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character that represents "yes".
|
||||
/// </summary>
|
||||
public char Yes { get; set; } = 'y';
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character that represents "no".
|
||||
/// </summary>
|
||||
public char No { get; set; } = 'n';
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the message for invalid choices.
|
||||
/// </summary>
|
||||
public string InvalidChoiceMessage { get; set; } = "[red]Please select one of the available options[/]";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not
|
||||
/// choices should be shown.
|
||||
/// </summary>
|
||||
public bool ShowChoices { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not
|
||||
/// default values should be shown.
|
||||
/// </summary>
|
||||
public bool ShowDefaultValue { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConfirmationPrompt"/> class.
|
||||
/// </summary>
|
||||
/// <param name="prompt">The prompt markup text.</param>
|
||||
public ConfirmationPrompt(string prompt)
|
||||
{
|
||||
_prompt = prompt ?? throw new System.ArgumentNullException(nameof(prompt));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Show(IAnsiConsole console)
|
||||
{
|
||||
var prompt = new TextPrompt<char>(_prompt)
|
||||
.InvalidChoiceMessage(InvalidChoiceMessage)
|
||||
.ValidationErrorMessage(InvalidChoiceMessage)
|
||||
.ShowChoices(ShowChoices)
|
||||
.ShowDefaultValue(ShowDefaultValue)
|
||||
.DefaultValue(Yes)
|
||||
.AddChoice(Yes)
|
||||
.AddChoice(No);
|
||||
|
||||
var result = prompt.Show(console);
|
||||
return result == Yes;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
src/Spectre.Console/CursorDirection.cs
Normal file
28
src/Spectre.Console/CursorDirection.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents cursor direction.
|
||||
/// </summary>
|
||||
public enum CursorDirection
|
||||
{
|
||||
/// <summary>
|
||||
/// Up
|
||||
/// </summary>
|
||||
Up,
|
||||
|
||||
/// <summary>
|
||||
/// Down
|
||||
/// </summary>
|
||||
Down,
|
||||
|
||||
/// <summary>
|
||||
/// Left
|
||||
/// </summary>
|
||||
Left,
|
||||
|
||||
/// <summary>
|
||||
/// Right
|
||||
/// </summary>
|
||||
Right,
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Spectre.Console
|
||||
@@ -8,6 +10,35 @@ namespace Spectre.Console
|
||||
public static partial class Emoji
|
||||
{
|
||||
private static readonly Regex _emojiCode = new Regex(@"(:(\S*?):)", RegexOptions.Compiled);
|
||||
private static readonly Dictionary<string, string> _remappings;
|
||||
|
||||
static Emoji()
|
||||
{
|
||||
_remappings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remaps a specific emoji tag with a new emoji.
|
||||
/// </summary>
|
||||
/// <param name="tag">The emoji tag.</param>
|
||||
/// <param name="emoji">The emoji.</param>
|
||||
public static void Remap(string tag, string emoji)
|
||||
{
|
||||
if (tag is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(tag));
|
||||
}
|
||||
|
||||
if (emoji is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(emoji));
|
||||
}
|
||||
|
||||
tag = tag.TrimStart(':').TrimEnd(':');
|
||||
emoji = emoji.TrimStart(':').TrimEnd(':');
|
||||
|
||||
_remappings[tag] = emoji;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces emoji markup with corresponding unicode characters.
|
||||
@@ -16,7 +47,23 @@ namespace Spectre.Console
|
||||
/// <returns>A string with emoji codes replaced with actual emoji.</returns>
|
||||
public static string Replace(string value)
|
||||
{
|
||||
static string ReplaceEmoji(Match match) => _emojis[match.Groups[2].Value];
|
||||
static string ReplaceEmoji(Match match)
|
||||
{
|
||||
var key = match.Groups[2].Value;
|
||||
|
||||
if (_remappings.Count > 0 && _remappings.TryGetValue(key, out var remappedEmoji))
|
||||
{
|
||||
return remappedEmoji;
|
||||
}
|
||||
|
||||
if (_emojis.TryGetValue(key, out var emoji))
|
||||
{
|
||||
return emoji;
|
||||
}
|
||||
|
||||
return match.Value;
|
||||
}
|
||||
|
||||
return _emojiCode.Replace(value, ReplaceEmoji);
|
||||
}
|
||||
}
|
||||
|
||||
41
src/Spectre.Console/ExceptionFormat.cs
Normal file
41
src/Spectre.Console/ExceptionFormat.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents how an exception is formatted.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ExceptionFormats
|
||||
{
|
||||
/// <summary>
|
||||
/// The default formatting.
|
||||
/// </summary>
|
||||
Default = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not paths should be shortened.
|
||||
/// </summary>
|
||||
ShortenPaths = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not types should be shortened.
|
||||
/// </summary>
|
||||
ShortenTypes = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not methods should be shortened.
|
||||
/// </summary>
|
||||
ShortenMethods = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to show paths as links in the terminal.
|
||||
/// </summary>
|
||||
ShowLinks = 8,
|
||||
|
||||
/// <summary>
|
||||
/// Shortens everything that can be shortened.
|
||||
/// </summary>
|
||||
ShortenEverything = ShortenMethods | ShortenTypes | ShortenPaths,
|
||||
}
|
||||
}
|
||||
27
src/Spectre.Console/ExceptionSettings.cs
Normal file
27
src/Spectre.Console/ExceptionSettings.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception settings.
|
||||
/// </summary>
|
||||
public sealed class ExceptionSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the exception format.
|
||||
/// </summary>
|
||||
public ExceptionFormats Format { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exception style.
|
||||
/// </summary>
|
||||
public ExceptionStyle Style { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExceptionSettings"/> class.
|
||||
/// </summary>
|
||||
public ExceptionSettings()
|
||||
{
|
||||
Format = ExceptionFormats.Default;
|
||||
Style = new ExceptionStyle();
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user