suspendInput<R> method

Future<R> suspendInput<R>(
  1. Future<R> body(
    1. Stream<List<int>> input
    )
)

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