Skip to content

Commit

Permalink
Merge pull request #23 from ynqa/promkit/v0.4.1/main
Browse files Browse the repository at this point in the history
(promkit) v0.4.1
  • Loading branch information
ynqa authored May 18, 2024
2 parents 069ff50 + 4322803 commit 9c2a931
Show file tree
Hide file tree
Showing 30 changed files with 791 additions and 708 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Put the package in your `Cargo.toml`.

```toml
[dependencies]
promkit = "0.4.0"
promkit = "0.4.1"
```

## Features
Expand Down
2 changes: 1 addition & 1 deletion promkit-async/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ anyhow = "1.0.81"
crossterm = { version = "0.27.0", features = ["use-dev-tty", "event-stream"] }
futures = "0.3.30"
futures-timer = "3.0.3"
promkit = { path = "../promkit", version = "0.4.0" }
promkit = "0.4.0"
tokio = { version = "1.36.0", features = ["full"] }
5 changes: 1 addition & 4 deletions promkit/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "promkit"
version = "0.4.0"
version = "0.4.1"
authors = ["ynqa <[email protected]>"]
edition = "2021"
description = "A toolkit for building your own interactive command-line tools"
Expand All @@ -20,6 +20,3 @@ radix_trie = "0.2.1"
serde = { version = "1.0.197" }
serde_json = { version = "1.0.114", features = ["preserve_order"] }
unicode-width = "0.1.8"

[dev-dependencies]
strip-ansi-escapes = "0.2.0"
18 changes: 9 additions & 9 deletions promkit/src/core/checkbox.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{collections::HashSet, fmt, iter::FromIterator};

use crate::core::listbox::Listbox;
use crate::{core::listbox::Listbox, grapheme::StyledGraphemes};

mod state;
pub use state::State;
Expand Down Expand Up @@ -67,7 +67,7 @@ impl Checkbox {
}

