Index: lib/src/log.dart |
diff --git a/lib/src/log.dart b/lib/src/log.dart |
index 0b14ab30eb0b2050557c973e18d2ddb75903856c..b61fe06fdb50f92a99cedcf513d68f2d35c8112e 100644 |
--- a/lib/src/log.dart |
+++ b/lib/src/log.dart |
@@ -48,6 +48,14 @@ Transcript<Entry> _transcript; |
/// This will also be in [_progresses]. |
Progress _animatedProgress; |
+/// The Timer used to coalesce a number of collapsible messages. |
+/// |
+/// This is `null` if no collapsible messages are waiting to be displayed. |
+Timer _collapsibleTimer; |
+ |
+/// The queue of collapsible messages waiting to be displayed. |
+final _collapsibleMessages = []; |
+ |
final _cyan = getSpecial('\u001b[36m'); |
final _green = getSpecial('\u001b[32m'); |
final _magenta = getSpecial('\u001b[35m'); |
@@ -209,6 +217,9 @@ void fine(message) => write(Level.FINE, message); |
/// Logs [message] at [level]. |
void write(Level level, message) { |
+ // Don't allow interleaving collapsible messages with other kinds. |
+ if (_collapsibleTimer != null) _flushCollapsible(); |
+ |
message = message.toString(); |
var lines = splitLines(message); |
@@ -409,6 +420,49 @@ void unmuteProgress() { |
_numMutes--; |
} |
+/// Logs a collapsible [message]. |
+/// |
+/// If a number of collapsible messages are printed in short succession, they |
+/// are collapsed to just showing the first one followed by a count of the |
+/// elided ones. Avoids spamming the output with not-very-interesting output. |
+/// |
+/// Internally, every time this is called, a time is set (or reset). When it |
+/// fires, any collapsible messages enqueued since the last time it fired are |
+/// displayed. |
+void collapsible(String message) { |
nweiz
2015/07/31 22:42:35
Rather than only printing this once the timeout ha
Bob Nystrom
2015/08/03 21:51:02
I thought about that, but the output lines can be
nweiz
2015/08/03 22:11:10
Since this is pub, we should be able to safely use
Bob Nystrom
2015/08/05 21:25:39
Tried a different approach based on our discussion
|
+ // Only collapse messages when the output is not verbose. |
+ if (verbosity._loggers[Level.MESSAGE] != _logToStdout) { |
+ write(Level.MESSAGE, message); |
+ return; |
+ } |
+ |
+ // Reset the timer. |
+ if (_collapsibleTimer != null) _collapsibleTimer.cancel(); |
+ |
+ _collapsibleMessages.add(message); |
+ _collapsibleTimer = new Timer(new Duration(milliseconds: 100), |
nweiz
2015/07/31 22:42:35
Consider making this duration a top-level constant
Bob Nystrom
2015/08/03 21:51:02
Done.
|
+ _flushCollapsible); |
+} |
+ |
+/// Displays any queued collapsible messages. |
+void _flushCollapsible() { |
+ if (_collapsibleMessages.isEmpty) return; |
+ |
+ if (_collapsibleTimer != null) { |
+ _collapsibleTimer.cancel(); |
+ _collapsibleTimer = null; |
+ } |
+ |
+ if (_collapsibleMessages.length == 1) { |
+ message(_collapsibleMessages.single); |
+ } else { |
+ var trailing = gray("(and ${_collapsibleMessages.length - 1} more...)"); |
+ message("${_collapsibleMessages.first} $trailing"); |
+ } |
+ |
+ _collapsibleMessages.clear(); |
+} |
+ |
/// Wraps [text] in the ANSI escape codes to make it bold when on a platform |
/// that supports that. |
/// |