Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom writer #36

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions promkit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,13 @@ pub trait Renderer: Finalizer {
/// event handling, and result production for a prompt.
pub struct Prompt<T: Renderer> {
pub renderer: T,
pub writer: Box<dyn io::Write>,
}

impl<T: Renderer> Drop for Prompt<T> {
fn drop(&mut self) {
execute!(
io::stdout(),
self.writer,
cursor::Show,
event::DisableMouseCapture,
cursor::MoveToNextLine(1),
Expand All @@ -250,23 +251,19 @@ impl<T: Renderer> Prompt<T> {
/// Returns a `Result` containing the produced result or an error.
pub fn run(&mut self) -> anyhow::Result<T::Return> {
enable_raw_mode()?;
execute!(io::stdout(), cursor::Hide)?;
execute!(self.writer, cursor::Hide)?;

let size = crossterm::terminal::size()?;
let panes = self.renderer.create_panes(size.0, size.1);
let mut terminal = Terminal::start_session(&panes)?;
let mut terminal = Terminal::start_session(&panes, &mut self.writer)?;
terminal.draw(&panes)?;

loop {
let ev = event::read()?;

match &ev {
Event::Resize(_, _) => {
terminal.position = (0, 0);
crossterm::execute!(
io::stdout(),
crossterm::terminal::Clear(crossterm::terminal::ClearType::Purge),
)?;
terminal.on_resize()?;
}
_ => {
if self.renderer.evaluate(&ev)? == PromptSignal::Quit {
Expand Down
13 changes: 12 additions & 1 deletion promkit/src/preset/checkbox.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{cell::RefCell, fmt::Display};
use std::{cell::RefCell, fmt::Display, io};

use crate::{
checkbox,
Expand All @@ -20,6 +20,8 @@ pub struct Checkbox {
title_state: text::State,
/// State for the checkbox list itself.
checkbox_state: checkbox::State,
/// Writer to which promptkit write its contents
writer: Box<dyn io::Write>,
}

impl Checkbox {
Expand Down Expand Up @@ -48,6 +50,7 @@ impl Checkbox {
lines: Default::default(),
},
keymap: ActiveKeySwitcher::new("default", self::keymap::default),
writer: Box::new(io::stdout()),
}
}

Expand All @@ -69,6 +72,7 @@ impl Checkbox {
lines: Default::default(),
},
keymap: ActiveKeySwitcher::new("default", self::keymap::default),
writer: Box::new(io::stdout()),
}
}

Expand Down Expand Up @@ -119,6 +123,12 @@ impl Checkbox {
self
}

/// Sets writer.
pub fn writer<W: io::Write + 'static>(mut self, writer: W) -> Self {
self.writer = Box::new(writer);
self
}

/// Displays the checkbox prompt and waits for user input.
/// Returns a `Result` containing the `Prompt` result,
/// which is a list of selected options.
Expand All @@ -129,6 +139,7 @@ impl Checkbox {
title_snapshot: Snapshot::<text::State>::new(self.title_state),
checkbox_snapshot: Snapshot::<checkbox::State>::new(self.checkbox_state),
},
writer: self.writer,
})
}
}
16 changes: 14 additions & 2 deletions promkit/src/preset/form.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::cell::RefCell;
use std::{cell::RefCell, io};

use crate::{
core::Cursor,
Expand All @@ -17,6 +17,8 @@ pub struct Form {
text_editor_states: Vec<text_editor::State>,
/// Overwrite the default styles of text editor states when unselected.
overwrite_styles: Vec<render::Style>,
/// Writer to which promptkit write its contents
writer: Box<dyn io::Write>,
}

impl Form {
Expand All @@ -42,9 +44,16 @@ impl Form {
keymap: ActiveKeySwitcher::new("default", self::keymap::default as keymap::Keymap),
text_editor_states,
overwrite_styles,
writer: Box::new(io::stdout()),
}
}

/// Sets writer.
pub fn writer<W: io::Write + 'static>(mut self, writer: W) -> Self {
self.writer = Box::new(writer);
self
}

pub fn prompt(self) -> anyhow::Result<Prompt<render::Renderer>> {
let default_styles = self
.text_editor_states
Expand All @@ -62,6 +71,9 @@ impl Form {
overwrite_styles: self.overwrite_styles,
};
renderer.overwrite_styles();
Ok(Prompt { renderer })
Ok(Prompt {
renderer,
writer: self.writer,
})
}
}
12 changes: 11 additions & 1 deletion promkit/src/preset/json.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::cell::RefCell;
use std::{cell::RefCell, io};

use crate::{
crossterm::style::{Attribute, Attributes, Color, ContentStyle},
Expand All @@ -17,6 +17,8 @@ pub struct Json {
keymap: ActiveKeySwitcher<keymap::Keymap>,
title_state: text::State,
json_state: json::State,
/// Writer to which promptkit write its contents
writer: Box<dyn io::Write>,
}

impl Json {
Expand Down Expand Up @@ -47,6 +49,7 @@ impl Json {
indent: 2,
},
keymap: ActiveKeySwitcher::new("default", self::keymap::default),
writer: Box::new(io::stdout()),
}
}

Expand Down Expand Up @@ -91,6 +94,12 @@ impl Json {
self
}

/// Sets writer.
pub fn writer<W: io::Write + 'static>(mut self, writer: W) -> Self {
self.writer = Box::new(writer);
self
}

/// Creates a prompt based on the current configuration of the `Json` instance.
pub fn prompt(self) -> anyhow::Result<Prompt<render::Renderer>> {
Ok(Prompt {
Expand All @@ -99,6 +108,7 @@ impl Json {
title_snapshot: Snapshot::<text::State>::new(self.title_state),
json_snapshot: Snapshot::<json::State>::new(self.json_state),
},
writer: self.writer,
})
}
}
12 changes: 11 additions & 1 deletion promkit/src/preset/listbox.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{cell::RefCell, fmt::Display};
use std::{cell::RefCell, fmt::Display, io};

