feat: implement --unbuffered mode for streaming input (#3555)

Repurpose the existing --unbuffered/-u flag (previously a POSIX no-op)
to enable unbuffered input reading using fill_buf()/consume() instead
of read_until(b'\n'). This allows partial lines to display immediately
when piping streaming input like `tail -f` into bat.

- Add unbuffered field to Config and InputReader
- Add read_line_unbuffered() using BufRead::fill_buf()/consume()
- Add flush() to OutputHandle, called after each line in unbuffered mode
- Auto-disable line numbers in unbuffered mode to avoid partial line confusion
- Update help text, man page, and shell completions
- Add unit tests and integration tests
This commit is contained in:
mainnebula committed 2026-02-11 23:27:08 -05:00
1 parent cb8b637574
commit 167dda63a8
14 files changed
+183 -12

No files matched your search

+1 -1
View File
@@ -173,7 +173,7 @@ Register-ArgumentCompleter -Native -CommandName '{{PROJECT_EXECUTABLE}}' -Script
# [CompletionResult]::new('-L' , 'L' , [CompletionResultType]::ParameterName, 'Display all supported languages.')
[CompletionResult]::new('--list-languages' , 'list-languages' , [CompletionResultType]::ParameterName, 'Display all supported languages.')
# [CompletionResult]::new('-u' , 'u' , [CompletionResultType]::ParameterName, 'u')
[CompletionResult]::new('--unbuffered' , 'unbuffered' , [CompletionResultType]::ParameterName, 'unbuffered')
[CompletionResult]::new('--unbuffered' , 'unbuffered' , [CompletionResultType]::ParameterName, 'Enable unbuffered input reading for streaming use cases')
[CompletionResult]::new('--completion' , 'completion' , [CompletionResultType]::ParameterName, 'Show shell completion for a certain shell. [possible values: bash, fish, zsh, ps1]')
[CompletionResult]::new('--no-config' , 'no-config' , [CompletionResultType]::ParameterName, 'Do not use the configuration file')
[CompletionResult]::new('--no-custom-assets' , 'no-custom-assets' , [CompletionResultType]::ParameterName, 'Do not load custom assets')
+1 -1
View File
@@ -190,8 +190,8 @@ _bat() {
$split && return 0
if [[ $cur == -* ]]; then
# --unbuffered excluded intentionally (no-op)
COMPREPLY=($(compgen -W "
--unbuffered
--show-all
--nonprintable-notation
--binary
+1 -1
View File
@@ -239,7 +239,7 @@ complete -c $bat -l theme-dark -x -a "(command $bat --list-themes | command cat)
complete -c $bat -l theme-light -x -a "(command $bat --list-themes | command cat)" -d "Set the syntax highlighting theme for light backgrounds" -n __bat_no_excl_args
complete -c $bat -s u -l unbuffered -d "This option exists for POSIX-compliance reasons" -n __bat_no_excl_args
complete -c $bat -s u -l unbuffered -d "Enable unbuffered input reading for streaming use cases" -n __bat_no_excl_args
complete -c $bat -s V -l version -f -d "Show version information" -n __fish_is_first_arg
+1 -1
View File
@@ -58,7 +58,7 @@ _{{PROJECT_EXECUTABLE}}_main() {
default auto full plain changes header header-filename header-filesize grid rule numbers snip'
\*{-r+,--line-range=}'[only print the specified line range]:start\:end'
'(* -)'{-L,--list-languages}'[display all supported languages]'
'(-u --unbuffered)'--unbuffered'[this option exists for POSIX-compliance reasons]'
'(-u --unbuffered)'--unbuffered'[enable unbuffered input reading for streaming use cases]'
--completion='[show shell completion for a certain shell]:shell:(bash fish zsh ps1)'
--set-terminal-title'[sets terminal title to filenames when using a pager]'
--diagnostic'[show diagnostic information for bug reports]'