zellij/default-plugins/strider/src/state.rs
Aram Drevekenin 1bedfc9002
feat(plugins): use protocol buffers for serializing across the wasm boundary (#2686)
* work

* almost done with command protobuffers

* done translating command data structures

* mid transferring of every command to protobuff command

* transferred plugin_command.rs, now moving on to shim.rs

* plugin command working with protobufs

* protobuffers in update

* protobuf event tests

* various TODOs and comments

* fix zellij-tile

* clean up prost deps

* remove version mismatch error

* fix panic

* some cleanups

* clean up event protobuffers

* clean up command protobuffers

* clean up various protobufs

* refactor protobufs

* update comments

* some transformation fixes

* use protobufs for workers

* style(fmt): rustfmt

* style(fmt): rustfmt

* chore(build): add protoc

* chore(build): authenticate protoc
2023-08-09 22:26:00 +02:00

132 lines
4.1 KiB
Rust

use crate::search::search_results::SearchResult;
use crate::search::search_state::SearchState;
use crate::search::search_state::SearchType;
use pretty_bytes::converter as pb;
use std::{
collections::{HashMap, VecDeque},
fs::read_dir,
path::{Path, PathBuf},
time::Instant,
};
use zellij_tile::prelude::*;
pub const ROOT: &str = "/host";
pub const CURRENT_SEARCH_TERM: &str = "/data/current_search_term";
#[derive(Default)]
pub struct State {
pub path: PathBuf,
pub files: Vec<FsEntry>,
pub cursor_hist: HashMap<PathBuf, (usize, usize)>,
pub hide_hidden_files: bool,
pub ev_history: VecDeque<(Event, Instant)>, // stores last event, can be expanded in future
pub search_state: SearchState,
pub search_paths: Vec<String>,
pub search_term: Option<String>,
pub file_name_search_results: Vec<SearchResult>,
pub file_contents_search_results: Vec<SearchResult>,
pub loading: bool,
pub loading_animation_offset: u8,
pub typing_search_term: bool,
pub selected_search_result: usize,
pub processed_search_index: usize,
pub should_open_floating: bool,
pub search_filter: SearchType,
}
impl State {
pub fn typing_search_term(&self) -> bool {
self.typing_search_term
}
pub fn start_typing_search_term(&mut self) {
self.typing_search_term = true;
}
pub fn stop_typing_search_term(&mut self) {
self.typing_search_term = false;
}
pub fn selected_mut(&mut self) -> &mut usize {
&mut self.cursor_hist.entry(self.path.clone()).or_default().0
}
pub fn selected(&self) -> usize {
self.cursor_hist.get(&self.path).unwrap_or(&(0, 0)).0
}
pub fn scroll_mut(&mut self) -> &mut usize {
&mut self.cursor_hist.entry(self.path.clone()).or_default().1
}
pub fn scroll(&self) -> usize {
self.cursor_hist.get(&self.path).unwrap_or(&(0, 0)).1
}
pub fn toggle_hidden_files(&mut self) {
self.hide_hidden_files = !self.hide_hidden_files;
}
pub fn traverse_dir_or_open_file(&mut self) {
if let Some(f) = self.files.get(self.selected()) {
match f.clone() {
FsEntry::Dir(p, _) => {
self.path = p;
refresh_directory(self);
},
FsEntry::File(p, _) => open_file(FileToOpen {
path: p.strip_prefix(ROOT).unwrap().into(),
..Default::default()
}),
}
}
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum FsEntry {
Dir(PathBuf, usize),
File(PathBuf, u64),
}
impl FsEntry {
pub fn name(&self) -> String {
let path = match self {
FsEntry::Dir(p, _) => p,
FsEntry::File(p, _) => p,
};
path.file_name().unwrap().to_string_lossy().into_owned()
}
pub fn as_line(&self, width: usize) -> String {
let info = match self {
FsEntry::Dir(_, s) => s.to_string(),
FsEntry::File(_, s) => pb::convert(*s as f64),
};
let space = width.saturating_sub(info.len());
let name = self.name();
if space.saturating_sub(1) < name.len() {
[&name[..space.saturating_sub(2)], &info].join("~ ")
} else {
let padding = " ".repeat(space - name.len());
[name, padding, info].concat()
}
}
pub fn is_hidden_file(&self) -> bool {
self.name().starts_with('.')
}
}
pub(crate) fn refresh_directory(state: &mut State) {
state.files = read_dir(Path::new(ROOT).join(&state.path))
.unwrap()
.filter_map(|res| {
res.and_then(|d| {
if d.metadata()?.is_dir() {
let children = read_dir(d.path())?.count();
Ok(FsEntry::Dir(d.path(), children))
} else {
let size = d.metadata()?.len();
Ok(FsEntry::File(d.path(), size))
}
})
.ok()
.filter(|d| !d.is_hidden_file() || !state.hide_hidden_files)
})
.collect();
state.files.sort_unstable();
}