Skip to content
This repository was archived by the owner on Dec 14, 2025. It is now read-only.
This repository was archived by the owner on Dec 14, 2025. It is now read-only.

Add built in support for REPL (read-eval-print-loop) #174

@myNameIsAndrew00

Description

@myNameIsAndrew00

Is there any built in support for REPL in Cocona?

Currently, the solution I found was to simply make use of ICoconaCommandDispatcher myself and to create a while loop that listens for console input (see example below)

using Cocona;
using Cocona.Command;
using Cocona.Command.Dispatcher;

var builder = CoconaApp.CreateBuilder();
var app = builder.Build();



app.AddCommand("hello", ([Argument] string name) => Console.WriteLine($"Hello {name}!"))
    .WithDescription("Say hello");

app.AddCommand("bye", ([Argument] string name) => Console.WriteLine($"Goodbye {name}!"))
    .WithDescription("Say goodbye");

// Main loop command.
app.AddCommand(async (CoconaAppContext ctx, ICoconaCommandDispatcher dispatcher, ICoconaCommandResolver resolver, ICoconaCommandProvider provider, ICoconaCommandMatcher matcher) =>
{
    var commandsCollection = provider.GetCommandCollection();

    while (!ctx.CancellationToken.IsCancellationRequested)
    {
        Console.Write("> ");



        var input = Console.ReadLine();

        if (string.IsNullOrWhiteSpace(input))
        {
            // Listen for another message.

            continue;
        }

        var tokens = input.Split(' ', StringSplitOptions.RemoveEmptyEntries);



        CommandResolverResult resolvedCommand = default;

        try
        {
            resolvedCommand = resolver.ParseAndResolve(commandsCollection, tokens);
        }
        catch (CommandNotFoundException)
        {
            // For some reason, instead of resolving the command and setting the success flag to 'False', the method may throw an exception.
        }

        // Ignore main loop or try again if resolver fain to build the command.
        if (!resolvedCommand.Success || resolvedCommand.MatchedCommand == null || resolvedCommand.MatchedCommand.IsPrimaryCommand)
        {
            Console.WriteLine($"Command input '{input}' couldn't be resolved");

            continue;
        }


        await dispatcher.DispatchAsync(resolvedCommand, ctx.CancellationToken);

    }
});


await app.RunAsync();

Is there a better way to do it? something like:

//...

app.AddCommand("hello", ([Argument] string name) => Console.WriteLine($"Hello {name}!"))
    .WithDescription("Say hello");

app.AddCommand("bye", ([Argument] string name) => Console.WriteLine($"Goodbye {name}!"))
    .WithDescription("Say goodbye");

app.UseRepl();

//...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions