From 3755f788ca1515f0b0377423cafcea643d64f227 Mon Sep 17 00:00:00 2001 From: Keith Hall Date: Sat, 29 Nov 2025 17:22:12 +0200 Subject: [PATCH] Improve -n detection to handle combined flags correctly Updated the logic to correctly handle combined short flags like -pn and -np. The -n flag is only honored when it's either: 1. A standalone flag (-n or --number) 2. The last flag in a combined form that includes -p (e.g., -pn), or 3. In a combined form without -p (e.g., -An) This ensures that -np (where -p overrides -n) correctly produces plain output, while -pn (where -n overrides -p) produces line numbers. --- src/bin/bat/app.rs | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/bin/bat/app.rs b/src/bin/bat/app.rs index e1051850..f8b429cb 100644 --- a/src/bin/bat/app.rs +++ b/src/bin/bat/app.rs @@ -58,15 +58,38 @@ impl App { let _ = nu_ansi_term::enable_ansi_support(); let interactive_output = std::io::stdout().is_terminal(); - + // Check if the -n / --number option was passed on the command line // (before merging with config file and environment variables). // This is needed to honor the -n flag when piping output, similar to `cat -n`. + // We need to handle both standalone (-n, --number) and combined short flags (-pn, -An, etc.) + // Note: We only check if -n appears and is not overridden by -p in the same combined flag. + // For combined flags like -np, -p comes after -n and overrides it, so we don't count it. + // For combined flags like -pn, -n comes after -p and takes effect. let number_from_cli = wild::args_os().any(|arg| { let arg_str = arg.to_string_lossy(); - arg_str == "-n" || arg_str == "--number" + if arg_str == "-n" || arg_str == "--number" { + return true; + } + // Handle combined short flags + // Only count -n if it's the LAST flag in the combined form (so -p doesn't override it) + // or if -p is not present in the combined form + if arg_str.starts_with('-') && !arg_str.starts_with("--") && arg_str.len() > 2 { + let chars: Vec = arg_str.chars().skip(1).collect(); + let n_pos = chars.iter().position(|&c| c == 'n'); + let p_pos = chars.iter().position(|&c| c == 'p'); + // -n is in the combined flag and either: + // - -p is not present, OR + // - -n comes after -p (so -n takes effect) + if let Some(n) = n_pos { + if p_pos.is_none() || n > p_pos.unwrap() { + return true; + } + } + } + false }); - + let matches = Self::matches(interactive_output)?; if matches.get_flag("help") {