zellij/default-plugins/strider/src/shared.rs
Aram Drevekenin ee16a4b8c3
feat(plugins): session manager cwd and new filepicker (#3200)
* prototype

* folder selection ui in session manager

* overhaul strider

* scan folder host command

* get strider to work from the cli and some cli pipe fixes

* some ux improvements to strider

* improve strider's ui

* make strider ui responsive

* make session-manager new ui parts responsive

* fix tests

* style(fmt): rustfmt
2024-03-18 09:19:58 +01:00

156 lines
5.5 KiB
Rust

use std::path::PathBuf;
use unicode_width::UnicodeWidthStr;
use zellij_tile::prelude::*;
pub fn render_instruction_line(y: usize, max_cols: usize) {
if max_cols > 78 {
let text = "Help: go back with <Ctrl c>, go to root with /, <Ctrl e> - toggle hidden files";
let text = Text::new(text)
.color_range(3, 19..27)
.color_range(3, 45..46)
.color_range(3, 48..56);
print_text_with_coordinates(text, 0, y, Some(max_cols), None);
} else if max_cols > 56 {
let text = "Help: <Ctrl c> - back, / - root, <Ctrl e> - hidden files";
let text = Text::new(text)
.color_range(3, 6..14)
.color_range(3, 23..24)
.color_range(3, 33..41);
print_text_with_coordinates(text, 0, y, Some(max_cols), None);
} else if max_cols > 25 {
let text = "<Ctrl c> - back, / - root";
let text = Text::new(text).color_range(3, ..8).color_range(3, 17..18);
print_text_with_coordinates(text, 0, y, Some(max_cols), None);
}
}
pub fn render_list_tip(y: usize, max_cols: usize) {
let tip = Text::new(format!("(<↓↑> - Navigate, <TAB> - Select)"))
.color_range(3, 1..5)
.color_range(3, 18..23);
print_text_with_coordinates(tip, 0, y, Some(max_cols), None);
}
// returns the list (start_index, selected_index_in_range, end_index)
pub fn calculate_list_bounds(
result_count: usize,
max_result_count: usize,
selected_index_in_all_results: Option<usize>,
) -> (usize, Option<usize>, usize) {
match selected_index_in_all_results {
Some(selected_index_in_all_results) => {
let mut room_in_list = max_result_count;
let mut start_index = selected_index_in_all_results;
let mut end_index = selected_index_in_all_results + 1;
let mut alternate = false;
loop {
if room_in_list == 0 {
break;
}
if !alternate && start_index > 0 {
start_index -= 1;
room_in_list -= 1;
} else if alternate && end_index < result_count {
end_index += 1;
room_in_list -= 1;
} else if start_index > 0 {
start_index -= 1;
room_in_list -= 1;
} else if end_index < result_count {
end_index += 1;
room_in_list -= 1;
} else {
break;
}
alternate = !alternate;
}
(start_index, Some(selected_index_in_all_results), end_index)
},
None => (0, None, max_result_count + 1),
}
}
pub fn render_search_term(search_term: &str) {
let prompt = "FIND: ";
let text = Text::new(format!("{}{}_", prompt, search_term))
.color_range(2, 0..prompt.len())
.color_range(3, prompt.len()..);
print_text(text);
println!("")
}
pub fn render_current_path(
initial_cwd: &PathBuf,
path: &PathBuf,
path_is_dir: bool,
handling_filepick: bool,
max_cols: usize,
) {
let prompt = "PATH: ";
let current_path = initial_cwd.join(path);
let current_path = current_path.display().to_string();
let prompt_len = prompt.width();
let current_path_len = current_path.width();
let enter_tip = if handling_filepick {
"Select"
} else if path_is_dir {
"Open terminal here"
} else {
"Open in editor"
};
if max_cols > prompt_len + current_path_len + enter_tip.width() + 13 {
let path_end = prompt_len + current_path_len;
let current_path = Text::new(format!(
"{}{} (<ENTER> - {})",
prompt, current_path, enter_tip
))
.color_range(2, 0..prompt_len)
.color_range(0, prompt_len..path_end)
.color_range(3, path_end + 2..path_end + 9);
print_text(current_path);
} else {
let max_path_len = max_cols
.saturating_sub(prompt_len)
.saturating_sub(8)
.saturating_sub(prompt_len);
let current_path = if current_path_len <= max_path_len {
current_path
} else {
truncate_path(
initial_cwd.join(path),
current_path_len.saturating_sub(max_path_len),
)
};
let current_path_len = current_path.width();
let path_end = prompt_len + current_path_len;
let current_path = Text::new(format!("{}{} <ENTER>", prompt, current_path))
.color_range(2, 0..prompt_len)
.color_range(0, prompt_len..path_end)
.color_range(3, path_end + 1..path_end + 9);
print_text(current_path);
}
println!();
println!();
}
fn truncate_path(path: PathBuf, mut char_count_to_remove: usize) -> String {
let mut truncated = String::new();
let component_count = path.iter().count();
for (i, component) in path.iter().enumerate() {
let mut component_str = component.to_string_lossy().to_string();
if char_count_to_remove > 0 {
truncated.push(component_str.remove(0));
if i != 0 && i + 1 != component_count {
truncated.push('/');
}
char_count_to_remove = char_count_to_remove.saturating_sub(component_str.width() + 1);
} else {
truncated.push_str(&component_str);
if i != 0 && i + 1 != component_count {
truncated.push('/');
}
}
}
truncated
}