Ejemplo n.º 1
0
    /// <inheritdoc cref="IPrompt.ReadLineAsync()" />
    public async Task <PromptResult> ReadLineAsync()
    {
        var renderer = new Renderer(console, configuration);

        renderer.RenderPrompt();

        // code pane contains the code the user is typing. It does not include the prompt (i.e. "> ")
        var codePane = new CodePane(console, configuration, clipboard);

        // completion pane is the pop-up window that shows potential autocompletions.
        var completionPane = new CompletionPane(
            codePane,
            promptCallbacks,
            configuration);

        codePane.Bind(completionPane);

        history.Track(codePane);
        cancellationManager.CaptureControlC();

        foreach (var key in KeyPress.ReadForever(console))
        {
            // grab the code area width every key press, so we rerender appropriately when the console is resized.
            codePane.MeasureConsole();

            await InterpretKeyPress(key, codePane, completionPane, cancellationToken : default).ConfigureAwait(false);

            // typing / word-wrapping may have scrolled the console, giving us more room.
            codePane.MeasureConsole();

            // render the typed input, with syntax highlighting
            var inputText  = codePane.Document.GetText();
            var highlights = await highlighter.HighlightAsync(inputText, cancellationToken : default).ConfigureAwait(false);

            // the key press may have caused the prompt to return its input, e.g. <Enter> or a callback.
            var result = await GetResult(codePane, key, inputText, cancellationToken : default).ConfigureAwait(false);

            await renderer.RenderOutput(result, codePane, completionPane, highlights, key, cancellationToken : default).ConfigureAwait(false);

            if (result is not null)
            {
                _ = history.SavePersistentHistoryAsync(inputText);
                cancellationManager.AllowControlCToCancelResult(result);
                return(result);
            }
        }

        Debug.Assert(false, "Should never reach here due to infinite " + nameof(KeyPress.ReadForever));
        return(null);
    }
Ejemplo n.º 2
0
    private async Task InterpretKeyPress(KeyPress key, CodePane codePane, CompletionPane completionPane, CancellationToken cancellationToken)
    {
        if (!completionPane.WouldKeyPressCommitCompletionItem(key))
        {
            key = await promptCallbacks.TransformKeyPressAsync(codePane.Document.GetText(), codePane.Document.Caret, key, cancellationToken).ConfigureAwait(false);
        }

        foreach (var panes in new IKeyPressHandler[] { completionPane, history, codePane })
        {
            await panes.OnKeyDown(key, cancellationToken).ConfigureAwait(false);
        }

        foreach (var panes in new IKeyPressHandler[] { completionPane, history, codePane })
        {
            await panes.OnKeyUp(key, cancellationToken).ConfigureAwait(false);
        }

        //we don't support text selection while completion list is open
        //text selection can put completion list into broken state, where filtering does not work
        //so we want this assert to be true
        Debug.Assert(!completionPane.IsOpen || (codePane.Selection is null));
    }