You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Stdout not printing until after reading stdin when using terminal #2164
I've noticed that stdout output and stdin input don't seem to be happening in the correct order if I set "console": "terminal" in my launch config. I'm guessing that maybe Dart-Code is caching the stdout output for some reason.
import'dart:convert';
import'dart:io';
import'package:io/io.dart';
finalStream<String> stdinUtf8 = sharedStdIn.transform(utf8.decoder).asBroadcastStream();
finalStream<String> stdinLined = stdinUtf8.transform(LineSplitter());
Future<T> prompt<T>(String question, {T fallback, T def, String hint, TFunction(String) parse}) async {
assert(TisString|| parse !=null, '`parse` can only be null if T is String. T is $T');
stdout.write('$question${hint != null || def != null ? ' (${hint ?? def})' : ''} >>> ');
final ret =await stdinLined.first;
print('[OUTPUT = $ret]'); // for debuggingif (ret.isEmpty && fallback !=null) return def;
elseif (parse !=null) {
try {
returnparse(ret);
} onFormatException {
return fallback;
}
}
return ret asT;
}
Example:
Future<void> main() async {
final name =awaitprompt<String>('What is your name?');
}
Expected Output (works in non-debug terminal):
$ dart bin/main.dart
What is your name? >>> <some user input>
[OUTPUT =<some user input>]
Actual Output:
$ dart bin/main.dart
<some user input>
What is your name? >>> [OUTPUT =<some user input>]
You're right - we do buffer the output until we get a newline. This was done because sometimes messages from Dart were coming through in pieces, and we sometimes missed paths in the stack traces, and failed to link them up (see 70a2a8a).
This does seem like a problem though. We could potentially flush the buffer periodically (eg. make it time-based rather than line-based), though I'm not sure if that might just introduce other issues.
@DanTup, thanks for the quick update! Could it be configured to print to the same line until a newline character is received, or does it only support full lines?
@mpfaff we can send characters at any time, the issue is just that we need to scan a whole line in order to detect stack frame paths. For example we might get:
[5:01:50] tion: Oop
[5:01:50] s
[5:01:50]
[5:01:50] #
[5:01:50] 0
[5:01:50]
[5:01:50]
[5:01:50] main (file:///D:/a/
[5:01:50] Dart-Code/Dart-Code/src/test/test_projects/hello_world/bin/broken.dart:2:3)
Each line is a chunk of data we received. If we sent each chunk as we got it, then we wouldn't be able to send a single line with the additional metadata required to make links. The links won't actually work in the terminal though, so it's a bit weird to have this limitation (it's because the terminal and the debug console share the same debug adapter code).
Some possible thoughts:
Just skip the buffering (or immediately flush the buffer) when in terminal mode
Test what happens if we send a line in multiple chunks and attach the location metadata only to the last chunk
Activity
DanTup commentedon Dec 10, 2019
You're right - we do buffer the output until we get a newline. This was done because sometimes messages from Dart were coming through in pieces, and we sometimes missed paths in the stack traces, and failed to link them up (see 70a2a8a).
This does seem like a problem though. We could potentially flush the buffer periodically (eg. make it time-based rather than line-based), though I'm not sure if that might just introduce other issues.
I'll have a think!
mpfaff commentedon Dec 10, 2019
@DanTup, thanks for the quick update! Could it be configured to print to the same line until a newline character is received, or does it only support full lines?
DanTup commentedon Dec 11, 2019
@mpfaff we can send characters at any time, the issue is just that we need to scan a whole line in order to detect stack frame paths. For example we might get:
Each line is a chunk of data we received. If we sent each chunk as we got it, then we wouldn't be able to send a single line with the additional metadata required to make links. The links won't actually work in the terminal though, so it's a bit weird to have this limitation (it's because the terminal and the debug console share the same debug adapter code).
Some possible thoughts: