-
Notifications
You must be signed in to change notification settings - Fork 11
Tree into structured #78
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
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
8a8bebb
chore: Row based implementations for tree-widgets
ynqa e5d10ea
chore: move tree widget into structured
ynqa 3590a52
chore: use RowOperation instead of definition
ynqa 61acd02
chore: define adapter for tree construction
ynqa 582557c
docs: tree
ynqa eb899c3
cargo fmt/clippy
ynqa 7143156
chore: create_rows into adapter
ynqa File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| use promkit_core::{Widget, grapheme::StyledGraphemes}; | ||
|
|
||
| mod document; | ||
| pub use document::Document; | ||
| pub mod config; | ||
| pub use config::Config; | ||
| pub mod path; | ||
| pub mod treez; | ||
| pub use treez::Row; | ||
|
|
||
| /// Represents the state of a tree structure within the application. | ||
| #[derive(Clone)] | ||
| pub struct State { | ||
| pub document: Document, | ||
| pub config: Config, | ||
| } | ||
|
|
||
| impl Widget for State { | ||
| fn create_graphemes(&self, _width: u16, height: u16) -> StyledGraphemes { | ||
| let symbol = |row: &Row| -> &str { | ||
| if row.has_children && !row.collapsed { | ||
| &self.config.unfolded_symbol | ||
| } else { | ||
| &self.config.folded_symbol | ||
| } | ||
| }; | ||
|
|
||
| let height = match self.config.lines { | ||
| Some(lines) => lines.min(height as usize), | ||
| None => height as usize, | ||
| }; | ||
|
|
||
| let rows = self.document.extract_rows_from_current(height); | ||
| let lines = rows.iter().enumerate().map(|(offset, row)| { | ||
| if offset == 0 { | ||
| StyledGraphemes::from_str( | ||
| format!( | ||
| "{}{}{}", | ||
| symbol(row), | ||
| " ".repeat(row.depth * self.config.indent), | ||
| row.id, | ||
| ), | ||
| self.config.active_item_style, | ||
| ) | ||
| } else { | ||
| StyledGraphemes::from_str( | ||
| format!( | ||
| "{}{}{}", | ||
| " ".repeat(StyledGraphemes::from(symbol(row)).widths()), | ||
| " ".repeat(row.depth * self.config.indent), | ||
| row.id, | ||
| ), | ||
| self.config.inactive_item_style, | ||
| ) | ||
| } | ||
| }); | ||
|
|
||
| StyledGraphemes::from_lines(lines) | ||
| } | ||
| } |
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| use crate::structured::RowOperation; | ||
|
|
||
| use super::{Row, path::PathAdapter, treez::Adapter}; | ||
|
|
||
| /// Represents a navigable tree document, allowing for efficient row navigation and folding. | ||
| #[derive(Clone)] | ||
| pub struct Document { | ||
| rows: Vec<Row>, | ||
| position: usize, | ||
| } | ||
|
|
||
| impl Document { | ||
| pub fn new(rows: Vec<Row>) -> Self { | ||
| Self { rows, position: 0 } | ||
| } | ||
|
|
||
| pub fn from_path(path: &std::path::Path) -> anyhow::Result<Self> { | ||
| Ok(Self::new(PathAdapter.create_rows(&path.to_path_buf())?)) | ||
| } | ||
| } | ||
|
|
||
| impl Document { | ||
| /// Returns a reference to the underlying vector of rows. | ||
| pub fn rows(&self) -> &[Row] { | ||
| &self.rows | ||
| } | ||
|
|
||
| /// Returns the selected tree path represented by visible row labels. | ||
| pub fn get(&self) -> Vec<String> { | ||
| self.rows | ||
| .get(self.position) | ||
| .map(|row| row.path.clone()) | ||
| .unwrap_or_default() | ||
| } | ||
|
|
||
| /// Extract rows from the current cursor position. | ||
| pub fn extract_rows_from_current(&self, n: usize) -> Vec<Row> { | ||
| self.rows.extract(self.position, n) | ||
| } | ||
|
|
||
| /// Toggles the visibility of a node at the cursor's current position. | ||
| pub fn toggle(&mut self) { | ||
| let index = self.rows.toggle(self.position); | ||
| self.position = index; | ||
| } | ||
|
|
||
| /// Sets the visibility of all rows. | ||
| pub fn set_nodes_visibility(&mut self, collapsed: bool) { | ||
| self.rows.set_rows_visibility(collapsed); | ||
| self.position = self.rows.head(); | ||
| } | ||
|
|
||
| /// Moves the cursor backward through rows. | ||
| pub fn up(&mut self) -> bool { | ||
| let index = self.rows.up(self.position); | ||
| let ret = index != self.position; | ||
| self.position = index; | ||
| ret | ||
| } | ||
|
|
||
| /// Moves the cursor to the head position. | ||
| pub fn head(&mut self) -> bool { | ||
| self.position = self.rows.head(); | ||
| true | ||
| } | ||
|
|
||
| /// Moves the cursor forward through rows. | ||
| pub fn down(&mut self) -> bool { | ||
| let index = self.rows.down(self.position); | ||
| let ret = index != self.position; | ||
| self.position = index; | ||
| ret | ||
| } | ||
|
|
||
| /// Moves the cursor to the last position. | ||
| pub fn tail(&mut self) -> bool { | ||
| self.position = self.rows.tail(); | ||
| true | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| use std::{fs, path}; | ||
|
|
||
| use super::treez::Adapter; | ||
|
|
||
| pub struct PathAdapter; | ||
|
|
||
| impl Adapter for PathAdapter { | ||
| type Node = path::PathBuf; | ||
| type Error = anyhow::Error; | ||
|
|
||
| fn id_of(&self, node: &Self::Node) -> Result<String, Self::Error> { | ||
| node.file_name() | ||
| .and_then(|name| name.to_str()) | ||
| .map(ToOwned::to_owned) | ||
| .or_else(|| { | ||
| let rendered = node.display().to_string(); | ||
| (!rendered.is_empty()).then_some(rendered) | ||
| }) | ||
| .ok_or_else(|| anyhow::anyhow!("Failed to convert path to string")) | ||
| } | ||
|
|
||
| fn children_of(&self, node: &Self::Node) -> Result<Vec<Self::Node>, Self::Error> { | ||
| if !node.is_dir() { | ||
| return Ok(Vec::new()); | ||
| } | ||
|
|
||
| let mut directories = Vec::new(); | ||
| let mut files = Vec::new(); | ||
|
|
||
| for entry in fs::read_dir(node)? { | ||
| let path = entry?.path(); | ||
| if path.is_dir() { | ||
| directories.push(path); | ||
| } else if path.is_file() { | ||
| files.push(path); | ||
| } | ||
| } | ||
|
|
||
| directories.sort_by(|a, b| a.file_name().cmp(&b.file_name())); | ||
| files.sort_by(|a, b| a.file_name().cmp(&b.file_name())); | ||
| directories.extend(files); | ||
|
|
||
| Ok(directories) | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the tree functionality moved under
structured, enabling thetreefeature no longer provides a top-levelpromkit_widgets::treemodule. This is a breaking public API change for downstream users. If backward compatibility is desired, consider adding apub use structured::tree as tree;(behind thetreefeature) or a small shim module re-exporting the previous public types.