mirror of
https://github.com/nushell/nushell.git
synced 2024-11-22 00:13:21 +01:00
[DRAFT] Check fix for emojie, wrap issues (#13430)
Hi there Here I am using latest tabled. My tests shows it does fixes panics, but I am wanna be sure. @fdncred could you verify that it does fixes those panics/errors? Closes #13405 Closes #12786
This commit is contained in:
parent
7003b007d5
commit
525eac1afd
1292
Cargo.lock
generated
1292
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -156,7 +156,7 @@ sha2 = "0.10"
|
|||||||
strip-ansi-escapes = "0.2.0"
|
strip-ansi-escapes = "0.2.0"
|
||||||
syn = "2.0"
|
syn = "2.0"
|
||||||
sysinfo = "0.30"
|
sysinfo = "0.30"
|
||||||
tabled = { version = "0.14.0", default-features = false }
|
tabled = { version = "0.16.0", default-features = false }
|
||||||
tempfile = "3.10"
|
tempfile = "3.10"
|
||||||
terminal_size = "0.3"
|
terminal_size = "0.3"
|
||||||
titlecase = "2.0"
|
titlecase = "2.0"
|
||||||
|
@ -83,7 +83,7 @@ serde_urlencoded = { workspace = true }
|
|||||||
serde_yaml = { workspace = true }
|
serde_yaml = { workspace = true }
|
||||||
sha2 = { workspace = true }
|
sha2 = { workspace = true }
|
||||||
sysinfo = { workspace = true }
|
sysinfo = { workspace = true }
|
||||||
tabled = { workspace = true, features = ["color"], default-features = false }
|
tabled = { workspace = true, features = ["ansi"], default-features = false }
|
||||||
terminal_size = { workspace = true }
|
terminal_size = { workspace = true }
|
||||||
titlecase = { workspace = true }
|
titlecase = { workspace = true }
|
||||||
toml = { workspace = true, features = ["preserve_order"] }
|
toml = { workspace = true, features = ["preserve_order"] }
|
||||||
|
@ -57,7 +57,7 @@ pub fn build_table(value: Value, description: String, termsize: usize) -> String
|
|||||||
Settings::default()
|
Settings::default()
|
||||||
.with(Style::rounded().corner_top_left('├').corner_top_right('┤'))
|
.with(Style::rounded().corner_top_left('├').corner_top_right('┤'))
|
||||||
.with(SetWidths(widths))
|
.with(SetWidths(widths))
|
||||||
.with(Wrap::new(width).priority::<PriorityMax>())
|
.with(Wrap::new(width).priority(PriorityMax))
|
||||||
.with(SetHorizontalChar::new('┼', '┴', 11 + 2 + 1)),
|
.with(SetHorizontalChar::new('┼', '┴', 11 + 2 + 1)),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -308,7 +308,7 @@ mod global_horizontal_char {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Records + ExactRecords> TableOption<R, CompleteDimensionVecRecords<'_>, ColoredConfig>
|
impl<R: Records + ExactRecords> TableOption<R, ColoredConfig, CompleteDimensionVecRecords<'_>>
|
||||||
for SetHorizontalChar
|
for SetHorizontalChar
|
||||||
{
|
{
|
||||||
fn change(
|
fn change(
|
||||||
@ -377,7 +377,7 @@ mod set_widths {
|
|||||||
|
|
||||||
pub struct SetWidths(pub Vec<usize>);
|
pub struct SetWidths(pub Vec<usize>);
|
||||||
|
|
||||||
impl<R> TableOption<R, CompleteDimensionVecRecords<'_>, ColoredConfig> for SetWidths {
|
impl<R> TableOption<R, ColoredConfig, CompleteDimensionVecRecords<'_>> for SetWidths {
|
||||||
fn change(
|
fn change(
|
||||||
self,
|
self,
|
||||||
_: &mut R,
|
_: &mut R,
|
||||||
|
@ -18,7 +18,7 @@ nu-color-config = { path = "../nu-color-config", version = "0.97.2" }
|
|||||||
nu-ansi-term = { workspace = true }
|
nu-ansi-term = { workspace = true }
|
||||||
once_cell = { workspace = true }
|
once_cell = { workspace = true }
|
||||||
fancy-regex = { workspace = true }
|
fancy-regex = { workspace = true }
|
||||||
tabled = { workspace = true, features = ["color"], default-features = false }
|
tabled = { workspace = true, features = ["ansi"], default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
# nu-test-support = { path="../nu-test-support", version = "0.97.2" }
|
# nu-test-support = { path="../nu-test-support", version = "0.97.2" }
|
@ -1,7 +1,7 @@
|
|||||||
use nu_ansi_term::{Color, Style};
|
use nu_ansi_term::{Color, Style};
|
||||||
use nu_color_config::TextStyle;
|
use nu_color_config::TextStyle;
|
||||||
use nu_table::{NuTable, NuTableConfig, TableTheme};
|
use nu_table::{NuTable, NuTableConfig, TableTheme};
|
||||||
use tabled::grid::records::vec_records::CellInfo;
|
use tabled::grid::records::vec_records::Text;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<_> = std::env::args().collect();
|
let args: Vec<_> = std::env::args().collect();
|
||||||
@ -80,10 +80,10 @@ fn make_table_data() -> (Vec<&'static str>, Vec<&'static str>) {
|
|||||||
(table_headers, row_data)
|
(table_headers, row_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_cell_info_vec(data: &[&str]) -> Vec<CellInfo<String>> {
|
fn to_cell_info_vec(data: &[&str]) -> Vec<Text<String>> {
|
||||||
let mut v = vec![];
|
let mut v = vec![];
|
||||||
for x in data {
|
for x in data {
|
||||||
v.push(CellInfo::new(String::from(*x)));
|
v.push(Text::new(String::from(*x)));
|
||||||
}
|
}
|
||||||
|
|
||||||
v
|
v
|
||||||
|
@ -7,12 +7,12 @@ use std::{cmp::min, collections::HashMap};
|
|||||||
use tabled::{
|
use tabled::{
|
||||||
builder::Builder,
|
builder::Builder,
|
||||||
grid::{
|
grid::{
|
||||||
color::AnsiColor,
|
ansi::ANSIBuf,
|
||||||
colors::Colors,
|
colors::Colors,
|
||||||
config::{AlignmentHorizontal, ColoredConfig, Entity, EntityMap, Position},
|
config::{AlignmentHorizontal, ColoredConfig, Entity, EntityMap, Position},
|
||||||
dimension::CompleteDimensionVecRecords,
|
dimension::CompleteDimensionVecRecords,
|
||||||
records::{
|
records::{
|
||||||
vec_records::{Cell, CellInfo, VecRecords},
|
vec_records::{Cell, Text, VecRecords},
|
||||||
ExactRecords, PeekableRecords, Records, Resizable,
|
ExactRecords, PeekableRecords, Records, Resizable,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -22,7 +22,7 @@ use tabled::{
|
|||||||
peaker::Peaker,
|
peaker::Peaker,
|
||||||
themes::ColumnNames,
|
themes::ColumnNames,
|
||||||
width::Truncate,
|
width::Truncate,
|
||||||
Color, Modify, Padding, Settings, TableOption, Width,
|
Alignment, Color, Modify, Padding, Settings, TableOption, Width,
|
||||||
},
|
},
|
||||||
Table,
|
Table,
|
||||||
};
|
};
|
||||||
@ -37,13 +37,13 @@ pub struct NuTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub type NuRecords = VecRecords<NuTableCell>;
|
pub type NuRecords = VecRecords<NuTableCell>;
|
||||||
pub type NuTableCell = CellInfo<String>;
|
pub type NuTableCell = Text<String>;
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
struct Styles {
|
struct Styles {
|
||||||
index: AnsiColor<'static>,
|
index: ANSIBuf,
|
||||||
header: AnsiColor<'static>,
|
header: ANSIBuf,
|
||||||
data: EntityMap<AnsiColor<'static>>,
|
data: EntityMap<ANSIBuf>,
|
||||||
data_is_set: bool,
|
data_is_set: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ impl NuTable {
|
|||||||
/// Creates an empty [`NuTable`] instance.
|
/// Creates an empty [`NuTable`] instance.
|
||||||
pub fn new(count_rows: usize, count_columns: usize) -> Self {
|
pub fn new(count_rows: usize, count_columns: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
data: VecRecords::new(vec![vec![CellInfo::default(); count_columns]; count_rows]),
|
data: VecRecords::new(vec![vec![Text::default(); count_columns]; count_rows]),
|
||||||
styles: Styles::default(),
|
styles: Styles::default(),
|
||||||
indent: (1, 1),
|
indent: (1, 1),
|
||||||
alignments: Alignments {
|
alignments: Alignments {
|
||||||
@ -84,12 +84,12 @@ impl NuTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, pos: Position, text: String) {
|
pub fn insert(&mut self, pos: Position, text: String) {
|
||||||
self.data[pos.0][pos.1] = CellInfo::new(text);
|
self.data[pos.0][pos.1] = Text::new(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_column_style(&mut self, column: usize, style: TextStyle) {
|
pub fn set_column_style(&mut self, column: usize, style: TextStyle) {
|
||||||
if let Some(style) = style.color_style {
|
if let Some(style) = style.color_style {
|
||||||
let style = AnsiColor::from(convert_style(style));
|
let style = ANSIBuf::from(convert_style(style));
|
||||||
self.styles.data.insert(Entity::Column(column), style);
|
self.styles.data.insert(Entity::Column(column), style);
|
||||||
self.styles.data_is_set = true;
|
self.styles.data_is_set = true;
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ impl NuTable {
|
|||||||
|
|
||||||
pub fn insert_style(&mut self, pos: Position, style: TextStyle) {
|
pub fn insert_style(&mut self, pos: Position, style: TextStyle) {
|
||||||
if let Some(style) = style.color_style {
|
if let Some(style) = style.color_style {
|
||||||
let style = AnsiColor::from(convert_style(style));
|
let style = ANSIBuf::from(convert_style(style));
|
||||||
self.styles.data.insert(Entity::Cell(pos.0, pos.1), style);
|
self.styles.data.insert(Entity::Cell(pos.0, pos.1), style);
|
||||||
self.styles.data_is_set = true;
|
self.styles.data_is_set = true;
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ impl NuTable {
|
|||||||
|
|
||||||
pub fn set_header_style(&mut self, style: TextStyle) {
|
pub fn set_header_style(&mut self, style: TextStyle) {
|
||||||
if let Some(style) = style.color_style {
|
if let Some(style) = style.color_style {
|
||||||
let style = AnsiColor::from(convert_style(style));
|
let style = ANSIBuf::from(convert_style(style));
|
||||||
self.styles.header = style;
|
self.styles.header = style;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ impl NuTable {
|
|||||||
|
|
||||||
pub fn set_index_style(&mut self, style: TextStyle) {
|
pub fn set_index_style(&mut self, style: TextStyle) {
|
||||||
if let Some(style) = style.color_style {
|
if let Some(style) = style.color_style {
|
||||||
let style = AnsiColor::from(convert_style(style));
|
let style = ANSIBuf::from(convert_style(style));
|
||||||
self.styles.index = style;
|
self.styles.index = style;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ impl NuTable {
|
|||||||
|
|
||||||
pub fn set_data_style(&mut self, style: TextStyle) {
|
pub fn set_data_style(&mut self, style: TextStyle) {
|
||||||
if let Some(style) = style.color_style {
|
if let Some(style) = style.color_style {
|
||||||
let style = AnsiColor::from(convert_style(style));
|
let style = ANSIBuf::from(convert_style(style));
|
||||||
self.styles.data.insert(Entity::Global, style);
|
self.styles.data.insert(Entity::Global, style);
|
||||||
self.styles.data_is_set = true;
|
self.styles.data_is_set = true;
|
||||||
}
|
}
|
||||||
@ -171,8 +171,8 @@ impl NuTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<Vec<CellInfo<String>>>> for NuTable {
|
impl From<Vec<Vec<Text<String>>>> for NuTable {
|
||||||
fn from(value: Vec<Vec<CellInfo<String>>>) -> Self {
|
fn from(value: Vec<Vec<Text<String>>>) -> Self {
|
||||||
let mut nutable = Self::new(0, 0);
|
let mut nutable = Self::new(0, 0);
|
||||||
nutable.data = VecRecords::new(value);
|
nutable.data = VecRecords::new(value);
|
||||||
|
|
||||||
@ -352,7 +352,7 @@ impl TableWidthCtrl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for TableWidthCtrl {
|
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for TableWidthCtrl {
|
||||||
fn change(
|
fn change(
|
||||||
self,
|
self,
|
||||||
rec: &mut NuRecords,
|
rec: &mut NuRecords,
|
||||||
@ -374,8 +374,8 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
|||||||
)
|
)
|
||||||
.change(rec, cfg, dim);
|
.change(rec, cfg, dim);
|
||||||
} else if self.cfg.expand && self.width_max > total_width {
|
} else if self.cfg.expand && self.width_max > total_width {
|
||||||
Settings::new(SetDimensions(self.width), Width::increase(self.width_max))
|
let opt = (SetDimensions(self.width), Width::increase(self.width_max));
|
||||||
.change(rec, cfg, dim)
|
TableOption::<VecRecords<_>, _, _>::change(opt, rec, cfg, dim)
|
||||||
} else {
|
} else {
|
||||||
SetDimensions(self.width).change(rec, cfg, dim);
|
SetDimensions(self.width).change(rec, cfg, dim);
|
||||||
}
|
}
|
||||||
@ -408,7 +408,7 @@ impl TableTrim {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for TableTrim {
|
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for TableTrim {
|
||||||
fn change(
|
fn change(
|
||||||
self,
|
self,
|
||||||
recs: &mut NuRecords,
|
recs: &mut NuRecords,
|
||||||
@ -424,27 +424,28 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
|||||||
|
|
||||||
match self.strategy {
|
match self.strategy {
|
||||||
TrimStrategy::Wrap { try_to_keep_words } => {
|
TrimStrategy::Wrap { try_to_keep_words } => {
|
||||||
let mut wrap = Width::wrap(self.width_max).priority::<PriorityMax>();
|
let wrap = Width::wrap(self.width_max)
|
||||||
if try_to_keep_words {
|
.keep_words(try_to_keep_words)
|
||||||
wrap = wrap.keep_words();
|
.priority(PriorityMax);
|
||||||
}
|
|
||||||
|
|
||||||
Settings::new(SetDimensions(self.width), wrap).change(recs, cfg, dims);
|
let opt = (SetDimensions(self.width), wrap);
|
||||||
|
TableOption::<NuRecords, _, _>::change(opt, recs, cfg, dims);
|
||||||
}
|
}
|
||||||
TrimStrategy::Truncate { suffix } => {
|
TrimStrategy::Truncate { suffix } => {
|
||||||
let mut truncate = Width::truncate(self.width_max).priority::<PriorityMax>();
|
let mut truncate = Width::truncate(self.width_max).priority(PriorityMax);
|
||||||
if let Some(suffix) = suffix {
|
if let Some(suffix) = suffix {
|
||||||
truncate = truncate.suffix(suffix).suffix_try_color(true);
|
truncate = truncate.suffix(suffix).suffix_try_color(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::new(SetDimensions(self.width), truncate).change(recs, cfg, dims);
|
let opt = (SetDimensions(self.width), truncate);
|
||||||
|
TableOption::<NuRecords, _, _>::change(opt, recs, cfg, dims);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trim_as_header(
|
fn trim_as_header(
|
||||||
recs: &mut VecRecords<CellInfo<String>>,
|
recs: &mut VecRecords<Text<String>>,
|
||||||
cfg: &mut ColoredConfig,
|
cfg: &mut ColoredConfig,
|
||||||
dims: &mut CompleteDimensionVecRecords,
|
dims: &mut CompleteDimensionVecRecords,
|
||||||
trim: TableTrim,
|
trim: TableTrim,
|
||||||
@ -456,7 +457,7 @@ fn trim_as_header(
|
|||||||
let headers = recs[0].to_owned();
|
let headers = recs[0].to_owned();
|
||||||
let headers_widths = headers
|
let headers_widths = headers
|
||||||
.iter()
|
.iter()
|
||||||
.map(CellInfo::width)
|
.map(Text::width)
|
||||||
.map(|v| v + trim.pad)
|
.map(|v| v + trim.pad)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let min_width_use = get_total_width2(&headers_widths, cfg);
|
let min_width_use = get_total_width2(&headers_widths, cfg);
|
||||||
@ -481,14 +482,10 @@ fn trim_as_header(
|
|||||||
|
|
||||||
match &trim.strategy {
|
match &trim.strategy {
|
||||||
TrimStrategy::Wrap { try_to_keep_words } => {
|
TrimStrategy::Wrap { try_to_keep_words } => {
|
||||||
let mut wrap = Width::wrap(use_width);
|
let wrap = Width::wrap(use_width).keep_words(*try_to_keep_words);
|
||||||
if *try_to_keep_words {
|
|
||||||
wrap = wrap.keep_words();
|
|
||||||
}
|
|
||||||
|
|
||||||
Modify::new(Columns::single(i))
|
let opt = Modify::new(Columns::single(i)).with(wrap);
|
||||||
.with(wrap)
|
TableOption::<VecRecords<Text<String>>, _, _>::change(opt, recs, cfg, dims);
|
||||||
.change(recs, cfg, dims);
|
|
||||||
}
|
}
|
||||||
TrimStrategy::Truncate { suffix } => {
|
TrimStrategy::Truncate { suffix } => {
|
||||||
let mut truncate = Width::truncate(use_width);
|
let mut truncate = Width::truncate(use_width);
|
||||||
@ -496,9 +493,8 @@ fn trim_as_header(
|
|||||||
truncate = truncate.suffix(suffix).suffix_try_color(true);
|
truncate = truncate.suffix(suffix).suffix_try_color(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Modify::new(Columns::single(i))
|
let opt = Modify::new(Columns::single(i)).with(truncate);
|
||||||
.with(truncate)
|
TableOption::<VecRecords<Text<String>>, _, _>::change(opt, recs, cfg, dims);
|
||||||
.change(recs, cfg, dims);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -579,19 +575,21 @@ fn load_theme(
|
|||||||
let mut theme = theme.get_theme();
|
let mut theme = theme.get_theme();
|
||||||
|
|
||||||
if !with_header {
|
if !with_header {
|
||||||
theme.set_horizontals(std::collections::HashMap::new());
|
theme.set_horizontal_lines(Default::default());
|
||||||
} else if with_footer && table.count_rows() > 2 {
|
|
||||||
if let Some(line) = theme.get_horizontal(1) {
|
|
||||||
theme.insert_horizontal(table.count_rows() - 1, line);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table.with(theme);
|
table.with(theme);
|
||||||
|
|
||||||
if let Some(style) = sep_color {
|
if let Some(style) = sep_color {
|
||||||
let color = convert_style(style);
|
let color = convert_style(style);
|
||||||
let color = AnsiColor::from(color);
|
let color = ANSIBuf::from(color);
|
||||||
table.get_config_mut().set_border_color_global(color);
|
table.get_config_mut().set_border_color_default(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !with_header {
|
||||||
|
table.with(RemoveHorizontalLine);
|
||||||
|
} else if with_footer {
|
||||||
|
table.with(CopyFirstHorizontalLineAtLast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -853,10 +851,6 @@ fn truncate_columns_by_head(
|
|||||||
pub struct PriorityMax;
|
pub struct PriorityMax;
|
||||||
|
|
||||||
impl Peaker for PriorityMax {
|
impl Peaker for PriorityMax {
|
||||||
fn create() -> Self {
|
|
||||||
Self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn peak(&mut self, _: &[usize], widths: &[usize]) -> Option<usize> {
|
fn peak(&mut self, _: &[usize], widths: &[usize]) -> Option<usize> {
|
||||||
let col = (0..widths.len()).rev().max_by_key(|&i| widths[i]);
|
let col = (0..widths.len()).rev().max_by_key(|&i| widths[i]);
|
||||||
col.filter(|&col| widths[col] != 0)
|
col.filter(|&col| widths[col] != 0)
|
||||||
@ -881,7 +875,7 @@ fn push_empty_column(data: &mut NuRecords) {
|
|||||||
let records = std::mem::take(data);
|
let records = std::mem::take(data);
|
||||||
let mut inner: Vec<Vec<_>> = records.into();
|
let mut inner: Vec<Vec<_>> = records.into();
|
||||||
|
|
||||||
let empty_cell = CellInfo::new(String::from("..."));
|
let empty_cell = Text::new(String::from("..."));
|
||||||
for row in &mut inner {
|
for row in &mut inner {
|
||||||
row.push(empty_cell.clone());
|
row.push(empty_cell.clone());
|
||||||
}
|
}
|
||||||
@ -920,7 +914,7 @@ fn convert_alignment(alignment: nu_color_config::Alignment) -> AlignmentHorizont
|
|||||||
|
|
||||||
struct SetAlignment(AlignmentHorizontal, Entity);
|
struct SetAlignment(AlignmentHorizontal, Entity);
|
||||||
|
|
||||||
impl<R, D> TableOption<R, D, ColoredConfig> for SetAlignment {
|
impl<R, D> TableOption<R, ColoredConfig, D> for SetAlignment {
|
||||||
fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
|
fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
|
||||||
cfg.set_alignment_horizontal(self.1, self.0);
|
cfg.set_alignment_horizontal(self.1, self.0);
|
||||||
}
|
}
|
||||||
@ -928,7 +922,7 @@ impl<R, D> TableOption<R, D, ColoredConfig> for SetAlignment {
|
|||||||
|
|
||||||
struct SetDimensions(Vec<usize>);
|
struct SetDimensions(Vec<usize>);
|
||||||
|
|
||||||
impl<R> TableOption<R, CompleteDimensionVecRecords<'_>, ColoredConfig> for SetDimensions {
|
impl<R> TableOption<R, ColoredConfig, CompleteDimensionVecRecords<'_>> for SetDimensions {
|
||||||
fn change(self, _: &mut R, _: &mut ColoredConfig, dims: &mut CompleteDimensionVecRecords<'_>) {
|
fn change(self, _: &mut R, _: &mut ColoredConfig, dims: &mut CompleteDimensionVecRecords<'_>) {
|
||||||
dims.set_widths(self.0);
|
dims.set_widths(self.0);
|
||||||
}
|
}
|
||||||
@ -951,7 +945,7 @@ fn build_width(records: &NuRecords, pad: usize) -> Vec<usize> {
|
|||||||
|
|
||||||
struct GetRow(usize, Vec<String>);
|
struct GetRow(usize, Vec<String>);
|
||||||
|
|
||||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for &mut GetRow {
|
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for &mut GetRow {
|
||||||
fn change(
|
fn change(
|
||||||
self,
|
self,
|
||||||
recs: &mut NuRecords,
|
recs: &mut NuRecords,
|
||||||
@ -965,7 +959,7 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
|||||||
|
|
||||||
struct GetRowSettings(usize, AlignmentHorizontal, Option<Color>);
|
struct GetRowSettings(usize, AlignmentHorizontal, Option<Color>);
|
||||||
|
|
||||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig>
|
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>>
|
||||||
for &mut GetRowSettings
|
for &mut GetRowSettings
|
||||||
{
|
{
|
||||||
fn change(
|
fn change(
|
||||||
@ -1007,7 +1001,7 @@ impl SetLineHeaders {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for SetLineHeaders {
|
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for SetLineHeaders {
|
||||||
fn change(
|
fn change(
|
||||||
self,
|
self,
|
||||||
recs: &mut NuRecords,
|
recs: &mut NuRecords,
|
||||||
@ -1020,7 +1014,7 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
|||||||
columns = columns
|
columns = columns
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(widths.iter().map(|w| w.checked_sub(2).unwrap_or(*w))) // exclude padding; which is generally 2
|
.zip(widths.iter().map(|w| w.checked_sub(2).unwrap_or(*w))) // exclude padding; which is generally 2
|
||||||
.map(|(s, width)| Truncate::truncate_text(&s, width).into_owned())
|
.map(|(s, width)| Truncate::truncate(&s, width).into_owned())
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
@ -1065,7 +1059,7 @@ impl MoveRowPrev {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for MoveRowNext {
|
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for MoveRowNext {
|
||||||
fn change(
|
fn change(
|
||||||
self,
|
self,
|
||||||
recs: &mut NuRecords,
|
recs: &mut NuRecords,
|
||||||
@ -1076,7 +1070,7 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for MoveRowPrev {
|
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for MoveRowPrev {
|
||||||
fn change(
|
fn change(
|
||||||
self,
|
self,
|
||||||
recs: &mut NuRecords,
|
recs: &mut NuRecords,
|
||||||
@ -1193,9 +1187,11 @@ fn set_column_names(
|
|||||||
align: AlignmentHorizontal,
|
align: AlignmentHorizontal,
|
||||||
color: Option<Color>,
|
color: Option<Color>,
|
||||||
) {
|
) {
|
||||||
let mut names = ColumnNames::new(head).set_line(line).set_alignment(align);
|
let mut names = ColumnNames::new(head)
|
||||||
|
.line(line)
|
||||||
|
.alignment(Alignment::from(align));
|
||||||
if let Some(color) = color {
|
if let Some(color) = color {
|
||||||
names = names.set_color(color);
|
names = names.color(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnNames::change(names, records, cfg, dims)
|
ColumnNames::change(names, records, cfg, dims)
|
||||||
@ -1214,7 +1210,7 @@ fn remove_row(recs: &mut NuRecords, row: usize) -> Vec<String> {
|
|||||||
|
|
||||||
struct StripColorFromRow(usize);
|
struct StripColorFromRow(usize);
|
||||||
|
|
||||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for StripColorFromRow {
|
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for StripColorFromRow {
|
||||||
fn change(
|
fn change(
|
||||||
self,
|
self,
|
||||||
recs: &mut NuRecords,
|
recs: &mut NuRecords,
|
||||||
@ -1222,7 +1218,32 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
|||||||
_: &mut CompleteDimensionVecRecords<'_>,
|
_: &mut CompleteDimensionVecRecords<'_>,
|
||||||
) {
|
) {
|
||||||
for cell in &mut recs[self.0] {
|
for cell in &mut recs[self.0] {
|
||||||
*cell = CellInfo::new(strip_ansi_unlikely(cell.as_ref()).into_owned());
|
*cell = Text::new(strip_ansi_unlikely(cell.as_ref()).into_owned());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RemoveHorizontalLine;
|
||||||
|
|
||||||
|
impl<D> TableOption<NuRecords, ColoredConfig, D> for RemoveHorizontalLine {
|
||||||
|
fn change(self, recs: &mut NuRecords, cfg: &mut ColoredConfig, _: &mut D) {
|
||||||
|
cfg.remove_horizontal_line(1, recs.count_rows());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CopyFirstHorizontalLineAtLast;
|
||||||
|
|
||||||
|
impl<D> TableOption<NuRecords, ColoredConfig, D> for CopyFirstHorizontalLineAtLast {
|
||||||
|
fn change(self, recs: &mut NuRecords, cfg: &mut ColoredConfig, _: &mut D) {
|
||||||
|
if recs.count_rows() <= 2 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let line = match cfg.get_horizontal_line(1) {
|
||||||
|
Some(line) => *line,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
cfg.insert_horizontal_line(recs.count_rows() - 1, line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,107 +1,78 @@
|
|||||||
use tabled::settings::style::{HorizontalLine, Line, RawStyle, Style};
|
use tabled::settings::style::{HorizontalLine, Style};
|
||||||
|
use tabled::settings::themes::Theme;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TableTheme {
|
pub struct TableTheme {
|
||||||
theme: RawStyle,
|
theme: Theme,
|
||||||
full_theme: RawStyle,
|
full_theme: Theme,
|
||||||
has_inner: bool,
|
has_inner: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TableTheme {
|
impl TableTheme {
|
||||||
pub fn basic() -> TableTheme {
|
pub fn new(theme: impl Into<Theme>, full_theme: impl Into<Theme>, has_inner: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
theme: Style::ascii().into(),
|
theme: theme.into(),
|
||||||
full_theme: Style::ascii().into(),
|
full_theme: full_theme.into(),
|
||||||
has_inner: true,
|
has_inner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn basic() -> TableTheme {
|
||||||
|
Self::new(Style::ascii(), Style::ascii(), true)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn thin() -> TableTheme {
|
pub fn thin() -> TableTheme {
|
||||||
Self {
|
Self::new(Style::modern(), Style::modern(), true)
|
||||||
theme: Style::modern().into(),
|
|
||||||
full_theme: Style::modern().into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn light() -> TableTheme {
|
pub fn light() -> TableTheme {
|
||||||
let theme = Style::blank()
|
let mut theme = Theme::from_style(Style::blank());
|
||||||
.horizontals([HorizontalLine::new(
|
theme.insert_horizontal_line(1, HorizontalLine::new('─').intersection('─'));
|
||||||
1,
|
|
||||||
Line::new(Some('─'), Some('─'), None, None),
|
Self::new(theme, Style::modern(), true)
|
||||||
)])
|
|
||||||
.into();
|
|
||||||
Self {
|
|
||||||
theme,
|
|
||||||
full_theme: Style::modern().into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn psql() -> TableTheme {
|
pub fn psql() -> TableTheme {
|
||||||
Self {
|
Self::new(Style::psql(), Style::psql(), true)
|
||||||
theme: Style::psql().into(),
|
|
||||||
full_theme: Style::psql().into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn markdown() -> TableTheme {
|
pub fn markdown() -> TableTheme {
|
||||||
Self {
|
Self::new(Style::markdown(), Style::markdown(), true)
|
||||||
theme: Style::markdown().into(),
|
|
||||||
full_theme: Style::markdown().into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dots() -> TableTheme {
|
pub fn dots() -> TableTheme {
|
||||||
let theme = Style::dots().remove_horizontal().into();
|
let theme = Style::dots().remove_horizontal();
|
||||||
Self {
|
|
||||||
theme,
|
Self::new(theme, Style::dots(), true)
|
||||||
full_theme: Style::dots().into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn restructured() -> TableTheme {
|
pub fn restructured() -> TableTheme {
|
||||||
Self {
|
Self::new(
|
||||||
theme: Style::re_structured_text().into(),
|
Style::re_structured_text(),
|
||||||
full_theme: Style::re_structured_text().into(),
|
Style::re_structured_text(),
|
||||||
has_inner: true,
|
true,
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ascii_rounded() -> TableTheme {
|
pub fn ascii_rounded() -> TableTheme {
|
||||||
Self {
|
Self::new(Style::ascii_rounded(), Style::ascii_rounded(), true)
|
||||||
theme: Style::ascii_rounded().into(),
|
|
||||||
full_theme: Style::ascii_rounded().into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn basic_compact() -> TableTheme {
|
pub fn basic_compact() -> TableTheme {
|
||||||
let theme = Style::ascii().remove_horizontal().into();
|
let theme = Style::ascii().remove_horizontal();
|
||||||
Self {
|
|
||||||
theme,
|
Self::new(theme, Style::ascii(), true)
|
||||||
full_theme: Style::ascii().into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compact() -> TableTheme {
|
pub fn compact() -> TableTheme {
|
||||||
|
let hline = HorizontalLine::inherit(Style::modern().remove_left().remove_right());
|
||||||
let theme = Style::modern()
|
let theme = Style::modern()
|
||||||
.remove_left()
|
.remove_left()
|
||||||
.remove_right()
|
.remove_right()
|
||||||
.remove_horizontal()
|
.remove_horizontal()
|
||||||
.horizontals([HorizontalLine::new(1, Style::modern().get_horizontal())
|
.horizontals([(1, hline)]);
|
||||||
.left(None)
|
|
||||||
.right(None)])
|
Self::new(theme, Style::modern(), true)
|
||||||
.into();
|
|
||||||
Self {
|
|
||||||
theme,
|
|
||||||
full_theme: Style::modern().into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_love() -> TableTheme {
|
pub fn with_love() -> TableTheme {
|
||||||
@ -109,10 +80,7 @@ impl TableTheme {
|
|||||||
.top('❤')
|
.top('❤')
|
||||||
.bottom('❤')
|
.bottom('❤')
|
||||||
.vertical('❤')
|
.vertical('❤')
|
||||||
.horizontals([HorizontalLine::new(
|
.horizontals([(1, HorizontalLine::new('❤').intersection('❤'))]);
|
||||||
1,
|
|
||||||
Line::new(Some('❤'), Some('❤'), None, None),
|
|
||||||
)]);
|
|
||||||
|
|
||||||
let full_theme = Style::empty()
|
let full_theme = Style::empty()
|
||||||
.top('❤')
|
.top('❤')
|
||||||
@ -131,53 +99,40 @@ impl TableTheme {
|
|||||||
.intersection_left('❤')
|
.intersection_left('❤')
|
||||||
.intersection('❤');
|
.intersection('❤');
|
||||||
|
|
||||||
Self {
|
Self::new(theme, full_theme, true)
|
||||||
theme: theme.into(),
|
|
||||||
full_theme: full_theme.into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compact_double() -> TableTheme {
|
pub fn compact_double() -> TableTheme {
|
||||||
|
let hline = HorizontalLine::inherit(Style::extended())
|
||||||
|
.remove_left()
|
||||||
|
.remove_right();
|
||||||
let theme = Style::extended()
|
let theme = Style::extended()
|
||||||
.remove_left()
|
.remove_left()
|
||||||
.remove_right()
|
.remove_right()
|
||||||
.remove_horizontal()
|
.remove_horizontal()
|
||||||
.horizontals([HorizontalLine::new(1, Style::extended().get_horizontal())
|
.horizontals([(1, hline)]);
|
||||||
.left(None)
|
|
||||||
.right(None)])
|
Self::new(theme, Style::extended(), true)
|
||||||
.into();
|
|
||||||
Self {
|
|
||||||
theme,
|
|
||||||
full_theme: Style::extended().into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rounded() -> TableTheme {
|
pub fn rounded() -> TableTheme {
|
||||||
Self {
|
let full = Style::modern()
|
||||||
theme: Style::rounded().into(),
|
.corner_top_left('╭')
|
||||||
full_theme: Style::modern()
|
.corner_top_right('╮')
|
||||||
.corner_top_left('╭')
|
.corner_bottom_left('╰')
|
||||||
.corner_top_right('╮')
|
.corner_bottom_right('╯');
|
||||||
.corner_bottom_left('╰')
|
|
||||||
.corner_bottom_right('╯')
|
Self::new(Style::rounded(), full, true)
|
||||||
.into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reinforced() -> TableTheme {
|
pub fn reinforced() -> TableTheme {
|
||||||
let full_theme = Style::modern()
|
let full = Style::modern()
|
||||||
.corner_top_left('┏')
|
.corner_top_left('┏')
|
||||||
.corner_top_right('┓')
|
.corner_top_right('┓')
|
||||||
.corner_bottom_left('┗')
|
.corner_bottom_left('┗')
|
||||||
.corner_bottom_right('┛');
|
.corner_bottom_right('┛');
|
||||||
Self {
|
|
||||||
theme: full_theme.clone().remove_horizontal().into(),
|
Self::new(full.clone().remove_horizontal(), full, true)
|
||||||
full_theme: full_theme.into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn heavy() -> TableTheme {
|
pub fn heavy() -> TableTheme {
|
||||||
@ -193,48 +148,32 @@ impl TableTheme {
|
|||||||
.corner_top_right('┓')
|
.corner_top_right('┓')
|
||||||
.corner_bottom_left('┗')
|
.corner_bottom_left('┗')
|
||||||
.corner_bottom_right('┛')
|
.corner_bottom_right('┛')
|
||||||
.horizontals([HorizontalLine::new(1, Line::full('━', '╋', '┣', '┫'))]);
|
.horizontals([(1, HorizontalLine::full('━', '╋', '┣', '┫'))]);
|
||||||
let full_theme = theme
|
let full = theme
|
||||||
.clone()
|
.clone()
|
||||||
.remove_horizontals()
|
.remove_horizontals()
|
||||||
.horizontal('━')
|
.horizontal('━')
|
||||||
.intersection_left('┣')
|
.intersection_left('┣')
|
||||||
.intersection_right('┫')
|
.intersection_right('┫')
|
||||||
.intersection('╋');
|
.intersection('╋');
|
||||||
Self {
|
|
||||||
theme: theme.into(),
|
Self::new(theme, full, true)
|
||||||
full_theme: full_theme.into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn none() -> TableTheme {
|
pub fn none() -> TableTheme {
|
||||||
Self {
|
Self::new(Style::blank(), Style::blank(), true)
|
||||||
theme: Style::blank().into(),
|
|
||||||
full_theme: Style::blank().into(),
|
|
||||||
has_inner: true,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_top_line(&self) -> bool {
|
pub fn has_top(&self) -> bool {
|
||||||
self.theme.get_top().is_some()
|
self.theme.borders_has_top()
|
||||||
|| self.theme.get_top_intersection().is_some()
|
|
||||||
|| self.theme.get_top_left().is_some()
|
|
||||||
|| self.theme.get_top_right().is_some()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_left(&self) -> bool {
|
pub fn has_left(&self) -> bool {
|
||||||
self.theme.get_left().is_some()
|
self.theme.borders_has_left()
|
||||||
|| self.theme.get_left_intersection().is_some()
|
|
||||||
|| self.theme.get_top_left().is_some()
|
|
||||||
|| self.theme.get_bottom_left().is_some()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_right(&self) -> bool {
|
pub fn has_right(&self) -> bool {
|
||||||
self.theme.get_right().is_some()
|
self.theme.borders_has_right()
|
||||||
|| self.theme.get_right_intersection().is_some()
|
|
||||||
|| self.theme.get_top_right().is_some()
|
|
||||||
|| self.theme.get_bottom_right().is_some()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_inner(&self) -> bool {
|
pub fn has_inner(&self) -> bool {
|
||||||
@ -245,11 +184,11 @@ impl TableTheme {
|
|||||||
self.full_theme.get_borders().has_horizontal()
|
self.full_theme.get_borders().has_horizontal()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_theme_full(&self) -> RawStyle {
|
pub fn get_theme_full(&self) -> Theme {
|
||||||
self.full_theme.clone()
|
self.full_theme.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_theme(&self) -> RawStyle {
|
pub fn get_theme(&self) -> Theme {
|
||||||
self.theme.clone()
|
self.theme.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,7 +358,7 @@ fn expanded_table_kv(record: &Record, cfg: Cfg<'_>) -> StringResult {
|
|||||||
// we could use Padding for it but,
|
// we could use Padding for it but,
|
||||||
// the easiest way to do so is just push a new_line char before
|
// the easiest way to do so is just push a new_line char before
|
||||||
let mut key = key.to_owned();
|
let mut key = key.to_owned();
|
||||||
if !key.is_empty() && is_expanded && theme.has_top_line() {
|
if !key.is_empty() && is_expanded && theme.has_top() {
|
||||||
key.insert(0, '\n');
|
key.insert(0, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,11 +3,11 @@ use nu_color_config::StyleComputer;
|
|||||||
use nu_protocol::{Config, Record, Span, Value};
|
use nu_protocol::{Config, Record, Span, Value};
|
||||||
use tabled::{
|
use tabled::{
|
||||||
grid::{
|
grid::{
|
||||||
color::{AnsiColor, StaticColor},
|
ansi::{ANSIBuf, ANSIStr},
|
||||||
config::{AlignmentHorizontal, Borders, CompactMultilineConfig},
|
config::{AlignmentHorizontal, Borders, CompactMultilineConfig},
|
||||||
dimension::{DimensionPriority, PoolTableDimension},
|
dimension::{DimensionPriority, PoolTableDimension},
|
||||||
},
|
},
|
||||||
settings::{style::RawStyle, Color, Padding, TableOption},
|
settings::{Color, Padding, TableOption, Theme},
|
||||||
tables::{PoolTable, TableValue},
|
tables::{PoolTable, TableValue},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ fn build_table(
|
|||||||
let mut table = PoolTable::from(val);
|
let mut table = PoolTable::from(val);
|
||||||
|
|
||||||
let mut theme = theme.get_theme_full();
|
let mut theme = theme.get_theme_full();
|
||||||
theme.set_horizontals(std::collections::HashMap::default());
|
theme.set_horizontal_lines(Default::default());
|
||||||
|
|
||||||
table.with(Padding::new(indent.0, indent.1, 0, 0));
|
table.with(Padding::new(indent.0, indent.1, 0, 0));
|
||||||
table.with(SetRawStyle(theme));
|
table.with(SetRawStyle(theme));
|
||||||
@ -73,12 +73,13 @@ fn build_table(
|
|||||||
// We just need this unsafe section to cope with some limitations of [`PoolTable`].
|
// We just need this unsafe section to cope with some limitations of [`PoolTable`].
|
||||||
// Mitigation of this is definitely on a todo list.
|
// Mitigation of this is definitely on a todo list.
|
||||||
|
|
||||||
let color: AnsiColor<'_> = color.into();
|
let color: ANSIBuf = color.into();
|
||||||
let prefix = color.get_prefix();
|
let prefix = color.get_prefix();
|
||||||
let suffix = color.get_suffix();
|
let suffix = color.get_suffix();
|
||||||
let prefix: &'static str = unsafe { std::mem::transmute(prefix) };
|
let prefix: &'static str = unsafe { std::mem::transmute(prefix) };
|
||||||
let suffix: &'static str = unsafe { std::mem::transmute(suffix) };
|
let suffix: &'static str = unsafe { std::mem::transmute(suffix) };
|
||||||
table.with(SetBorderColor(StaticColor::new(prefix, suffix)));
|
|
||||||
|
table.with(SetBorderColor(ANSIStr::new(prefix, suffix)));
|
||||||
let table = table.to_string();
|
let table = table.to_string();
|
||||||
|
|
||||||
return table;
|
return table;
|
||||||
@ -217,29 +218,29 @@ fn get_columns_in_record(vals: &[Value]) -> Vec<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SetRawStyle(RawStyle);
|
struct SetRawStyle(Theme);
|
||||||
|
|
||||||
impl<R, D> TableOption<R, D, CompactMultilineConfig> for SetRawStyle {
|
impl<R, D> TableOption<R, CompactMultilineConfig, D> for SetRawStyle {
|
||||||
fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
|
fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
|
||||||
let borders = self.0.get_borders();
|
let borders = *self.0.get_borders();
|
||||||
*cfg = cfg.set_borders(borders);
|
cfg.set_borders(borders);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SetBorderColor(StaticColor);
|
struct SetBorderColor(ANSIStr<'static>);
|
||||||
|
|
||||||
impl<R, D> TableOption<R, D, CompactMultilineConfig> for SetBorderColor {
|
impl<R, D> TableOption<R, CompactMultilineConfig, D> for SetBorderColor {
|
||||||
fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
|
fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
|
||||||
let borders = Borders::filled(self.0);
|
let borders = Borders::filled(self.0);
|
||||||
*cfg = cfg.set_borders_color(borders);
|
cfg.set_borders_color(borders);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SetAlignment(AlignmentHorizontal);
|
struct SetAlignment(AlignmentHorizontal);
|
||||||
|
|
||||||
impl<R, D> TableOption<R, D, CompactMultilineConfig> for SetAlignment {
|
impl<R, D> TableOption<R, CompactMultilineConfig, D> for SetAlignment {
|
||||||
fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
|
fn change(self, _: &mut R, cfg: &mut CompactMultilineConfig, _: &mut D) {
|
||||||
*cfg = cfg.set_alignment_horizontal(self.0);
|
cfg.set_alignment_horizontal(self.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,9 @@ use nu_color_config::StyleComputer;
|
|||||||
use tabled::{
|
use tabled::{
|
||||||
builder::Builder,
|
builder::Builder,
|
||||||
grid::{
|
grid::{
|
||||||
color::AnsiColor, records::vec_records::CellInfo, util::string::string_width_multiline,
|
ansi::{ANSIBuf, ANSIStr},
|
||||||
|
records::vec_records::Text,
|
||||||
|
util::string::get_text_width,
|
||||||
},
|
},
|
||||||
settings::{width::Truncate, Color, Modify, Padding, Style, Width},
|
settings::{width::Truncate, Color, Modify, Padding, Style, Width},
|
||||||
};
|
};
|
||||||
@ -10,7 +12,7 @@ use tabled::{
|
|||||||
use crate::common::get_leading_trailing_space_style;
|
use crate::common::get_leading_trailing_space_style;
|
||||||
|
|
||||||
pub fn string_width(text: &str) -> usize {
|
pub fn string_width(text: &str) -> usize {
|
||||||
string_width_multiline(text)
|
get_text_width(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn string_wrap(text: &str, width: usize, keep_words: bool) -> String {
|
pub fn string_wrap(text: &str, width: usize, keep_words: bool) -> String {
|
||||||
@ -24,7 +26,7 @@ pub fn string_wrap(text: &str, width: usize, keep_words: bool) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let wrap = if keep_words {
|
let wrap = if keep_words {
|
||||||
Width::wrap(width).keep_words()
|
Width::wrap(width).keep_words(true)
|
||||||
} else {
|
} else {
|
||||||
Width::wrap(width)
|
Width::wrap(width)
|
||||||
};
|
};
|
||||||
@ -45,7 +47,7 @@ pub fn string_truncate(text: &str, width: usize) -> String {
|
|||||||
None => return String::new(),
|
None => return String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Truncate::truncate_text(line, width).into_owned()
|
Truncate::truncate(line, width).into_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clean_charset(text: &str) -> String {
|
pub fn clean_charset(text: &str) -> String {
|
||||||
@ -53,24 +55,26 @@ pub fn clean_charset(text: &str) -> String {
|
|||||||
text.replace('\t', " ").replace('\r', "")
|
text.replace('\t', " ").replace('\r', "")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn colorize_space(data: &mut [Vec<CellInfo<String>>], style_computer: &StyleComputer<'_>) {
|
pub fn colorize_space(data: &mut [Vec<Text<String>>], style_computer: &StyleComputer<'_>) {
|
||||||
if let Some(style) = get_leading_trailing_space_style(style_computer).color_style {
|
if let Some(style) = get_leading_trailing_space_style(style_computer).color_style {
|
||||||
let style = convert_style(style).into();
|
let style = ANSIBuf::from(convert_style(style));
|
||||||
colorize_lead_trail_space(data, Some(&style), Some(&style));
|
let style = style.as_ref();
|
||||||
|
colorize_lead_trail_space(data, Some(style), Some(style));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn colorize_space_str(text: &mut String, style_computer: &StyleComputer<'_>) {
|
pub fn colorize_space_str(text: &mut String, style_computer: &StyleComputer<'_>) {
|
||||||
if let Some(style) = get_leading_trailing_space_style(style_computer).color_style {
|
if let Some(style) = get_leading_trailing_space_style(style_computer).color_style {
|
||||||
let style = convert_style(style).into();
|
let style = ANSIBuf::from(convert_style(style));
|
||||||
*text = colorize_space_one(text, Some(&style), Some(&style));
|
let style = style.as_ref();
|
||||||
|
*text = colorize_space_one(text, Some(style), Some(style));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn colorize_lead_trail_space(
|
fn colorize_lead_trail_space(
|
||||||
data: &mut [Vec<CellInfo<String>>],
|
data: &mut [Vec<Text<String>>],
|
||||||
lead: Option<&AnsiColor<'_>>,
|
lead: Option<ANSIStr<'_>>,
|
||||||
trail: Option<&AnsiColor<'_>>,
|
trail: Option<ANSIStr<'_>>,
|
||||||
) {
|
) {
|
||||||
if lead.is_none() && trail.is_none() {
|
if lead.is_none() && trail.is_none() {
|
||||||
return;
|
return;
|
||||||
@ -79,16 +83,12 @@ fn colorize_lead_trail_space(
|
|||||||
for row in data.iter_mut() {
|
for row in data.iter_mut() {
|
||||||
for cell in row {
|
for cell in row {
|
||||||
let buf = colorize_space_one(cell.as_ref(), lead, trail);
|
let buf = colorize_space_one(cell.as_ref(), lead, trail);
|
||||||
*cell = CellInfo::new(buf);
|
*cell = Text::new(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn colorize_space_one(
|
fn colorize_space_one(text: &str, lead: Option<ANSIStr<'_>>, trail: Option<ANSIStr<'_>>) -> String {
|
||||||
text: &str,
|
|
||||||
lead: Option<&AnsiColor<'_>>,
|
|
||||||
trail: Option<&AnsiColor<'_>>,
|
|
||||||
) -> String {
|
|
||||||
use fancy_regex::Captures;
|
use fancy_regex::Captures;
|
||||||
use fancy_regex::Regex;
|
use fancy_regex::Regex;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use nu_table::{string_width, NuTable, NuTableConfig};
|
use nu_table::{string_width, NuTable, NuTableConfig};
|
||||||
use tabled::grid::records::vec_records::CellInfo;
|
use tabled::grid::records::vec_records::Text;
|
||||||
|
|
||||||
pub struct TestCase {
|
pub struct TestCase {
|
||||||
cfg: NuTableConfig,
|
cfg: NuTableConfig,
|
||||||
@ -19,7 +19,7 @@ impl TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Data = Vec<Vec<CellInfo<String>>>;
|
type Data = Vec<Vec<Text<String>>>;
|
||||||
|
|
||||||
pub fn test_table<I: IntoIterator<Item = TestCase>>(data: Data, tests: I) {
|
pub fn test_table<I: IntoIterator<Item = TestCase>>(data: Data, tests: I) {
|
||||||
for (i, test) in tests.into_iter().enumerate() {
|
for (i, test) in tests.into_iter().enumerate() {
|
||||||
@ -42,15 +42,15 @@ pub fn create_table(data: Data, config: NuTableConfig, termwidth: usize) -> Opti
|
|||||||
table.draw(config, termwidth)
|
table.draw(config, termwidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_row(count_columns: usize) -> Vec<CellInfo<String>> {
|
pub fn create_row(count_columns: usize) -> Vec<Text<String>> {
|
||||||
let mut row = Vec::with_capacity(count_columns);
|
let mut row = Vec::with_capacity(count_columns);
|
||||||
for i in 0..count_columns {
|
for i in 0..count_columns {
|
||||||
row.push(CellInfo::new(i.to_string()));
|
row.push(Text::new(i.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
row
|
row
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cell(text: &str) -> CellInfo<String> {
|
pub fn cell(text: &str) -> Text<String> {
|
||||||
CellInfo::new(text.to_string())
|
Text::new(text.to_string())
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ mod common;
|
|||||||
use common::{create_row, test_table, TestCase};
|
use common::{create_row, test_table, TestCase};
|
||||||
use nu_protocol::TrimStrategy;
|
use nu_protocol::TrimStrategy;
|
||||||
use nu_table::{NuTable, NuTableConfig, TableTheme as theme};
|
use nu_table::{NuTable, NuTableConfig, TableTheme as theme};
|
||||||
use tabled::grid::records::vec_records::CellInfo;
|
use tabled::grid::records::vec_records::Text;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn data_and_header_has_different_size_doesnt_work() {
|
fn data_and_header_has_different_size_doesnt_work() {
|
||||||
@ -194,7 +194,7 @@ fn width_control_test_0() {
|
|||||||
test_width(data, &tests);
|
test_width(data, &tests);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_width(data: Vec<Vec<CellInfo<String>>>, tests: &[(usize, &str)]) {
|
fn test_width(data: Vec<Vec<Text<String>>>, tests: &[(usize, &str)]) {
|
||||||
let config = NuTableConfig {
|
let config = NuTableConfig {
|
||||||
theme: theme::heavy(),
|
theme: theme::heavy(),
|
||||||
trim: TrimStrategy::truncate(Some(String::from("..."))),
|
trim: TrimStrategy::truncate(Some(String::from("..."))),
|
||||||
|
@ -2,7 +2,7 @@ mod common;
|
|||||||
|
|
||||||
use common::create_row as row;
|
use common::create_row as row;
|
||||||
use nu_table::{NuTable, NuTableConfig, TableTheme as theme};
|
use nu_table::{NuTable, NuTableConfig, TableTheme as theme};
|
||||||
use tabled::grid::records::vec_records::CellInfo;
|
use tabled::grid::records::vec_records::Text;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rounded() {
|
fn test_rounded() {
|
||||||
@ -451,7 +451,7 @@ fn test_with_love() {
|
|||||||
assert_eq!(create_table_with_size(vec![], true, theme::with_love()), "");
|
assert_eq!(create_table_with_size(vec![], true, theme::with_love()), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_table(data: Vec<Vec<CellInfo<String>>>, with_header: bool, theme: theme) -> String {
|
fn create_table(data: Vec<Vec<Text<String>>>, with_header: bool, theme: theme) -> String {
|
||||||
let config = NuTableConfig {
|
let config = NuTableConfig {
|
||||||
theme,
|
theme,
|
||||||
with_header,
|
with_header,
|
||||||
@ -463,11 +463,7 @@ fn create_table(data: Vec<Vec<CellInfo<String>>>, with_header: bool, theme: them
|
|||||||
out.expect("not expected to get None")
|
out.expect("not expected to get None")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_table_with_size(
|
fn create_table_with_size(data: Vec<Vec<Text<String>>>, with_header: bool, theme: theme) -> String {
|
||||||
data: Vec<Vec<CellInfo<String>>>,
|
|
||||||
with_header: bool,
|
|
||||||
theme: theme,
|
|
||||||
) -> String {
|
|
||||||
let config = NuTableConfig {
|
let config = NuTableConfig {
|
||||||
theme,
|
theme,
|
||||||
with_header,
|
with_header,
|
||||||
|
Loading…
Reference in New Issue
Block a user