Compare commits

..

23 Commits

Author SHA1 Message Date
Patrik Svensson
a977fdadff Fix tree node collection type 2021-01-10 16:59:40 +01:00
Patrik Svensson
8261b25e5c Fix tree rendering
Fixes some tree rendering problems where lines were not properly drawn
at some levels during some circumstances.

* Change the API back to only allow one root.
* Now uses a stack based approach to rendering instead of recursion.
* Removes the need for measuring the whole tree in advance.
  Leave this up to each child to render.
2021-01-10 15:55:11 +01:00
Patrik Svensson
0e0f4b4220 Add interactive prompts for selecting values
* Adds SelectionPrompt
* Adds MultiSelectionPrompt

Closes #210
2021-01-09 09:37:28 +01:00
Patrik Svensson
3a593857c8 Add progress and status result overloads 2021-01-06 09:54:45 +01:00
Patrik Svensson
11e192e750 Update Canvas tests 2021-01-06 09:54:45 +01:00
Thomas Freudenberg
8901450283 Allow returning a result from Progress.StartAsync/Status.StartAsync 2021-01-06 08:08:38 +01:00
Patrik Svensson
0796bad598 Add contributing guidelines 2021-01-05 14:38:29 +01:00
Matt Constable
5b553a4106 Added canvas unit tests & fix canvas scaling bug 2021-01-05 14:00:04 +01:00
Patrik Svensson
1bb0b9ccc6 Fix expectation structure 2021-01-05 11:09:35 +01:00
Matt Constable
9ad5f2daeb Fix console detection for Cygwin/WSL-Shell on Windows 2021-01-04 18:24:56 +01:00
Patrik Svensson
1f211d3e1f Add convenience methods for tree nodes 2021-01-03 23:28:55 +01:00
Patrik Svensson
87e6b42409 Add tree example 2021-01-03 23:28:55 +01:00
Patrik Svensson
1aa958ced3 Add support for multiple tree roots 2021-01-03 23:28:55 +01:00
Patrik Svensson
4bfb24bfcb Streamline tree API a bit 2021-01-03 23:28:55 +01:00
Matt Constable
b136d0299b Add tree widget 2021-01-02 10:01:16 +01:00
Patrik Svensson
179e243214 Clean up table rendering a bit 2021-01-02 09:33:22 +01:00
Patrik Svensson
c6210f75ca Prevent endless loop in tokenization
Closes #198
2021-01-01 23:01:51 +01:00
Patrik Svensson
b81739567b Fix argument order in help
Closes #188
2021-01-01 13:43:28 +01:00
Patrik Svensson
5cf41725a5 Do not split remaining args on space
Closes #186
2021-01-01 12:19:37 +01:00
Matthew Constable
f561d71e4e Remove unused Segment.TruncateWithEllipsis method 2020-12-31 17:29:50 +01:00
Simon Cropp
e71db7f78c fix some nullability issues 2020-12-31 11:09:03 +01:00
Patrik Svensson
79742ce9e3 Parse quoted strings correctly
When parsing quoted strings, space was not handled
properly in remaining arguments.

Fixes #186
2020-12-30 18:43:29 +01:00
Patrik Svensson
241423dd16 Do not truncate command table
Temporary fix for commands not showing up if they
are missing a description. This is really a bug in the table
rendering and should be fixed there at some point.

Closes #192
2020-12-30 18:43:29 +01:00
302 changed files with 3755 additions and 893 deletions

1
.gitignore vendored
View File

@@ -79,7 +79,6 @@ x64/
_ReSharper*
# NCrunch
*.ncrunch*
.*crunch*.local.xml
_NCrunch_*

161
CONTRIBUTING.md Normal file
View 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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View 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>

View 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);
}
```

View 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!");
```

View File

@@ -1,5 +1,6 @@
Title: Prompt
Order: 4
Title: Text
Order: 0
RedirectFrom: prompt
---
Sometimes you want to get some input from the user, and for this

View File

@@ -1,5 +1,5 @@
Title: Bar Chart
Order: 1
Order: 20
---
Use `BarChart` to render bar charts to the console.

View File

@@ -1,5 +1,5 @@
Title: Calendar
Order: 3
Order: 40
RedirectFrom: calendar
---

View File

