Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Deploy docs to GitHub Pages

on:
push:
branches: [master]
paths:
- 'docs/**'
- '.github/workflows/docs.yml'
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: docs
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version-file: docs/package.json
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actions/setup-node is configured with node-version-file: docs/package.json, but that file doesn't define an engines.node field (it only has a volta section). setup-node typically reads Node version from .nvmrc/.node-version or package.json#engines.node, so this is likely to fail or pick an unintended Node version, which can break the docs build (Vite/VitePress have Node minimums). Consider either adding an engines.node entry, adding a .nvmrc/.node-version file and pointing node-version-file to it, or setting node-version explicitly in the workflow.

Suggested change
node-version-file: docs/package.json
node-version: 20

Copilot uses AI. Check for mistakes.
cache: npm
cache-dependency-path: docs/package-lock.json

- run: npm ci
- run: npm run docs:build

- uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0

- uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
with:
path: docs/.vitepress/dist

deploy:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,10 @@ FodyWeavers.xsd
*.msm
*.msp

# VitePress
docs/.vitepress/dist/
docs/.vitepress/cache/

# JetBrains Rider
.idea/
*.sln.iml
*.sln.iml
56 changes: 56 additions & 0 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { defineConfig } from 'vitepress'

export default defineConfig({
title: 'Sharprompt',
description: 'Interactive command-line based application framework for C#',
base: '/Sharprompt/',
cleanUrls: true,
head: [
['link', { rel: 'icon', href: '/Sharprompt/icon.png' }]
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The head favicon URL is hard-coded as /Sharprompt/icon.png while base is already set to /Sharprompt/. VitePress typically applies base to absolute asset URLs, so this can result in a doubled path (e.g., /Sharprompt/Sharprompt/icon.png) and a broken favicon. Use /icon.png here (or construct the path using the configured base) to keep it consistent with themeConfig.logo and the home hero image.

Suggested change
['link', { rel: 'icon', href: '/Sharprompt/icon.png' }]
['link', { rel: 'icon', href: '/icon.png' }]

Copilot uses AI. Check for mistakes.
],
themeConfig: {
logo: '/icon.png',
nav: [
{ text: 'Guide', link: '/getting-started' },
{ text: 'NuGet', link: 'https://www.nuget.org/packages/Sharprompt/' }
],
sidebar: [
{
text: 'Introduction',
items: [
{ text: 'Getting Started', link: '/getting-started' }
]
},
{
text: 'Prompt Types',
items: [
{ text: 'Input', link: '/prompt-types/input' },
{ text: 'Confirm', link: '/prompt-types/confirm' },
{ text: 'Password', link: '/prompt-types/password' },
{ text: 'Select', link: '/prompt-types/select' },
{ text: 'MultiSelect', link: '/prompt-types/multi-select' },
{ text: 'List', link: '/prompt-types/list' },
{ text: 'Bind', link: '/prompt-types/bind' }
]
},
{
text: 'Reference',
items: [
{ text: 'Validators', link: '/validators' },
{ text: 'Configuration', link: '/configuration' },
{ text: 'Advanced Features', link: '/advanced' }
]
}
],
socialLinks: [
{ icon: 'github', link: 'https://github.com/shibayan/Sharprompt' }
],
search: {
provider: 'local'
},
footer: {
message: 'Released under the MIT License.',
copyright: 'Copyright © shibayan'
}
}
})
20 changes: 20 additions & 0 deletions docs/.vitepress/theme/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
:root {
/* Icon Blue */
--vp-c-brand-1: #4878b8;
--vp-c-brand-2: #3d6aa8;
--vp-c-brand-3: #345d96;
--vp-c-brand-soft: rgba(72, 120, 184, 0.14);

/* Hero gradient */
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: linear-gradient(135deg, #4878b8, #5a9bd6);
--vp-home-hero-image-background-image: linear-gradient(135deg, rgba(72, 120, 184, 0.2), rgba(90, 155, 214, 0.2));
--vp-home-hero-image-filter: blur(44px);
}

.dark {
--vp-c-brand-1: #6fa8dc;
--vp-c-brand-2: #5a9bd6;
--vp-c-brand-3: #4878b8;
--vp-c-brand-soft: rgba(111, 168, 220, 0.14);
}
4 changes: 4 additions & 0 deletions docs/.vitepress/theme/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import DefaultTheme from 'vitepress/theme'
import './custom.css'

export default DefaultTheme
85 changes: 85 additions & 0 deletions docs/advanced.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Advanced Features

## Enum Type Support

When using an enum type with `Select` or `MultiSelect`, items are automatically generated from the enum values. You can use the `[Display]` attribute to customize the display names:

```csharp
using System.ComponentModel.DataAnnotations;

public enum MyEnum
{
[Display(Name = "First value")]
First,
[Display(Name = "Second value")]
Second,
[Display(Name = "Third value")]
Third
}

var value = Prompt.Select<MyEnum>("Select enum value");
Console.WriteLine($"You selected {value}");
```

For `MultiSelect`:

```csharp
var values = Prompt.MultiSelect<MyEnum>("Select enum values");
Console.WriteLine($"You picked {string.Join(", ", values)}");
```

## Unicode Support

Sharprompt supports multi-byte characters and emoji. For best results, set the output encoding to UTF-8:

```csharp
Console.OutputEncoding = Encoding.UTF8;

var name = Prompt.Input<string>("What's your name?");
Console.WriteLine($"Hello, {name}!");
```

## Fluent Interface

All prompt types support a fluent interface via the `Sharprompt.Fluent` namespace:

```csharp
using Sharprompt.Fluent;

var city = Prompt.Select<string>(o => o.WithMessage("Select your city")
.WithItems(new[] { "Seattle", "London", "Tokyo" })
.WithDefaultValue("Seattle"));
```

The fluent API provides `With*` methods for setting properties and `Add*` methods for adding to collections (like validators).

## Text Selector

For `Select` and `MultiSelect`, you can provide a custom function to control how items are displayed:

```csharp
var user = Prompt.Select("Select user", users, textSelector: u => u.Name);
```

## Pagination

Both `Select` and `MultiSelect` support pagination via the `pageSize` parameter:

```csharp
var city = Prompt.Select("Select your city",
new[] { "Seattle", "London", "Tokyo", "New York", "Singapore", "Shanghai" },
pageSize: 3);
```

## Looping Selection

By default, selection lists loop when reaching the beginning or end. This can be disabled via the options class:

```csharp
var city = Prompt.Select(new SelectOptions<string>
{
Message = "Select your city",
Items = new[] { "Seattle", "London", "Tokyo" },
LoopingSelection = false
});
```
85 changes: 85 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Configuration

Sharprompt allows you to customize the appearance and behavior of prompts globally.

## Symbols

You can customize the symbols used by prompts:

```csharp
Prompt.Symbols.Prompt = new Symbol("🤔", "?");
Prompt.Symbols.Done = new Symbol("😎", "V");
Prompt.Symbols.Error = new Symbol("😱", ">>");

var name = Prompt.Input<string>("What's your name?");
```

The `Symbol` class takes two arguments: a Unicode value and a fallback value for terminals that don't support Unicode.

### Available Symbols

| Symbol | Default (Unicode) | Default (Fallback) | Description |
|--------|-------------------|-------------------|-------------|
| `Prompt` | `?` | `?` | Displayed before the prompt message |
| `Done` | `✔` | `V` | Displayed when the prompt is completed |
| `Error` | `»` | `>>` | Displayed when validation fails |
| `Selector` | `›` | `>` | Points to the currently highlighted item |
| `Selected` | `◉` | `(*)` | Marks a selected item in MultiSelect |
| `NotSelect` | `◯` | `( )` | Marks an unselected item in MultiSelect |

## Color Schema

Customize the colors used by prompts:

```csharp
Prompt.ColorSchema.Answer = ConsoleColor.DarkRed;
Prompt.ColorSchema.Select = ConsoleColor.DarkCyan;

var name = Prompt.Input<string>("What's your name?");
```

### Available Colors

| Property | Default | Description |
|----------|---------|-------------|
| `DoneSymbol` | `Green` | Color of the done symbol |
| `PromptSymbol` | `Green` | Color of the prompt symbol |
| `Answer` | `Cyan` | Color of the user's answer |
| `Select` | `Green` | Color of the selected item |
| `Error` | `Red` | Color of error messages |
| `Hint` | `DarkGray` | Color of hints and placeholders |
| `DisabledOption` | `DarkCyan` | Color of disabled options |

## Cancellation Support

By default, pressing `Ctrl+C` returns the default value. You can change this behavior to throw an exception:
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cancellation behavior described here doesn't match the current implementation. DefaultConsoleDriver invokes the cancellation callback on Ctrl+C, and FormBase.CancellationHandler() calls Environment.Exit(1) unless Prompt.ThrowExceptionOnCancel is true. The docs currently say Ctrl+C returns the default value, but it actually terminates the process by default.

Suggested change
By default, pressing `Ctrl+C` returns the default value. You can change this behavior to throw an exception:
By default, pressing `Ctrl+C` cancels the prompt and terminates the process (for example with exit code `1`). You can change this behavior to throw an exception instead of exiting:

Copilot uses AI. Check for mistakes.

```csharp
Prompt.ThrowExceptionOnCancel = true;

try
{
var name = Prompt.Input<string>("What's your name?");
Console.WriteLine($"Hello, {name}!");
}
catch (PromptCanceledException ex)
{
Console.WriteLine("Prompt canceled");
}
```

## Culture

Set the culture for localized messages:

```csharp
Prompt.Culture = new CultureInfo("ja");
```

## Console Driver

You can provide a custom console driver factory:

```csharp
Prompt.ConsoleDriverFactory = () => new MyCustomConsoleDriver();
```
52 changes: 52 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Getting Started

## Installation

Install Sharprompt via NuGet:

::: code-group

```powershell [Package Manager]
Install-Package Sharprompt
```

```sh [.NET CLI]
dotnet add package Sharprompt
```

:::

## Quick Start

```csharp
using Sharprompt;

// Simple input
var name = Prompt.Input<string>("What's your name?");
Console.WriteLine($"Hello, {name}!");

// Password input
var secret = Prompt.Password("Type new password",
validators: new[] { Validators.Required(), Validators.MinLength(8) });
Console.WriteLine("Password OK");

// Confirmation
var answer = Prompt.Confirm("Are you ready?", defaultValue: true);
Console.WriteLine($"Your answer is {answer}");
```

## Running the Examples

The repository includes a sample project with all prompt types:

```sh
dotnet run --project samples/Sharprompt.Example
```

## Supported Platforms

| Platform | Terminal |
|----------|----------|
| Windows | Command Prompt, PowerShell, Windows Terminal |
| Linux | Windows Terminal (WSL 2), various terminal emulators |
| macOS | Terminal.app, iTerm2, etc. |
Loading
Loading