Adapt text output to terminal size

Previously, we wrapped all lines at 100 characters and just printed to
stdout.  With this patch, we use the pager crate to spawn a pager
(typically less) before printing the text.  Also, we try to use the
terminal size to determine the line length:  The default line length is
still 100 characters but can be reduced to fit the terminal.
This commit is contained in:
Robin Krahl 2020-07-17 15:41:08 +02:00
parent fdabe11c4a
commit 02b3116ecd
5 changed files with 73 additions and 9 deletions

38
Cargo.lock generated
View File

@ -106,6 +106,25 @@ dependencies = [
"dtoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "errno"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "futf"
version = "0.1.4"
@ -123,6 +142,11 @@ dependencies = [
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gcc"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "getrandom"
version = "0.1.14"
@ -269,6 +293,15 @@ name = "object"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pager"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"errno 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "phf"
version = "0.8.0"
@ -444,6 +477,7 @@ dependencies = [
"anyhow 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"html2text 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"kuchiki 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pager 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -703,8 +737,11 @@ dependencies = [
"checksum derive_more 0.99.9 (registry+https://github.com/rust-lang/crates.io-index)" = "298998b1cf6b5b2c8a7b023dfd45821825ce3ba8a8af55c921a0e734e4653f76"
"checksum dtoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
"checksum dtoa-short 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59020b8513b76630c49d918c33db9f4c91638e7d3404a28084083b87e33f76f2"
"checksum errno 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6eab5ee3df98a279d9b316b1af6ac95422127b1290317e6d18c1743c99418b01"
"checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
"checksum futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b"
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
"checksum gimli 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
@ -724,6 +761,7 @@ dependencies = [
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
"checksum object 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
"checksum pager 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b69ced2bfa977c4541743a7427b89c94120684791a9629941fe6028dccab6528"
"checksum phf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
"checksum phf_codegen 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815"
"checksum phf_generator 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"

View File

@ -16,6 +16,7 @@ license = "MIT"
anyhow = "1.0.31"
html2text = "0.1.12"
kuchiki = "0.8.0"
pager = "0.15.0"
termion = "1.5.5"
[dependencies.structopt]

View File

@ -4,6 +4,7 @@
mod rich;
mod text;
use std::cmp;
use std::fmt;
use std::io;
@ -28,3 +29,15 @@ pub fn get_default() -> Box<dyn Viewer> {
Box::new(text::TextViewer::new())
}
}
pub fn spawn_pager() {
pager::Pager::with_default_pager("less -cr").setup()
}
pub fn get_line_length() -> usize {
if let Ok((cols, _)) = termion::terminal_size() {
cmp::min(cols.into(), 100)
} else {
100
}
}

View File

@ -6,18 +6,22 @@ use html2text::render::text_renderer;
use crate::doc;
use crate::viewer;
type TaggedString = text_renderer::TaggedString<Vec<text_renderer::RichAnnotation>>;
type RichString = text_renderer::TaggedString<Vec<text_renderer::RichAnnotation>>;
#[derive(Clone, Debug)]
pub struct RichViewer {}
pub struct RichViewer {
line_length: usize,
}
impl RichViewer {
pub fn new() -> Self {
Self {}
Self {
line_length: viewer::get_line_length(),
}
}
fn print(&self, s: &str) {
let lines = html2text::from_read_rich(s.as_bytes(), 100);
let lines = html2text::from_read_rich(s.as_bytes(), self.line_length);
for line in lines {
for element in line.iter() {
if let text_renderer::TaggedLineElement::Str(ts) = element {
@ -41,7 +45,7 @@ impl RichViewer {
print!("{}", termion::style::Reset);
}
fn render_string(&self, ts: &TaggedString) {
fn render_string(&self, ts: &RichString) {
let start_style = get_style(ts, get_start_style);
let end_style = get_style(ts, get_end_style);
print!("{}{}{}", start_style, ts.s, end_style);
@ -50,6 +54,8 @@ impl RichViewer {
impl viewer::Viewer for RichViewer {
fn open(&self, doc: &doc::Doc) -> anyhow::Result<()> {
viewer::spawn_pager();
self.print_heading(&doc.title, 1);
self.print_opt(doc.definition.as_deref());
self.print_opt(doc.description.as_deref());
@ -57,7 +63,7 @@ impl viewer::Viewer for RichViewer {
}
}
fn get_style<F>(ts: &TaggedString, f: F) -> String
fn get_style<F>(ts: &RichString, f: F) -> String
where
F: Fn(&text_renderer::RichAnnotation) -> String,
{

View File

@ -7,7 +7,9 @@ use crate::doc;
use crate::viewer;
#[derive(Clone, Debug)]
pub struct TextViewer {}
pub struct TextViewer {
line_length: usize,
}
struct Decorator {
links: Vec<String>,
@ -16,13 +18,15 @@ struct Decorator {
impl TextViewer {
pub fn new() -> Self {
Self {}
Self {
line_length: viewer::get_line_length(),
}
}
fn print(&self, s: &str) {
println!(
"{}",
html2text::from_read_with_decorator(s.as_bytes(), 100, Decorator::new())
html2text::from_read_with_decorator(s.as_bytes(), self.line_length, Decorator::new())
);
}
@ -35,6 +39,8 @@ impl TextViewer {
impl viewer::Viewer for TextViewer {
fn open(&self, doc: &doc::Doc) -> anyhow::Result<()> {
viewer::spawn_pager();
self.print(&doc.title);
self.print_opt(doc.definition.as_deref());
self.print_opt(doc.description.as_deref());