Fix help on smaller terminal

COLUMNS not working, using term_size crate for a more portable
solution.
This commit is contained in:
Ivan Tham 2020-11-03 01:45:45 +08:00
parent ea95516537
commit 8ff40835cc
3 changed files with 31 additions and 19 deletions

11
Cargo.lock generated
View File

@ -158,6 +158,7 @@ dependencies = [
"radix_fmt",
"regex",
"rustyline",
"term_size",
]
[[package]]
@ -373,6 +374,16 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "term_size"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "textwrap"
version = "0.11.0"

View File

@ -19,3 +19,4 @@ lazy_static = "1.3.0"
directories = "2.0.1"
regex = "1.1.7"
num = "0.2"
term_size = "0.3"

View File

@ -30,30 +30,30 @@ pub fn handler(e: CalcError) -> String {
},
CalcError::Syntax(details) => format!("Syntax Error: {}", details),
CalcError::Parser(details) => format!("Parser Error: {}", details),
CalcError::Help => format!(
"Constants\n{}\nFunctions\n{}\nOperators\n{}\n",
blocks(lex::CONSTANTS.keys().cloned()),
blocks(lex::FUNCTIONS.keys().cloned()),
{
let l: Vec<_> = lex::OPERATORS.keys().map(|c| c.to_string()).collect();
l.join(" ")
CalcError::Help => {
// calculate max width but ideally this should be calculated once
let mut max_width = 79; // capped at 79
if let Some((w, _)) = term_size::dimensions() {
if w < max_width {
max_width = w;
}
}
),
let operators: Vec<_> = lex::OPERATORS.keys().map(|c| c.to_string()).collect();
format!(
"Constants\n{}\nFunctions\n{}\nOperators\n{}\n",
blocks(max_width, lex::CONSTANTS.keys().cloned()),
blocks(max_width, lex::FUNCTIONS.keys().cloned()),
operators.join(" ")
)
}
}
}
/// Convert iterator into strings of chunks of 8 right padded with space.
fn blocks(mut iter: impl Iterator<Item = &'static str> + ExactSizeIterator) -> String {
// calculate max width but ideally this should be calculated once
let mut max_width = 79; // capped at 79
if let Ok(s) = std::env::var("COLUMNS") {
if let Ok(n) = s.parse() {
if n < max_width {
max_width = n;
}
}
}
fn blocks(
max_width: usize,
mut iter: impl Iterator<Item = &'static str> + ExactSizeIterator,
) -> String {
// multiply by eight since we are formatting it into chunks of 8
let items_per_line = max_width / 8;
let full_bytes = (iter.len() - iter.len() % items_per_line) * 8;