Compare commits
78 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4dda283bb | ||
|
|
da9c6ee4c2 | ||
|
|
855127f32a | ||
|
|
fa731070d8 | ||
|
|
ef08c5bf2b | ||
|
|
1c769c6610 | ||
|
|
1cd335e785 | ||
|
|
29e6e34f83 | ||
|
|
bff3438a5a | ||
|
|
c64884854f | ||
|
|
3a42c0a119 | ||
|
|
525b414ff8 | ||
|
|
ed0fb29be4 | ||
|
|
04d0e663d5 | ||
|
|
17ee8990f4 | ||
|
|
a1050fc676 | ||
|
|
9312663bde | ||
|
|
102e2dc38d | ||
|
|
28e9c14de4 | ||
|
|
fd217ffc83 | ||
|
|
95ec04df40 | ||
|
|
705cf745ea | ||
|
|
b64e016e8c | ||
|
|
58400fe74e | ||
|
|
e20f6284f9 | ||
|
|
953008b5e3 | ||
|
|
ad49b6aa67 | ||
|
|
31a5e17a45 | ||
|
|
f06dc7e7d8 | ||
|
|
a23bec4082 | ||
|
|
913a7b1e37 | ||
|
|
63bae278a9 | ||
|
|
1a747696a8 | ||
|
|
994540d97f | ||
|
|
dee3c01629 | ||
|
|
a3e11b24e5 | ||
|
|
35568ab823 | ||
|
|
07db28bb6f | ||
|
|
d87d8e4422 | ||
|
|
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 |
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.
|
||||||
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.
|
||||||
77
README.fa.md
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
# `Spectre.Console`
|
||||||
|
|
||||||
|
_[](https://www.nuget.org/packages/spectre.console)_
|
||||||
|
|
||||||
|
<div dir="rtl">
|
||||||
|
|
||||||
|
یک کتابخانه NET Standard 2.0/.NET 5. که ایجاد Console Applicationهای زیبا و cross platform را آسانتر میکند.
|
||||||
|
از کتابخانه عالی [Rich](https://github.com/willmcgugan/rich) برای پایتون، بسیار الهام گرفته شده است.
|
||||||
|
|
||||||
|
## فهرست
|
||||||
|
|
||||||
|
1. [امکانات](#features)
|
||||||
|
2. [نصب](#installing)
|
||||||
|
3. [مستندات](#documentation)
|
||||||
|
4. [مثالها](#examples)
|
||||||
|
5. [مجوز](#license)
|
||||||
|
|
||||||
|
<h2 id="features">امکانات</h2>
|
||||||
|
|
||||||
|
* با در نظر گرفتن تست واحد نوشته شده است.
|
||||||
|
* جداول، چارچوبها، پنلها و یک زبان نشانه گذاری که از [rich](https://github.com/willmcgugan/rich) الهام گرفته شده است را پشتیبانی میکند.
|
||||||
|
* از رایج ترین پارامترهای SRG در هنگام فرم دهی متن مانند پررنگ، کم نور، اریب، زیرخط، خط زدن و چشمک زدن پشتیبانی میکند.
|
||||||
|
* پشتیبانی از رنگهای 28/8/4/3-بیت در ترمینال.
|
||||||
|
این کتابخانه توانایی ترمینال فعلی را تشخیص داده و در صورت لزوم رنگها را کاهش میدهد.
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
<h2 id="installing">نصب</h2>
|
||||||
|
|
||||||
|
سریع ترین راه برای شروع `Spectre.Console` نصب از طریق NuGet Package میباشد.
|
||||||
|
|
||||||
|
<pre dir="ltr">
|
||||||
|
dotnet add package Spectre.Console
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h2 id="documentation">مستندات</h2>
|
||||||
|
|
||||||
|
مستندات `Spectre.Console` را در اینجا میتوایند پیدا کنید:
|
||||||
|
|
||||||
|
<div dir="ltr">
|
||||||
|
https://spectresystems.github.io/spectre.console/
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 id="examples">مثالها</h2>
|
||||||
|
|
||||||
|
برای بررسی `Spectre.Console` در عمل، ابزار سراسری
|
||||||
|
[dotnet-example](https://github.com/patriksvensson/dotnet-example)
|
||||||
|
را نصب کنید.
|
||||||
|
|
||||||
|
<pre dir="ltr">
|
||||||
|
> dotnet tool restore
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
حالا شما میتوانید مثالهای موجود در این مخزن را لیست کنید:
|
||||||
|
|
||||||
|
<pre dir="ltr">
|
||||||
|
> dotnet example
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
و برای اجرای مثال:
|
||||||
|
|
||||||
|
<pre dir="ltr">
|
||||||
|
> dotnet example tables
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h2 id="license">مجوز</h2>
|
||||||
|
|
||||||
|
<div dir="ltr">
|
||||||
|
Copyright © Spectre Systems.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
همانطور که Spectre.Console تحت مجوز MIT ارائه شده است؛ برای کسب اطلاعات بیشتر به مجوز مراجعه کنید.
|
||||||
|
|
||||||
|
* برای SixLabors.ImageSharp، مشاهده کنید: https://github.com/SixLabors/ImageSharp/blob/master/LICENSE
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -29,7 +29,7 @@ Python用の素晴らしい[Rich ライブラリ](https://github.com/willmcgugan
|
|||||||
|
|
||||||
## 例
|
## 例
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## 使用方法
|
## 使用方法
|
||||||
|
|
||||||
@@ -111,6 +111,7 @@ Spectre.Consoleでできることを見るために、
|
|||||||
│ Panels │ examples/Panels/Panels.csproj │ Demonstrates how to render items in panels. │
|
│ Panels │ examples/Panels/Panels.csproj │ Demonstrates how to render items in panels. │
|
||||||
│ Rules │ examples/Rules/Rules.csproj │ Demonstrates how to render horizontal rules (lines). │
|
│ Rules │ examples/Rules/Rules.csproj │ Demonstrates how to render horizontal rules (lines). │
|
||||||
│ Tables │ examples/Tables/Tables.csproj │ Demonstrates how to render tables in a console. │
|
│ Tables │ examples/Tables/Tables.csproj │ Demonstrates how to render tables in a console. │
|
||||||
|
│ Trees │ examples/Trees/Trees.csproj │ Demonstrates how to render trees in a console. │
|
||||||
╰────────────┴───────────────────────────────────────┴──────────────────────────────────────────────────────╯
|
╰────────────┴───────────────────────────────────────┴──────────────────────────────────────────────────────╯
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
21
README.md
@@ -12,6 +12,7 @@ for Python.
|
|||||||
2. [Installing](#installing)
|
2. [Installing](#installing)
|
||||||
3. [Documentation](#documentation)
|
3. [Documentation](#documentation)
|
||||||
4. [Examples](#examples)
|
4. [Examples](#examples)
|
||||||
|
5. [Sponsors](#sponsors)
|
||||||
5. [License](#license)
|
5. [License](#license)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
@@ -26,7 +27,7 @@ for Python.
|
|||||||
and downgrade colors as needed.
|
and downgrade colors as needed.
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|
||||||
@@ -63,6 +64,24 @@ And to run an example:
|
|||||||
> dotnet example tables
|
> dotnet example tables
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Sponsors
|
||||||
|
|
||||||
|
The following people are [sponsoring](https://github.com/sponsors/patriksvensson)
|
||||||
|
Spectre.Console to show their support and to ensure the longevity of the project.
|
||||||
|
|
||||||
|
* [Rodney Littles II](https://github.com/RLittlesII)
|
||||||
|
* [Martin Björkström](https://github.com/bjorkstromm)
|
||||||
|
* [Dave Glick](https://github.com/daveaglick)
|
||||||
|
* [Kim Gunanrsson](https://github.com/kimgunnarsson)
|
||||||
|
* [Andrew McClenaghan](https://github.com/andymac4182)
|
||||||
|
* [C. Augusto Proiete](https://github.com/augustoproiete)
|
||||||
|
* [Viktor Elofsson](https://github.com/vktr)
|
||||||
|
* [Steven Knox](https://github.com/stevenknox)
|
||||||
|
* [David Pendray](https://github.com/dpen2000)
|
||||||
|
|
||||||
|
I really appreciate it.
|
||||||
|
**Thank you very much!**
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright © Spectre Systems.
|
Copyright © Spectre Systems.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ To start contributing to the [Spectre.Console](https://github.com/spectresystems
|
|||||||
The documentation site uses [Statiq](https://statiq.dev), a static site generator. To build the documentation site run the following in a command-line terminal.
|
The documentation site uses [Statiq](https://statiq.dev), a static site generator. To build the documentation site run the following in a command-line terminal.
|
||||||
|
|
||||||
```
|
```
|
||||||
> dotnet run preview --virtual-dir "spectre.console"
|
> Preview.ps1
|
||||||
```
|
```
|
||||||
|
|
||||||
After the build is complete, you can navigate to [http://localhost:5080/spectre.console](http://localhost:5080/spectre.console).
|
After the build is complete, you can navigate to [http://localhost:5080/spectre.console](http://localhost:5080/spectre.console).
|
||||||
@@ -29,13 +29,7 @@ Layout and styling can also be found in the [input](./input) directory. Look for
|
|||||||
|
|
||||||
## Custom Build Features
|
## Custom Build Features
|
||||||
|
|
||||||
The documentation site has custom enhancements to Statiq located under the [./src](./src) directory. Enhancements to the build process include:
|
The documentation site has custom enhancements to Statiq located under the [./src](./src) directory.
|
||||||
|
|
||||||
- [Extension Methods](./src/Extensions)
|
|
||||||
- [Models](./src/Models)
|
|
||||||
- [Pipelines](./src/Pipelines)
|
|
||||||
- [Shortcodes](./src/Shortcodes)
|
|
||||||
- [Utilities](./src/Utilities)
|
|
||||||
|
|
||||||
## License
|
## 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/example.png
Normal file
|
After Width: | Height: | Size: 219 KiB |
BIN
docs/input/assets/images/multiselection.gif
Normal file
|
After Width: | Height: | Size: 229 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>
|
||||||
119
docs/input/cli/introduction.md
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
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(CommandContext context, AddPackageSettings settings)
|
||||||
|
{
|
||||||
|
// Omitted
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AddReferenceCommand : Command<AddReferenceSettings>
|
||||||
|
{
|
||||||
|
public override int Execute(CommandContext context, AddReferenceSettings settings)
|
||||||
|
{
|
||||||
|
// Omitted
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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;
|
||||||
|
```
|
||||||
@@ -2,7 +2,7 @@ Title: Exceptions
|
|||||||
Order: 3
|
Order: 3
|
||||||
---
|
---
|
||||||
|
|
||||||
Exceptions isn't always readable when viewed in the terminal.
|
Exceptions aren't always readable when viewed in the terminal.
|
||||||
You can make exception a bit more readable by using the `WriteException` method.
|
You can make exception a bit more readable by using the `WriteException` method.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
|||||||
@@ -22,5 +22,5 @@ for Python written by Will McGugan.
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
<img src="assets/images/table.gif" style="max-width: 100%; margin-top: 15px; margin-bottom: 25px;" />
|
<img src="./assets/images/example.png" style="max-width: 100%; margin-top: 15px; margin-bottom: 25px;" />
|
||||||
<img src="https://github.com/spectresystems/spectre.console/raw/main/resources/gfx/screenshots/example.png" style="max-width: 100%;" />
|
<img src="./assets/images/table.gif" style="max-width: 100%;" />
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ await AnsiConsole.Progress()
|
|||||||
AnsiConsole.Progress()
|
AnsiConsole.Progress()
|
||||||
.AutoRefresh(false) // Turn off auto refresh
|
.AutoRefresh(false) // Turn off auto refresh
|
||||||
.AutoClear(false) // Do not remove the task list when done
|
.AutoClear(false) // Do not remove the task list when done
|
||||||
|
.HideCompleted(false) // Hide tasks as they are completed
|
||||||
.Columns(new ProgressColumn[]
|
.Columns(new ProgressColumn[]
|
||||||
{
|
{
|
||||||
new TaskDescriptionColumn(), // Task description
|
new TaskDescriptionColumn(), // Task description
|
||||||
|
|||||||
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
|
||||||
19
docs/input/sponsors.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Title: Sponsors
|
||||||
|
Order: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
The following people are [sponsoring](https://github.com/sponsors/patriksvensson)
|
||||||
|
Spectre.Console to show their support and to ensure the longevity of the project.
|
||||||
|
|
||||||
|
* [Rodney Littles II](https://github.com/RLittlesII)
|
||||||
|
* [Martin Björkström](https://github.com/bjorkstromm)
|
||||||
|
* [Dave Glick](https://github.com/daveaglick)
|
||||||
|
* [Kim Gunanrsson](https://github.com/kimgunnarsson)
|
||||||
|
* [Andrew McClenaghan](https://github.com/andymac4182)
|
||||||
|
* [C. Augusto Proiete](https://github.com/augustoproiete)
|
||||||
|
* [Viktor Elofsson](https://github.com/vktr)
|
||||||
|
* [Steven Knox](https://github.com/stevenknox)
|
||||||
|
* [David Pendray](https://github.com/dpen2000)
|
||||||
|
|
||||||
|
I really appreciate it.
|
||||||
|
**Thank you very much!**
|
||||||
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
|
||||||
|
|||||||
@@ -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}!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
examples/Cli/Injection/Infrastructure/TypeRegistrar.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterLazy(Type service, Func<object> func)
|
||||||
|
{
|
||||||
|
if (func is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(func));
|
||||||
|
}
|
||||||
|
|
||||||
|
_builder.AddSingleton(service, (provider) => func());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
examples/Cli/Logging/Commands/HelloCommand.cs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Spectre.Console;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Logging.Commands
|
||||||
|
{
|
||||||
|
public class HelloCommand : Command<HelloCommand.Settings>
|
||||||
|
{
|
||||||
|
private ILogger<HelloCommand> _logger;
|
||||||
|
private IAnsiConsole _console;
|
||||||
|
|
||||||
|
public HelloCommand(IAnsiConsole console, ILogger<HelloCommand> logger)
|
||||||
|
{
|
||||||
|
_console = console;
|
||||||
|
_logger = logger;
|
||||||
|
_logger.LogDebug("{0} initialized", nameof(HelloCommand));
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Settings : LogCommandSettings
|
||||||
|
{
|
||||||
|
[CommandArgument(0, "[Name]")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override int Execute(CommandContext context, Settings settings)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Starting my command");
|
||||||
|
AnsiConsole.MarkupLine($"Hello, [blue]{settings.Name}[/]");
|
||||||
|
_logger.LogInformation("Completed my command");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
56
examples/Cli/Logging/Commands/LogCommandSettings.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
using Serilog.Events;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Logging.Commands
|
||||||
|
{
|
||||||
|
public class LogCommandSettings : CommandSettings
|
||||||
|
{
|
||||||
|
[CommandOption("--logFile")]
|
||||||
|
[Description("Path and file name for logging")]
|
||||||
|
public string LogFile { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("--logLevel")]
|
||||||
|
[Description("Minimum level for logging")]
|
||||||
|
[TypeConverter(typeof(VerbosityConverter))]
|
||||||
|
[DefaultValue(LogEventLevel.Information)]
|
||||||
|
public LogEventLevel LogLevel { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class VerbosityConverter : TypeConverter
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, LogEventLevel> _lookup;
|
||||||
|
|
||||||
|
public VerbosityConverter()
|
||||||
|
{
|
||||||
|
_lookup = new Dictionary<string, LogEventLevel>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
{"d", LogEventLevel.Debug},
|
||||||
|
{"v", LogEventLevel.Verbose},
|
||||||
|
{"i", LogEventLevel.Information},
|
||||||
|
{"w", LogEventLevel.Warning},
|
||||||
|
{"e", LogEventLevel.Error},
|
||||||
|
{"f", LogEventLevel.Fatal}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
|
{
|
||||||
|
if (value is string stringValue)
|
||||||
|
{
|
||||||
|
var result = _lookup.TryGetValue(stringValue, out var verbosity);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
const string format = "The value '{0}' is not a valid verbosity.";
|
||||||
|
var message = string.Format(CultureInfo.InvariantCulture, format, value);
|
||||||
|
throw new InvalidOperationException(message);
|
||||||
|
}
|
||||||
|
return verbosity;
|
||||||
|
}
|
||||||
|
throw new NotSupportedException("Can't convert value to verbosity.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
examples/Cli/Logging/Infrastructure/LogInterceptor.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using Logging.Commands;
|
||||||
|
using Serilog.Core;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Logging
|
||||||
|
{
|
||||||
|
public class LogInterceptor : ICommandInterceptor
|
||||||
|
{
|
||||||
|
public static readonly LoggingLevelSwitch LogLevel = new();
|
||||||
|
|
||||||
|
public void Intercept(CommandContext context, CommandSettings settings)
|
||||||
|
{
|
||||||
|
if (settings is LogCommandSettings logSettings)
|
||||||
|
{
|
||||||
|
LoggingEnricher.Path = logSettings.LogFile ?? "application.log";
|
||||||
|
LogLevel.MinimumLevel = logSettings.LogLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
38
examples/Cli/Logging/Infrastructure/LoggingEnricher.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using Serilog.Core;
|
||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace Logging
|
||||||
|
{
|
||||||
|
internal class LoggingEnricher : ILogEventEnricher
|
||||||
|
{
|
||||||
|
private string _cachedLogFilePath;
|
||||||
|
private LogEventProperty _cachedLogFilePathProperty;
|
||||||
|
|
||||||
|
// this path and level will be set by the LogInterceptor.cs after parsing the settings
|
||||||
|
public static string Path = string.Empty;
|
||||||
|
|
||||||
|
public const string LogFilePathPropertyName = "LogFilePath";
|
||||||
|
|
||||||
|
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
|
||||||
|
{
|
||||||
|
// the settings might not have a path or we might not be within a command in which case
|
||||||
|
// we won't have the setting so a default value for the log file will be required
|
||||||
|
LogEventProperty logFilePathProperty;
|
||||||
|
|
||||||
|
if (_cachedLogFilePathProperty != null && Path.Equals(_cachedLogFilePath))
|
||||||
|
{
|
||||||
|
// Path hasn't changed, so let's use the cached property
|
||||||
|
logFilePathProperty = _cachedLogFilePathProperty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We've got a new path for the log. Let's create a new property
|
||||||
|
// and cache it for future log events to use
|
||||||
|
_cachedLogFilePath = Path;
|
||||||
|
_cachedLogFilePathProperty = logFilePathProperty = propertyFactory.CreateProperty(LogFilePathPropertyName, Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
logEvent.AddPropertyIfAbsent(logFilePathProperty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
examples/Cli/Logging/Infrastructure/TypeRegistrar.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Logging
|
||||||
|
{
|
||||||
|
public sealed class TypeRegistrar : ITypeRegistrar
|
||||||
|
{
|
||||||
|
private readonly IServiceCollection _builder;
|
||||||
|
|
||||||
|
public TypeRegistrar(IServiceCollection builder)
|
||||||
|
{
|
||||||
|
_builder = builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITypeResolver Build()
|
||||||
|
{
|
||||||
|
return new TypeResolver(_builder.BuildServiceProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Register(Type service, Type implementation)
|
||||||
|
{
|
||||||
|
_builder.AddSingleton(service, implementation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterInstance(Type service, object implementation)
|
||||||
|
{
|
||||||
|
_builder.AddSingleton(service, implementation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterLazy(Type service, Func<object> func)
|
||||||
|
{
|
||||||
|
if (func is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(func));
|
||||||
|
}
|
||||||
|
|
||||||
|
_builder.AddSingleton(service, _ => func());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
examples/Cli/Logging/Infrastructure/TypeResolver.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Logging
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
examples/Cli/Logging/Logging.csproj
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<ExampleName>Logging</ExampleName>
|
||||||
|
<ExampleDescription>Demonstrates how to dynamically configure Serilog for logging using parameters from a command.</ExampleDescription>
|
||||||
|
<ExampleGroup>Cli</ExampleGroup>
|
||||||
|
<ExampleVisible>false</ExampleVisible>
|
||||||
|
<Nullable>disable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
|
||||||
|
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||||
|
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.Map" Version="1.0.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
54
examples/Cli/Logging/Program.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using Logging.Commands;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Serilog;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dynamically control serilog configuration via command line parameters
|
||||||
|
*
|
||||||
|
* This works around the chicken and egg situation with configuring serilog via the command line.
|
||||||
|
* The logger needs to be configured prior to executing the parser, but the logger needs the parsed values
|
||||||
|
* to be configured. By using serilog.sinks.map we can defer configuration. We use a LogLevelSwitch to control the
|
||||||
|
* logging levels dynamically, and then we use a serilog enricher that has it's state populated via a
|
||||||
|
* Spectre.Console CommandInterceptor
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Logging
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
static int Main(string[] args)
|
||||||
|
{
|
||||||
|
// to retrieve the log file name, we must first parse the command settings
|
||||||
|
// this will require us to delay setting the file path for the file writer.
|
||||||
|
// With serilog we can use an enricher and Serilog.Sinks.Map to dynamically
|
||||||
|
// pull this setting.
|
||||||
|
var serviceCollection = new ServiceCollection()
|
||||||
|
.AddLogging(configure =>
|
||||||
|
configure.AddSerilog(new LoggerConfiguration()
|
||||||
|
// log level will be dynamically be controlled by our log interceptor upon running
|
||||||
|
.MinimumLevel.ControlledBy(LogInterceptor.LogLevel)
|
||||||
|
// the log enricher will add a new property with the log file path from the settings
|
||||||
|
// that we can use to set the path dynamically
|
||||||
|
.Enrich.With<LoggingEnricher>()
|
||||||
|
// serilog.sinks.map will defer the configuration of the sink to be ondemand
|
||||||
|
// allowing us to look at the properties set by the enricher to set the path appropriately
|
||||||
|
.WriteTo.Map(LoggingEnricher.LogFilePathPropertyName,
|
||||||
|
(logFilePath, wt) => wt.File($"{logFilePath}"), 1)
|
||||||
|
.CreateLogger()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
var registrar = new TypeRegistrar(serviceCollection);
|
||||||
|
var app = new CommandApp(registrar);
|
||||||
|
|
||||||
|
app.Configure(config =>
|
||||||
|
{
|
||||||
|
config.SetInterceptor(new LogInterceptor()); // add the interceptor
|
||||||
|
config.AddCommand<HelloCommand>("hello");
|
||||||
|
});
|
||||||
|
|
||||||
|
return app.Run(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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>net5.0</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>
|
||||||
|
<EmbeddedResource Include="cake.png">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.Reflection;
|
||||||
using SixLabors.ImageSharp.Processing;
|
using SixLabors.ImageSharp.Processing;
|
||||||
using Spectre.Console;
|
using Spectre.Console;
|
||||||
using Spectre.Console.Rendering;
|
using Spectre.Console.Rendering;
|
||||||
@@ -23,6 +25,16 @@ namespace CanvasExample
|
|||||||
image.NoMaxWidth();
|
image.NoMaxWidth();
|
||||||
image.Mutate(ctx => ctx.Grayscale().Rotate(-45).EntropyCrop());
|
image.Mutate(ctx => ctx.Grayscale().Rotate(-45).EntropyCrop());
|
||||||
Render(image, "Image from file (fit, greyscale, rotated)");
|
Render(image, "Image from file (fit, greyscale, rotated)");
|
||||||
|
|
||||||
|
// Draw image again, but load from embedded resource rather than file
|
||||||
|
using (var fileStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Canvas.cake.png"))
|
||||||
|
{
|
||||||
|
Debug.Assert(fileStream != null);
|
||||||
|
var embeddedImage = new CanvasImage(fileStream);
|
||||||
|
embeddedImage.BilinearResampler();
|
||||||
|
embeddedImage.MaxWidth(16);
|
||||||
|
Render(embeddedImage, "Image from embedded resource (16 wide)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Render(IRenderable canvas, string title)
|
private static void Render(IRenderable canvas, string title)
|
||||||
|
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>
|
||||||
42
examples/Console/Charts/Program.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using Spectre.Console;
|
||||||
|
using Spectre.Console.Rendering;
|
||||||
|
|
||||||
|
namespace Charts
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
// Render a bar chart
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
Render("Fruits per month", new BarChart()
|
||||||
|
.Width(60)
|
||||||
|
.Label("[green bold underline]Number of fruits[/]")
|
||||||
|
.CenterLabel()
|
||||||
|
.AddItem("Apple", 12, Color.Yellow)
|
||||||
|
.AddItem("Orange", 54, Color.Green)
|
||||||
|
.AddItem("Banana", 33, Color.Red));
|
||||||
|
|
||||||
|
// Render a breakdown chart
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
Render("Languages used", new BreakdownChart()
|
||||||
|
.FullSize()
|
||||||
|
.Width(60)
|
||||||
|
.ShowPercentage()
|
||||||
|
.AddItem("SCSS", 37, Color.Red)
|
||||||
|
.AddItem("HTML", 28.3, Color.Blue)
|
||||||
|
.AddItem("C#", 22.6, Color.Green)
|
||||||
|
.AddItem("JavaScript", 6, Color.Yellow)
|
||||||
|
.AddItem("Ruby", 6, Color.LightGreen)
|
||||||
|
.AddItem("Shell", 0.1, Color.Aqua));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Render(string title, IRenderable chart)
|
||||||
|
{
|
||||||
|
AnsiConsole.Render(
|
||||||
|
new Panel(chart)
|
||||||
|
.Padding(1, 1)
|
||||||
|
.Header(title));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
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>
|
||||||
@@ -6,7 +6,7 @@ namespace ColorExample
|
|||||||
{
|
{
|
||||||
public static void Main()
|
public static void Main()
|
||||||
{
|
{
|
||||||
if (AnsiConsole.Capabilities.ColorSystem == ColorSystem.NoColors)
|
if (AnsiConsole.Profile.ColorSystem == ColorSystem.NoColors)
|
||||||
{
|
{
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
// No colors
|
// No colors
|
||||||
@@ -16,7 +16,7 @@ namespace ColorExample
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AnsiConsole.Capabilities.Supports(ColorSystem.Legacy))
|
if (AnsiConsole.Profile.Supports(ColorSystem.Legacy))
|
||||||
{
|
{
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
// 3-BIT
|
// 3-BIT
|
||||||
@@ -39,7 +39,7 @@ namespace ColorExample
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AnsiConsole.Capabilities.Supports(ColorSystem.Standard))
|
if (AnsiConsole.Profile.Supports(ColorSystem.Standard))
|
||||||
{
|
{
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
// 4-BIT
|
// 4-BIT
|
||||||
@@ -62,7 +62,7 @@ namespace ColorExample
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AnsiConsole.Capabilities.Supports(ColorSystem.EightBit))
|
if (AnsiConsole.Profile.Supports(ColorSystem.EightBit))
|
||||||
{
|
{
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
// 8-BIT
|
// 8-BIT
|
||||||
@@ -89,7 +89,7 @@ namespace ColorExample
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AnsiConsole.Capabilities.Supports(ColorSystem.TrueColor))
|
if (AnsiConsole.Profile.Supports(ColorSystem.TrueColor))
|
||||||
{
|
{
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
// 24-BIT
|
// 24-BIT
|
||||||
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>
|
||||||
@@ -9,12 +9,16 @@ namespace InfoExample
|
|||||||
var grid = new Grid()
|
var grid = new Grid()
|
||||||
.AddColumn(new GridColumn().NoWrap().PadRight(4))
|
.AddColumn(new GridColumn().NoWrap().PadRight(4))
|
||||||
.AddColumn()
|
.AddColumn()
|
||||||
.AddRow("[b]Color system[/]", $"{AnsiConsole.Capabilities.ColorSystem}")
|
.AddRow("[b]Enrichers[/]", string.Join(", ", AnsiConsole.Profile.Enrichers))
|
||||||
.AddRow("[b]Supports ansi?[/]", $"{YesNo(AnsiConsole.Capabilities.SupportsAnsi)}")
|
.AddRow("[b]Color system[/]", $"{AnsiConsole.Profile.ColorSystem}")
|
||||||
.AddRow("[b]Legacy console?[/]", $"{YesNo(AnsiConsole.Capabilities.LegacyConsole)}")
|
.AddRow("[b]Supports ansi?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Ansi)}")
|
||||||
.AddRow("[b]Interactive?[/]", $"{YesNo(AnsiConsole.Capabilities.SupportsInteraction)}")
|
.AddRow("[b]Supports links?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Links)}")
|
||||||
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Width}")
|
.AddRow("[b]Legacy console?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Legacy)}")
|
||||||
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Height}");
|
.AddRow("[b]Interactive?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Interactive)}")
|
||||||
|
.AddRow("[b]TTY?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Tty)}")
|
||||||
|
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Profile.Width}")
|
||||||
|
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Profile.Height}")
|
||||||
|
.AddRow("[b]Encoding[/]", $"{AnsiConsole.Console.Profile.Encoding.EncodingName}");
|
||||||
|
|
||||||
AnsiConsole.Render(
|
AnsiConsole.Render(
|
||||||
new Panel(grid)
|
new Panel(grid)
|
||||||
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>
|
||||||