summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Tay <sam.chong.tay@gmail.com>2020-06-07 18:01:22 -0700
committerSam Tay <sam.chong.tay@gmail.com>2020-06-07 18:01:22 -0700
commit556612119a77d8235904819a2f17a8ed82ca304c (patch)
treee59ee68b900af1744e4d5ba48830df080e9b1052
parent1942882d2825b205cec89c8cb5990d637ebdf838 (diff)
Start using termimad
Getting feet wet by scrapping manual crossterm calls and just letting termimad do the heavy lifting via markdown
-rw-r--r--Cargo.lock132
-rw-r--r--Cargo.toml3
-rw-r--r--src/error.rs10
-rw-r--r--src/macros.rs32
-rw-r--r--src/main.rs30
-rw-r--r--src/term.rs10
6 files changed, 208 insertions, 9 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b54aaa0..838d441 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -159,6 +159,66 @@ dependencies = [
]
[[package]]
+name = "crossbeam"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e"
+dependencies = [
+ "cfg-if",
+ "crossbeam-channel",
+ "crossbeam-deque",
+ "crossbeam-epoch",
+ "crossbeam-queue",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061"
+dependencies = [
+ "crossbeam-utils",
+ "maybe-uninit",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
+dependencies = [
+ "crossbeam-epoch",
+ "crossbeam-utils",
+ "maybe-uninit",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "crossbeam-utils",
+ "lazy_static",
+ "maybe-uninit",
+ "memoffset",
+ "scopeguard",
+]
+
+[[package]]
+name = "crossbeam-queue"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab6bffe714b6bb07e42f201352c34f51fefd355ace793f9e638ebd52d23f98d2"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -531,12 +591,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
[[package]]
+name = "maybe-uninit"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
+
+[[package]]
name = "memchr"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
[[package]]
+name = "memoffset"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
name = "mime"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -553,6 +628,15 @@ dependencies = [
]
[[package]]
+name = "minimad"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a208cf4e8311b21538dd3fd63218ffcb102bf1ef1ce6fabbfb44e2237763ce5"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
name = "miniz_oxide"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -754,6 +838,17 @@ dependencies = [
]
[[package]]
+name = "pulldown-cmark"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e142c3b8f49d2200605ee6ba0b1d757310e9e7a72afe78c36ee2ef67300ee00"
+dependencies = [
+ "bitflags",
+ "memchr",
+ "unicase",
+]
+
+[[package]]
name = "quote"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1016,10 +1111,14 @@ dependencies = [
"crossterm",
"directories",
"flate2",
+ "lazy_static",
+ "minimad",
+ "pulldown-cmark",
"reqwest",
"serde",
"serde_json",
"serde_yaml",
+ "termimad",
]
[[package]]
@@ -1066,6 +1165,19 @@ dependencies = [
]
[[package]]
+name = "termimad"
+version = "0.8.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d457a91d0c9fbc663c18961e78f541e61aa9446dc1c0cdd87109543f7289447f"
+dependencies = [
+ "crossbeam",
+ "crossterm",
+ "lazy_static",
+ "minimad",
+ "thiserror",
+]
+
+[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1075,6 +1187,26 @@ dependencies = [
]
[[package]]
+name = "thiserror"
+version = "1.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b13f926965ad00595dd129fa12823b04bbf866e9085ab0a5f2b05b850fbfc344"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "893582086c2f98cde18f906265a65b5030a074b1046c674ae898be6519a7f479"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "time"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 708d51f..076e22a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,3 +15,6 @@ reqwest = { version = "0.10", features = ["blocking"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.8"
+termimad = "0.8"
+minimad = "0.6"
+lazy_static = "1.4"
diff --git a/src/error.rs b/src/error.rs
index b6046af..b2afd60 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -15,6 +15,7 @@ pub enum ErrorKind {
Panic,
EmptySites,
NoResults,
+ Termimad(termimad::Error),
}
impl From<&str> for Error {
@@ -26,6 +27,15 @@ impl From<&str> for Error {
}
}
+impl From<termimad::Error> for Error {
+ fn from(err: termimad::Error) -> Self {
+ Error {
+ kind: ErrorKind::Termimad(err),
+ error: String::from(""),
+ }
+ }
+}
+
// TODO add others
impl Error {
pub fn malformed(path: &PathBuf) -> Self {
diff --git a/src/macros.rs b/src/macros.rs
index a41443c..2b1de62 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -13,3 +13,35 @@ macro_rules! printerr {
).ok();
})
}
+
+#[macro_export]
+macro_rules! print_error {
+ ($skin: expr, $md: literal $(, $value: expr )* $(,)? ) => {{
+ use lazy_static::lazy_static;
+ use minimad::mad_inline;
+ use crate::error::Error;
+ let err = &mut std::io::stderr();
+ let p = $skin.paragraph.clone();
+ $skin.paragraph.set_fg(crossterm::style::Color::Red);
+ termimad::mad_write_inline!(err, $skin, "✖ ").map_err(Error::from)?;
+ $skin.write_composite(err, mad_inline!($md $(, $value)*)).map_err(Error::from)?;
+ $skin.paragraph = p;
+ Ok::<(), Error>(())
+ }};
+}
+
+#[macro_export]
+macro_rules! print_notice {
+ ($skin: expr, $md: literal $(, $value: expr )* $(,)? ) => {{
+ use lazy_static::lazy_static;
+ use minimad::mad_inline;
+ use crate::error::Error;
+ let err = &mut std::io::stderr();
+ let p = $skin.paragraph.clone();
+ $skin.paragraph.set_fg(crossterm::style::Color::Yellow);
+ termimad::mad_write_inline!(err, $skin, "✖ ").map_err(Error::from)?;
+ $skin.write_composite(err, mad_inline!($md $(, $value)*)).map_err(Error::from)?;
+ $skin.paragraph = p;
+ Ok::<(), Error>(())
+ }};
+}
diff --git a/src/main.rs b/src/main.rs
index 0f390df..9c75662 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,10 +6,14 @@ mod stackexchange;
mod term;
use config::Config;
+use crossterm::style::Color;
use error::{Error, ErrorKind};
+use lazy_static::lazy_static;
+use minimad::mad_inline;
use stackexchange::{LocalStorage, StackExchange};
use std::io::stderr;
-use term::ColoredOutput;
+use term::{prefix_err, ColoredOutput};
+use termimad::MadSkin;
fn main() {
(|| {
@@ -17,6 +21,10 @@ fn main() {
let config = opts.config;
let site = &config.site;
let mut ls = LocalStorage::new()?;
+ // TODO style configuration
+ let mut skin = MadSkin::default();
+ skin.inline_code.set_fg(Color::Cyan);
+ skin.code_block.set_fg(Color::Cyan);
if opts.update_sites {
ls.update_sites()?;
@@ -27,6 +35,7 @@ fn main() {
match sites.iter().map(|s| s.api_site_parameter.len()).max() {
Some(max_w) => {
for s in sites {
+ // TODO print as table!
println!("{:>w$}: {}", s.api_site_parameter, s.site_url, w = max_w);
}
}
@@ -43,14 +52,17 @@ fn main() {
match ls.validate_site(site) {
Ok(true) => (),
Ok(false) => {
- stderr()
- .queue_error(&format!("{} is not a valid StackExchange site.\n\n", site)[..])
- .queue_notice("If you think this is in error, try running\n\n")
- .queue_code("so --update-sites\n\n")
- .queue_notice_inline("to update the cached site listing. You can also run ")
- .queue_code_inline("so --list-sites")
- .queue_notice_inline(" to list all available sites.")
- .unsafe_flush();
+ print_error!(skin, "$0 is not a valid StackExchange site.\n\n", site)?;
+ // TODO what about using text wrapping feature?
+ print_notice!(
+ skin,
+ "If you think this is incorrect, try running\n\
+ ```\n\
+ so --update-sites\n\
+ ```\n\
+ to update the cached site listing. You can also run `so --list-sites` \
+ to list all available sites.",
+ )?;
return Ok(());
}
Err(Error {
diff --git a/src/term.rs b/src/term.rs
index 7507d31..cd2db46 100644
--- a/src/term.rs
+++ b/src/term.rs
@@ -1,6 +1,16 @@
use crossterm::style::{Color, Print, ResetColor, SetForegroundColor};
use crossterm::QueueableCommand;
+use lazy_static::lazy_static;
+use minimad::mad_inline;
use std::io::Write;
+use termimad::{mad_write_inline, MadSkin};
+
+pub fn prefix_err() -> Result<MadSkin, termimad::Error> {
+ let mut skin = MadSkin::default();
+ skin.paragraph.set_fg(Color::Red);
+ mad_write_inline!(&mut std::io::stderr(), &skin, "✖ ")?;
+ Ok(skin)
+}
pub trait ColoredOutput {
fn queue_general(&mut self, color: Color, prefix: &str, s: &str) -> &mut Self;