async Task InteractiveLine(string line, UnixShell shell, ITerminalStream console) { using (ResponsiveReadLine readLine = new ResponsiveReadLine(console: console)) { // use a separate history! using (readLine.UseHistory(new InputHistory())) { // read line callback readLine.Callback = shell.Environment.Input.ToReadLineCallback(); // task for running the command Task commandRunning = Task.Run(async() => { await shell.InteractiveAsync(line: line); await shell.Environment.Input.TryClose(); }); // wait for both await Task.WhenAll(new [] { commandRunning }); } } }
async Task Interactive(UnixShell shell, ITerminalStream console) { using (ResponsiveReadLine readLine = new ResponsiveReadLine(console: console)) { using (readLine.UseHistory(shell.History)) { bool done = false; shell.Environment.Input.PipeToLimbo(); await console.WriteAsync(shell.Prompt()); PortableBlockingQueue <ILine> queue = new PortableBlockingQueue <ILine> (); readLine.Callback = async line => await queue.EnqueueAsync(item : line); while (!done && console.IsOpen) { while (queue.Count > 0) { ILine line = await queue.DequeueAsync(); // handle a special command? if (line.SpecialCommand != SpecialCommands.None) { // do something done |= line.SpecialCommand == SpecialCommands.CloseStream; } // normal string input else { // filter empty lines if (!string.IsNullOrWhiteSpace(line.Line)) { await InteractiveLine(line : line.Line, shell : shell, console : console); } } await console.WriteAsync(shell.Prompt()); } await Task.Delay(50); } } } await console.WriteLineAsync(); }