Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a977fdadff | ||
|
|
8261b25e5c | ||
|
|
0e0f4b4220 | ||
|
|
3a593857c8 | ||
|
|
11e192e750 | ||
|
|
8901450283 | ||
|
|
0796bad598 | ||
|
|
5b553a4106 | ||
|
|
1bb0b9ccc6 | ||
|
|
9ad5f2daeb | ||
|
|
1f211d3e1f | ||
|
|
87e6b42409 | ||
|
|
1aa958ced3 | ||
|
|
4bfb24bfcb | ||
|
|
b136d0299b | ||
|
|
179e243214 | ||
|
|
c6210f75ca | ||
|
|
b81739567b | ||
|
|
5cf41725a5 | ||
|
|
f561d71e4e | ||
|
|
e71db7f78c | ||
|
|
79742ce9e3 | ||
|
|
241423dd16 | ||
|
|
4e2251fd62 | ||
|
|
0ae419326d | ||
|
|
0bbf9b81a9 | ||
|
|
041aea2ae5 | ||
|
|
f417e297cd | ||
|
|
5045b8b959 | ||
|
|
7dccb310f3 | ||
|
|
1cf30f62fc | ||
|
|
e280b82679 | ||
|
|
6932c95731 | ||
|
|
ee305702e8 | ||
|
|
63abcc92ba | ||
|
|
acf01e056f | ||
|
|
501db5d287 | ||
|
|
cbed41e637 | ||
|
|
3c504155bc | ||
|
|
ae32785f21 | ||
|
|
c61e386440 | ||
|
|
b7cd7dd53e | ||
|
|
3e1251b86a |
28
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Information**
|
||||||
|
- OS: [eg Windows/Linux/MacOS]
|
||||||
|
- Version: [e.g. 0.33.0]
|
||||||
|
- Terminal: [e.g Windows Terminal]
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior.
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: enhancement
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
9
.github/workflows/ci.yaml
vendored
@@ -69,14 +69,7 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
dotnet tool restore
|
dotnet tool restore
|
||||||
dotnet example info
|
dotnet example --all
|
||||||
dotnet example tables
|
|
||||||
dotnet example grids
|
|
||||||
dotnet example panels
|
|
||||||
dotnet example colors
|
|
||||||
dotnet example emojis
|
|
||||||
dotnet example exceptions
|
|
||||||
dotnet example calendars
|
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
1
.gitignore
vendored
@@ -79,7 +79,6 @@ x64/
|
|||||||
_ReSharper*
|
_ReSharper*
|
||||||
|
|
||||||
# NCrunch
|
# NCrunch
|
||||||
*.ncrunch*
|
|
||||||
.*crunch*.local.xml
|
.*crunch*.local.xml
|
||||||
_NCrunch_*
|
_NCrunch_*
|
||||||
|
|
||||||
|
|||||||
161
CONTRIBUTING.md
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
# Contribution Guidelines
|
||||||
|
|
||||||
|
* [Prerequisites](#prerequisites)
|
||||||
|
* [Definition of trivial contributions](#definition-of-trivial-contributions)
|
||||||
|
* [Code](#code)
|
||||||
|
* [Code style](#code-style)
|
||||||
|
* [Dependencies](#dependencies)
|
||||||
|
* [Unit tests](#unit-tests)
|
||||||
|
* [Contributing process](#contributing-process)
|
||||||
|
* [Get buyoff or find open community issues or features](#get-buyoff-or-find-open-community-issues-or-features)
|
||||||
|
* [Set up your environment](#Set-up-your-environment)
|
||||||
|
* [Prepare commits](#prepare-commits)
|
||||||
|
* [Submit pull request](#Submit-pull-request)
|
||||||
|
* [Respond to feedback on pull request](#respond-to-feedback-on-pull-request)
|
||||||
|
* [Other general information](#other-general-information)
|
||||||
|
* [Acknowledgement](#acknowledgement)
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
By contributing to Spectre.Console, you assert that:
|
||||||
|
|
||||||
|
* The contribution is your own original work.
|
||||||
|
* You have the right to assign the copyright for the work (it is not owned by your employer, or
|
||||||
|
you have been given copyright assignment in writing).
|
||||||
|
* You [license](https://github.com/spectresystems/spectre.console/blob/main/LICENSE) the contribution under the terms applied to the rest of the Spectre.Console project.
|
||||||
|
* You agree to follow the [code of conduct](https://github.com/spectresystems/spectre.console/blob/main/CODE_OF_CONDUCT.md).
|
||||||
|
|
||||||
|
## Definition of trivial contributions
|
||||||
|
It's hard to define what is a trivial contribution. Sometimes even a 1 character change can be considered significant.
|
||||||
|
Unfortunately because it can be subjective, the decision on what is trivial comes from the maintainers of the project
|
||||||
|
and not from folks contributing to the project.
|
||||||
|
|
||||||
|
What is generally considered trivial:
|
||||||
|
|
||||||
|
* Fixing a typo.
|
||||||
|
* Documentation changes.
|
||||||
|
|
||||||
|
## Code
|
||||||
|
### Code style
|
||||||
|
|
||||||
|
Normal .NET coding guidelines apply.
|
||||||
|
See the [Framework Design Guidelines](https://msdn.microsoft.com/en-us/library/ms229042%28v=vs.110%29.aspx) for more information.
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
The assembly `Spectre.Console` should have no dependencies except the .NET BCL library.
|
||||||
|
|
||||||
|
### Unit tests
|
||||||
|
|
||||||
|
Make sure to run all unit tests before creating a pull request.
|
||||||
|
Any new code should also have reasonable unit test coverage.
|
||||||
|
|
||||||
|
## Contributing process
|
||||||
|
### Get buyoff or find open community issues or features
|
||||||
|
|
||||||
|
* Through GitHub, or through the [GitHub discussions](https://github.com/spectresystems/spectre.console/discussions) (preferred),
|
||||||
|
you talk about a feature you would like to see (or a bug), and why it should be in Spectre.Console.
|
||||||
|
* If approved through the GitHub discussions, ensure an accompanying GitHub issue is created with
|
||||||
|
information and a link back to the discussion.
|
||||||
|
* Once you get a nod from someone in the Spectre.Console Team, you can start on the feature.
|
||||||
|
* Alternatively, if a feature is on the issues list with the
|
||||||
|
[Up For Grabs](https://github.com/spectresystems/spectre.console/labels/up-for-grabs) label,
|
||||||
|
it is open for a community member (contributor) to patch. You should comment that you are signing up for it on
|
||||||
|
the issue so someone else doesn't also sign up for the work.
|
||||||
|
|
||||||
|
### Set up your environment
|
||||||
|
|
||||||
|
* You create, or update, a fork of `spectresystems/spectre.console` under your GitHub account.
|
||||||
|
* From there you create a branch named specific to the feature.
|
||||||
|
* In the branch you do work specific to the feature.
|
||||||
|
* Please also observe the following:
|
||||||
|
* No reformatting
|
||||||
|
* No changing files that are not specific to the feature.
|
||||||
|
* More covered below in the **Prepare commits** section.
|
||||||
|
* Test your changes and please help us out by updating and implementing some automated tests.
|
||||||
|
It is recommended that all contributors spend some time looking over the tests in the source code.
|
||||||
|
You can't go wrong emulating one of the existing tests and then changing it specific to the behavior you are testing.
|
||||||
|
* Please do not update your branch from the main branch unless we ask you to. See the responding to feedback section below.
|
||||||
|
|
||||||
|
### Prepare commits
|
||||||
|
This section serves to help you understand what makes a good commit.
|
||||||
|
|
||||||
|
A commit should observe the following:
|
||||||
|
|
||||||
|
* A commit is a small logical unit that represents a change.
|
||||||
|
* Should include new or changed tests relevant to the changes you are making.
|
||||||
|
* No unnecessary whitespace. Check for whitespace with `git diff --check` and `git diff --cached --check` before commit.
|
||||||
|
* You can stage parts of a file for commit.
|
||||||
|
|
||||||
|
### Submit pull request
|
||||||
|
Prerequisites:
|
||||||
|
|
||||||
|
* You are making commits in a feature branch.
|
||||||
|
* All code should compile without errors or warnings.
|
||||||
|
* All tests should be passing.
|
||||||
|
|
||||||
|
Submitting PR:
|
||||||
|
|
||||||
|
* Once you feel it is ready, submit the pull request to the `spectresystems/spectre.console` repository against the `main` branch
|
||||||
|
unless specifically requested to submit it against another branch.
|
||||||
|
* In the case of a larger change that is going to require more discussion,
|
||||||
|
please submit a PR sooner. Waiting until you are ready may mean more changes than you are
|
||||||
|
interested in if the changes are taking things in a direction the maintainers do not want to go.
|
||||||
|
* In the pull request, outline what you did and point to specific conversations (as in URLs)
|
||||||
|
and issues that you are resolving. This is a tremendous help for us in evaluation and acceptance.
|
||||||
|
* Once the pull request is in, please do not delete the branch or close the pull request
|
||||||
|
(unless something is wrong with it).
|
||||||
|
* One of the Spectre.Console team members, or one of the maintainers, will evaluate it within a
|
||||||
|
reasonable time period (which is to say usually within 1-3 weeks). Some things get evaluated
|
||||||
|
faster or fast tracked. We are human and we have active lives outside of open source so don't
|
||||||
|
fret if you haven't seen any activity on your pull request within a month or two.
|
||||||
|
We don't have a Service Level Agreement (SLA) for pull requests.
|
||||||
|
Just know that we will evaluate your pull request.
|
||||||
|
|
||||||
|
### Respond to feedback on pull request
|
||||||
|
|
||||||
|
We may have feedback for you to fix or change some things. We generally like to see that pushed against
|
||||||
|
the same topic branch (it will automatically update the Pull Request). You can also fix/squash/rebase
|
||||||
|
commits and push the same topic branch with `--force` (it's generally acceptable to do this on topic
|
||||||
|
branches not in the main repository, it is generally unacceptable and should be avoided at all costs
|
||||||
|
against the main repository).
|
||||||
|
|
||||||
|
If we have comments or questions when we do evaluate it and receive no response, it will probably
|
||||||
|
lessen the chance of getting accepted. Eventually, this means it will be closed if it is not accepted.
|
||||||
|
Please know this doesn't mean we don't value your contribution, just that things go stale. If in the
|
||||||
|
future you want to pick it back up, feel free to address our concerns/questions/feedback and reopen
|
||||||
|
the issue/open a new PR (referencing old one).
|
||||||
|
|
||||||
|
Sometimes we may need you to rebase your commit against the latest code before we can review it further.
|
||||||
|
If this happens, you can do the following:
|
||||||
|
|
||||||
|
* `git fetch upstream` (upstream remote would be `spectresystems/spectre.console`)
|
||||||
|
* `git checkout main`
|
||||||
|
* `git rebase upstream/main`
|
||||||
|
* `git checkout your-branch`
|
||||||
|
* `git rebase main`
|
||||||
|
* Fix any merge conflicts
|
||||||
|
* `git push origin your-branch` (origin would be your GitHub repo or `your-github-username/spectre.console` in this case).
|
||||||
|
You may need to `git push origin your-branch --force` to get the commits pushed.
|
||||||
|
This is generally acceptable with topic branches not in the mainstream repository.
|
||||||
|
|
||||||
|
The only reasons a pull request should be closed and resubmitted are as follows:
|
||||||
|
|
||||||
|
* When the pull request is targeting the wrong branch (this doesn't happen as often).
|
||||||
|
* When there are updates made to the original by someone other than the original contributor.
|
||||||
|
Then the old branch is closed with a note on the newer branch this supersedes #github_number.
|
||||||
|
|
||||||
|
## Other general information
|
||||||
|
If you reformat code or hit core functionality without an approval from a person on the Spectre.Console Team,
|
||||||
|
it's likely that no matter how awesome it looks afterwards, it will probably not get accepted.
|
||||||
|
Reformatting code makes it harder for us to evaluate exactly what was changed.
|
||||||
|
|
||||||
|
If you do these things, it will be make evaluation and acceptance easy.
|
||||||
|
Now if you stray outside of the guidelines we have above, it doesn't mean we are going to ignore
|
||||||
|
your pull request. It will just make things harder for us.
|
||||||
|
Harder for us roughly translates to a longer SLA for your pull request.
|
||||||
|
|
||||||
|
## Acknowledgement
|
||||||
|
|
||||||
|
This contribution guide was taken from the [Chocolatey project](https://chocolatey.org/)
|
||||||
|
with permission and was edited to follow Spectre.Console's conventions and processes.
|
||||||
65
README.zh.md
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# `Spectre.Console`
|
||||||
|
|
||||||
|
_[](https://www.nuget.org/packages/spectre.console)_
|
||||||
|
|
||||||
|
`Spectre.Console`是一个 .NET 5/.NET Standard 2.0 的库,能让您在终端里更方便地生成精美的界面。
|
||||||
|
|
||||||
|
深受 [Rich](https://github.com/willmcgugan/rich) 这个优秀库的启发。
|
||||||
|
|
||||||
|
## 目录
|
||||||
|
|
||||||
|
1. [功能](#features)
|
||||||
|
2. [安装](#installing)
|
||||||
|
3. [文档](#documentation)
|
||||||
|
4. [例子](#examples)
|
||||||
|
5. [License](#license)
|
||||||
|
|
||||||
|
## 功能
|
||||||
|
|
||||||
|
* 编写时考虑到了单元测试。
|
||||||
|
* 支持 tables、grid、panel 和 [rich](https://github.com/willmcgugan/rich) 所支持的标记语言。
|
||||||
|
* 支持大部分的 SRG 参数,包括粗体、暗淡字、斜体、下划线、删除线和闪烁文本。
|
||||||
|
* 支持终端显示 3/4/8/24 位色。自动检测终端类型,自适应颜色范围。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 安装
|
||||||
|
|
||||||
|
最快的安装方式,就是用NuGet包管理直接安装Spectre.Console。
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
dotnet add package Spectre.Console
|
||||||
|
```
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
|
||||||
|
`Spectre.Console`的文档可以在这里查看
|
||||||
|
https://spectresystems.github.io/spectre.console/
|
||||||
|
|
||||||
|
## 例子
|
||||||
|
|
||||||
|
如果想直接运行`Spectre.Console`的例子,则需要安装[dotnet-example](https://github.com/patriksvensson/dotnet-example)工具。
|
||||||
|
|
||||||
|
```
|
||||||
|
> dotnet tool restore
|
||||||
|
```
|
||||||
|
|
||||||
|
然后你可以列出仓库里的所有例子:
|
||||||
|
|
||||||
|
```
|
||||||
|
> dotnet example
|
||||||
|
```
|
||||||
|
|
||||||
|
跑一个看看效果:
|
||||||
|
|
||||||
|
```
|
||||||
|
> dotnet example tables
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
版权所有 © Spectre Systems。
|
||||||
|
|
||||||
|
Spectre.Console 基于 MIT 协议提供。查看 LICENSE 文件了解更多信息。
|
||||||
|
|
||||||
|
* SixLabors.ImageSharp 的协议请查看 https://github.com/SixLabors/ImageSharp/blob/master/LICENSE
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
Title: Appendix
|
Title: Appendix
|
||||||
Order: 10
|
Order: 100
|
||||||
---
|
---
|
||||||
|
|
||||||
<h1>Sections</h1>
|
<h1>Sections</h1>
|
||||||
|
|||||||
43
docs/input/appendix/spinners.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
Title: Spinners
|
||||||
|
Order: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
For all available spinners, see https://jsfiddle.net/sindresorhus/2eLtsbey/embedded/result/
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
Spinners can be used with [Progress](xref:progress) and [Status](xref:status).
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
AnsiConsole.Status()
|
||||||
|
.Spinner(Spinner.Known.Star)
|
||||||
|
.Start("Thinking...", ctx => {
|
||||||
|
// Omitted
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
# Implementing a spinner
|
||||||
|
|
||||||
|
To implement your own spinner, all you have to do is
|
||||||
|
inherit from the `Spinner` base class.
|
||||||
|
|
||||||
|
In the example below, the spinner will alterate between
|
||||||
|
the characters `A`, `B` and `C` every 100 ms.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public sealed class MySpinner : Spinner
|
||||||
|
{
|
||||||
|
// The interval for each frame
|
||||||
|
public override TimeSpan Interval => TimeSpan.FromMilliseconds(100);
|
||||||
|
|
||||||
|
// Whether or not the spinner contains unicode characters
|
||||||
|
public override bool IsUnicode => false;
|
||||||
|
|
||||||
|
// The individual frames of the spinner
|
||||||
|
public override IReadOnlyList<string> Frames =>
|
||||||
|
new List<string>
|
||||||
|
{
|
||||||
|
"A", "B", "C",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
BIN
docs/input/assets/images/barchart.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
docs/input/assets/images/multiselection.gif
Normal file
|
After Width: | Height: | Size: 229 KiB |
BIN
docs/input/assets/images/progress.gif
Normal file
|
After Width: | Height: | Size: 164 KiB |
BIN
docs/input/assets/images/progress.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
docs/input/assets/images/progress_fallback.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
docs/input/assets/images/selection.gif
Normal file
|
After Width: | Height: | Size: 208 KiB |
BIN
docs/input/assets/images/status.gif
Normal file
|
After Width: | Height: | Size: 257 KiB |
BIN
docs/input/assets/images/tree.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
@@ -31,5 +31,4 @@ $(document).ready(function () {
|
|||||||
}; // keyup
|
}; // keyup
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
}); // ready
|
}); // ready
|
||||||
12
docs/input/cli/index.cshtml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Title: CLI
|
||||||
|
Order: 10
|
||||||
|
---
|
||||||
|
|
||||||
|
<h1>Sections</h1>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
@foreach (IDocument child in OutputPages.GetChildrenOf(Document))
|
||||||
|
{
|
||||||
|
<li>@Html.DocumentLink(child)</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
117
docs/input/cli/introduction.md
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
Title: Introduction
|
||||||
|
Order: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
`Spectre.Console.Cli` is a modern library for parsing command line arguments. While it's extremely
|
||||||
|
opinionated in what it does, it tries to follow established industry conventions, and draws
|
||||||
|
its inspiration from applications you use everyday.
|
||||||
|
|
||||||
|
# How does it work?
|
||||||
|
|
||||||
|
The underlying philosophy behind `Spectre.Console.Cli` is to rely on the .NET type system to
|
||||||
|
declare the commands, but tie everything together via composition.
|
||||||
|
|
||||||
|
Imagine the following command structure:
|
||||||
|
|
||||||
|
* dotnet *(executable)*
|
||||||
|
* add `[PROJECT]`
|
||||||
|
* package `<PACKAGE_NAME>` --version `<VERSION>`
|
||||||
|
* reference `<PROJECT_REFERENCE>`
|
||||||
|
|
||||||
|
For this I would like to implement the commands (the different levels in the tree that
|
||||||
|
executes something) separately from the settings (the options, flags and arguments),
|
||||||
|
which I want to be able to inherit from each other.
|
||||||
|
|
||||||
|
## Specify the settings
|
||||||
|
|
||||||
|
We start by creating some settings that represents the options, flags and arguments
|
||||||
|
that we want to act upon.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class AddSettings : CommandSettings
|
||||||
|
{
|
||||||
|
[CommandArgument(0, "[PROJECT]")]
|
||||||
|
public string Project { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AddPackageSettings : AddSettings
|
||||||
|
{
|
||||||
|
[CommandArgument(0, "<PACKAGE_NAME>")]
|
||||||
|
public string PackageName { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("-v|--version <VERSION>")]
|
||||||
|
public string Version { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AddReferenceSettings : AddSettings
|
||||||
|
{
|
||||||
|
[CommandArgument(0, "<PROJECT_REFERENCE>")]
|
||||||
|
public string ProjectReference { get; set; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Specify the commands
|
||||||
|
|
||||||
|
Now it's time to specify the commands that act on the settings we created
|
||||||
|
in the previous step.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class AddPackageCommand : Command<AddPackageSettings>
|
||||||
|
{
|
||||||
|
public override int Execute(AddPackageSettings settings, ILookup<string, string> remaining)
|
||||||
|
{
|
||||||
|
// Omitted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AddReferenceCommand : Command<AddReferenceSettings>
|
||||||
|
{
|
||||||
|
public override int Execute(AddReferenceSettings settings, ILookup<string, string> remaining)
|
||||||
|
{
|
||||||
|
// Omitted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Let's tie it together
|
||||||
|
|
||||||
|
Now when we have our commands and settings implemented, we can compose a command tree
|
||||||
|
that tells the parser how to interpret user input.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace MyApp
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static int Main(string[] args)
|
||||||
|
{
|
||||||
|
var app = new CommandApp();
|
||||||
|
|
||||||
|
app.Configure(config =>
|
||||||
|
{
|
||||||
|
config.AddBranch<AddSettings>("add", add =>
|
||||||
|
{
|
||||||
|
add.AddCommand<AddPackageCommand>("package");
|
||||||
|
add.AddCommand<AddReferenceCommand>("reference");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return app.Run(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# So why this way?
|
||||||
|
|
||||||
|
Now you might wonder, why do things like this? Well, for starters the different parts
|
||||||
|
of the application are separated, while still having the option to share things like options,
|
||||||
|
flags and arguments between them.
|
||||||
|
|
||||||
|
This make the resulting code very clean and easy to navigate, not to mention to unit test.
|
||||||
|
And most importantly at all, the type system guides me to do the right thing. I can't configure
|
||||||
|
commands in non-compatible ways, and if I want to add a new top-level `add-package` command
|
||||||
|
(or move the command completely), it's just a single line to change. This makes it easy to
|
||||||
|
experiment and makes the CLI experience a first class citizen of your application.
|
||||||
47
docs/input/cli/migration.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
Title: Migrate from Spectre.Cli
|
||||||
|
Order: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
The functionality in `Spectre.Cli` has been moved into the `Spectre.Console`
|
||||||
|
library. If you're using `Spectre.Cli`, you will need to migrate to ensure
|
||||||
|
that you get updates or fixes.
|
||||||
|
|
||||||
|
## 1. Remove Spectre.Cli NuGet package
|
||||||
|
|
||||||
|
Start with removing the `Spectre.Cli` package reference from your project(s).
|
||||||
|
|
||||||
|
```text
|
||||||
|
> dotnet remove package Spectre.Cli
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Add Spectre.Console NuGet package
|
||||||
|
|
||||||
|
Add the [Spectre.Console](https://www.nuget.org/packages/spectre.console) NuGet package to your project(s).
|
||||||
|
|
||||||
|
```text
|
||||||
|
> dotnet add package Spectre.Console
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Change using statements
|
||||||
|
|
||||||
|
Change all using statements from `Spectre.Cli`
|
||||||
|
to `Spectre.Console.CLi`.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- using Spectre.Cli;
|
||||||
|
+ using Spectre.Console.Cli;
|
||||||
|
```
|
||||||
|
|
||||||
|
# Breaking Changes
|
||||||
|
|
||||||
|
In the process of moving `Spectre.Cli`, there have been some minor breaking changes.
|
||||||
|
|
||||||
|
## Spectre.Cli.Exceptions namespace moved
|
||||||
|
|
||||||
|
All exceptions have been moved from the `Spectre.Cli.Exceptions` namespace to
|
||||||
|
the `Spectre.Console.Cli` namespace.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- using Spectre.Cli.Exceptions;
|
||||||
|
+ using Spectre.Console.Cli;
|
||||||
|
```
|
||||||
78
docs/input/progress.md
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
Title: Progress
|
||||||
|
Order: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
Spectre.Console can display information about long running tasks in the console.
|
||||||
|
|
||||||
|
<img src="assets/images/progress.png" style="max-width: 100%;margin-bottom:20px;">
|
||||||
|
|
||||||
|
If the current terminal isn't considered "interactive", such as when running
|
||||||
|
in a continuous integration system, or the terminal can't display
|
||||||
|
ANSI control sequence, any progress will be displayed in a simpler way.
|
||||||
|
|
||||||
|
<img src="assets/images/progress_fallback.png" style="max-width: 100%;">
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Synchronous
|
||||||
|
AnsiConsole.Progress()
|
||||||
|
.Start(ctx =>
|
||||||
|
{
|
||||||
|
// Define tasks
|
||||||
|
var task1 = ctx.AddTask("[green]Reticulating splines[/]");
|
||||||
|
var task2 = ctx.AddTask("[green]Folding space[/]");
|
||||||
|
|
||||||
|
while(!ctx.IsFinished)
|
||||||
|
{
|
||||||
|
task1.Increment(1.5);
|
||||||
|
task2.Increment(0.5);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Asynchronous progress
|
||||||
|
|
||||||
|
If you prefer to use async/await, you can use `StartAsync` instead of `Start`.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Asynchronous
|
||||||
|
await AnsiConsole.Progress()
|
||||||
|
.StartAsync(async ctx =>
|
||||||
|
{
|
||||||
|
// Define tasks
|
||||||
|
var task1 = ctx.AddTask("[green]Reticulating splines[/]");
|
||||||
|
var task2 = ctx.AddTask("[green]Folding space[/]");
|
||||||
|
|
||||||
|
while (!ctx.IsFinished)
|
||||||
|
{
|
||||||
|
// Simulate some work
|
||||||
|
await Task.Delay(250);
|
||||||
|
|
||||||
|
// Increment
|
||||||
|
task1.Increment(1.5);
|
||||||
|
task2.Increment(0.5);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
# Configure
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Asynchronous
|
||||||
|
AnsiConsole.Progress()
|
||||||
|
.AutoRefresh(false) // Turn off auto refresh
|
||||||
|
.AutoClear(false) // Do not remove the task list when done
|
||||||
|
.Columns(new ProgressColumn[]
|
||||||
|
{
|
||||||
|
new TaskDescriptionColumn(), // Task description
|
||||||
|
new ProgressBarColumn(), // Progress bar
|
||||||
|
new PercentageColumn(), // Percentage
|
||||||
|
new RemainingTimeColumn(), // Remaining time
|
||||||
|
new SpinnerColumn(), // Spinner
|
||||||
|
})
|
||||||
|
.Start(ctx =>
|
||||||
|
{
|
||||||
|
// Omitted
|
||||||
|
});
|
||||||
|
```
|
||||||
12
docs/input/prompts/index.cshtml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Title: Prompts
|
||||||
|
Order: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
<h1>Sections</h1>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
@foreach (IDocument child in OutputPages.GetChildrenOf(Document))
|
||||||
|
{
|
||||||
|
<li>@Html.DocumentLink(child)</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
31
docs/input/prompts/multiselection.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
Title: Multi Selection
|
||||||
|
Order: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
The `MultiSelectionPrompt` can be used when you want the user to select
|
||||||
|
one or many items from a provided list.
|
||||||
|
|
||||||
|
<img src="../assets/images/multiselection.gif" style="width: 100%;" />
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Ask for the user's favorite fruits
|
||||||
|
var fruits = AnsiConsole.Prompt(
|
||||||
|
new MultiSelectionPrompt<string>()
|
||||||
|
.Title("What are your [green]favorite fruits[/]?")
|
||||||
|
.NotRequired() // Not required to have a favorite fruit
|
||||||
|
.PageSize(10)
|
||||||
|
.AddChoice("Apple")
|
||||||
|
.AddChoices(new[] {
|
||||||
|
"Apricot", "Avocado",
|
||||||
|
"Banana", "Blackcurrant", "Blueberry",
|
||||||
|
"Cherry", "Cloudberry", "Cocunut",
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Write the selected fruits to the terminal
|
||||||
|
foreach (string fruit in fruits)
|
||||||
|
{
|
||||||
|
AnsiConsole.WriteLine(fruit);
|
||||||
|
}
|
||||||
|
```
|
||||||
27
docs/input/prompts/selection.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
Title: Selection
|
||||||
|
Order: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
The `SelectionPrompt` can be used when you want the user to select
|
||||||
|
a single item from a provided list.
|
||||||
|
|
||||||
|
<img src="../assets/images/selection.gif" style="width: 100%;" />
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Ask for the user's favorite fruit
|
||||||
|
var fruit = AnsiConsole.Prompt(
|
||||||
|
new SelectionPrompt<string>()
|
||||||
|
.Title("What's your [green]favorite fruit[/]?")
|
||||||
|
.PageSize(10)
|
||||||
|
.AddChoice("Apple")
|
||||||
|
.AddChoices(new[] {
|
||||||
|
"Apricot", "Avocado",
|
||||||
|
"Banana", "Blackcurrant", "Blueberry",
|
||||||
|
"Cherry", "Cloudberry", "Cocunut",
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Echo the fruit back to the terminal
|
||||||
|
AnsiConsole.WriteLine($"I agree. {fruit} is tasty!");
|
||||||
|
```
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
Title: Prompt
|
Title: Text
|
||||||
Order: 4
|
Order: 0
|
||||||
|
RedirectFrom: prompt
|
||||||
---
|
---
|
||||||
|
|
||||||
Sometimes you want to get some input from the user, and for this
|
Sometimes you want to get some input from the user, and for this
|
||||||
60
docs/input/status.md
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
Title: Status
|
||||||
|
Order: 6
|
||||||
|
---
|
||||||
|
|
||||||
|
Spectre.Console can display information about long running tasks in the console.
|
||||||
|
|
||||||
|
<img src="assets/images/status.gif" style="max-width: 100%;margin-bottom:20px;">
|
||||||
|
|
||||||
|
If the current terminal isn't considered "interactive", such as when running
|
||||||
|
in a continuous integration system, or the terminal can't display
|
||||||
|
ANSI control sequence, any progress will be displayed in a simpler way.
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Synchronous
|
||||||
|
AnsiConsole.Status()
|
||||||
|
.Start("Thinking...", ctx =>
|
||||||
|
{
|
||||||
|
// Simulate some work
|
||||||
|
AnsiConsole.MarkupLine("Doing some work...");
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
|
||||||
|
// Update the status and spinner
|
||||||
|
ctx.Status("Thinking some more");
|
||||||
|
ctx.Spinner(Spinner.Known.Star);
|
||||||
|
ctx.SpinnerStyle(Style.Parse("green"));
|
||||||
|
|
||||||
|
// Simulate some work
|
||||||
|
AnsiConsole.MarkupLine("Doing some more work...");
|
||||||
|
Thread.Sleep(2000);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Asynchronous progress
|
||||||
|
|
||||||
|
If you prefer to use async/await, you can use `StartAsync` instead of `Start`.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Asynchronous
|
||||||
|
await AnsiConsole.Status()
|
||||||
|
.StartAsync("Thinking...", async ctx =>
|
||||||
|
{
|
||||||
|
// Omitted
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
# Configure
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
AnsiConsole.Status()
|
||||||
|
.AutoRefresh(false)
|
||||||
|
.Spinner(Spinner.Known.Star)
|
||||||
|
.SpinnerStyle(Style.Parse("green bold"))
|
||||||
|
.Start("Thinking...", ctx =>
|
||||||
|
{
|
||||||
|
// Omitted
|
||||||
|
ctx.Refresh();
|
||||||
|
});
|
||||||
|
```
|
||||||
75
docs/input/widgets/barchart.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
Title: Bar Chart
|
||||||
|
Order: 20
|
||||||
|
---
|
||||||
|
|
||||||
|
Use `BarChart` to render bar charts to the console.
|
||||||
|
|
||||||
|
<img src="../assets/images/barchart.png" style="width: 100%;" />
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
## Basic usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
AnsiConsole.Render(new BarChart()
|
||||||
|
.Width(60)
|
||||||
|
.Label("[green bold underline]Number of fruits[/]")
|
||||||
|
.CenterLabel()
|
||||||
|
.AddItem("Apple", 12, Color.Yellow)
|
||||||
|
.AddItem("Orange", 54, Color.Green)
|
||||||
|
.AddItem("Banana", 33, Color.Red));
|
||||||
|
```
|
||||||
|
|
||||||
|
## Add items with converter
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Create a list of fruits
|
||||||
|
var items = new List<(string Label, double Value)>
|
||||||
|
{
|
||||||
|
("Apple", 12),
|
||||||
|
("Orange", 54),
|
||||||
|
("Banana", 33),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Render bar chart
|
||||||
|
AnsiConsole.Render(new BarChart()
|
||||||
|
.Width(60)
|
||||||
|
.Label("[green bold underline]Number of fruits[/]")
|
||||||
|
.CenterLabel()
|
||||||
|
.AddItems(items, (item) => new BarChartItem(
|
||||||
|
item.Label, item.Value, Color.Yellow)));
|
||||||
|
```
|
||||||
|
|
||||||
|
## Add items implementing IBarChartItem
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public sealed class Fruit : IBarChartItem
|
||||||
|
{
|
||||||
|
public string Label { get; set; }
|
||||||
|
public double Value { get; set; }
|
||||||
|
public Color? Color { get; set; }
|
||||||
|
|
||||||
|
public Fruit(string label, double value, Color? color = null)
|
||||||
|
{
|
||||||
|
Label = label;
|
||||||
|
Value = value;
|
||||||
|
Color = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a list of fruits
|
||||||
|
var items = new List<Fruit>
|
||||||
|
{
|
||||||
|
new Fruit("Apple", 12, Color.Yellow),
|
||||||
|
new Fruit("Orange", 54, Color.Red),
|
||||||
|
new Fruit("Banana", 33, Color.Green),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Render bar chart
|
||||||
|
AnsiConsole.Render(new BarChart()
|
||||||
|
.Width(60)
|
||||||
|
.Label("[green bold underline]Number of fruits[/]")
|
||||||
|
.CenterLabel()
|
||||||
|
.AddItem(new Fruit("Mango", 3))
|
||||||
|
.AddItems(items));
|
||||||
|
```
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
Title: Calendar
|
Title: Calendar
|
||||||
Order: 2
|
Order: 40
|
||||||
RedirectFrom: calendar
|
RedirectFrom: calendar
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Title: Canvas Image
|
Title: Canvas Image
|
||||||
Order: 5
|
Order: 70
|
||||||
---
|
---
|
||||||
|
|
||||||
To add [ImageSharp](https://github.com/SixLabors/ImageSharp) superpowers to
|
To add [ImageSharp](https://github.com/SixLabors/ImageSharp) superpowers to
|
||||||
@@ -51,8 +51,8 @@ AnsiConsole.Render(image);
|
|||||||
|
|
||||||
# Manipulating images
|
# Manipulating images
|
||||||
|
|
||||||
You can take full advantage of using [ImageSharp](https://github.com/SixLabors/ImageSharp)
|
You can take full advantage of [ImageSharp](https://github.com/SixLabors/ImageSharp)
|
||||||
and manipulate images directly via the [ImageSharp Processing API](https://docs.sixlabors.com/api/ImageSharp/SixLabors.ImageSharp.Processing.html).
|
and manipulate images directly via it's [Processing API](https://docs.sixlabors.com/api/ImageSharp/SixLabors.ImageSharp.Processing.html).
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// Load an image
|
// Load an image
|
||||||
@@ -69,7 +69,7 @@ image.Mutate(ctx => ctx.Grayscale().Rotate(-45).EntropyCrop());
|
|||||||
AnsiConsole.Render(image);
|
AnsiConsole.Render(image);
|
||||||
```
|
```
|
||||||
|
|
||||||
# Result
|
## Result
|
||||||
|
|
||||||
<pre style="font-size:90%;font-family:consolas,'Courier New',monospace;line-height: normal; padding: 0px;background-color: #222222; padding: 20px;">
|
<pre style="font-size:90%;font-family:consolas,'Courier New',monospace;line-height: normal; padding: 0px;background-color: #222222; padding: 20px;">
|
||||||
<span> </span><span style="background-color: #282828"> </span><span style="background-color: #222222"> </span><span style="background-color: #232323"> </span><span style="background-color: #353535"> </span><span style="background-color: #4B4B4B"> </span><span style="background-color: #595959"> </span><span style="background-color: #3B3B3B"> </span><span style="background-color: #202020"> </span><span style="background-color: #191919"> </span><span> </span>
|
<span> </span><span style="background-color: #282828"> </span><span style="background-color: #222222"> </span><span style="background-color: #232323"> </span><span style="background-color: #353535"> </span><span style="background-color: #4B4B4B"> </span><span style="background-color: #595959"> </span><span style="background-color: #3B3B3B"> </span><span style="background-color: #202020"> </span><span style="background-color: #191919"> </span><span> </span>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Title: Canvas
|
Title: Canvas
|
||||||
Order: 4
|
Order: 60
|
||||||
---
|
---
|
||||||
|
|
||||||
`Canvas` is a widget that allows you to render arbitrary "pixels"
|
`Canvas` is a widget that allows you to render arbitrary "pixels"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Title: Figlet
|
Title: Figlet
|
||||||
Order: 3
|
Order: 50
|
||||||
RedirectFrom: figlet
|
RedirectFrom: figlet
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Title: Rule
|
Title: Rule
|
||||||
Order: 1
|
Order: 30
|
||||||
RedirectFrom: rule
|
RedirectFrom: rule
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
70
docs/input/widgets/tree.md
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
Title: Tree
|
||||||
|
Order: 10
|
||||||
|
---
|
||||||
|
|
||||||
|
The `Tree` widget can be used to render hierarchical data.
|
||||||
|
|
||||||
|
<img src="../assets/images/tree.png" style="width: 100%;" />
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Create the tree
|
||||||
|
var tree = new Tree("Root");
|
||||||
|
|
||||||
|
// Add some nodes
|
||||||
|
var foo = tree.AddNode("[yellow]Foo[/]");
|
||||||
|
var table = foo.AddNode(new Table()
|
||||||
|
.RoundedBorder()
|
||||||
|
.AddColumn("First")
|
||||||
|
.AddColumn("Second")
|
||||||
|
.AddRow("1", "2")
|
||||||
|
.AddRow("3", "4")
|
||||||
|
.AddRow("5", "6"));
|
||||||
|
|
||||||
|
table.AddNode("[blue]Baz[/]");
|
||||||
|
foo.AddNode("Qux");
|
||||||
|
|
||||||
|
var bar = tree.AddNode("[yellow]Bar[/]");
|
||||||
|
bar.AddNode(new Calendar(2020, 12)
|
||||||
|
.AddCalendarEvent(2020, 12, 12)
|
||||||
|
.HideHeader());
|
||||||
|
|
||||||
|
// Render the tree
|
||||||
|
AnsiConsole.Render(root);
|
||||||
|
```
|
||||||
|
|
||||||
|
# Collapsing nodes
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
root.AddNode("Label").Collapsed();
|
||||||
|
```
|
||||||
|
|
||||||
|
# Appearance
|
||||||
|
|
||||||
|
## Style
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
var root = new Tree("Root")
|
||||||
|
.Style("white on red");
|
||||||
|
```
|
||||||
|
|
||||||
|
## Guide lines
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// ASCII guide lines
|
||||||
|
var root = new Tree("Root")
|
||||||
|
.Guide(TreeGuide.Ascii);
|
||||||
|
|
||||||
|
// Default guide lines
|
||||||
|
var root = new Tree("Root")
|
||||||
|
.Guide(TreeGuide.Line);
|
||||||
|
|
||||||
|
// Double guide lines
|
||||||
|
var root = new Tree("Root")
|
||||||
|
.Guide(TreeGuide.DoubleLine);
|
||||||
|
|
||||||
|
// Bold guide lines
|
||||||
|
var root = new Tree("Root")
|
||||||
|
.Guide(TreeGuide.BoldLine);
|
||||||
|
```
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"isRoot": true,
|
"isRoot": true,
|
||||||
"tools": {
|
"tools": {
|
||||||
"cake.tool": {
|
"cake.tool": {
|
||||||
"version": "1.0.0-rc0001",
|
"version": "1.0.0-rc0002",
|
||||||
"commands": [
|
"commands": [
|
||||||
"dotnet-cake"
|
"dotnet-cake"
|
||||||
]
|
]
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dotnet-example": {
|
"dotnet-example": {
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"commands": [
|
"commands": [
|
||||||
"dotnet-example"
|
"dotnet-example"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net5.0</TargetFramework>
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
<Title>Borders</Title>
|
|
||||||
<Description>Demonstrates the different kind of borders.</Description>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<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>
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
<Title>Canvas</Title>
|
|
||||||
<Description>Demonstrates how to render pixels and images.</Description>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\src\Spectre.Console.ImageSharp\Spectre.Console.ImageSharp.csproj" />
|
|
||||||
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Update="cake.png">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
16
examples/Cli/Delegates/BarSettings.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Delegates
|
||||||
|
{
|
||||||
|
public static partial class Program
|
||||||
|
{
|
||||||
|
public sealed class BarSettings : CommandSettings
|
||||||
|
{
|
||||||
|
[CommandOption("--count")]
|
||||||
|
[Description("The number of bars to print")]
|
||||||
|
[DefaultValue(1)]
|
||||||
|
public int Count { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
examples/Cli/Delegates/Delegates.csproj
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<ExampleName>Delegates</ExampleName>
|
||||||
|
<ExampleDescription>Demonstrates how to specify commands as delegates.</ExampleDescription>
|
||||||
|
<ExampleGroup>Cli</ExampleGroup>
|
||||||
|
<ExampleVisible>false</ExampleVisible>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
39
examples/Cli/Delegates/Program.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Delegates
|
||||||
|
{
|
||||||
|
public static partial class Program
|
||||||
|
{
|
||||||
|
public static int Main(string[] args)
|
||||||
|
{
|
||||||
|
var app = new CommandApp();
|
||||||
|
app.Configure(config =>
|
||||||
|
{
|
||||||
|
config.AddDelegate("foo", Foo)
|
||||||
|
.WithDescription("Foos the bars");
|
||||||
|
|
||||||
|
config.AddDelegate<BarSettings>("bar", Bar)
|
||||||
|
.WithDescription("Bars the foos"); ;
|
||||||
|
});
|
||||||
|
|
||||||
|
return app.Run(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int Foo(CommandContext context)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Foo");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int Bar(CommandContext context, BarSettings settings)
|
||||||
|
{
|
||||||
|
for (var index = 0; index < settings.Count; index++)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Bar");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
47
examples/Cli/Demo/Commands/Add/AddPackageCommand.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Demo.Utilities;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Demo.Commands
|
||||||
|
{
|
||||||
|
[Description("Add a NuGet package reference to the project.")]
|
||||||
|
public sealed class AddPackageCommand : Command<AddPackageCommand.Settings>
|
||||||
|
{
|
||||||
|
public sealed class Settings : AddSettings
|
||||||
|
{
|
||||||
|
[CommandArgument(0, "<PACKAGENAME>")]
|
||||||
|
[Description("The package reference to add.")]
|
||||||
|
public string PackageName { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("-v|--version <VERSION>")]
|
||||||
|
[Description("The version of the package to add.")]
|
||||||
|
public string Version { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("-f|--framework <FRAMEWORK>")]
|
||||||
|
[Description("Add the reference only when targeting a specific framework.")]
|
||||||
|
public string Framework { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--no-restore")]
|
||||||
|
[Description("Add the reference without performing restore preview and compatibility check.")]
|
||||||
|
public bool NoRestore { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--source <SOURCE>")]
|
||||||
|
[Description("The NuGet package source to use during the restore.")]
|
||||||
|
public string Source { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--package-directory <PACKAGEDIR>")]
|
||||||
|
[Description("The directory to restore packages to.")]
|
||||||
|
public string PackageDirectory { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--interactive")]
|
||||||
|
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
||||||
|
public bool Interactive { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Execute(CommandContext context, Settings settings)
|
||||||
|
{
|
||||||
|
SettingsDumper.Dump(settings);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
examples/Cli/Demo/Commands/Add/AddReferenceCommand.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Demo.Utilities;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Demo.Commands
|
||||||
|
{
|
||||||
|
public sealed class AddReferenceCommand : Command<AddReferenceCommand.Settings>
|
||||||
|
{
|
||||||
|
public sealed class Settings : AddSettings
|
||||||
|
{
|
||||||
|
[CommandArgument(0, "<PROJECTPATH>")]
|
||||||
|
[Description("The package reference to add.")]
|
||||||
|
public string ProjectPath { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("-f|--framework <FRAMEWORK>")]
|
||||||
|
[Description("Add the reference only when targeting a specific framework.")]
|
||||||
|
public string Framework { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--interactive")]
|
||||||
|
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
||||||
|
public bool Interactive { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Execute(CommandContext context, Settings settings)
|
||||||
|
{
|
||||||
|
SettingsDumper.Dump(settings);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
examples/Cli/Demo/Commands/Add/AddSettings.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Demo.Commands
|
||||||
|
{
|
||||||
|
public abstract class AddSettings : CommandSettings
|
||||||
|
{
|
||||||
|
[CommandArgument(0, "<PROJECT>")]
|
||||||
|
[Description("The project file to operate on. If a file is not specified, the command will search the current directory for one.")]
|
||||||
|
public string Project { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
70
examples/Cli/Demo/Commands/Run/RunCommand.cs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Demo.Utilities;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Demo.Commands
|
||||||
|
{
|
||||||
|
[Description("Build and run a .NET project output.")]
|
||||||
|
public sealed class RunCommand : Command<RunCommand.Settings>
|
||||||
|
{
|
||||||
|
public sealed class Settings : CommandSettings
|
||||||
|
{
|
||||||
|
[CommandOption("-c|--configuration <CONFIGURATION>")]
|
||||||
|
[Description("The configuration to run for. The default for most projects is '[grey]Debug[/]'.")]
|
||||||
|
[DefaultValue("Debug")]
|
||||||
|
public string Configuration { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("-f|--framework <FRAMEWORK>")]
|
||||||
|
[Description("The target framework to run for. The target framework must also be specified in the project file.")]
|
||||||
|
public string Framework { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("-r|--runtime <RUNTIMEIDENTIFIER>")]
|
||||||
|
[Description("The target runtime to run for.")]
|
||||||
|
public string RuntimeIdentifier { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("-p|--project <PROJECTPATH>")]
|
||||||
|
[Description("The path to the project file to run (defaults to the current directory if there is only one project).")]
|
||||||
|
public string ProjectPath { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--launch-profile <LAUNCHPROFILE>")]
|
||||||
|
[Description("The name of the launch profile (if any) to use when launching the application.")]
|
||||||
|
public string LaunchProfile { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--no-launch-profile")]
|
||||||
|
[Description("Do not attempt to use [grey]launchSettings.json[/] to configure the application.")]
|
||||||
|
public bool NoLaunchProfile { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--no-build")]
|
||||||
|
[Description("Do not build the project before running. Implies [grey]--no-restore[/].")]
|
||||||
|
public bool NoBuild { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--interactive")]
|
||||||
|
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
|
||||||
|
public string Interactive { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--no-restore")]
|
||||||
|
[Description("Do not restore the project before building.")]
|
||||||
|
public bool NoRestore { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--verbosity <VERBOSITY>")]
|
||||||
|
[Description("Set the MSBuild verbosity level. Allowed values are q[grey]uiet[/], m[grey]inimal[/], n[grey]ormal[/], d[grey]etailed[/], and diag[grey]nostic[/].")]
|
||||||
|
[TypeConverter(typeof(VerbosityConverter))]
|
||||||
|
[DefaultValue(Verbosity.Normal)]
|
||||||
|
public Verbosity Verbosity { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--no-dependencies")]
|
||||||
|
[Description("Do not restore project-to-project references and only restore the specified project.")]
|
||||||
|
public bool NoDependencies { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--force")]
|
||||||
|
[Description("Force all dependencies to be resolved even if the last restore was successful. This is equivalent to deleting [grey]project.assets.json[/].")]
|
||||||
|
public bool Force { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Execute(CommandContext context, Settings settings)
|
||||||
|
{
|
||||||
|
SettingsDumper.Dump(settings);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
examples/Cli/Demo/Commands/Serve/ServeCommand.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using Demo.Utilities;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Demo.Commands
|
||||||
|
{
|
||||||
|
[Description("Launches a web server in the current working directory and serves all files in it.")]
|
||||||
|
public sealed class ServeCommand : Command<ServeCommand.Settings>
|
||||||
|
{
|
||||||
|
public sealed class Settings : CommandSettings
|
||||||
|
{
|
||||||
|
[CommandOption("-p|--port <PORT>")]
|
||||||
|
[Description("Port to use. Defaults to [grey]8080[/]. Use [grey]0[/] for a dynamic port.")]
|
||||||
|
public int Port { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("-o|--open-browser [BROWSER]")]
|
||||||
|
[Description("Open a web browser when the server starts. You can also specify which browser to use. If none is specified, the default one will be used.")]
|
||||||
|
public FlagValue<string> OpenBrowser { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Execute(CommandContext context, Settings settings)
|
||||||
|
{
|
||||||
|
if (settings.OpenBrowser.IsSet)
|
||||||
|
{
|
||||||
|
var browser = settings.OpenBrowser.Value;
|
||||||
|
if (browser != null)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Open in {browser}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Open in default browser.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsDumper.Dump(settings);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
examples/Cli/Demo/Demo.csproj
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<ExampleName>Demo</ExampleName>
|
||||||
|
<ExampleDescription>Demonstrates the most common use cases of Spectre.Cli.</ExampleDescription>
|
||||||
|
<ExampleGroup>Cli</ExampleGroup>
|
||||||
|
<ExampleVisible>false</ExampleVisible>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
37
examples/Cli/Demo/Program.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using Demo.Commands;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Demo
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static int Main(string[] args)
|
||||||
|
{
|
||||||
|
var app = new CommandApp();
|
||||||
|
app.Configure(config =>
|
||||||
|
{
|
||||||
|
config.SetApplicationName("fake-dotnet");
|
||||||
|
config.ValidateExamples();
|
||||||
|
config.AddExample(new[] { "run", "--no-build" });
|
||||||
|
|
||||||
|
// Run
|
||||||
|
config.AddCommand<RunCommand>("run");
|
||||||
|
|
||||||
|
// Add
|
||||||
|
config.AddBranch<AddSettings>("add", add =>
|
||||||
|
{
|
||||||
|
add.SetDescription("Add a package or reference to a .NET project");
|
||||||
|
add.AddCommand<AddPackageCommand>("package");
|
||||||
|
add.AddCommand<AddReferenceCommand>("reference");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Serve
|
||||||
|
config.AddCommand<ServeCommand>("serve")
|
||||||
|
.WithExample(new[] { "serve", "-o", "firefox" })
|
||||||
|
.WithExample(new[] { "serve", "--port", "80", "-o", "firefox" });
|
||||||
|
});
|
||||||
|
|
||||||
|
return app.Run(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
examples/Cli/Demo/Utilities/SettingsDumper.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using Spectre.Console;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Demo.Utilities
|
||||||
|
{
|
||||||
|
public static class SettingsDumper
|
||||||
|
{
|
||||||
|
public static void Dump(CommandSettings settings)
|
||||||
|
{
|
||||||
|
var table = new Table().RoundedBorder();
|
||||||
|
table.AddColumn("[grey]Name[/]");
|
||||||
|
table.AddColumn("[grey]Value[/]");
|
||||||
|
|
||||||
|
var properties = settings.GetType().GetProperties();
|
||||||
|
foreach (var property in properties)
|
||||||
|
{
|
||||||
|
var value = property.GetValue(settings)
|
||||||
|
?.ToString()
|
||||||
|
?.Replace("[", "[[");
|
||||||
|
|
||||||
|
table.AddRow(
|
||||||
|
property.Name,
|
||||||
|
value ?? "[grey]null[/]");
|
||||||
|
}
|
||||||
|
|
||||||
|
AnsiConsole.Render(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
54
examples/Cli/Demo/Verbosity.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Demo
|
||||||
|
{
|
||||||
|
public enum Verbosity
|
||||||
|
{
|
||||||
|
Quiet,
|
||||||
|
Minimal,
|
||||||
|
Normal,
|
||||||
|
Detailed,
|
||||||
|
Diagnostic
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class VerbosityConverter : TypeConverter
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, Verbosity> _lookup;
|
||||||
|
|
||||||
|
public VerbosityConverter()
|
||||||
|
{
|
||||||
|
_lookup = new Dictionary<string, Verbosity>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
{ "q", Verbosity.Quiet },
|
||||||
|
{ "quiet", Verbosity.Quiet },
|
||||||
|
{ "m", Verbosity.Minimal },
|
||||||
|
{ "minimal", Verbosity.Minimal },
|
||||||
|
{ "n", Verbosity.Normal },
|
||||||
|
{ "normal", Verbosity.Normal },
|
||||||
|
{ "d", Verbosity.Detailed },
|
||||||
|
{ "detailed", Verbosity.Detailed },
|
||||||
|
{ "diag", Verbosity.Diagnostic },
|
||||||
|
{ "diagnostic", Verbosity.Diagnostic }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
|
{
|
||||||
|
if (value is string stringValue)
|
||||||
|
{
|
||||||
|
var result = _lookup.TryGetValue(stringValue, out var verbosity);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
const string format = "The value '{0}' is not a valid verbosity.";
|
||||||
|
var message = string.Format(CultureInfo.InvariantCulture, format, value);
|
||||||
|
throw new InvalidOperationException(message);
|
||||||
|
}
|
||||||
|
return verbosity;
|
||||||
|
}
|
||||||
|
throw new NotSupportedException("Can't convert value to verbosity.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
examples/Cli/Dynamic/Dynamic.csproj
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<ExampleName>Dynamic</ExampleName>
|
||||||
|
<ExampleDescription>Demonstrates how to define dynamic commands.</ExampleDescription>
|
||||||
|
<ExampleGroup>Cli</ExampleGroup>
|
||||||
|
<ExampleVisible>false</ExampleVisible>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
20
examples/Cli/Dynamic/MyCommand.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Dynamic
|
||||||
|
{
|
||||||
|
public sealed class MyCommand : Command
|
||||||
|
{
|
||||||
|
public override int Execute(CommandContext context)
|
||||||
|
{
|
||||||
|
if (!(context.Data is int data))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Command has no associated data.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Value = {0}", data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
examples/Cli/Dynamic/Program.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Dynamic
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static int Main(string[] args)
|
||||||
|
{
|
||||||
|
var app = new CommandApp();
|
||||||
|
app.Configure(config =>
|
||||||
|
{
|
||||||
|
foreach(var index in Enumerable.Range(1, 10))
|
||||||
|
{
|
||||||
|
config.AddCommand<MyCommand>($"c{index}")
|
||||||
|
.WithDescription($"Prints the number {index}")
|
||||||
|
.WithData(index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return app.Run(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
examples/Cli/Injection/Commands/DefaultCommand.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Injection.Commands
|
||||||
|
{
|
||||||
|
public sealed class DefaultCommand : Command<DefaultCommand.Settings>
|
||||||
|
{
|
||||||
|
private readonly IGreeter _greeter;
|
||||||
|
|
||||||
|
public sealed class Settings : CommandSettings
|
||||||
|
{
|
||||||
|
[CommandOption("-n|--name <NAME>")]
|
||||||
|
[Description("The person or thing to greet.")]
|
||||||
|
[DefaultValue("World")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public DefaultCommand(IGreeter greeter)
|
||||||
|
{
|
||||||
|
_greeter = greeter ?? throw new ArgumentNullException(nameof(greeter));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Execute(CommandContext context, Settings settings)
|
||||||
|
{
|
||||||
|
_greeter.Greet(settings.Name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
examples/Cli/Injection/IGreeter.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Injection
|
||||||
|
{
|
||||||
|
public interface IGreeter
|
||||||
|
{
|
||||||
|
void Greet(string name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class HelloWorldGreeter : IGreeter
|
||||||
|
{
|
||||||
|
public void Greet(string name)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Hello {name}!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
31
examples/Cli/Injection/Infrastructure/TypeRegistrar.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Injection
|
||||||
|
{
|
||||||
|
public sealed class TypeRegistrar : ITypeRegistrar
|
||||||
|
{
|
||||||
|
private readonly IServiceCollection _builder;
|
||||||
|
|
||||||
|
public TypeRegistrar(IServiceCollection builder)
|
||||||
|
{
|
||||||
|
_builder = builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITypeResolver Build()
|
||||||
|
{
|
||||||
|
return new TypeResolver(_builder.BuildServiceProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Register(Type service, Type implementation)
|
||||||
|
{
|
||||||
|
_builder.AddSingleton(service, implementation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterInstance(Type service, object implementation)
|
||||||
|
{
|
||||||
|
_builder.AddSingleton(service, implementation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
examples/Cli/Injection/Infrastructure/TypeResolver.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Injection
|
||||||
|
{
|
||||||
|
public sealed class TypeResolver : ITypeResolver
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider _provider;
|
||||||
|
|
||||||
|
public TypeResolver(IServiceProvider provider)
|
||||||
|
{
|
||||||
|
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Resolve(Type type)
|
||||||
|
{
|
||||||
|
return _provider.GetRequiredService(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
examples/Cli/Injection/Injection.csproj
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<ExampleName>Injection</ExampleName>
|
||||||
|
<ExampleDescription>Demonstrates how to use dependency injection with Spectre.Cli.</ExampleDescription>
|
||||||
|
<ExampleGroup>Cli</ExampleGroup>
|
||||||
|
<ExampleVisible>false</ExampleVisible>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.8" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
23
examples/Cli/Injection/Program.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using Injection.Commands;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Injection
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static int Main(string[] args)
|
||||||
|
{
|
||||||
|
// Create a type registrar and register any dependencies.
|
||||||
|
// A type registrar is an adapter for a DI framework.
|
||||||
|
var registrations = new ServiceCollection();
|
||||||
|
registrations.AddSingleton<IGreeter, HelloWorldGreeter>();
|
||||||
|
var registrar = new TypeRegistrar(registrations);
|
||||||
|
|
||||||
|
// Create a new command app with the registrar
|
||||||
|
// and run it with the provided arguments.
|
||||||
|
var app = new CommandApp<DefaultCommand>(registrar);
|
||||||
|
return app.Run(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<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>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Spectre.Console;
|
|
||||||
|
|
||||||
namespace ColumnsExample
|
|
||||||
{
|
|
||||||
public static class Program
|
|
||||||
{
|
|
||||||
public static async Task Main()
|
|
||||||
{
|
|
||||||
// Download some random users
|
|
||||||
using var client = new HttpClient();
|
|
||||||
dynamic users = JObject.Parse(
|
|
||||||
await client.GetStringAsync("https://randomuser.me/api/?results=15"));
|
|
||||||
|
|
||||||
// Create a card for each user
|
|
||||||
var cards = new List<Panel>();
|
|
||||||
foreach(var user in users.results)
|
|
||||||
{
|
|
||||||
cards.Add(new Panel(GetCardContent(user))
|
|
||||||
.Header($"{user.location.country}")
|
|
||||||
.RoundedBorder().Expand());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render all cards in columns
|
|
||||||
AnsiConsole.Render(new Columns(cards));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetCardContent(dynamic user)
|
|
||||||
{
|
|
||||||
var name = $"{user.name.first} {user.name.last}";
|
|
||||||
var country = $"{user.location.city}";
|
|
||||||
|
|
||||||
return $"[b]{name}[/]\n[yellow]{country}[/]";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
15
examples/Console/Borders/Borders.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Borders</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates the different kind of borders.</ExampleDescription>
|
||||||
|
<ExampleGroup>Widgets</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
15
examples/Console/Calendars/Calendars.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Calendars</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to render calendars.</ExampleDescription>
|
||||||
|
<ExampleGroup>Widgets</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
22
examples/Console/Canvas/Canvas.csproj
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
<ExampleTitle>Canvas</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to render pixels and images.</ExampleDescription>
|
||||||
|
<ExampleGroup>Widgets</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console.ImageSharp\Spectre.Console.ImageSharp.csproj" />
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="cake.png">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
15
examples/Console/Charts/Charts.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Charts</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to render charts in a console.</ExampleDescription>
|
||||||
|
<ExampleGroup>Widgets</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
21
examples/Console/Charts/Program.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace InfoExample
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
var chart = new BarChart()
|
||||||
|
.Width(60)
|
||||||
|
.Label("[green bold underline]Number of fruits[/]")
|
||||||
|
.CenterLabel()
|
||||||
|
.AddItem("Apple", 12, Color.Yellow)
|
||||||
|
.AddItem("Orange", 54, Color.Green)
|
||||||
|
.AddItem("Banana", 33, Color.Red);
|
||||||
|
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.Render(chart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
examples/Console/Colors/Colors.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Colors</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to use [yellow]c[/][red]o[/][green]l[/][blue]o[/][aqua]r[/][lime]s[/] in the console.</ExampleDescription>
|
||||||
|
<ExampleGroup>Misc</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
19
examples/Console/Columns/Columns.csproj
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Columns</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to render data into columns.</ExampleDescription>
|
||||||
|
<ExampleGroup>Widgets</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
31
examples/Console/Columns/Program.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace ColumnsExample
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
var cards = new List<Panel>();
|
||||||
|
foreach(var user in User.LoadUsers())
|
||||||
|
{
|
||||||
|
cards.Add(
|
||||||
|
new Panel(GetCardContent(user))
|
||||||
|
.Header($"{user.Country}")
|
||||||
|
.RoundedBorder().Expand());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render all cards in columns
|
||||||
|
AnsiConsole.Render(new Columns(cards));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetCardContent(User user)
|
||||||
|
{
|
||||||
|
var name = $"{user.FirstName} {user.LastName}";
|
||||||
|
var city = $"{user.City}";
|
||||||
|
|
||||||
|
return $"[b]{name}[/]\n[yellow]{city}[/]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
89
examples/Console/Columns/User.cs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ColumnsExample
|
||||||
|
{
|
||||||
|
public sealed class User
|
||||||
|
{
|
||||||
|
public string FirstName { get; set; }
|
||||||
|
public string LastName { get; set; }
|
||||||
|
public string City { get; set; }
|
||||||
|
public string Country { get; set; }
|
||||||
|
|
||||||
|
public static List<User> LoadUsers()
|
||||||
|
{
|
||||||
|
return new List<User>
|
||||||
|
{
|
||||||
|
new User
|
||||||
|
{
|
||||||
|
FirstName = "Andrea",
|
||||||
|
LastName = "Johansen",
|
||||||
|
City = "Hornbæk",
|
||||||
|
Country = "Denmark",
|
||||||
|
},
|
||||||
|
new User
|
||||||
|
{
|
||||||
|
FirstName = "Brandon",
|
||||||
|
LastName = "Cole",
|
||||||
|
City = "Washington",
|
||||||
|
Country = "United States",
|
||||||
|
},
|
||||||
|
new User
|
||||||
|
{
|
||||||
|
FirstName = "Patrik",
|
||||||
|
LastName = "Svensson",
|
||||||
|
City = "Stockholm",
|
||||||
|
Country = "Sweden",
|
||||||
|
},
|
||||||
|
new User
|
||||||
|
{
|
||||||
|
FirstName = "Freya",
|
||||||
|
LastName = "Thompson",
|
||||||
|
City = "Rotorua",
|
||||||
|
Country = "New Zealand",
|
||||||
|
},
|
||||||
|
new User
|
||||||
|
{
|
||||||
|
FirstName = "طاها",
|
||||||
|
LastName = "رضایی",
|
||||||
|
City = "اهواز",
|
||||||
|
Country = "Iran",
|
||||||
|
},
|
||||||
|
new User
|
||||||
|
{
|
||||||
|
FirstName = "Yara",
|
||||||
|
LastName = "Simon",
|
||||||
|
City = "Develier",
|
||||||
|
Country = "Switzerland",
|
||||||
|
},
|
||||||
|
new User
|
||||||
|
{
|
||||||
|
FirstName = "Giray",
|
||||||
|
LastName = "Erbay",
|
||||||
|
City = "Karabük",
|
||||||
|
Country = "Turkey",
|
||||||
|
},
|
||||||
|
new User
|
||||||
|
{
|
||||||
|
FirstName = "Miodrag",
|
||||||
|
LastName = "Schaffer",
|
||||||
|
City = "Möckern",
|
||||||
|
Country = "Germany",
|
||||||
|
},
|
||||||
|
new User
|
||||||
|
{
|
||||||
|
FirstName = "Carmela",
|
||||||
|
LastName = "Lo Castro",
|
||||||
|
City = "Firenze",
|
||||||
|
Country = "Italy",
|
||||||
|
},
|
||||||
|
new User
|
||||||
|
{
|
||||||
|
FirstName = "Roberto",
|
||||||
|
LastName = "Sims",
|
||||||
|
City = "Mallow",
|
||||||
|
Country = "Ireland",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
examples/Console/Cursor/Cursor.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Cursor</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to move the cursor.</ExampleDescription>
|
||||||
|
<ExampleGroup>Misc</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
15
examples/Console/Emojis/Emojis.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Emojis</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to render emojis.</ExampleDescription>
|
||||||
|
<ExampleGroup>Misc</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
15
examples/Console/Exceptions/Exceptions.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Exceptions</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to render formatted exceptions.</ExampleDescription>
|
||||||
|
<ExampleGroup>Misc</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
15
examples/Console/Figlet/Figlet.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Figlet</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to render FIGlet text.</ExampleDescription>
|
||||||
|
<ExampleGroup>Widgets</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
15
examples/Console/Grids/Grids.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Grids</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to render grids in a console.</ExampleDescription>
|
||||||
|
<ExampleGroup>Widgets</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
15
examples/Console/Info/Info.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Info</ExampleTitle>
|
||||||
|
<ExampleDescription>Displays the capabilities of the current console.</ExampleDescription>
|
||||||
|
<ExampleGroup>Misc</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using Spectre.Console;
|
using Spectre.Console;
|
||||||
|
|
||||||
namespace InfoExample
|
namespace InfoExample
|
||||||
@@ -13,7 +12,7 @@ namespace InfoExample
|
|||||||
.AddRow("[b]Color system[/]", $"{AnsiConsole.Capabilities.ColorSystem}")
|
.AddRow("[b]Color system[/]", $"{AnsiConsole.Capabilities.ColorSystem}")
|
||||||
.AddRow("[b]Supports ansi?[/]", $"{YesNo(AnsiConsole.Capabilities.SupportsAnsi)}")
|
.AddRow("[b]Supports ansi?[/]", $"{YesNo(AnsiConsole.Capabilities.SupportsAnsi)}")
|
||||||
.AddRow("[b]Legacy console?[/]", $"{YesNo(AnsiConsole.Capabilities.LegacyConsole)}")
|
.AddRow("[b]Legacy console?[/]", $"{YesNo(AnsiConsole.Capabilities.LegacyConsole)}")
|
||||||
.AddRow("[b]Interactive?[/]", $"{YesNo(Environment.UserInteractive)}")
|
.AddRow("[b]Interactive?[/]", $"{YesNo(AnsiConsole.Capabilities.SupportsInteraction)}")
|
||||||
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Width}")
|
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Width}")
|
||||||
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Height}");
|
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Height}");
|
||||||
|
|
||||||
15
examples/Console/Links/Links.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Links</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to render links in a console.</ExampleDescription>
|
||||||
|
<ExampleGroup>Misc</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
15
examples/Console/Panels/Panels.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Panels</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to render items in panels.</ExampleDescription>
|
||||||
|
<ExampleGroup>Widgets</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
45
examples/Console/Progress/DescriptionGenerator.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ProgressExample
|
||||||
|
{
|
||||||
|
public static class DescriptionGenerator
|
||||||
|
{
|
||||||
|
private static readonly string[] _verbs = new[] { "Downloading", "Rerouting", "Retriculating", "Collapsing", "Folding", "Solving", "Colliding", "Measuring" };
|
||||||
|
private static readonly string[] _nouns = new[] { "internet", "splines", "space", "capacitators", "quarks", "algorithms", "data structures", "spacetime" };
|
||||||
|
|
||||||
|
private static readonly Random _random;
|
||||||
|
private static readonly HashSet<string> _used;
|
||||||
|
|
||||||
|
static DescriptionGenerator()
|
||||||
|
{
|
||||||
|
_random = new Random(DateTime.Now.Millisecond);
|
||||||
|
_used = new HashSet<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGenerate(out string name)
|
||||||
|
{
|
||||||
|
var iterations = 0;
|
||||||
|
while (iterations < 25)
|
||||||
|
{
|
||||||
|
name = Generate();
|
||||||
|
if (!_used.Contains(name))
|
||||||
|
{
|
||||||
|
_used.Add(name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterations++;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = Generate();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Generate()
|
||||||
|
{
|
||||||
|
return _verbs[_random.Next(0, _verbs.Length)]
|
||||||
|
+ " " + _nouns[_random.Next(0, _nouns.Length)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
examples/Console/Progress/Program.cs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace ProgressExample
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine("[yellow]Initializing warp drive[/]...");
|
||||||
|
|
||||||
|
// Show progress
|
||||||
|
AnsiConsole.Progress()
|
||||||
|
.AutoClear(false)
|
||||||
|
.Columns(new ProgressColumn[]
|
||||||
|
{
|
||||||
|
new TaskDescriptionColumn(), // Task description
|
||||||
|
new ProgressBarColumn(), // Progress bar
|
||||||
|
new PercentageColumn(), // Percentage
|
||||||
|
new RemainingTimeColumn(), // Remaining time
|
||||||
|
new SpinnerColumn(), // Spinner
|
||||||
|
})
|
||||||
|
.Start(ctx =>
|
||||||
|
{
|
||||||
|
var random = new Random(DateTime.Now.Millisecond);
|
||||||
|
var tasks = CreateTasks(ctx, random);
|
||||||
|
|
||||||
|
while (!ctx.IsFinished)
|
||||||
|
{
|
||||||
|
// Increment progress
|
||||||
|
foreach (var (task, increment) in tasks)
|
||||||
|
{
|
||||||
|
task.Increment(random.NextDouble() * increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write some random things to the terminal
|
||||||
|
if (random.NextDouble() < 0.1)
|
||||||
|
{
|
||||||
|
WriteLogMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate some delay
|
||||||
|
Thread.Sleep(100);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Done
|
||||||
|
AnsiConsole.MarkupLine("[green]Done![/]");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<(ProgressTask, int)> CreateTasks(ProgressContext progress, Random random)
|
||||||
|
{
|
||||||
|
var tasks = new List<(ProgressTask, int)>();
|
||||||
|
while (tasks.Count < 5)
|
||||||
|
{
|
||||||
|
if (DescriptionGenerator.TryGenerate(out var name))
|
||||||
|
{
|
||||||
|
tasks.Add((progress.AddTask(name), random.Next(2, 10)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteLogMessage()
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine(
|
||||||
|
"[grey]LOG:[/] " +
|
||||||
|
DescriptionGenerator.Generate() +
|
||||||
|
"[grey]...[/]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
examples/Console/Progress/Progress.csproj
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Progress</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to show progress bars.</ExampleDescription>
|
||||||
|
<ExampleGroup>Status</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -6,6 +6,13 @@ namespace Cursor
|
|||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
// Check if we can accept key strokes
|
||||||
|
if (!AnsiConsole.Capabilities.SupportsInteraction)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine("[red]Environment does not support interaction.[/]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Confirmation
|
// Confirmation
|
||||||
if (!AnsiConsole.Confirm("Run prompt example?"))
|
if (!AnsiConsole.Confirm("Run prompt example?"))
|
||||||
{
|
{
|
||||||
@@ -13,26 +20,87 @@ namespace Cursor
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// String
|
// Ask the user for some different things
|
||||||
|
var name = AskName();
|
||||||
|
var fruit = AskFruit();
|
||||||
|
var sport = AskSport();
|
||||||
|
var age = AskAge();
|
||||||
|
var password = AskPassword();
|
||||||
|
var color = AskColor();
|
||||||
|
|
||||||
|
// 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]Favorite sport[/]", sport)
|
||||||
|
.AddRow("[grey]Age[/]", age.ToString())
|
||||||
|
.AddRow("[grey]Password[/]", password)
|
||||||
|
.AddRow("[grey]Favorite color[/]", string.IsNullOrEmpty(color) ? "Unknown" : color));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string AskName()
|
||||||
|
{
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
AnsiConsole.Render(new Rule("[yellow]Strings[/]").RuleStyle("grey").LeftAligned());
|
AnsiConsole.Render(new Rule("[yellow]Strings[/]").RuleStyle("grey").LeftAligned());
|
||||||
var name = AnsiConsole.Ask<string>("What's your [green]name[/]?");
|
var name = AnsiConsole.Ask<string>("What's your [green]name[/]?");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
// String with choices
|
private static string AskFruit()
|
||||||
|
{
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.Render(new Rule("[yellow]Lists[/]").RuleStyle("grey").LeftAligned());
|
||||||
|
|
||||||
|
var favorites = AnsiConsole.Prompt(
|
||||||
|
new MultiSelectionPrompt<string>()
|
||||||
|
.PageSize(10)
|
||||||
|
.Title("What are your [green]favorite fruits[/]?")
|
||||||
|
.AddChoices(new[]
|
||||||
|
{
|
||||||
|
"Apple", "Apricot", "Avocado", "Banana", "Blackcurrant", "Blueberry",
|
||||||
|
"Cherry", "Cloudberry", "Cocunut", "Date", "Dragonfruit", "Durian",
|
||||||
|
"Egg plant", "Elderberry", "Fig", "Grape", "Guava", "Honeyberry",
|
||||||
|
"Jackfruit", "Jambul", "Kiwano", "Kiwifruit", "Lime", "Lylo",
|
||||||
|
"Lychee", "Melon", "Mulberry", "Nectarine", "Orange", "Olive"
|
||||||
|
}));
|
||||||
|
|
||||||
|
var fruit = favorites.Count == 1 ? favorites[0] : null;
|
||||||
|
if (string.IsNullOrWhiteSpace(fruit))
|
||||||
|
{
|
||||||
|
fruit = AnsiConsole.Prompt(
|
||||||
|
new SelectionPrompt<string>()
|
||||||
|
.Title("Ok, but if you could only choose [green]one[/]?")
|
||||||
|
.AddChoices(favorites));
|
||||||
|
}
|
||||||
|
|
||||||
|
AnsiConsole.MarkupLine("Your selected: [yellow]{0}[/]", fruit);
|
||||||
|
return fruit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string AskSport()
|
||||||
|
{
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
AnsiConsole.Render(new Rule("[yellow]Choices[/]").RuleStyle("grey").LeftAligned());
|
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
|
return AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<string>("What's your [green]favorite sport[/]?")
|
||||||
|
.InvalidChoiceMessage("[red]That's not a valid fruit[/]")
|
||||||
|
.DefaultValue("Lol")
|
||||||
|
.AddChoice("Soccer")
|
||||||
|
.AddChoice("Hockey")
|
||||||
|
.AddChoice("Basketball"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int AskAge()
|
||||||
|
{
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
AnsiConsole.Render(new Rule("[yellow]Integers[/]").RuleStyle("grey").LeftAligned());
|
AnsiConsole.Render(new Rule("[yellow]Integers[/]").RuleStyle("grey").LeftAligned());
|
||||||
var age = AnsiConsole.Prompt(
|
|
||||||
|
return AnsiConsole.Prompt(
|
||||||
new TextPrompt<int>("How [green]old[/] are you?")
|
new TextPrompt<int>("How [green]old[/] are you?")
|
||||||
.PromptStyle("green")
|
.PromptStyle("green")
|
||||||
.ValidationErrorMessage("[red]That's not a valid age[/]")
|
.ValidationErrorMessage("[red]That's not a valid age[/]")
|
||||||
@@ -45,33 +113,27 @@ namespace Cursor
|
|||||||
_ => ValidationResult.Success(),
|
_ => ValidationResult.Success(),
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
// Secret
|
private static string AskPassword()
|
||||||
|
{
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
AnsiConsole.Render(new Rule("[yellow]Secrets[/]").RuleStyle("grey").LeftAligned());
|
AnsiConsole.Render(new Rule("[yellow]Secrets[/]").RuleStyle("grey").LeftAligned());
|
||||||
var password = AnsiConsole.Prompt(
|
|
||||||
|
return AnsiConsole.Prompt(
|
||||||
new TextPrompt<string>("Enter [green]password[/]?")
|
new TextPrompt<string>("Enter [green]password[/]?")
|
||||||
.PromptStyle("red")
|
.PromptStyle("red")
|
||||||
.Secret());
|
.Secret());
|
||||||
|
}
|
||||||
|
|
||||||
// Optional
|
private static string AskColor()
|
||||||
|
{
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
AnsiConsole.Render(new Rule("[yellow]Optional[/]").RuleStyle("grey").LeftAligned());
|
AnsiConsole.Render(new Rule("[yellow]Optional[/]").RuleStyle("grey").LeftAligned());
|
||||||
var color = AnsiConsole.Prompt(
|
|
||||||
|
return AnsiConsole.Prompt(
|
||||||
new TextPrompt<string>("[grey][[Optional]][/] What is your [green]favorite color[/]?")
|
new TextPrompt<string>("[grey][[Optional]][/] What is your [green]favorite color[/]?")
|
||||||
.AllowEmpty());
|
.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/Console/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>
|
||||||
|
<ExampleTitle>Prompt</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to get input from a user.</ExampleDescription>
|
||||||
|
<ExampleGroup>Misc</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
15
examples/Console/Rules/Rules.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<ExampleTitle>Rules</ExampleTitle>
|
||||||
|
<ExampleDescription>Demonstrates how to render horizontal rules (lines).</ExampleDescription>
|
||||||
|
<ExampleGroup>Widgets</ExampleGroup>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
70
examples/Console/Status/Program.cs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
using System.Threading;
|
||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace ProgressExample
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
AnsiConsole.Status()
|
||||||
|
.AutoRefresh(true)
|
||||||
|
.Spinner(Spinner.Known.Default)
|
||||||
|
.Start("[yellow]Initializing warp drive[/]", ctx =>
|
||||||
|
{
|
||||||
|
// Initialize
|
||||||
|
Thread.Sleep(3000);
|
||||||
|
WriteLogMessage("Starting gravimetric field displacement manifold");
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
WriteLogMessage("Warming up deuterium chamber");
|
||||||
|
Thread.Sleep(2000);
|
||||||
|
WriteLogMessage("Generating antideuterium");
|
||||||
|
|
||||||
|
// Warp nacelles
|
||||||
|
Thread.Sleep(3000);
|
||||||
|
ctx.Spinner(Spinner.Known.BouncingBar);
|
||||||
|
ctx.Status("[bold blue]Unfolding warp nacelles[/]");
|
||||||
|
WriteLogMessage("Unfolding left warp nacelle");
|
||||||
|
Thread.Sleep(2000);
|
||||||
|
WriteLogMessage("Left warp nacelle [green]online[/]");
|
||||||
|
WriteLogMessage("Unfolding right warp nacelle");
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
WriteLogMessage("Right warp nacelle [green]online[/]");
|
||||||
|
|
||||||
|
// Warp bubble
|
||||||
|
Thread.Sleep(3000);
|
||||||
|
ctx.Spinner(Spinner.Known.Star2);
|
||||||
|
ctx.Status("[bold blue]Generating warp bubble[/]");
|
||||||
|
Thread.Sleep(3000);
|
||||||
|
ctx.Spinner(Spinner.Known.Star);
|
||||||
|
ctx.Status("[bold blue]Stabilizing warp bubble[/]");
|
||||||
|
|
||||||
|
// Safety
|
||||||
|
ctx.Spinner(Spinner.Known.Monkey);
|
||||||
|
ctx.Status("[bold blue]Performing safety checks[/]");
|
||||||
|
WriteLogMessage("Enabling interior dampening");
|
||||||
|
Thread.Sleep(2000);
|
||||||
|
WriteLogMessage("Interior dampening [green]enabled[/]");
|
||||||
|
|
||||||
|
// Warp!
|
||||||
|
Thread.Sleep(3000);
|
||||||
|
ctx.Spinner(Spinner.Known.Moon);
|
||||||
|
WriteLogMessage("Preparing for warp");
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
for (var warp = 1; warp < 10; warp++)
|
||||||
|
{
|
||||||
|
ctx.Status($"[bold blue]Warp {warp}[/]");
|
||||||
|
Thread.Sleep(500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Done
|
||||||
|
AnsiConsole.MarkupLine("[bold green]Crusing at Warp 9.8[/]");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteLogMessage(string message)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine($"[grey]LOG:[/] {message}[grey]...[/]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||