use crate::{error::MinusError, input, minus_core::commands::Command, ExitStrategy, LineNumbers};
use crossbeam_channel::{Receiver, Sender};
use std::fmt;
#[cfg(feature = "search")]
use crate::search::SearchOpts;
#[derive(Clone)]
pub struct Pager {
pub(crate) tx: Sender<Command>,
pub(crate) rx: Receiver<Command>,
}
impl Pager {
#[must_use]
pub fn new() -> Self {
let (tx, rx) = crossbeam_channel::unbounded();
Self { tx, rx }
}
pub fn set_text(&self, s: impl Into<String>) -> Result<(), MinusError> {
Ok(self.tx.send(Command::SetData(s.into()))?)
}
pub fn push_str(&self, s: impl Into<String>) -> Result<(), MinusError> {
Ok(self.tx.send(Command::AppendData(s.into()))?)
}
pub fn set_line_numbers(&self, l: LineNumbers) -> Result<(), MinusError> {
Ok(self.tx.send(Command::SetLineNumbers(l))?)
}
pub fn set_prompt(&self, text: impl Into<String>) -> Result<(), MinusError> {
let text: String = text.into();
assert!(!text.contains('\n'), "Prompt cannot contain newlines");
Ok(self.tx.send(Command::SetPrompt(text))?)
}
pub fn send_message(&self, text: impl Into<String>) -> Result<(), MinusError> {
let text: String = text.into();
assert!(!text.contains('\n'), "Message cannot contain newlines");
Ok(self.tx.send(Command::SendMessage(text))?)
}
pub fn set_exit_strategy(&self, es: ExitStrategy) -> Result<(), MinusError> {
Ok(self.tx.send(Command::SetExitStrategy(es))?)
}
#[cfg(feature = "static_output")]
#[cfg_attr(docsrs, doc(cfg(feature = "static_output")))]
pub fn set_run_no_overflow(&self, val: bool) -> Result<(), MinusError> {
Ok(self.tx.send(Command::SetRunNoOverflow(val))?)
}
pub fn horizontal_scroll(&self, value: bool) -> Result<(), MinusError> {
Ok(self.tx.send(Command::LineWrapping(!value))?)
}
pub fn set_input_classifier(
&self,
handler: Box<dyn input::InputClassifier + Send + Sync>,
) -> Result<(), MinusError> {
Ok(self.tx.send(Command::SetInputClassifier(handler))?)
}
pub fn add_exit_callback(
&self,
cb: Box<dyn FnMut() + Send + Sync + 'static>,
) -> Result<(), MinusError> {
Ok(self.tx.send(Command::AddExitCallback(cb))?)
}
#[cfg(feature = "search")]
#[cfg_attr(docsrs, doc(cfg(feature = "search")))]
pub fn set_incremental_search_condition(
&self,
cb: Box<dyn Fn(&SearchOpts) -> bool + Send + Sync + 'static>,
) -> crate::Result {
self.tx.send(Command::IncrementalSearchCondition(cb))?;
Ok(())
}
pub fn show_prompt(&self, show: bool) -> crate::Result {
self.tx.send(Command::ShowPrompt(show))?;
Ok(())
}
pub fn follow_output(&self, follow_output: bool) -> crate::Result {
self.tx.send(Command::FollowOutput(follow_output))?;
Ok(())
}
}
impl Default for Pager {
fn default() -> Self {
Self::new()
}
}
impl fmt::Write for Pager {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.push_str(s).map_err(|_| fmt::Error)
}
}