diff --git a/crates/nu-command/src/viewers/table.rs b/crates/nu-command/src/viewers/table.rs index f146d0e310..e8120841b2 100644 --- a/crates/nu-command/src/viewers/table.rs +++ b/crates/nu-command/src/viewers/table.rs @@ -18,6 +18,16 @@ use terminal_size::{Height, Width}; const STREAM_PAGE_SIZE: usize = 1000; const STREAM_TIMEOUT_CHECK_INTERVAL: usize = 100; +fn get_width_param(width_param: Option) -> usize { + if let Some(col) = width_param { + col as usize + } else if let Some((Width(w), Height(_h))) = terminal_size::terminal_size() { + (w - 1) as usize + } else { + 80usize + } +} + #[derive(Clone)] pub struct Table; @@ -44,6 +54,12 @@ impl Command for Table { Some('n'), ) .switch("list", "list available table modes/themes", Some('l')) + .named( + "width", + SyntaxShape::Int, + "number of terminal columns wide (not output columns)", + Some('w'), + ) .category(Category::Viewers) } @@ -62,11 +78,8 @@ impl Command for Table { let row_offset = start_num.unwrap_or_default() as usize; let list: bool = call.has_flag("list"); - let term_width = if let Some((Width(w), Height(_h))) = terminal_size::terminal_size() { - (w - 1) as usize - } else { - 80usize - }; + let width_param: Option = call.get_flag(engine_state, stack, "width")?; + let term_width = get_width_param(width_param); if list { let table_modes = vec![ @@ -222,7 +235,7 @@ impl Command for Table { #[allow(clippy::too_many_arguments)] fn handle_row_stream( engine_state: &EngineState, - stack: &Stack, + stack: &mut Stack, stream: ListStream, call: &Call, row_offset: usize, @@ -306,6 +319,7 @@ fn handle_row_stream( }; let head = call.head; + let width_param: Option = call.get_flag(engine_state, stack, "width")?; Ok(PipelineData::ExternalStream { stdout: Some(RawStream::new( @@ -315,6 +329,7 @@ fn handle_row_stream( ctrlc: ctrlc.clone(), head, stream, + width_param, }), ctrlc, head, @@ -469,6 +484,7 @@ struct PagingTableCreator { ctrlc: Option>, config: Config, row_offset: usize, + width_param: Option, } impl Iterator for PagingTableCreator { @@ -507,12 +523,7 @@ impl Iterator for PagingTableCreator { } let color_hm = get_color_config(&self.config); - - let term_width = if let Some((Width(w), Height(_h))) = terminal_size::terminal_size() { - (w - 1) as usize - } else { - 80usize - }; + let term_width = get_width_param(self.width_param); let table = convert_to_table( self.row_offset, diff --git a/crates/nu-table/src/table.rs b/crates/nu-table/src/table.rs index cd5f3fb5e4..3c0cd4016a 100644 --- a/crates/nu-table/src/table.rs +++ b/crates/nu-table/src/table.rs @@ -491,14 +491,20 @@ pub fn draw_table( config: &Config, ) -> String { // Remove the edges, if used - let termwidth = if table.theme.print_left_border && table.theme.print_right_border { - termwidth - 3 + let edges_width = if table.theme.print_left_border && table.theme.print_right_border { + 3 } else if table.theme.print_left_border || table.theme.print_right_border { - termwidth - 1 + 1 } else { - termwidth + 0 }; + if termwidth < edges_width { + return format!("Couldn't fit table into {} columns!", termwidth); + } + + let termwidth = termwidth - edges_width; + let mut processed_table = process_table(table); let max_per_column = get_max_column_widths(&processed_table);