Open aharpervc opened 2 years ago
Hello @aharpervc, Thank you for opening the issue.
Current there's no easy way to handle it. But I think we could add a support for this functionality.
I tried to accomplish this goal via current means it it seems like can be achieved but quite hardly. (Interesting, I was thinking that it's easier than it turned out to be 😥)
You can find an example I've created which may cover some of your needs.
Correct me if I am wrong about these:
use tabled::{Tabled, TableIteratorExt, Modify, Full};
use terminal_size::{Width, terminal_size};
#[derive(Debug, Tabled)]
struct Issue {
author: &'static str,
index: usize,
title: &'static str,
}
impl Issue {
fn new(author: &'static str, index: usize, title: &'static str) -> Self { Self { author, index, title } }
}
fn main() {
let (Width(width), _) = terminal_size().unwrap();
println!("Terminal has width={}", width);
let data = vec![
Issue::new("aharpervc", 73, "How to set table width to be terminal width"),
Issue::new("zhiburt", 67, "Is it valuable to support ordering in derive macro?"),
Issue::new("111", 0, ""),
Issue::new("", 0, "111"),
];
let table = data.table().with(Modify::new(Full).with(move |s: &str| make_term_str(width as usize, 3, s)));
println!("{}", table);
}
fn make_term_str(term_width: usize, part: usize, s: &str) -> String {
// fixme: not totally correct
// for our example we lose 2 character of width.
let width = (term_width / part) - 4;
let str_length = s.chars().count();
if str_length >= width {
s.chars().take(width).collect()
} else {
let remaining = width - str_length;
format!("{}{}", " ".repeat(remaining), s)
}
}
You can check this out seems like works. And it's not probably exactly what you'd love to see.
Thanks for the response. That's an interesting approach. For your questions above, the idea is to print a table where the max width of the table is less than or equal to the terminal width; eg, rows never wrap. However, cell contents can wrap if necessary; but not wrap if not necessary.
This seems to work fairly well (might be off by 1/2 chars due to padding math, but it's basically fine)
let dimensions = terminal_size();
let (terminal_size::Width(w), terminal_size::Height(_)) = dimensions.unwrap_or_else(|| (terminal_size::Width(80 * 2), terminal_size::Height(0)));
let variable_size_column_count = 4;
let available_width_for_variable_sizing = w - (6 + 24 + 3);
let variable_size_column_max_width = (available_width_for_variable_sizing / variable_size_column_count) - 2;
let table = Table::new(items)
.with(Modify::new(Full)
.with(Alignment::left())
.with(Alignment::top())
.with(MaxWidth::wrapping(variable_size_column_max_width.into()).keep_words()))
.with(Modify::new(Column(0..1)).with(MaxWidth::wrapping(4)))
.with(Modify::new(Column(2..3)).with(MaxWidth::wrapping(22)))
.with(Modify::new(Column(6..7)).with(MaxWidth::wrapping(1)));
Hi @aharpervc
I think it's a valuable feature to have at the end of the day. So I tried to add a support for this.
Could you check add-total-width-support branch?
You can use it by fixing Cargo.toml
[dependencies]
tabled = { git = "https://github.com/zhiburt/tabled", branch = "add-total-width-support" }
You can also inspect by cloning this repo and running terminal_table
example.
Looking forward to your response.
PS: TotalWidth
misses a correct Panel
handling yet.
Also the name of the struct may be not the best....
Here's the code from the former mentioned example
#[derive(Tabled)]
struct Release {
version: &'static str,
published_date: &'static str,
is_active: bool,
major_feature: &'static str,
}
const DATA: [Release; 3] = [
Release {
version: "0.2.1",
published_date: "2021-06-23",
is_active: true,
major_feature: "#[header(inline)] attribute",
},
Release {
version: "0.2.0",
published_date: "2021-06-19",
is_active: false,
major_feature: "API changes",
},
Release {
version: "0.1.4",
published_date: "2021-06-07",
is_active: false,
major_feature: "display_with attribute",
},
];
fn main() {
let (terminal_size::Width(width), _) = terminal_size::terminal_size().unwrap();
let table = DATA
.table()
.with(Style::extended())
.with(Modify::new(Full).with(Alignment::center_horizontal()))
.with(TotalWidth::new(width as usize));
println!("{}", table);
}
ping @aharpervc
Nice, that definitely getting closer. I can see it sizing the max width how I hoped. Can this be used in conjunction with cell content wrapping instead of truncation? Eg, cells can always be extended to fill the max table width if necessary, but a cell whose contents extends the cell bounds should have word wrapping, so the content is always shown
Can this be used in conjunction with cell content wrapping instead of truncation? Eg, cells can always be extended to fill the max table width if necessary, but a cell whose contents extends the cell bounds should have word wrapping, so the content is always shown
I think it's reasonable 👍,
we could set whether truncating or wrapping will be used as a optional argument to TotalWidth
.
Hi @aharpervc
I did a couple of fixes and add a support for wrapping, could you check this out
Using terminal_table
example on add-total-width-support branch?
Also could I ask you what do you think about cases like, TotalWidth::new(0)
should it render an empty table? (no borders)
Сurrently TotalWidth
doesn't "clears" borders in such case.
Therefore it's the case where actual width won't be 0.
ping
ping.
Sorry if it's bothering you.
Yes, I see your updates, I'm subscribed to this discussion. I haven't had time to look at it again yet this week. I'll let you know when I'm able to give it a try.
Hi @aharpervc I hope you'll get a chance to take a look at the example I've provided.
I just want to let you know that we've merged TotalWidth
in master so you can use it from there
I came with a conclusion that TotalWidth
name is not very explicit.
So I split the functionality between MinWidth
and MaxWidth
.
Look at this example.
@aharpervc Hi once again I really don't want to bother you including the fact that you've already mentioned that. And I neither want to spam your inbox.
Just wan't to verify if we fixed your original issues. Or maybe you have some thoughts.
Sorry...
No problem, it's not spam if it's my own issue 😁. I had a limited amount of time to look into this question, and ran out of time
I came with a conclusion that
TotalWidth
name is not very explicit. So I split the functionality betweenMinWidth
andMaxWidth
.
This seems reasonable to me! My recommendation is to go with this and not wait on me, and if something else comes up in the future I'll put in a separate issue
Hi, I'm experimenting with this library, and I'm wondering if it's possible to set the table width automatically so that it's the same as the terminal's width. I can get the terminal width using the
terminal_size
crate or similar, but I'm unsure how to do actually use that to configure the table. This would be very useful for me if possible. Thanks!