use std::env;
use std::io::{IsTerminal, Read};
use std::process::ExitCode;
mod highlight;
mod pager;
use pager::Source;
const USAGE: &str = "usage: cless [-S] [-N] <file>...";
fn main() -> ExitCode {
let args: Vec<String> = env::args().collect();
let mut wrap = true;
let mut numbers = false;
let mut paths: Vec<&str> = Vec::new();
for arg in &args[1..] {
match arg.as_str() {
"-h" | "--help" => {
eprintln!("{}", USAGE);
return ExitCode::from(2);
}
"-S" => wrap = false,
"-N" => numbers = true,
other if other.starts_with('-') && other.len() > 1 => {
eprintln!("cless: unknown option: {}", other);
return ExitCode::from(2);
}
other => paths.push(other),
}
}
let read_stdin =
(paths.is_empty() && !std::io::stdin().is_terminal()) || (paths == ["-"]);
if !read_stdin && paths.iter().any(|p| *p == "-") {
eprintln!("cless: '-' (stdin) cannot be combined with files");
return ExitCode::from(2);
}
let sources = if read_stdin {
let mut buf = String::new();
if let Err(e) = std::io::stdin().read_to_string(&mut buf) {
eprintln!("cless: <stdin>: {}", e);
return ExitCode::from(1);
}
vec![Source::memory("(stdin)", highlight::highlight_file(&buf, ""))]
} else {
if paths.is_empty() {
eprintln!("{}", USAGE);
return ExitCode::from(2);
}
paths.iter().map(|p| Source::file(*p, *p)).collect()
};
if let Err(e) = pager::run(sources, wrap, numbers) {
eprintln!("cless: {}", e);
return ExitCode::from(1);
}
ExitCode::SUCCESS
}