/// <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); }
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)); }