Skip to content

Additional API's for extending PSRL #752

Open
@SeeminglyScience

Description

@SeeminglyScience

I had some ideas about how to flesh out some of the extensibility APIs. The original motivation was to allow context specific key handler assignments in menus like MenuComplete. As I was looking into how PSRL might be changed to allow this, I came up with some ideas that would make extending PSRL a lot easier in general.

I do realize that the changes I'm about to propose would be unavoidably less performant, but I'd like to hear your thoughts. Here's a rough draft of what I have in mind.

Stories

As a user I want to

  • Customize input handling of menus created by key handlers (both default and custom)

As a writer of custom key handlers I want to

  • Temporarily take over a default action when I present a menu, regardless of what key that action is assigned to

  • Allow PSRL to handle string manipulation of a custom input buffer

Bind keys to "dispatch" codes instead of delegates

Assigning keys

// Enum-like for default commands, borrowing a little from the
// design of System.Reflection.Emit.OpCodes.
class KeyHandlerCommand
{
    // Default dispatch codes
    static ListMoveDown { get; }
    static ListMoveUp { get; }
    static Accept { get; }
    static SearchHistoryBackward { get; }
    ...

    // Registering custom dispatch codes
    static KeyHandlerCommand RegisterCustomCommand(
        string dispatchCode,
        Action<ConsoleKeyInfo?, object> defaultHandler);

    static KeyHandlerCommand GetCustomCommand(
        string dispatchCode);

    // Instance properties
    string DispatchCode { get; }
    Action<ConsoleKeyInfo?, object> DefaultHandler { get; }
}
void SetKeyHandler(
    string[] key,
    KeyHandlerCommand command);

Assigning dispatch

IDisposable RegisterAction(
    KeyHandlerCommand command,
    Action<ConsoleKeyInfo?, object> handler);

The idea here is that a key handler that implements a menu would take over a command using this API and dispose of the return value to relinquish control back to PSRL. If this was a public API it would allow external custom menus to use existing key bindings.

Nested input buffers

This one in particular might be a long shot, but the ability tap into PSRL's string manipulation would greatly reduce the barrier of entry for custom menu creators.

IDisposable EnterNestedInputBuffer(
    StringBuilder buffer,
    Action<Edit> onBufferChange,
    Action<int> onCursorMove);

Accepting dispatch

class KeyHandlerDispatch
{
    KeyHandlerCommand Command { get; }
    Action<ConsoleKeyInfo?, object> CurrentHandler { get; }
    ConsoleKeyInfo? Key { get; }
    object Argument { get; }
}
KeyHandlerDispatch ReadDispatch(
    string contextName,
    CancellationToken cancellationToken);

This would be the last piece needed to fully enable both context specific key bindings and extending PSRL's input loop.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions