Repository: sharkdp/fd (language: rust)

Issue:
Add a streaming mode when running under pipe
Currently when not running under an interactive shell, it will buffer its output and output everything in one go.
However, I am writing a GUI front end and need this "streaming" mode similar to when running under an interactive shell so users can see the result in a faster manner.

Expected behaviour is that the user can instantly see the initial result with more items being added along the way.

Am I missing something or is there any switch to customize this behavior?


Discussion / hints:
I also find this pretty bizarre, and would argue the current behavior is straight up incorrect.

`fd pattern / | head 1 ` for example, should not wait until it scans my entire file-system
default buffering maybe  should be _different_ for non-interactive, but it certainly should not wait _indefinitely_ to flush.
 
It is definitely possible for `fd` to do better here, so I'm self-assigning this.  That said, *many* (most?) command line tools operate just like `fd` here, so it's hard to say that the current behaviour is "incorrect."
@blueforesticarus for that particular use case there is the `-1` option or `--max-results=1`. 

For some context on why it behaves this way, see #736 and #885

Fix patch:
diff --git a/src/walk.rs b/src/walk.rs
index c6737edf1..c81d2a4da 100644
--- a/src/walk.rs
+++ b/src/walk.rs
@@ -214,7 +214,6 @@ impl<'a, W: Write> ReceiverBuffer<'a, W> {
                                 }
                                 ReceiverMode::Streaming => {
                                     self.print(&dir_entry)?;
-                                    self.flush()?;
                                 }
                             }
 
@@ -232,6 +231,11 @@ impl<'a, W: Write> ReceiverBuffer<'a, W> {
                         }
                     }
                 }
+
+                // If we don't have another batch ready, flush before waiting
+                if self.mode == ReceiverMode::Streaming && self.rx.is_empty() {
+                    self.flush()?;
+                }
             }
             Err(RecvTimeoutError::Timeout) => {
                 self.stream()?;
@@ -285,7 +289,7 @@ impl<'a, W: Write> ReceiverBuffer<'a, W> {
 
     /// Flush stdout if necessary.
     fn flush(&mut self) -> Result<(), ExitCode> {
-        if self.config.interactive_terminal && self.stdout.flush().is_err() {
+        if self.stdout.flush().is_err() {
             // Probably a broken pipe. Exit gracefully.
             return Err(ExitCode::GeneralError);
         }


Test patch: