Finish move to nu-table (#2025)

This commit is contained in:
Jonathan Turner 2020-06-20 12:25:07 -07:00 committed by GitHub
parent 4e83363dd3
commit 89c737f456
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 111 additions and 161 deletions

23
Cargo.lock generated
View File

@ -1899,9 +1899,9 @@ dependencies = [
[[package]] [[package]]
name = "kstring" name = "kstring"
version = "0.1.0" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6382df53100fd22e149030b6634720c94a151076db8d727b3274d7070975d609" checksum = "fbbc30beb80d56ddf6346e935c7abcba96329ee5c5a4cde8984a4e6b6f18b58e"
dependencies = [ dependencies = [
"serde 1.0.110", "serde 1.0.110",
] ]
@ -2038,9 +2038,9 @@ dependencies = [
[[package]] [[package]]
name = "liquid-core" name = "liquid-core"
version = "0.20.1" version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ea59709d9530bab4e9cc0ece12f20fe4999fdef90f7d89391b0fc9ff563b62b" checksum = "4dc58422728185d54cd044bba4d45a2ef2a7111a421f84d344f65629949de4f1"
dependencies = [ dependencies = [
"anymap", "anymap",
"chrono", "chrono",
@ -2481,7 +2481,6 @@ dependencies = [
"pin-utils", "pin-utils",
"pretty-hex", "pretty-hex",
"pretty_env_logger", "pretty_env_logger",
"prettytable-rs",
"ptree", "ptree",
"query_interface", "query_interface",
"quickcheck", "quickcheck",
@ -3235,20 +3234,6 @@ dependencies = [
"log", "log",
] ]
[[package]]
name = "prettytable-rs"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fd04b170004fa2daccf418a7f8253aaf033c27760b5f225889024cf66d7ac2e"
dependencies = [
"atty",
"csv",
"encode_unicode",
"lazy_static 1.4.0",
"term",
"unicode-width",
]
[[package]] [[package]]
name = "proc-macro-error" name = "proc-macro-error"
version = "1.0.2" version = "1.0.2"

View File

@ -62,7 +62,6 @@ parking_lot = "0.10.2"
pin-utils = "0.1.0" pin-utils = "0.1.0"
pretty-hex = "0.1.1" pretty-hex = "0.1.1"
pretty_env_logger = "0.4.0" pretty_env_logger = "0.4.0"
prettytable-rs = "0.8.0"
ptree = {version = "0.2" } ptree = {version = "0.2" }
query_interface = "0.3.5" query_interface = "0.3.5"
rand = "0.7" rand = "0.7"

View File

@ -6,10 +6,7 @@ use nu_errors::ShellError;
use nu_protocol::{hir, hir::Expression, hir::Literal, hir::SpannedExpression}; use nu_protocol::{hir, hir::Expression, hir::Literal, hir::SpannedExpression};
use nu_protocol::{Primitive, Scope, Signature, UntaggedValue, Value}; use nu_protocol::{Primitive, Scope, Signature, UntaggedValue, Value};
use parking_lot::Mutex; use parking_lot::Mutex;
use prettytable::format::{FormatBuilder, LinePosition, LineSeparator};
use prettytable::{color, Attr, Cell, Row, Table};
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use textwrap::fill;
pub struct Autoview; pub struct Autoview;
@ -268,90 +265,28 @@ pub async fn autoview(context: RunnableContext) -> Result<OutputStream, ShellErr
+ row.entries.iter().count() * 2) + row.entries.iter().count() * 2)
> textwrap::termwidth()) => > textwrap::termwidth()) =>
{ {
let termwidth = std::cmp::max(textwrap::termwidth(), 20); let mut entries = vec![];
enum TableMode {
Light,
Normal,
}
let mut table = Table::new();
let table_mode = crate::data::config::config(Tag::unknown());
let table_mode = if let Some(s) = table_mode?.get("table_mode") {
match s.as_string() {
Ok(typ) if typ == "light" => TableMode::Light,
_ => TableMode::Normal,
}
} else {
TableMode::Normal
};
match table_mode {
TableMode::Light => {
table.set_format(
FormatBuilder::new()
.separator(
LinePosition::Title,
LineSeparator::new('─', '─', ' ', ' '),
)
.separator(
LinePosition::Bottom,
LineSeparator::new(' ', ' ', ' ', ' '),
)
.padding(1, 1)
.build(),
);
}
_ => {
table.set_format(
FormatBuilder::new()
.column_separator('│')
.separator(
LinePosition::Top,
LineSeparator::new('─', '┬', ' ', ' '),
)
.separator(
LinePosition::Title,
LineSeparator::new('─', '┼', ' ', ' '),
)
.separator(
LinePosition::Bottom,
LineSeparator::new('─', '┴', ' ', ' '),
)
.padding(1, 1)
.build(),
);
}
}
let mut max_key_len = 0;
for (key, _) in row.entries.iter() {
max_key_len = std::cmp::max(max_key_len, key.chars().count());
}
if max_key_len > (termwidth / 2 - 1) {
max_key_len = termwidth / 2 - 1;
}
let max_val_len = termwidth - max_key_len - 5;
for (key, value) in row.entries.iter() { for (key, value) in row.entries.iter() {
table.add_row(Row::new(vec![ entries.push(vec![
Cell::new(&fill(&key, max_key_len)) nu_table::StyledString::new(
.with_style(Attr::ForegroundColor(color::GREEN)) key.to_string(),
.with_style(Attr::Bold), nu_table::TextStyle {
Cell::new(&fill( alignment: nu_table::Alignment::Left,
&format_leaf(value).plain_string(100_000), color: Some(ansi_term::Color::Green),
max_val_len, is_bold: true,
)), },
])); ),
nu_table::StyledString::new(
format_leaf(value).plain_string(100_000),
nu_table::TextStyle::basic(),
),
]);
} }
table.printstd(); let table =
nu_table::Table::new(vec![], entries, nu_table::Theme::compact());
// table.print_term(&mut *context.host.lock().out_terminal().ok_or_else(|| ShellError::untagged_runtime_error("Could not open terminal for output"))?) nu_table::draw_table(&table, textwrap::termwidth());
// .map_err(|_| ShellError::untagged_runtime_error("Internal error: could not print to terminal (for unix systems check to make sure TERM is set)"))?;
} }
Value { Value {

View File

@ -56,7 +56,7 @@ fn str_to_color(s: String) -> Option<ansi_term::Color> {
pub fn from_list(values: &[Value], starting_idx: usize) -> nu_table::Table { pub fn from_list(values: &[Value], starting_idx: usize) -> nu_table::Table {
let config = crate::data::config::config(Tag::unknown()); let config = crate::data::config::config(Tag::unknown());
let header_style = if let Ok(config) = config { let header_style = if let Ok(config) = &config {
let header_align = config.get("header_align").map_or(Alignment::Left, |a| { let header_align = config.get("header_align").map_or(Alignment::Left, |a| {
a.as_string() a.as_string()
.map_or(Alignment::Center, |a| match a.to_lowercase().as_str() { .map_or(Alignment::Center, |a| match a.to_lowercase().as_str() {
@ -97,6 +97,19 @@ pub fn from_list(values: &[Value], starting_idx: usize) -> nu_table::Table {
.collect(); .collect();
let entries = values_to_entries(values, &mut headers, starting_idx); let entries = values_to_entries(values, &mut headers, starting_idx);
if let Ok(config) = config {
if let Some(style) = config.get("table_mode") {
if let Ok(table_mode) = style.as_string() {
if table_mode == "light" {
return nu_table::Table {
headers,
data: entries,
theme: Theme::light(),
};
}
}
}
}
nu_table::Table { nu_table::Table {
headers, headers,
data: entries, data: entries,

View File

@ -81,6 +81,8 @@ pub struct Theme {
pub print_left_border: bool, pub print_left_border: bool,
pub print_right_border: bool, pub print_right_border: bool,
pub print_top_border: bool,
pub print_bottom_border: bool,
} }
impl Theme { impl Theme {
@ -108,6 +110,8 @@ impl Theme {
print_left_border: true, print_left_border: true,
print_right_border: true, print_right_border: true,
print_top_border: true,
print_bottom_border: true,
} }
} }
#[allow(unused)] #[allow(unused)]
@ -136,6 +140,8 @@ impl Theme {
print_left_border: true, print_left_border: true,
print_right_border: true, print_right_border: true,
print_top_border: true,
print_bottom_border: true,
} }
} }
#[allow(unused)] #[allow(unused)]
@ -160,10 +166,12 @@ impl Theme {
right_vertical: ' ', right_vertical: ' ',
separate_header: true, separate_header: true,
separate_rows: true, separate_rows: false,
print_left_border: true, print_left_border: true,
print_right_border: true, print_right_border: true,
print_top_border: false,
print_bottom_border: true,
} }
} }
#[allow(unused)] #[allow(unused)]
@ -191,6 +199,8 @@ impl Theme {
print_left_border: false, print_left_border: false,
print_right_border: false, print_right_border: false,
print_top_border: true,
print_bottom_border: true,
} }
} }
} }
@ -227,84 +237,77 @@ pub struct WrappedTable {
} }
impl WrappedTable { impl WrappedTable {
//TODO: optimize this
fn print_separator(&self, separator_position: SeparatorPosition) { fn print_separator(&self, separator_position: SeparatorPosition) {
let column_count = self.column_widths.len(); let column_count = self.column_widths.len();
let mut output = String::new();
match separator_position { match separator_position {
SeparatorPosition::Top => { SeparatorPosition::Top => {
for column in self.column_widths.iter().enumerate() { for column in self.column_widths.iter().enumerate() {
if column.0 == 0 && self.theme.print_left_border { if column.0 == 0 && self.theme.print_left_border {
print!("{}", self.theme.top_left); output.push(self.theme.top_left);
} }
print!(
"{}",
std::iter::repeat(self.theme.top_horizontal)
.take(*column.1)
.collect::<String>()
);
print!("{}{}", self.theme.top_horizontal, self.theme.top_horizontal); for _ in 0..*column.1 {
output.push(self.theme.top_horizontal);
}
output.push(self.theme.top_horizontal);
output.push(self.theme.top_horizontal);
if column.0 == column_count - 1 { if column.0 == column_count - 1 {
if self.theme.print_right_border { if self.theme.print_right_border {
print!("{}", self.theme.top_right); output.push(self.theme.top_right);
} }
} else { } else {
print!("{}", self.theme.top_center); output.push(self.theme.top_center);
} }
} }
} }
SeparatorPosition::Middle => { SeparatorPosition::Middle => {
for column in self.column_widths.iter().enumerate() { for column in self.column_widths.iter().enumerate() {
if column.0 == 0 && self.theme.print_left_border { if column.0 == 0 && self.theme.print_left_border {
print!("{}", self.theme.middle_left); output.push(self.theme.middle_left);
} }
print!(
"{}",
std::iter::repeat(self.theme.middle_horizontal)
.take(*column.1)
.collect::<String>()
);
print!( for _ in 0..*column.1 {
"{}{}", output.push(self.theme.middle_horizontal);
self.theme.middle_horizontal, self.theme.middle_horizontal }
);
output.push(self.theme.middle_horizontal);
output.push(self.theme.middle_horizontal);
if column.0 == column_count - 1 { if column.0 == column_count - 1 {
if self.theme.print_right_border { if self.theme.print_right_border {
print!("{}", self.theme.middle_right); output.push(self.theme.middle_right);
} }
} else { } else {
print!("{}", self.theme.center); output.push(self.theme.center);
} }
} }
} }
SeparatorPosition::Bottom => { SeparatorPosition::Bottom => {
for column in self.column_widths.iter().enumerate() { for column in self.column_widths.iter().enumerate() {
if column.0 == 0 && self.theme.print_left_border { if column.0 == 0 && self.theme.print_left_border {
print!("{}", self.theme.bottom_left); output.push(self.theme.bottom_left);
} }
print!( for _ in 0..*column.1 {
"{}", output.push(self.theme.bottom_horizontal);
std::iter::repeat(self.theme.bottom_horizontal) }
.take(*column.1) output.push(self.theme.bottom_horizontal);
.collect::<String>() output.push(self.theme.bottom_horizontal);
);
print!(
"{}{}",
self.theme.bottom_horizontal, self.theme.bottom_horizontal
);
if column.0 == column_count - 1 { if column.0 == column_count - 1 {
if self.theme.print_right_border { if self.theme.print_right_border {
print!("{}", self.theme.bottom_right); output.push(self.theme.bottom_right);
} }
} else { } else {
print!("{}", self.theme.bottom_center); output.push(self.theme.bottom_center);
} }
} }
} }
} }
println!("{}", output);
} }
fn print_cell_contents(&self, cells: &[WrappedCell]) { fn print_cell_contents(&self, cells: &[WrappedCell]) {
@ -399,10 +402,13 @@ impl WrappedTable {
return; return;
} }
self.print_separator(SeparatorPosition::Top); if self.theme.print_top_border {
println!(); self.print_separator(SeparatorPosition::Top);
}
self.print_cell_contents(&self.headers); if !self.headers.is_empty() {
self.print_cell_contents(&self.headers);
}
let mut first_row = true; let mut first_row = true;
@ -410,21 +416,21 @@ impl WrappedTable {
if !first_row { if !first_row {
if self.theme.separate_rows { if self.theme.separate_rows {
self.print_separator(SeparatorPosition::Middle); self.print_separator(SeparatorPosition::Middle);
println!();
} }
} else { } else {
first_row = false; first_row = false;
if self.theme.separate_header { if self.theme.separate_header && !self.headers.is_empty() {
self.print_separator(SeparatorPosition::Middle); self.print_separator(SeparatorPosition::Middle);
println!();
} }
} }
self.print_cell_contents(row); self.print_cell_contents(row);
} }
self.print_separator(SeparatorPosition::Bottom);
println!(); if self.theme.print_bottom_border {
self.print_separator(SeparatorPosition::Bottom);
}
} }
} }
@ -499,6 +505,17 @@ pub fn draw_table(table: &Table, termwidth: usize) {
// maybe_truncate_columns(&mut headers, &mut entries, termwidth); // maybe_truncate_columns(&mut headers, &mut entries, termwidth);
let headers_len = table.headers.len(); let headers_len = table.headers.len();
// fix the length of the table if there are no headers:
let headers_len = if headers_len == 0 {
if !table.data.is_empty() && !table.data[0].is_empty() {
table.data[0].len()
} else {
return;
}
} else {
headers_len
};
// Measure how big our columns need to be (accounting for separators also) // Measure how big our columns need to be (accounting for separators also)
let max_naive_column_width = (termwidth - 3 * (headers_len - 1)) / headers_len; let max_naive_column_width = (termwidth - 3 * (headers_len - 1)) / headers_len;
@ -518,18 +535,23 @@ pub fn draw_table(table: &Table, termwidth: usize) {
// This should give us the final max column width // This should give us the final max column width
let max_column_width = column_space.max_width(termwidth); let max_column_width = column_space.max_width(termwidth);
let wrapped_table = wrap_cells( let wrapped_table = wrap_cells(processed_table, max_column_width);
processed_table,
// max_per_column,
// max_naive_column_width,
max_column_width,
);
wrapped_table.new_print_table(); wrapped_table.new_print_table();
} }
fn wrap_cells(processed_table: ProcessedTable, max_column_width: usize) -> WrappedTable { fn wrap_cells(processed_table: ProcessedTable, max_column_width: usize) -> WrappedTable {
let mut column_widths = vec![0; processed_table.headers.len()]; let mut column_widths = vec![
0;
std::cmp::max(
processed_table.headers.len(),
if !processed_table.data.is_empty() {
processed_table.data[0].len()
} else {
0
}
)
];
let mut output_headers = vec![]; let mut output_headers = vec![];
for header in processed_table.headers.into_iter().enumerate() { for header in processed_table.headers.into_iter().enumerate() {
let wrapped = wrap( let wrapped = wrap(

View File

@ -134,11 +134,7 @@ pub fn view_text_value(value: &Value) {
_ => (), _ => (),
} }
} }
} else {
println!("Couldn't find bat section in config");
} }
} else {
println!("Error reading config!");
} }
let value_anchor = value.anchor(); let value_anchor = value.anchor();