use crate::{
crossterm::style::{Attribute, Attributes, Color, ContentStyle},
Expand All @@ -19,6 +19,8 @@ pub struct Listbox {
title_state: text::State,
/// State for the selectable list itself.
listbox_state: listbox::State,
/// Writer to which promptkit write its contents
writer: Box<dyn io::Write>,
}

impl Listbox {
Expand All @@ -45,6 +47,7 @@ impl Listbox {
lines: Default::default(),
},
keymap: ActiveKeySwitcher::new("default", self::keymap::default),
writer: Box::new(io::stdout()),
}
}

Expand Down Expand Up @@ -89,6 +92,12 @@ impl Listbox {
self
}

/// Sets writer.
pub fn writer<W: io::Write + 'static>(mut self, writer: W) -> Self {
self.writer = Box::new(writer);
self
}

/// Displays the select prompt and waits for user input.
/// Returns a `Result` containing the `Prompt` result,
/// which is the selected option.
Expand All @@ -99,6 +108,7 @@ impl Listbox {
title_snapshot: Snapshot::<text::State>::new(self.title_state),
listbox_snapshot: Snapshot::<listbox::State>::new(self.listbox_state),
},
writer: self.writer,
})
}
}
12 changes: 11 additions & 1 deletion promkit/src/preset/query_selector.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{cell::RefCell, fmt::Display};
use std::{cell::RefCell, fmt::Display, io};

use crate::{
crossterm::style::{Attribute, Attributes, Color, ContentStyle},
Expand Down Expand Up @@ -28,6 +28,8 @@ pub struct QuerySelector {
/// A filter function to apply to the list box items
/// based on the text editor input.
filter: render::Filter,
/// Writer to which promptkit write its contents
writer: Box<dyn io::Write>,
}

impl QuerySelector {
Expand Down Expand Up @@ -74,6 +76,7 @@ impl QuerySelector {
},
keymap: ActiveKeySwitcher::new("default", self::keymap::default),
filter,
writer: Box::new(io::stdout()),
}
}

Expand Down Expand Up @@ -154,6 +157,12 @@ impl QuerySelector {
self
}

/// Sets writer.
pub fn writer<W: io::Write + 'static>(mut self, writer: W) -> Self {
self.writer = Box::new(writer);
self
}

/// Displays the query select prompt and waits for user input.
/// Returns a `Result` containing the `Prompt` result,
/// which is the selected option.
Expand All @@ -166,6 +175,7 @@ impl QuerySelector {
listbox_snapshot: Snapshot::<listbox::State>::new(self.listbox_state),
filter: self.filter,
},
writer: self.writer,
})
}
}
12 changes: 11 additions & 1 deletion promkit/src/preset/readline.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{cell::RefCell, collections::HashSet};
use std::{cell::RefCell, collections::HashSet, io};

use crate::{
crossterm::style::{Attribute, Attributes, Color, ContentStyle},
Expand Down Expand Up @@ -34,6 +34,8 @@ pub struct Readline {
validator: Option<ValidatorManager<str>>,
/// State for displaying error messages based on input validation.
error_message_state: text::State,
/// Writer to which promptkit write its contents
writer: Box<dyn io::Write>,
}

impl Default for Readline {
Expand Down Expand Up @@ -80,6 +82,7 @@ impl Default for Readline {
.attrs(Attributes::from(Attribute::Bold))
.build(),
},
writer: Box::new(io::stdout()),
}
}
}
Expand Down Expand Up @@ -172,6 +175,12 @@ impl Readline {
self
}

/// Sets writer.
pub fn writer<W: io::Write + 'static>(mut self, writer: W) -> Self {
self.writer = Box::new(writer);
self
}

/// Initiates the prompt process,
/// displaying the configured UI elements and handling user input.
pub fn prompt(self) -> anyhow::Result<Prompt<render::Renderer>> {
Expand All @@ -185,6 +194,7 @@ impl Readline {
validator: self.validator,
error_message_snapshot: Snapshot::<text::State>::new(self.error_message_state),
},
writer: self.writer,
})
}
}
12 changes: 11 additions & 1 deletion promkit/src/preset/tree.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::cell::RefCell;
use std::{cell::RefCell, io};

use crate::{
crossterm::style::{Attribute, Attributes, Color, ContentStyle},
Expand All @@ -21,6 +21,8 @@ pub struct Tree {
title_state: text::State,
/// State for the tree itself.
tree_state: tree::State,
/// Writer to which promptkit write its contents
writer: Box<dyn io::Write>,
}

impl Tree {
Expand All @@ -47,6 +49,7 @@ impl Tree {
lines: Default::default(),
indent: 2,
},
writer: Box::new(io::stdout()),
}
}

Expand Down Expand Up @@ -103,6 +106,12 @@ impl Tree {
self
}

/// Sets writer.
pub fn writer<W: io::Write + 'static>(mut self, writer: W) -> Self {
self.writer = Box::new(writer);
self
}

/// Displays the tree prompt and waits for user input.
/// Returns a `Result` containing the `Prompt` result,
/// which is a list of selected options.
Expand All @@ -113,6 +122,7 @@ impl Tree {
title_snapshot: Snapshot::<text::State>::new(self.title_state),
tree_snapshot: Snapshot::<tree::State>::new(self.tree_state),
},
writer: self.writer,
})
}
}
Loading