Skip to content

Commit

Permalink
crate docs
Browse files Browse the repository at this point in the history
  • Loading branch information
ynqa committed Oct 21, 2023
1 parent fde119e commit 8185564
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 36 deletions.
54 changes: 44 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ promkit = "0.2.0"

## Examples

*promkit* provides presets so that users can utilize prompts immediately without having to build complex Components for specific use cases.
*promkit* provides presets so that users can utilize prompts immediately without
having to build complex Components for specific use cases.

```
cargo run --example readline
```

See [examples](https://github.com/ynqa/promkit/tree/main/examples/README.md) for more examples.
![readline](https://github.com/ynqa/promkit/assets/6745370/afa75a49-f84b-444f-88e3-3dabca959164)

See [examples](https://github.com/ynqa/promkit/tree/main/examples/README.md)
for more examples.

## Why *promkit*?

Expand All @@ -44,17 +48,33 @@ Similar libraries in this category include the following:

### Resilience to terminal resizing

Performing operations that involve executing a command in one pane while simultaneously opening a new pane is a common occurrence. During such operations, if UI corruption is caused by resizing the terminal size, it may adversely affect the user experience.
Other libraries can struggle when the terminal is resized, making typing and interaction difficult or impossible. For example:
Performing operations that involve executing a command in one pane while
simultaneously opening a new pane is a common occurrence. During such operations,
if UI corruption is caused by resizing the terminal size, it may adversely affect
the user experience.
Other libraries can struggle when the terminal is resized, making typing and
interaction difficult or impossible. For example:

- [(console-rs/dialoguer) Automatic re-render on terminal window resize](https://github.com/console-rs/dialoguer/issues/178)

*promkit* processes the data to fit the screen size, reducing the likelihood of rendering issues, such as misalignment. This approach ensures that UI elements remain consistent even when the terminal is resized, providing a smoother user experience.
*promkit* processes the data to fit the screen size, reducing the likelihood of
rendering issues, such as misalignment. This approach ensures that UI elements
remain consistent even when the terminal is resized, providing a smoother user
experience.

### Unified component approach

*promkit* takes a unified approach by having all of its components inherit the same `Component` trait. This design choice enables users to seamlessly support their custom data structures for display, similar to the relationships seen in TUI projects like [ratatui-org/ratatui](https://github.com/ratatui-org/ratatui) and [EdJoPaTo/tui-rs-tree-widget](https://github.com/EdJoPaTo/tui-rs-tree-widget). In other words, it's straightforward for anyone to display their own data structures using widgets within promkit.
In contrast, other libraries tend to treat each prompt as a mostly independent entity. If you want to display a new data structure, you often have to build the UI from scratch, which can be a time-consuming and less flexible process.
*promkit* takes a unified approach by having all of its components inherit the
same `Component` trait. This design choice enables users to seamlessly support
their custom data structures for display, similar to the relationships seen in
TUI projects like [ratatui-org/ratatui](https://github.com/ratatui-org/ratatui)
and
[EdJoPaTo/tui-rs-tree-widget](https://github.com/EdJoPaTo/tui-rs-tree-widget).
In other words, it's straightforward for anyone to display their own data
structures using widgets within promkit.
In contrast, other libraries tend to treat each prompt as a mostly independent
entity. If you want to display a new data structure, you often have to build the
UI from scratch, which can be a time-consuming and less flexible process.

```rust
pub trait Component {
Expand All @@ -64,9 +84,18 @@ In contrast, other libraries tend to treat each prompt as a mostly independent e
}
```

In the provided presets of *promkit*, this mechanism is implemented. If you'd like to try it out, you can refer to [the implementations of preset](https://github.com/ynqa/promkit/tree/dev-0.2.0/src/preset) for guidance.
In the provided presets of *promkit*, this mechanism is implemented. If you'd
like to try it out, you can refer to
[the implementations of preset](https://github.com/ynqa/promkit/tree/dev-0.2.0/src/preset)
for guidance.

In summary, *promkit*'s resilience to terminal resizing and its unified component approach make it a compelling choice for interactive command-line applications, especially when compared to [console-rs/dialoguer](https://github.com/console-rs/dialoguer) and [mikaelmello/inquire](https://github.com/mikaelmello/inquire/tree/main/inquire). These features provide a more reliable and extensible experience for developers, allowing them to focus on building powerful command-line interfaces.
In summary, *promkit*'s resilience to terminal resizing and its unified component
approach make it a compelling choice for interactive command-line applications,
especially when compared to
[console-rs/dialoguer](https://github.com/console-rs/dialoguer) and
[mikaelmello/inquire](https://github.com/mikaelmello/inquire/tree/main/inquire).
These features provide a more reliable and extensible experience for developers,
allowing them to focus on building powerful command-line interfaces.

## Concept

Expand All @@ -87,4 +116,9 @@ graph
end
```

When an event comes in, it is handled by the handler inside the `TextEditor` component. The handler then edits (e.g. insert character) `TextBuffer`. This `TextBuffer` is used to construct a `Pane`, which is essentially a matrix of lines divided by a specific width. The panes are extracted a certain number of lines in order to fit within the terminal screen when rendering. Finally, these Lines are passed to a `draw` function which renders them on the screen.
When an event comes in, it is handled by the handler inside the `TextEditor`
component. The handler then edits (e.g. insert character) `TextBuffer`.
This `TextBuffer` is used to construct a `Pane`, which is essentially a matrix of
lines divided by a specific width. The panes are extracted a certain number of
lines in order to fit within the terminal screen when rendering.
Finally, these Lines are passed to a `draw` function which renders them on the screen.
105 changes: 79 additions & 26 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! # promkit
//!
//! A toolkit for building your own interactive command-line tools in Rust,
//! utilizing [crossterm](https://github.com/crossterm-rs/crossterm).
//! [![.github/workflows/promkit.yml](https://github.com/ynqa/promkit/actions/workflows/promkit.yml/badge.svg)](https://github.com/ynqa/promkit/actions/workflows/promkit.yml)
//! [![docs.rs](https://img.shields.io/docsrs/promkit)](https://docs.rs/promkit)
//!
//! A toolkit for building your own interactive command-line tools in Rust.
//!
//! ## Getting Started
//!
Expand All @@ -12,37 +14,88 @@
//! promkit = "0.2.0"
//! ```
//!
//! ## Examples
//! ## Features
//!
//! Readline:
//! - Support cross-platform both UNIX and Windows owing to [crossterm](https://github.com/crossterm-rs/crossterm)
//! - Various building methods
//! - Support ranging from presets for easy use to layout building using `Component`s, and even for displaying your own data structures
//! - Versatile customization capabilities
//! - Themes for defining the outer shell style, including text and cursor colors
//! - Validation for user input and error message construction
//! - and so on...
//!
//! ## Examples
//!
//! ```ignore
//! use promkit::{build::Builder, readline, Result};
//! *promkit* provides presets so that users can utilize prompts immediately without
//! having to build complex Components for specific use cases.
//!
//! fn main() -> Result<()> {
//! let mut p = readline::Builder::default().build()?;
//! loop {
//! let line = p.run()?;
//! println!("result: {:?}", line);
//! }
//! }
//! ```bash
//! cargo run --example readline
//! ```
//!
//! Select:
//! ![readline](https://github.com/ynqa/promkit/assets/6745370/afa75a49-f84b-444f-88e3-3dabca959164)
//!
//! ```ignore
//! use promkit::{build::Builder, crossterm::style, select, Result};
//! See [examples](https://github.com/ynqa/promkit/tree/main/examples/README.md)
//! for more examples.
//!
//! fn main() -> Result<()> {
//! let mut p = select::Builder::new(0..100)
//! .title("Q: What number do you like?")
//! .title_color(style::Color::DarkGreen)
//! .build()?;
//! let line = p.run()?;
//! println!("result: {:?}", line);
//! Ok(())
//! }
//! ```
//! ## Why *promkit*?
//!
//! Similar libraries in this category include the following:
//! - [console-rs/dialoguer](https://github.com/console-rs/dialoguer)
//! - [mikaelmello/inquire](https://github.com/mikaelmello/inquire/tree/main/inquire)
//!
//! *promkit* offers several advantages over these libraries:
//!
//! ### Resilience to terminal resizing
//!
//! Performing operations that involve executing a command in one pane while
//! simultaneously opening a new pane is a common occurrence. During such operations,
//! if UI corruption is caused by resizing the terminal size, it may adversely affect
//! the user experience.
//! Other libraries can struggle when the terminal is resized, making typing and
//! interaction difficult or impossible. For example:
//!
//! - [(console-rs/dialoguer) Automatic re-render on terminal window resize](https://github.com/console-rs/dialoguer/issues/178)
//!
//! *promkit* processes the data to fit the screen size, reducing the likelihood of
//! rendering issues, such as misalignment. This approach ensures that UI elements
//! remain consistent even when the terminal is resized, providing a smoother user
//! experience.
//!
//! ### Unified component approach
//!
//! *promkit* takes a unified approach by having all of its components inherit the
//! same `Component` trait. This design choice enables users to seamlessly support
//! their custom data structures for display, similar to the relationships seen in
//! TUI projects like [ratatui-org/ratatui](https://github.com/ratatui-org/ratatui)
//! and
//! [EdJoPaTo/tui-rs-tree-widget](https://github.com/EdJoPaTo/tui-rs-tree-widget).
//! In other words, it's straightforward for anyone to display their own data
//! structures using widgets within promkit.
//! In contrast, other libraries tend to treat each prompt as a mostly independent
//! entity. If you want to display a new data structure, you often have to build the
//! UI from scratch, which can be a time-consuming and less flexible process.
//!
//! ```ignore
//! pub trait Component {
//! fn make_pane(&self, width: u16) -> Pane;
//! fn handle_event(&mut self, event: &Event);
//! fn postrun(&mut self);
//! }
//! ```
//!
//! In the provided presets of *promkit*, this mechanism is implemented. If you'd
//! like to try it out, you can refer to
//! [the implementations of preset](https://github.com/ynqa/promkit/tree/dev-0.2.0/src/preset)
//! for guidance.
//!
//! In summary, *promkit*'s resilience to terminal resizing and its unified component
//! approach make it a compelling choice for interactive command-line applications,
//! especially when compared to
//! [console-rs/dialoguer](https://github.com/console-rs/dialoguer) and
//! [mikaelmello/inquire](https://github.com/mikaelmello/inquire/tree/main/inquire).
//! These features provide a more reliable and extensible experience for developers,
//! allowing them to focus on building powerful command-line interfaces.
extern crate scopeguard;

Expand Down

0 comments on commit 8185564

Please sign in to comment.