Skip to content
Open
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
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ Works for humans and AI agents alike.
| Alias | Description | Options |
| --- | --- | --- |
| `select` | Presents a list of options and returns the text of the selected item. | `--options`, `args...` |
| `text` | Prompts for free-form text input and returns the entered string. | |
| `multiline-text`, `mt` | Prompts for multi-line text input and returns the entered string. | |
| `text`, `multiline-text`, `mt` | Prompts for multi-line text input using an editor and returns the entered string. | |
| `int` | Prompts for an integer value using a numeric spinner. | `--step` |
| `decimal` | Prompts for a decimal value using a numeric spinner. | `--step` |
| `confirm` | Prompts for a yes/no confirmation and returns a boolean. | `--prompt` |
Expand Down
5 changes: 2 additions & 3 deletions specs/clet-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,7 @@ For schema-lock at v0.5, the shape of `value` is fixed per alias.

| Alias | `value` shape |
|-------------------------------|--------------------------------------------------------------|
| `text` | string |
| `multiline-text` | string (newlines preserved as `\n`) |
| `text` | string (newlines preserved as `\n`) |
| `int` | integer |
| `decimal` | number (JSON number; consumer decides float vs decimal) |
| `confirm` | boolean |
Expand All @@ -237,7 +236,7 @@ For schema-lock at v0.5, the shape of `value` is fixed per alias.

### 4.4 Registration

`BuiltInClets.RegisterAll(ICletRegistry)` hand-registers all 15 clets. Auto-discovery via a source generator was explored and dropped — there is no `[Clet]` attribute in shipped code, and no source-generator project in the repo.
`BuiltInClets.RegisterAll(ICletRegistry)` hand-registers all 18 clets. Auto-discovery via a source generator was explored and dropped — there is no `[Clet]` attribute in shipped code, and no source-generator project in the repo.

### 4.5 Built-in clet implementation pattern

Expand Down
79 changes: 0 additions & 79 deletions src/Clet/Clets/Input/MultilineTextClet.cs

This file was deleted.

58 changes: 48 additions & 10 deletions src/Clet/Clets/Input/TextClet.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Terminal.Gui.App;
using Terminal.Gui.Document;
using Terminal.Gui.Drawing;
using Terminal.Gui.Editor;
using Terminal.Gui.Input;
using Terminal.Gui.ViewBase;
using Terminal.Gui.Views;
Expand All @@ -9,8 +11,8 @@ namespace Clet;
internal sealed class TextClet : IClet<string?>
{
public string PrimaryAlias => "text";
public IReadOnlyList<string> Aliases => ["text"];
public string Description => "Prompts for free-form text input and returns the entered string.";
public IReadOnlyList<string> Aliases => ["text", "multiline-text", "mt"];
public string Description => "Prompts for multi-line text input using an editor and returns the entered string.";
public CletKind Kind => CletKind.Input;
public Type ResultType => typeof (string);

Expand All @@ -22,20 +24,56 @@ internal sealed class TextClet : IClet<string?>
CletRunOptions options,
CancellationToken cancellationToken)
{
TextField textField = new ()
if (cancellationToken.IsCancellationRequested)
{
Text = initial ?? string.Empty,
return new () { Status = CletRunStatus.Cancelled };
}

int rows = options.Rows ?? 5;

Editor editor = new ()
{
Document = new TextDocument (initial ?? string.Empty),
Width = Dim.Fill (),
Height = rows,
ConvertTabsToSpaces = true,
};

RunnableWrapper<TextField, string?> wrapper = new (textField)
Button okButton = new ()
{
ResultExtractor = t => t.Text,
Text = "_OK",
Y = Pos.Bottom (editor),
};

RunnableWrapper<Editor, string?> wrapper = new (editor)
{
Title = options.Title ?? "Enter text (OK to accept, Esc to cancel)",
Width = Dim.Fill (),
BorderStyle = LineStyle.Rounded,
ResultExtractor = e => e.Document?.Text,
SchemeName = CletStyling.BaseSchemeName,
};
wrapper.Border.Thickness = new Thickness (0, 1, 0, 0);
wrapper.Add (okButton);

okButton.Accepted += (_, _) => wrapper.InvokeCommand (Command.Accept);

try
{
await app.RunAsync (wrapper, cancellationToken);
}
catch (OperationCanceledException)
{
return new () { Status = CletRunStatus.Cancelled };
}

if (cancellationToken.IsCancellationRequested)
{
return new () { Status = CletRunStatus.Cancelled };
}

string? result = wrapper.Result;

return await InputCletRunner.RunAsync (
app, wrapper, options,
"Enter text (Enter to accept, Esc to cancel)",
cancellationToken);
return new () { Status = CletRunStatus.Ok, Value = result };
}
}
16 changes: 0 additions & 16 deletions src/Clet/Help/multiline-text.md