/// Returns a reference to the vector of items in the listbox.
pub fn items(&self) -> &Vec<String> {
pub fn items(&self) -> &Vec<StyledGraphemes> {
self.listbox.items()
}

Expand All @@ -82,10 +82,10 @@ impl Checkbox {
}

/// Retrieves the items at the picked (selected) indices as a vector of strings.
pub fn get(&self) -> Vec<String> {
pub fn get(&self) -> Vec<StyledGraphemes> {
self.picked
.iter()
.fold(Vec::<String>::new(), |mut ret, idx| {
.fold(Vec::<StyledGraphemes>::new(), |mut ret, idx| {
ret.push(self.listbox.items().get(*idx).unwrap().to_owned());
ret
})
Expand Down Expand Up @@ -121,10 +121,6 @@ impl Checkbox {
pub fn move_to_tail(&mut self) {
self.listbox.move_to_tail()
}

pub fn viewport_range(&self, height: usize) -> (usize, usize) {
self.listbox.viewport_range(height)
}
}

#[cfg(test)]
Expand All @@ -149,7 +145,11 @@ mod tests {
// Verify the items in the listbox
assert_eq!(
checkbox.items(),
&vec!["1".to_string(), "2".to_string(), "3".to_string()]
&vec![
StyledGraphemes::from("1"),
StyledGraphemes::from("2"),
StyledGraphemes::from("3"),
]
);

// Verify the picked (selected) indices
Expand Down
53 changes: 24 additions & 29 deletions promkit/src/core/checkbox/state.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
use crate::{
crossterm::style::ContentStyle,
grapheme::{trim, Graphemes, StyledGraphemes},
pane::Pane,
PaneFactory,
};
use crate::{crossterm::style::ContentStyle, grapheme::StyledGraphemes, pane::Pane, PaneFactory};

use super::Checkbox;

Expand Down Expand Up @@ -37,11 +32,11 @@ pub struct State {

impl PaneFactory for State {
fn create_pane(&self, width: u16, height: u16) -> Pane {
let f = |idx: usize, item: &String| -> String {
let f = |idx: usize| -> StyledGraphemes {
if self.checkbox.picked_indexes().contains(&idx) {
format!("{} {}", self.active_mark, item)
StyledGraphemes::from(format!("{} ", self.active_mark))
} else {
format!("{} {}", self.inactive_mark, item)
StyledGraphemes::from(format!("{} ", self.inactive_mark))
}
};

Expand All @@ -50,37 +45,37 @@ impl PaneFactory for State {
None => height as usize,
};

let viewport = self.checkbox.viewport_range(height);

let relative_position = self.checkbox.position().saturating_sub(viewport.0);

let matrix = self
.checkbox
.items()
.iter()
.enumerate()
.filter(|(i, _)| *i >= viewport.0 && *i < viewport.1)
.filter(|(i, _)| {
*i >= self.checkbox.position() && *i < self.checkbox.position() + height
})
.map(|(i, item)| {
if i == self.checkbox.position() {
StyledGraphemes::from_str(
format!("{}{}", self.cursor, f(i, item)),
self.active_item_style,
)
StyledGraphemes::from_iter([&StyledGraphemes::from(&self.cursor), &f(i), item])
.apply_style(self.active_item_style)
} else {
StyledGraphemes::from_str(
format!(
"{}{}",
" ".repeat(Graphemes::from(self.cursor.clone()).widths()),
f(i, item)
StyledGraphemes::from_iter([
&StyledGraphemes::from(
" ".repeat(StyledGraphemes::from(&self.cursor).widths()),
),
self.inactive_item_style,
)
&f(i),
item,
])
.apply_style(self.inactive_item_style)
}
})
.collect::<Vec<StyledGraphemes>>();

let trimed = matrix.iter().map(|row| trim(width as usize, row)).collect();
.fold((vec![], 0), |(mut acc, pos), item| {
let rows = item.matrixify(width as usize, height, 0).0;
if pos < self.checkbox.position() + height {
acc.extend(rows);
}
(acc, pos + 1)
});

Pane::new(trimed, relative_position)
Pane::new(matrix.0, 0)
}
}
44 changes: 3 additions & 41 deletions promkit/src/core/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,14 @@ impl<C: Len> Cursor<C> {
false
}
}

pub fn viewport_range(&self, height: usize) -> (usize, usize) {
let end = std::cmp::min(self.position + height, self.contents.len());
let start = if end > height { end - height } else { 0 };
(start, end)
}
}

#[cfg(test)]
mod test {
use super::*;

mod shift {
use super::super::*;
use super::*;

#[test]
fn test_cyclic_forward() {
Expand Down Expand Up @@ -175,7 +169,7 @@ mod test {
}

mod backward {
use super::super::*;
use super::*;

#[test]
fn test() {
Expand All @@ -187,7 +181,7 @@ mod test {
}

mod forward {
use super::super::*;
use super::*;

#[test]
fn test() {
Expand All @@ -197,36 +191,4 @@ mod test {
assert!(!b.forward());
}
}

mod viewport_range {
use super::*;

#[test]
fn test_within_bounds() {
let cursor = Cursor::new(vec![1, 2, 3, 4, 5], 2, false);
let (start, end) = cursor.viewport_range(2);
assert_eq!((start, end), (2, 4));
}

#[test]
fn test_at_start() {
let cursor = Cursor::new(vec![1, 2, 3, 4, 5], 0, false);
let (start, end) = cursor.viewport_range(3);
assert_eq!((start, end), (0, 3));
}

#[test]
fn test_at_end() {
let cursor = Cursor::new(vec![1, 2, 3, 4, 5], 4, false);
let (start, end) = cursor.viewport_range(2);
assert_eq!((start, end), (3, 5));
}

#[test]
fn test_exceeds_bounds() {
let cursor = Cursor::new(vec![1, 2, 3, 4, 5], 3, false);
let (start, end) = cursor.viewport_range(5);
assert_eq!((start, end), (0, 5));
}
}
}
39 changes: 0 additions & 39 deletions promkit/src/core/cursor/composite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,6 @@ impl<C: Len> CompositeCursor<C> {
self.cross_contents_position = total_len.saturating_sub(1);
}
}

pub fn viewport_range(&self, height: usize) -> (usize, usize) {
let total_len: usize = self.bundle.iter().map(|c| c.len()).sum();
let end = std::cmp::min(self.cross_contents_position + height, total_len);
let start = if end > height { end - height } else { 0 };
(start, end)
}
}

#[cfg(test)]
Expand Down Expand Up @@ -146,36 +139,4 @@ mod tests {
assert_eq!(cursor.cross_contents_position(), 2);
}
}

mod viewport_range {
use super::*;

#[test]
fn test_viewport_range_within_bounds() {
let cursor = CompositeCursor::new(vec![vec![1, 2], vec![3, 4, 5]], 2);
let (start, end) = cursor.viewport_range(2);
assert_eq!((start, end), (2, 4));
}

#[test]
fn test_viewport_range_at_start() {
let cursor = CompositeCursor::new(vec![vec![1, 2], vec![3, 4, 5]], 0);
let (start, end) = cursor.viewport_range(2);
assert_eq!((start, end), (0, 2));
}

#[test]
fn test_viewport_range_at_end() {
let cursor = CompositeCursor::new(vec![vec![1, 2], vec![3, 4, 5]], 4);
let (start, end) = cursor.viewport_range(2);
assert_eq!((start, end), (3, 5));
}

#[test]
fn test_viewport_range_exceeds_total_length() {
let cursor = CompositeCursor::new(vec![vec![1, 2], vec![3, 4, 5]], 1);
let (start, end) = cursor.viewport_range(10);
assert_eq!((start, end), (0, 5));
}
}
}
4 changes: 2 additions & 2 deletions promkit/src/core/cursor/len.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::VecDeque;

use crate::grapheme::Graphemes;
use crate::grapheme::StyledGraphemes;

/// Defines a `Len` trait for obtaining the length of a collection
/// and checking if it is empty.
Expand Down Expand Up @@ -51,7 +51,7 @@ impl Len for String {
}
}

impl Len for Graphemes {
impl Len for StyledGraphemes {
/// Returns the number of `Grapheme` instances in the collection.
fn len(&self) -> usize {
self.0.len()
Expand Down
6 changes: 1 addition & 5 deletions promkit/src/core/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::core::cursor::CompositeCursor;
mod node;
pub use node::{JsonNode, JsonPath, JsonPathSegment, JsonSyntaxKind};
mod state;
pub use state::{State, Theme};
pub use state::State;

/// Represents a stream of JSON data, allowing for efficient navigation and manipulation.
///
Expand Down Expand Up @@ -166,8 +166,4 @@ impl JsonStream {
pub fn move_to_tail(&mut self) {
self.cursor.move_to_tail()
}

pub fn viewport_range(&self, height: usize) -> (usize, usize) {
self.cursor.viewport_range(height)
}
}
Loading

0 comments on commit 9c2a931

Please sign in to comment.