@@ -1,5 +1,5 @@
Title: Canvas Image
Order: 6
Order: 70
---
To add [ImageSharp](https://github.com/SixLabors/ImageSharp) superpowers to

View File

@@ -1,5 +1,5 @@
Title: Canvas
Order: 5
Order: 60
---
`Canvas` is a widget that allows you to render arbitrary "pixels"

View File

@@ -1,5 +1,5 @@
Title: Figlet
Order: 4
Order: 50
RedirectFrom: figlet
---

View File

@@ -1,5 +1,5 @@
Title: Rule
Order: 2
Order: 30
RedirectFrom: rule
---

View 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);
```

View File

@@ -20,26 +20,87 @@ namespace Cursor
return;
}
// String
// Ask the user for some different things
var name = AskName();
var fruit = AskFruit();
var sport = AskSport();
var age = AskAge();
var password = AskPassword();
var color = AskColor();
// Summary
AnsiConsole.WriteLine();
AnsiConsole.Render(new Rule("[yellow]Results[/]").RuleStyle("grey").LeftAligned());
AnsiConsole.Render(new Table().AddColumns("[grey]Question[/]", "[grey]Answer[/]")
.RoundedBorder()
.BorderColor(Color.Grey)
.AddRow("[grey]Name[/]", name)
.AddRow("[grey]Favorite fruit[/]", fruit)
.AddRow("[grey]Favorite sport[/]", sport)
.AddRow("[grey]Age[/]", age.ToString())
.AddRow("[grey]Password[/]", password)
.AddRow("[grey]Favorite color[/]", string.IsNullOrEmpty(color) ? "Unknown" : color));
}
private static string AskName()
{
AnsiConsole.WriteLine();
AnsiConsole.Render(new Rule("[yellow]Strings[/]").RuleStyle("grey").LeftAligned());
var name = AnsiConsole.Ask<string>("What's your [green]name[/]?");
return name;
}
// String with choices
private static string AskFruit()
{
AnsiConsole.WriteLine();
AnsiConsole.Render(new Rule("[yellow]Lists[/]").RuleStyle("grey").LeftAligned());
var favorites = AnsiConsole.Prompt(
new MultiSelectionPrompt<string>()
.PageSize(10)
.Title("What are your [green]favorite fruits[/]?")
.AddChoices(new[]
{
"Apple", "Apricot", "Avocado", "Banana", "Blackcurrant", "Blueberry",
"Cherry", "Cloudberry", "Cocunut", "Date", "Dragonfruit", "Durian",
"Egg plant", "Elderberry", "Fig", "Grape", "Guava", "Honeyberry",
"Jackfruit", "Jambul", "Kiwano", "Kiwifruit", "Lime", "Lylo",
"Lychee", "Melon", "Mulberry", "Nectarine", "Orange", "Olive"
}));
var fruit = favorites.Count == 1 ? favorites[0] : null;
if (string.IsNullOrWhiteSpace(fruit))
{
fruit = AnsiConsole.Prompt(
new SelectionPrompt<string>()
.Title("Ok, but if you could only choose [green]one[/]?")
.AddChoices(favorites));
}
AnsiConsole.MarkupLine("Your selected: [yellow]{0}[/]", fruit);
return fruit;
}
private static string AskSport()
{
AnsiConsole.WriteLine();
AnsiConsole.Render(new Rule("[yellow]Choices[/]").RuleStyle("grey").LeftAligned());
var fruit = AnsiConsole.Prompt(
new TextPrompt<string>("What's your [green]favorite fruit[/]?")
.InvalidChoiceMessage("[red]That's not a valid fruit[/]")
.DefaultValue("Orange")
.AddChoice("Apple")
.AddChoice("Banana")
.AddChoice("Orange"));
// Integer
return AnsiConsole.Prompt(
new TextPrompt<string>("What's your [green]favorite sport[/]?")
.InvalidChoiceMessage("[red]That's not a valid fruit[/]")
.DefaultValue("Lol")
.AddChoice("Soccer")
.AddChoice("Hockey")
.AddChoice("Basketball"));
}
private static int AskAge()
{
AnsiConsole.WriteLine();
AnsiConsole.Render(new Rule("[yellow]Integers[/]").RuleStyle("grey").LeftAligned());
var age = AnsiConsole.Prompt(
return AnsiConsole.Prompt(
new TextPrompt<int>("How [green]old[/] are you?")
.PromptStyle("green")
.ValidationErrorMessage("[red]That's not a valid age[/]")
@@ -52,33 +113,27 @@ namespace Cursor
_ => ValidationResult.Success(),
};
}));
}
// Secret
private static string AskPassword()
{
AnsiConsole.WriteLine();
AnsiConsole.Render(new Rule("[yellow]Secrets[/]").RuleStyle("grey").LeftAligned());
var password = AnsiConsole.Prompt(
return AnsiConsole.Prompt(
new TextPrompt<string>("Enter [green]password[/]?")
.PromptStyle("red")
.Secret());
}
// Optional
private static string AskColor()
{
AnsiConsole.WriteLine();
AnsiConsole.Render(new Rule("[yellow]Optional[/]").RuleStyle("grey").LeftAligned());
var color = AnsiConsole.Prompt(
return AnsiConsole.Prompt(
new TextPrompt<string>("[grey][[Optional]][/] What is your [green]favorite color[/]?")
.AllowEmpty());
// Summary
AnsiConsole.WriteLine();
AnsiConsole.Render(new Rule("[yellow]Results[/]").RuleStyle("grey").LeftAligned());
AnsiConsole.Render(new Table().AddColumns("[grey]Question[/]", "[grey]Answer[/]")
.RoundedBorder()
.BorderColor(Color.Grey)
.AddRow("[grey]Name[/]", name)
.AddRow("[grey]Favorite fruit[/]", fruit)
.AddRow("[grey]Age[/]", age.ToString())
.AddRow("[grey]Password[/]", password)
.AddRow("[grey]Favorite color[/]", string.IsNullOrEmpty(color) ? "Unknown" : color));
}
}
}

View File

@@ -0,0 +1,45 @@
using Spectre.Console;
namespace TableExample
{
public static class Program
{
public static void Main()
{
AnsiConsole.WriteLine();
// Render the tree
var tree = BuildTree();
AnsiConsole.Render(tree);
}
private static Tree BuildTree()
{
// Create the tree
var tree = new Tree("Root")
.Style(Style.Parse("red"))
.Guide(TreeGuide.BoldLine);
// 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());
// Return the tree
return tree;
}
}
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<ExampleTitle>Trees</ExampleTitle>
<ExampleDescription>Demonstrates how to render trees in a console.</ExampleDescription>
<ExampleGroup>Widgets</ExampleGroup>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,5 @@
<ProjectConfiguration>
<Settings>
<XUnit2Enabled>False</XUnit2Enabled>
</Settings>
</ProjectConfiguration>

View File

@@ -0,0 +1,39 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Spectre.Console.Cli;
namespace Spectre.Console.Tests.Data
{
public sealed class DumpRemainingCommand : Command<EmptyCommandSettings>
{
private readonly IAnsiConsole _console;
public DumpRemainingCommand(IAnsiConsole console)
{
_console = console;
}
public override int Execute([NotNull] CommandContext context, [NotNull] EmptyCommandSettings settings)
{
if (context.Remaining.Raw.Count > 0)
{
_console.WriteLine("# Raw");
foreach (var item in context.Remaining.Raw)
{
_console.WriteLine(item);
}
}
if (context.Remaining.Parsed.Count > 0)
{
_console.WriteLine("# Parsed");
foreach (var item in context.Remaining.Parsed)
{
_console.WriteLine(string.Format("{0}={1}", item.Key, string.Join(",", item.Select(x => x))));
}
}
return 0;
}
}
}

View File

@@ -1,22 +0,0 @@
using System;
using Spectre.Console.Cli;
namespace Spectre.Console.Tests.Data
{
public sealed class InterceptingCommand<TSettings> : Command<TSettings>
where TSettings : CommandSettings
{
private readonly Action<CommandContext, TSettings> _action;
public InterceptingCommand(Action<CommandContext, TSettings> action)
{
_action = action ?? throw new ArgumentNullException(nameof(action));
}
public override int Execute(CommandContext context, TSettings settings)
{
_action(context, settings);
return 0;
}
}
}

View File

@@ -0,0 +1,16 @@
using System.Diagnostics.CodeAnalysis;
using Spectre.Console.Cli;
namespace Spectre.Console.Tests.Data
{
public sealed class NoDescriptionCommand : Command<EmptyCommandSettings>
{
[CommandOption("-f|--foo <VALUE>")]
public int Foo { get; set; }
public override int Execute([NotNull] CommandContext context, [NotNull] EmptyCommandSettings settings)
{
return 0;
}
}
}

View File

@@ -0,0 +1,22 @@
using Spectre.Console.Cli;
namespace Spectre.Console.Tests.Data
{
public sealed class ArgumentOrderSettings : CommandSettings
{
[CommandArgument(0, "[QUX]")]
public int Qux { get; set; }
[CommandArgument(3, "<CORGI>")]
public int Corgi { get; set; }
[CommandArgument(1, "<BAR>")]
public int Bar { get; set; }
[CommandArgument(2, "<BAZ>")]
public int Baz { get; set; }
[CommandArgument(0, "<FOO>")]
public int Foo { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
USAGE:
myapp <FOO> <BAR> <BAZ> <CORGI> [QUX] [OPTIONS]
ARGUMENTS:
<FOO>
<BAR>
<BAZ>
<CORGI>
[QUX]
OPTIONS:
-h, --help Prints help information

View File

@@ -2,8 +2,8 @@ USAGE:
myapp <TEETH> [LEGS] [OPTIONS]
ARGUMENTS:
[LEGS] The number of legs
<TEETH> The number of teeth the lion has
[LEGS] The number of legs
OPTIONS:
-h, --help Prints help information

View File

@@ -5,8 +5,8 @@ EXAMPLES:
myapp 12 -c 3
ARGUMENTS:
[LEGS] The number of legs
<TEETH> The number of teeth the lion has
[LEGS] The number of legs
OPTIONS:
-h, --help Prints help information

View File

@@ -0,0 +1,9 @@
USAGE:
myapp [OPTIONS] <COMMAND>
OPTIONS:
-h, --help Prints help information
-v, --version Prints version information
COMMANDS:
bar

View File

@@ -0,0 +1,3 @@
# Raw
/c
set && pause

Some files were not shown because too many files have changed in this diff Show More