This file was deleted.

6 changes: 6 additions & 0 deletions src/Clet/Help/text.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ clet text --title "Enter your name"
# Pre-filled initial value:
clet text --initial "John Doe"

# Multi-line text editor:
clet text --rows 10

# Using the multiline-text alias:
clet multiline-text --title "Enter a commit message"

# JSON output:
clet text --json
# → {"schemaVersion":1,"status":"ok","value":"Hello world"}
Expand Down
1 change: 0 additions & 1 deletion src/Clet/Registry/BuiltInClets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ public static void RegisterAll (ICletRegistry registry)
{
registry.Register (new SelectClet ());
registry.Register (new TextClet ());
registry.Register (new MultilineTextClet ());
registry.Register (new IntClet ());
registry.Register (new DecimalClet ());
registry.Register (new ConfirmClet ());
Expand Down
76 changes: 0 additions & 76 deletions tests/Clet.IntegrationTests/MultilineTextCletIntegrationTests.cs

This file was deleted.

34 changes: 34 additions & 0 deletions tests/Clet.IntegrationTests/TextCletIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,38 @@ public async Task RunAsync_WithInitialValue_SetsText ()

Assert.Equal (CletRunStatus.Ok, result.Status);
}

[Fact]
public async Task RunAsync_WithMultilineInitialValue_ReturnsOk ()
{
using IApplication app = Application.Create ();
app.Init ("ansi");
app.StopAfterFirstIteration = true;

TextClet clet = new ();
CletRunOptions options = new ();

using CancellationTokenSource cts = new ();

CletRunResult<string?> result = await clet.RunAsync (app, "line1\nline2", options, cts.Token);

Assert.Equal (CletRunStatus.Ok, result.Status);
}

[Fact]
public async Task RunAsync_WithRows_ReturnsOk ()
{
using IApplication app = Application.Create ();
app.Init ("ansi");
app.StopAfterFirstIteration = true;

TextClet clet = new ();
CletRunOptions options = new () { Rows = 10 };

using CancellationTokenSource cts = new ();

CletRunResult<string?> result = await clet.RunAsync (app, null, options, cts.Token);

Assert.Equal (CletRunStatus.Ok, result.Status);
}
}
2 changes: 1 addition & 1 deletion tests/Clet.UnitTests/BuiltInCletsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,6 @@ public void RegisterAll_Registers19Clets ()
CletRegistry registry = new ();
BuiltInClets.RegisterAll (registry);

Assert.Equal (19, registry.All.Count);
Assert.Equal (18, registry.All.Count);
}
}
1 change: 0 additions & 1 deletion tests/Clet.UnitTests/CletMetadataTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ public static IEnumerable<object[]> AllCletMetadata ()
yield return [new DateClet (), "date", CletKind.Input, typeof (string), false];
yield return [new TimeClet (), "time", CletKind.Input, typeof (string), false];
yield return [new DurationClet (), "duration", CletKind.Input, typeof (string), false];
yield return [new MultilineTextClet (), "multiline-text", CletKind.Input, typeof (string), false];
yield return [new MultiSelectClet (), "multi-select", CletKind.Input, typeof (System.Text.Json.Nodes.JsonArray), true];
yield return [new LinearRangeClet (), "linear-range", CletKind.Input, typeof (System.Text.Json.Nodes.JsonObject), true];
yield return [new PickFileClet (), "pick-file", CletKind.Input, typeof (System.Text.Json.Nodes.JsonNode), false];
Expand Down
Loading
Loading