suspendInput<R> method
Hands the input stream to body for the duration of a full-screen takeover
(e.g. the :ide TUI), then resumes line editing.
The editor's own input subscription is cancelled first so body can listen
to the terminal directly (stdin is single-subscription); when body
completes — however it returns or throws — the editor re-subscribes and
repaints the current prompt line. In non-interactive mode it just runs
body. The terminal's raw mode is left untouched (the editor already runs
raw, and full-screen apps manage their own alternate screen on top).
Implementation
Future<R> suspendInput<R>(
Future<R> Function(Stream<List<int>> input) body,
) async {
// stdin is single-subscription, so the takeover cannot `listen` to it
// itself. Instead the editor keeps its existing subscription and forwards
// raw bytes into [controller], which [body] consumes as its input stream.
final controller = StreamController<List<int>>();
if (!interactive) {
// No raw input to route; run the takeover against an empty stream.
try {
return await body(controller.stream);
} finally {
await controller.close();
}
}
_rawSink = controller.add;
try {
return await body(controller.stream);
} finally {
_rawSink = null;
await controller.close();
// The takeover owned the screen; forget the old paint so the repaint
// starts clean rather than clearing rows that are no longer ours.
_resetRenderTracking();
if (!_closed) _refresh();
}
}