mirror of
https://github.com/nushell/nushell.git
synced 2024-11-21 16:03:19 +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"
|
||||
syn = "2.0"
|
||||
sysinfo = "0.30"
|
||||
tabled = { version = "0.14.0", default-features = false }
|
||||
tabled = { version = "0.16.0", default-features = false }
|
||||
tempfile = "3.10"
|
||||
terminal_size = "0.3"
|
||||
titlecase = "2.0"
|
||||
|
@ -83,7 +83,7 @@ serde_urlencoded = { workspace = true }
|
||||
serde_yaml = { workspace = true }
|
||||
sha2 = { 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 }
|
||||
titlecase = { workspace = true }
|
||||
toml = { workspace = true, features = ["preserve_order"] }
|
||||
|
@ -57,7 +57,7 @@ pub fn build_table(value: Value, description: String, termsize: usize) -> String
|
||||
Settings::default()
|
||||
.with(Style::rounded().corner_top_left('├').corner_top_right('┤'))
|
||||
.with(SetWidths(widths))
|
||||
.with(Wrap::new(width).priority::<PriorityMax>())
|
||||
.with(Wrap::new(width).priority(PriorityMax))
|
||||
.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
|
||||
{
|
||||
fn change(
|
||||
@ -377,7 +377,7 @@ mod set_widths {
|
||||
|
||||
pub struct SetWidths(pub Vec<usize>);
|
||||
|
||||
impl<R> TableOption<R, CompleteDimensionVecRecords<'_>, ColoredConfig> for SetWidths {
|
||||
impl<R> TableOption<R, ColoredConfig, CompleteDimensionVecRecords<'_>> for SetWidths {
|
||||
fn change(
|
||||
self,
|
||||
_: &mut R,
|
||||
|
@ -18,7 +18,7 @@ nu-color-config = { path = "../nu-color-config", version = "0.97.2" }
|
||||
nu-ansi-term = { workspace = true }
|
||||
once_cell = { workspace = true }
|
||||
fancy-regex = { workspace = true }
|
||||
tabled = { workspace = true, features = ["color"], default-features = false }
|
||||
tabled = { workspace = true, features = ["ansi"], default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
# nu-test-support = { path="../nu-test-support", version = "0.97.2" }
|
@ -1,7 +1,7 @@
|
||||
use nu_ansi_term::{Color, Style};
|
||||
use nu_color_config::TextStyle;
|
||||
use nu_table::{NuTable, NuTableConfig, TableTheme};
|
||||
use tabled::grid::records::vec_records::CellInfo;
|
||||
use tabled::grid::records::vec_records::Text;
|
||||
|
||||
fn main() {
|
||||
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)
|
||||
}
|
||||
|
||||
fn to_cell_info_vec(data: &[&str]) -> Vec<CellInfo<String>> {
|
||||
fn to_cell_info_vec(data: &[&str]) -> Vec<Text<String>> {
|
||||
let mut v = vec![];
|
||||
for x in data {
|
||||
v.push(CellInfo::new(String::from(*x)));
|
||||
v.push(Text::new(String::from(*x)));
|
||||
}
|
||||
|
||||
v
|
||||
|
@ -7,12 +7,12 @@ use std::{cmp::min, collections::HashMap};
|
||||
use tabled::{
|
||||
builder::Builder,
|
||||
grid::{
|
||||
color::AnsiColor,
|
||||
ansi::ANSIBuf,
|
||||
colors::Colors,
|
||||
config::{AlignmentHorizontal, ColoredConfig, Entity, EntityMap, Position},
|
||||
dimension::CompleteDimensionVecRecords,
|
||||
records::{
|
||||
vec_records::{Cell, CellInfo, VecRecords},
|
||||
vec_records::{Cell, Text, VecRecords},
|
||||
ExactRecords, PeekableRecords, Records, Resizable,
|
||||
},
|
||||
},
|
||||
@ -22,7 +22,7 @@ use tabled::{
|
||||
peaker::Peaker,
|
||||
themes::ColumnNames,
|
||||
width::Truncate,
|
||||
Color, Modify, Padding, Settings, TableOption, Width,
|
||||
Alignment, Color, Modify, Padding, Settings, TableOption, Width,
|
||||
},
|
||||
Table,
|
||||
};
|
||||
@ -37,13 +37,13 @@ pub struct NuTable {
|
||||
}
|
||||
|
||||
pub type NuRecords = VecRecords<NuTableCell>;
|
||||
pub type NuTableCell = CellInfo<String>;
|
||||
pub type NuTableCell = Text<String>;
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
struct Styles {
|
||||
index: AnsiColor<'static>,
|
||||
header: AnsiColor<'static>,
|
||||
data: EntityMap<AnsiColor<'static>>,
|
||||
index: ANSIBuf,
|
||||
header: ANSIBuf,
|
||||
data: EntityMap<ANSIBuf>,
|
||||
data_is_set: bool,
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ impl NuTable {
|
||||
/// Creates an empty [`NuTable`] instance.
|
||||
pub fn new(count_rows: usize, count_columns: usize) -> 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(),
|
||||
indent: (1, 1),
|
||||
alignments: Alignments {
|
||||
@ -84,12 +84,12 @@ impl NuTable {
|
||||
}
|
||||
|
||||
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) {
|
||||
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_is_set = true;
|
||||
}
|
||||
@ -102,7 +102,7 @@ impl NuTable {
|
||||
|
||||
pub fn insert_style(&mut self, pos: Position, style: TextStyle) {
|
||||
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_is_set = true;
|
||||
}
|
||||
@ -115,7 +115,7 @@ impl NuTable {
|
||||
|
||||
pub fn set_header_style(&mut self, style: TextStyle) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -124,7 +124,7 @@ impl NuTable {
|
||||
|
||||
pub fn set_index_style(&mut self, style: TextStyle) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ impl NuTable {
|
||||
|
||||
pub fn set_data_style(&mut self, style: TextStyle) {
|
||||
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_is_set = true;
|
||||
}
|
||||
@ -171,8 +171,8 @@ impl NuTable {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<Vec<CellInfo<String>>>> for NuTable {
|
||||
fn from(value: Vec<Vec<CellInfo<String>>>) -> Self {
|
||||
impl From<Vec<Vec<Text<String>>>> for NuTable {
|
||||
fn from(value: Vec<Vec<Text<String>>>) -> Self {
|
||||
let mut nutable = Self::new(0, 0);
|
||||
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(
|
||||
self,
|
||||
rec: &mut NuRecords,
|
||||
@ -374,8 +374,8 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
||||
)
|
||||
.change(rec, cfg, dim);
|
||||
} else if self.cfg.expand && self.width_max > total_width {
|
||||
Settings::new(SetDimensions(self.width), Width::increase(self.width_max))
|
||||
.change(rec, cfg, dim)
|
||||
let opt = (SetDimensions(self.width), Width::increase(self.width_max));
|
||||
TableOption::<VecRecords<_>, _, _>::change(opt, rec, cfg, dim)
|
||||
} else {
|
||||
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(
|
||||
self,
|
||||
recs: &mut NuRecords,
|
||||
@ -424,27 +424,28 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
||||
|
||||
match self.strategy {
|
||||
TrimStrategy::Wrap { try_to_keep_words } => {
|
||||
let mut wrap = Width::wrap(self.width_max).priority::<PriorityMax>();
|
||||
if try_to_keep_words {
|
||||
wrap = wrap.keep_words();
|
||||
}
|
||||
let wrap = Width::wrap(self.width_max)
|
||||
.keep_words(try_to_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 } => {
|
||||
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 {
|
||||
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(
|
||||
recs: &mut VecRecords<CellInfo<String>>,
|
||||
recs: &mut VecRecords<Text<String>>,
|
||||
cfg: &mut ColoredConfig,
|
||||
dims: &mut CompleteDimensionVecRecords,
|
||||
trim: TableTrim,
|
||||
@ -456,7 +457,7 @@ fn trim_as_header(
|
||||
let headers = recs[0].to_owned();
|
||||
let headers_widths = headers
|
||||
.iter()
|
||||
.map(CellInfo::width)
|
||||
.map(Text::width)
|
||||
.map(|v| v + trim.pad)
|
||||
.collect::<Vec<_>>();
|
||||
let min_width_use = get_total_width2(&headers_widths, cfg);
|
||||
@ -481,14 +482,10 @@ fn trim_as_header(
|
||||
|
||||
match &trim.strategy {
|
||||
TrimStrategy::Wrap { try_to_keep_words } => {
|
||||
let mut wrap = Width::wrap(use_width);
|
||||
if *try_to_keep_words {
|
||||
wrap = wrap.keep_words();
|
||||
}
|
||||
let wrap = Width::wrap(use_width).keep_words(*try_to_keep_words);
|
||||
|
||||
Modify::new(Columns::single(i))
|
||||
.with(wrap)
|
||||
.change(recs, cfg, dims);
|
||||
let opt = Modify::new(Columns::single(i)).with(wrap);
|
||||
TableOption::<VecRecords<Text<String>>, _, _>::change(opt, recs, cfg, dims);
|
||||
}
|
||||
TrimStrategy::Truncate { suffix } => {
|
||||
let mut truncate = Width::truncate(use_width);
|
||||
@ -496,9 +493,8 @@ fn trim_as_header(
|
||||
truncate = truncate.suffix(suffix).suffix_try_color(true);
|
||||
}
|
||||
|
||||
Modify::new(Columns::single(i))
|
||||
.with(truncate)
|
||||
.change(recs, cfg, dims);
|
||||
let opt = Modify::new(Columns::single(i)).with(truncate);
|
||||
TableOption::<VecRecords<Text<String>>, _, _>::change(opt, recs, cfg, dims);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -579,19 +575,21 @@ fn load_theme(
|
||||
let mut theme = theme.get_theme();
|
||||
|
||||
if !with_header {
|
||||
theme.set_horizontals(std::collections::HashMap::new());
|
||||
} else if with_footer && table.count_rows() > 2 {
|
||||
if let Some(line) = theme.get_horizontal(1) {
|
||||
theme.insert_horizontal(table.count_rows() - 1, line);
|
||||
}
|
||||
theme.set_horizontal_lines(Default::default());
|
||||
}
|
||||
|
||||
table.with(theme);
|
||||
|
||||
if let Some(style) = sep_color {
|
||||
let color = convert_style(style);
|
||||
let color = AnsiColor::from(color);
|
||||
table.get_config_mut().set_border_color_global(color);
|
||||
let color = ANSIBuf::from(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;
|
||||
|
||||
impl Peaker for PriorityMax {
|
||||
fn create() -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
fn peak(&mut self, _: &[usize], widths: &[usize]) -> Option<usize> {
|
||||
let col = (0..widths.len()).rev().max_by_key(|&i| widths[i]);
|
||||
col.filter(|&col| widths[col] != 0)
|
||||
@ -881,7 +875,7 @@ fn push_empty_column(data: &mut NuRecords) {
|
||||
let records = std::mem::take(data);
|
||||
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 {
|
||||
row.push(empty_cell.clone());
|
||||
}
|
||||
@ -920,7 +914,7 @@ fn convert_alignment(alignment: nu_color_config::Alignment) -> AlignmentHorizont
|
||||
|
||||
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) {
|
||||
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>);
|
||||
|
||||
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<'_>) {
|
||||
dims.set_widths(self.0);
|
||||
}
|
||||
@ -951,7 +945,7 @@ fn build_width(records: &NuRecords, pad: usize) -> Vec<usize> {
|
||||
|
||||
struct GetRow(usize, Vec<String>);
|
||||
|
||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for &mut GetRow {
|
||||
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for &mut GetRow {
|
||||
fn change(
|
||||
self,
|
||||
recs: &mut NuRecords,
|
||||
@ -965,7 +959,7 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
||||
|
||||
struct GetRowSettings(usize, AlignmentHorizontal, Option<Color>);
|
||||
|
||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig>
|
||||
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>>
|
||||
for &mut GetRowSettings
|
||||
{
|
||||
fn change(
|
||||
@ -1007,7 +1001,7 @@ impl SetLineHeaders {
|
||||
}
|
||||
}
|
||||
|
||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for SetLineHeaders {
|
||||
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for SetLineHeaders {
|
||||
fn change(
|
||||
self,
|
||||
recs: &mut NuRecords,
|
||||
@ -1020,7 +1014,7 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
||||
columns = columns
|
||||
.into_iter()
|
||||
.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();
|
||||
}
|
||||
None => {
|
||||
@ -1065,7 +1059,7 @@ impl MoveRowPrev {
|
||||
}
|
||||
}
|
||||
|
||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for MoveRowNext {
|
||||
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for MoveRowNext {
|
||||
fn change(
|
||||
self,
|
||||
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(
|
||||
self,
|
||||
recs: &mut NuRecords,
|
||||
@ -1193,9 +1187,11 @@ fn set_column_names(
|
||||
align: AlignmentHorizontal,
|
||||
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 {
|
||||
names = names.set_color(color);
|
||||
names = names.color(color);
|
||||
}
|
||||
|
||||
ColumnNames::change(names, records, cfg, dims)
|
||||
@ -1214,7 +1210,7 @@ fn remove_row(recs: &mut NuRecords, row: usize) -> Vec<String> {
|
||||
|
||||
struct StripColorFromRow(usize);
|
||||
|
||||
impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for StripColorFromRow {
|
||||
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for StripColorFromRow {
|
||||
fn change(
|
||||
self,
|
||||
recs: &mut NuRecords,
|
||||
@ -1222,7 +1218,32 @@ impl TableOption<NuRecords, CompleteDimensionVecRecords<'_>, ColoredConfig> for
|
||||
_: &mut CompleteDimensionVecRecords<'_>,
|
||||
) {
|
||||
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)]
|
||||
pub struct TableTheme {
|
||||
theme: RawStyle,
|
||||
full_theme: RawStyle,
|
||||
theme: Theme,
|
||||
full_theme: Theme,
|
||||
has_inner: bool,
|
||||
}
|
||||
|
||||
impl TableTheme {
|
||||
pub fn basic() -> TableTheme {
|
||||
pub fn new(theme: impl Into<Theme>, full_theme: impl Into<Theme>, has_inner: bool) -> Self {
|
||||
Self {
|
||||
theme: Style::ascii().into(),
|
||||
full_theme: Style::ascii().into(),
|
||||
has_inner: true,
|
||||
theme: theme.into(),
|
||||
full_theme: full_theme.into(),
|
||||
has_inner,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn basic() -> TableTheme {
|
||||
Self::new(Style::ascii(), Style::ascii(), true)
|
||||
}
|
||||
|
||||
pub fn thin() -> TableTheme {
|
||||
Self {
|
||||
theme: Style::modern().into(),
|
||||
full_theme: Style::modern().into(),
|
||||
has_inner: true,
|
||||
}
|
||||
Self::new(Style::modern(), Style::modern(), true)
|
||||
}
|
||||
|
||||
pub fn light() -> TableTheme {
|
||||
let theme = Style::blank()
|
||||
.horizontals([HorizontalLine::new(
|
||||
1,
|
||||
Line::new(Some('─'), Some('─'), None, None),
|
||||
)])
|
||||
.into();
|
||||
Self {
|
||||
theme,
|
||||
full_theme: Style::modern().into(),
|
||||
has_inner: true,
|
||||
}
|
||||
let mut theme = Theme::from_style(Style::blank());
|
||||
theme.insert_horizontal_line(1, HorizontalLine::new('─').intersection('─'));
|
||||
|
||||
Self::new(theme, Style::modern(), true)
|
||||
}
|
||||
|
||||
pub fn psql() -> TableTheme {
|
||||
Self {
|
||||
theme: Style::psql().into(),
|
||||
full_theme: Style::psql().into(),
|
||||
has_inner: true,
|
||||
}
|
||||
Self::new(Style::psql(), Style::psql(), true)
|
||||
}
|
||||
|
||||
pub fn markdown() -> TableTheme {
|
||||
Self {
|
||||
theme: Style::markdown().into(),
|
||||
full_theme: Style::markdown().into(),
|
||||
has_inner: true,
|
||||
}
|
||||
Self::new(Style::markdown(), Style::markdown(), true)
|
||||
}
|
||||
|
||||
pub fn dots() -> TableTheme {
|
||||
let theme = Style::dots().remove_horizontal().into();
|
||||
Self {
|
||||
theme,
|
||||
full_theme: Style::dots().into(),
|
||||
has_inner: true,
|
||||
}
|
||||
let theme = Style::dots().remove_horizontal();
|
||||
|
||||
Self::new(theme, Style::dots(), true)
|
||||
}
|
||||
|
||||
pub fn restructured() -> TableTheme {
|
||||
Self {
|
||||
theme: Style::re_structured_text().into(),
|
||||
full_theme: Style::re_structured_text().into(),
|
||||
has_inner: true,
|
||||
}
|
||||
Self::new(
|
||||
Style::re_structured_text(),
|
||||
Style::re_structured_text(),
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn ascii_rounded() -> TableTheme {
|
||||
Self {
|
||||
theme: Style::ascii_rounded().into(),
|
||||
full_theme: Style::ascii_rounded().into(),
|
||||
has_inner: true,
|
||||
}
|
||||
Self::new(Style::ascii_rounded(), Style::ascii_rounded(), true)
|
||||
}
|
||||
|
||||
pub fn basic_compact() -> TableTheme {
|
||||
let theme = Style::ascii().remove_horizontal().into();
|
||||
Self {
|
||||
theme,
|
||||
full_theme: Style::ascii().into(),
|
||||
has_inner: true,
|
||||
}
|
||||
let theme = Style::ascii().remove_horizontal();
|
||||
|
||||
Self::new(theme, Style::ascii(), true)
|
||||
}
|
||||
|
||||
pub fn compact() -> TableTheme {
|
||||
let hline = HorizontalLine::inherit(Style::modern().remove_left().remove_right());
|
||||
let theme = Style::modern()
|
||||
.remove_left()
|
||||
.remove_right()
|
||||
.remove_horizontal()
|
||||
.horizontals([HorizontalLine::new(1, Style::modern().get_horizontal())
|
||||
.left(None)
|
||||
.right(None)])
|
||||
.into();
|
||||
Self {
|
||||
theme,
|
||||
full_theme: Style::modern().into(),
|
||||
has_inner: true,
|
||||
}
|
||||
.horizontals([(1, hline)]);
|
||||
|
||||
Self::new(theme, Style::modern(), true)
|
||||
}
|
||||
|
||||
pub fn with_love() -> TableTheme {
|
||||
@ -109,10 +80,7 @@ impl TableTheme {
|
||||
.top('❤')
|
||||
.bottom('❤')
|
||||
.vertical('❤')
|
||||
.horizontals([HorizontalLine::new(
|
||||
1,
|
||||
Line::new(Some('❤'), Some('❤'), None, None),
|
||||
)]);
|
||||
.horizontals([(1, HorizontalLine::new('❤').intersection('❤'))]);
|
||||
|
||||
let full_theme = Style::empty()
|
||||
.top('❤')
|
||||
@ -131,53 +99,40 @@ impl TableTheme {
|
||||
.intersection_left('❤')
|
||||
.intersection('❤');
|
||||
|
||||
Self {
|
||||
theme: theme.into(),
|
||||
full_theme: full_theme.into(),
|
||||
has_inner: true,
|
||||
}
|
||||
Self::new(theme, full_theme, true)
|
||||
}
|
||||
|
||||
pub fn compact_double() -> TableTheme {
|
||||
let hline = HorizontalLine::inherit(Style::extended())
|
||||
.remove_left()
|
||||
.remove_right();
|
||||
let theme = Style::extended()
|
||||
.remove_left()
|
||||
.remove_right()
|
||||
.remove_horizontal()
|
||||
.horizontals([HorizontalLine::new(1, Style::extended().get_horizontal())
|
||||
.left(None)
|
||||
.right(None)])
|
||||
.into();
|
||||
Self {
|
||||
theme,
|
||||
full_theme: Style::extended().into(),
|
||||
has_inner: true,
|
||||
}
|
||||
.horizontals([(1, hline)]);
|
||||
|
||||
Self::new(theme, Style::extended(), true)
|
||||
}
|
||||
|
||||
pub fn rounded() -> TableTheme {
|
||||
Self {
|
||||
theme: Style::rounded().into(),
|
||||
full_theme: Style::modern()
|
||||
.corner_top_left('╭')
|
||||
.corner_top_right('╮')
|
||||
.corner_bottom_left('╰')
|
||||
.corner_bottom_right('╯')
|
||||
.into(),
|
||||
has_inner: true,
|
||||
}
|
||||
let full = Style::modern()
|
||||
.corner_top_left('╭')
|
||||
.corner_top_right('╮')
|
||||
.corner_bottom_left('╰')
|
||||
.corner_bottom_right('╯');
|
||||
|
||||
Self::new(Style::rounded(), full, true)
|
||||
}
|
||||
|
||||
pub fn reinforced() -> TableTheme {
|
||||
let full_theme = Style::modern()
|
||||
let full = Style::modern()
|
||||
.corner_top_left('┏')
|
||||
.corner_top_right('┓')
|
||||
.corner_bottom_left('┗')
|
||||
.corner_bottom_right('┛');
|
||||
Self {
|
||||
theme: full_theme.clone().remove_horizontal().into(),
|
||||
full_theme: full_theme.into(),
|
||||
has_inner: true,
|
||||
}
|
||||
|
||||
Self::new(full.clone().remove_horizontal(), full, true)
|
||||
}
|
||||
|
||||
pub fn heavy() -> TableTheme {
|
||||
@ -193,48 +148,32 @@ impl TableTheme {
|
||||
.corner_top_right('┓')
|
||||
.corner_bottom_left('┗')
|
||||
.corner_bottom_right('┛')
|
||||
.horizontals([HorizontalLine::new(1, Line::full('━', '╋', '┣', '┫'))]);
|
||||
let full_theme = theme
|
||||
.horizontals([(1, HorizontalLine::full('━', '╋', '┣', '┫'))]);
|
||||
let full = theme
|
||||
.clone()
|
||||
.remove_horizontals()
|
||||
.horizontal('━')
|
||||
.intersection_left('┣')
|
||||
.intersection_right('┫')
|
||||
.intersection('╋');
|
||||
Self {
|
||||
theme: theme.into(),
|
||||
full_theme: full_theme.into(),
|
||||
has_inner: true,
|
||||
}
|
||||
|
||||
Self::new(theme, full, true)
|
||||
}
|
||||
|
||||
pub fn none() -> TableTheme {
|
||||
Self {
|
||||
theme: Style::blank().into(),
|
||||
full_theme: Style::blank().into(),
|
||||
has_inner: true,
|
||||
}
|
||||
Self::new(Style::blank(), Style::blank(), true)
|
||||
}
|
||||
|
||||
pub fn has_top_line(&self) -> bool {
|
||||
self.theme.get_top().is_some()
|
||||
|| self.theme.get_top_intersection().is_some()
|
||||
|| self.theme.get_top_left().is_some()
|
||||
|| self.theme.get_top_right().is_some()
|
||||
pub fn has_top(&self) -> bool {
|
||||
self.theme.borders_has_top()
|
||||
}
|
||||
|
||||
pub fn has_left(&self) -> bool {
|
||||
self.theme.get_left().is_some()
|
||||
|| self.theme.get_left_intersection().is_some()
|
||||
|| self.theme.get_top_left().is_some()
|
||||
|| self.theme.get_bottom_left().is_some()
|
||||
self.theme.borders_has_left()
|
||||
}
|
||||
|
||||
pub fn has_right(&self) -> bool {
|
||||
self.theme.get_right().is_some()
|
||||
|| self.theme.get_right_intersection().is_some()
|
||||
|| self.theme.get_top_right().is_some()
|
||||
|| self.theme.get_bottom_right().is_some()
|
||||
self.theme.borders_has_right()
|
||||
}
|
||||
|
||||
pub fn has_inner(&self) -> bool {
|
||||
@ -245,11 +184,11 @@ impl TableTheme {
|
||||
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()
|
||||
}
|
||||
|
||||
pub fn get_theme(&self) -> RawStyle {
|
||||
pub fn get_theme(&self) -> Theme {
|
||||
self.theme.clone()
|
||||
}
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ fn expanded_table_kv(record: &Record, cfg: Cfg<'_>) -> StringResult {
|
||||
// we could use Padding for it but,
|
||||
// the easiest way to do so is just push a new_line char before
|
||||
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');
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,11 @@ use nu_color_config::StyleComputer;
|
||||
use nu_protocol::{Config, Record, Span, Value};
|
||||
use tabled::{
|
||||
grid::{
|
||||
color::{AnsiColor, StaticColor},
|
||||
ansi::{ANSIBuf, ANSIStr},
|
||||
config::{AlignmentHorizontal, Borders, CompactMultilineConfig},
|
||||
dimension::{DimensionPriority, PoolTableDimension},
|
||||
},
|
||||
settings::{style::RawStyle, Color, Padding, TableOption},
|
||||
settings::{Color, Padding, TableOption, Theme},
|
||||
tables::{PoolTable, TableValue},
|
||||
};
|
||||
|
||||
@ -53,7 +53,7 @@ fn build_table(
|
||||
let mut table = PoolTable::from(val);
|
||||
|
||||
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(SetRawStyle(theme));
|
||||
@ -73,12 +73,13 @@ fn build_table(
|
||||
// We just need this unsafe section to cope with some limitations of [`PoolTable`].
|
||||
// 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 suffix = color.get_suffix();
|
||||
let prefix: &'static str = unsafe { std::mem::transmute(prefix) };
|
||||
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();
|
||||
|
||||
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) {
|
||||
let borders = self.0.get_borders();
|
||||
*cfg = cfg.set_borders(borders);
|
||||
let borders = *self.0.get_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) {
|
||||
let borders = Borders::filled(self.0);
|
||||
*cfg = cfg.set_borders_color(borders);
|
||||
cfg.set_borders_color(borders);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
*cfg = cfg.set_alignment_horizontal(self.0);
|
||||
cfg.set_alignment_horizontal(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,9 @@ use nu_color_config::StyleComputer;
|
||||
use tabled::{
|
||||
builder::Builder,
|
||||
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},
|
||||
};
|
||||
@ -10,7 +12,7 @@ use tabled::{
|
||||
use crate::common::get_leading_trailing_space_style;
|
||||
|
||||
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 {
|
||||
@ -24,7 +26,7 @@ pub fn string_wrap(text: &str, width: usize, keep_words: bool) -> String {
|
||||
}
|
||||
|
||||
let wrap = if keep_words {
|
||||
Width::wrap(width).keep_words()
|
||||
Width::wrap(width).keep_words(true)
|
||||
} else {
|
||||
Width::wrap(width)
|
||||
};
|
||||
@ -45,7 +47,7 @@ pub fn string_truncate(text: &str, width: usize) -> String {
|
||||
None => return String::new(),
|
||||
};
|
||||
|
||||
Truncate::truncate_text(line, width).into_owned()
|
||||
Truncate::truncate(line, width).into_owned()
|
||||
}
|
||||
|
||||
pub fn clean_charset(text: &str) -> String {
|
||||
@ -53,24 +55,26 @@ pub fn clean_charset(text: &str) -> String {
|
||||
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 {
|
||||
let style = convert_style(style).into();
|
||||
colorize_lead_trail_space(data, Some(&style), Some(&style));
|
||||
let style = ANSIBuf::from(convert_style(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<'_>) {
|
||||
if let Some(style) = get_leading_trailing_space_style(style_computer).color_style {
|
||||
let style = convert_style(style).into();
|
||||
*text = colorize_space_one(text, Some(&style), Some(&style));
|
||||
let style = ANSIBuf::from(convert_style(style));
|
||||
let style = style.as_ref();
|
||||
*text = colorize_space_one(text, Some(style), Some(style));
|
||||
}
|
||||
}
|
||||
|
||||
fn colorize_lead_trail_space(
|
||||
data: &mut [Vec<CellInfo<String>>],
|
||||
lead: Option<&AnsiColor<'_>>,
|
||||
trail: Option<&AnsiColor<'_>>,
|
||||
data: &mut [Vec<Text<String>>],
|
||||
lead: Option<ANSIStr<'_>>,
|
||||
trail: Option<ANSIStr<'_>>,
|
||||
) {
|
||||
if lead.is_none() && trail.is_none() {
|
||||
return;
|
||||
@ -79,16 +83,12 @@ fn colorize_lead_trail_space(
|
||||
for row in data.iter_mut() {
|
||||
for cell in row {
|
||||
let buf = colorize_space_one(cell.as_ref(), lead, trail);
|
||||
*cell = CellInfo::new(buf);
|
||||
*cell = Text::new(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn colorize_space_one(
|
||||
text: &str,
|
||||
lead: Option<&AnsiColor<'_>>,
|
||||
trail: Option<&AnsiColor<'_>>,
|
||||
) -> String {
|
||||
fn colorize_space_one(text: &str, lead: Option<ANSIStr<'_>>, trail: Option<ANSIStr<'_>>) -> String {
|
||||
use fancy_regex::Captures;
|
||||
use fancy_regex::Regex;
|
||||
use once_cell::sync::Lazy;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use nu_table::{string_width, NuTable, NuTableConfig};
|
||||
use tabled::grid::records::vec_records::CellInfo;
|
||||
use tabled::grid::records::vec_records::Text;
|
||||
|
||||
pub struct TestCase {
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
|
||||
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);
|
||||
for i in 0..count_columns {
|
||||
row.push(CellInfo::new(i.to_string()));
|
||||
row.push(Text::new(i.to_string()));
|
||||
}
|
||||
|
||||
row
|
||||
}
|
||||
|
||||
pub fn cell(text: &str) -> CellInfo<String> {
|
||||
CellInfo::new(text.to_string())
|
||||
pub fn cell(text: &str) -> Text<String> {
|
||||
Text::new(text.to_string())
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ mod common;
|
||||
use common::{create_row, test_table, TestCase};
|
||||
use nu_protocol::TrimStrategy;
|
||||
use nu_table::{NuTable, NuTableConfig, TableTheme as theme};
|
||||
use tabled::grid::records::vec_records::CellInfo;
|
||||
use tabled::grid::records::vec_records::Text;
|
||||
|
||||
#[test]
|
||||
fn data_and_header_has_different_size_doesnt_work() {
|
||||
@ -194,7 +194,7 @@ fn width_control_test_0() {
|
||||
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 {
|
||||
theme: theme::heavy(),
|
||||
trim: TrimStrategy::truncate(Some(String::from("..."))),
|
||||
|
@ -2,7 +2,7 @@ mod common;
|
||||
|
||||
use common::create_row as row;
|
||||
use nu_table::{NuTable, NuTableConfig, TableTheme as theme};
|
||||
use tabled::grid::records::vec_records::CellInfo;
|
||||
use tabled::grid::records::vec_records::Text;
|
||||
|
||||
#[test]
|
||||
fn test_rounded() {
|
||||
@ -451,7 +451,7 @@ fn test_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 {
|
||||
theme,
|
||||
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")
|
||||
}
|
||||
|
||||
fn create_table_with_size(
|
||||
data: Vec<Vec<CellInfo<String>>>,
|
||||
with_header: bool,
|
||||
theme: theme,
|
||||
) -> String {
|
||||
fn create_table_with_size(data: Vec<Vec<Text<String>>>, with_header: bool, theme: theme) -> String {
|
||||
let config = NuTableConfig {
|
||||
theme,
|
||||
with_header,
|
||||
|
Loading…
Reference in New Issue
Block a user