From afd054909617320ad8b4a4bf7c9a386c385125b4 Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Wed, 27 Mar 2024 18:35:00 +0100 Subject: [PATCH 1/4] remove fs watch --- src/backend_workers.rs | 47 ++------------------------------------ src/main.rs | 51 ------------------------------------------ 2 files changed, 2 insertions(+), 96 deletions(-) diff --git a/src/backend_workers.rs b/src/backend_workers.rs index 55e0229..ce7cd81 100644 --- a/src/backend_workers.rs +++ b/src/backend_workers.rs @@ -6,7 +6,7 @@ use ignore::Walk; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, BTreeSet, HashMap}; use std::io::{self, BufRead}; -use std::path::{Path, PathBuf}; +use std::path::Path; use unicode_width::UnicodeWidthStr; use crate::search_results::{ResultsOfSearch, SearchResult}; @@ -30,7 +30,7 @@ impl Search { ..Default::default() } } - fn on_message(&mut self, message: String, payload: String) { + fn on_message(&mut self, message: String, _payload: String) { match serde_json::from_str::(&message) { Ok(MessageToSearch::ScanFolder) => { self.scan_hd(); @@ -44,15 +44,6 @@ impl Search { self.search(current_search_term); } } - Ok(MessageToSearch::FileSystemCreate) => { - self.rescan_files(payload); - } - Ok(MessageToSearch::FileSystemUpdate) => { - self.rescan_files(payload); - } - Ok(MessageToSearch::FileSystemDelete) => { - self.delete_files(payload); - } Err(e) => eprintln!("Failed to deserialize worker message {:?}", e), } } @@ -119,28 +110,6 @@ impl Search { )); } } - pub fn rescan_files(&mut self, paths: String) { - match serde_json::from_str::>(&paths) { - Ok(paths) => { - for path in paths { - self.add_file_entry(&path, path.metadata().ok()); - } - self.cached_file_name_results.clear(); - self.cached_file_contents_results.clear(); - } - Err(e) => eprintln!("Failed to deserialize paths: {:?}", e), - } - } - pub fn delete_files(&mut self, paths: String) { - match serde_json::from_str::>(&paths) { - Ok(paths) => { - self.remove_existing_entries(&paths); - self.cached_file_name_results.clear(); - self.cached_file_contents_results.clear(); - } - Err(e) => eprintln!("Failed to deserialize paths: {:?}", e), - } - } fn add_file_entry(&mut self, file_name: &Path, file_metadata: Option) { let file_path = file_name.display().to_string(); let file_path_stripped_prefix = self.strip_file_prefix(&file_name); @@ -226,24 +195,12 @@ impl Search { _ => None, } } - fn remove_existing_entries(&mut self, paths: &Vec) { - let file_path_stripped_prefixes: Vec = - paths.iter().map(|p| self.strip_file_prefix(&p)).collect(); - self.file_names - .retain(|file_name| !file_path_stripped_prefixes.contains(file_name)); - self.file_contents.retain(|(file_name, _line_in_file), _| { - !file_path_stripped_prefixes.contains(file_name) - }); - } } #[derive(Serialize, Deserialize)] pub enum MessageToSearch { ScanFolder, Search, - FileSystemCreate, - FileSystemUpdate, - FileSystemDelete, } #[derive(Serialize, Deserialize)] diff --git a/src/main.rs b/src/main.rs index f894ed2..9727c05 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,9 +50,6 @@ impl ZellijPlugin for State { EventType::Mouse, EventType::CustomMessage, EventType::Timer, - EventType::FileSystemCreate, - EventType::FileSystemUpdate, - EventType::FileSystemDelete, ]); post_message_to(PluginMessage::new_to_worker( "file_name_search", @@ -103,54 +100,6 @@ impl ZellijPlugin for State { self.handle_key(key); should_render = true; } - Event::FileSystemCreate(paths) => { - let paths: Vec = paths - .iter() - .map(|p| p.to_string_lossy().to_string()) - .collect(); - post_message_to(PluginMessage::new_to_worker( - "file_name_search", - &serde_json::to_string(&MessageToSearch::FileSystemCreate).unwrap(), - &serde_json::to_string(&paths).unwrap(), - )); - post_message_to(PluginMessage::new_to_worker( - "file_contents_search", - &serde_json::to_string(&MessageToSearch::FileSystemCreate).unwrap(), - &serde_json::to_string(&paths).unwrap(), - )); - } - Event::FileSystemUpdate(paths) => { - let paths: Vec = paths - .iter() - .map(|p| p.to_string_lossy().to_string()) - .collect(); - post_message_to(PluginMessage::new_to_worker( - "file_name_search", - &serde_json::to_string(&MessageToSearch::FileSystemUpdate).unwrap(), - &serde_json::to_string(&paths).unwrap(), - )); - post_message_to(PluginMessage::new_to_worker( - "file_contents_search", - &serde_json::to_string(&MessageToSearch::FileSystemUpdate).unwrap(), - &serde_json::to_string(&paths).unwrap(), - )); - } - Event::FileSystemDelete(paths) => { - let paths: Vec = paths - .iter() - .map(|p| p.to_string_lossy().to_string()) - .collect(); - post_message_to(PluginMessage::new_to_worker( - "file_name_search", - &serde_json::to_string(&MessageToSearch::FileSystemDelete).unwrap(), - &serde_json::to_string(&paths).unwrap(), - )); - post_message_to(PluginMessage::new_to_worker( - "file_contents_search", - &serde_json::to_string(&MessageToSearch::FileSystemDelete).unwrap(), - &serde_json::to_string(&paths).unwrap(), - )); - } _ => { eprintln!("Unknown event: {}", event.to_string()); } From 2633e100cffb5a35f00eaa53632a9b2df8be4053 Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Wed, 27 Mar 2024 18:35:36 +0100 Subject: [PATCH 2/4] allow configuring search filter --- src/main.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main.rs b/src/main.rs index 9727c05..1efb18c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,6 +40,14 @@ impl ZellijPlugin for State { fn load(&mut self, config: BTreeMap) { self.loading = true; self.kiosk_mode = config.get("kiosk").map(|k| k == "true").unwrap_or(false); + if let Some(search_type) = config.get("search_filter") { + match search_type.as_str() { + "file_names" => self.search_filter = SearchType::Names, + "file_contents" => self.search_filter = SearchType::Contents, + "all" => self.search_filter = SearchType::NamesAndContents, + _ => {} + } + } request_permission(&[ PermissionType::OpenFiles, PermissionType::ChangeApplicationState, From e0b5863abf209f925fd78dc3ab3a15fe0e4aaf1d Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Wed, 27 Mar 2024 18:35:52 +0100 Subject: [PATCH 3/4] fix wide character issue with displaying search results --- src/search_results.rs | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/search_results.rs b/src/search_results.rs index d905a5d..f01dc67 100644 --- a/src/search_results.rs +++ b/src/search_results.rs @@ -1,5 +1,5 @@ use serde::{Deserialize, Serialize}; -use unicode_width::UnicodeWidthStr; +use unicode_width::{UnicodeWidthStr, UnicodeWidthChar}; use crate::ui::{ bold, styled_text, styled_text_background, styled_text_foreground, underline, GRAY_LIGHT, @@ -233,27 +233,35 @@ impl SearchResult { let truncate_end_position = truncate_positions .map(|p| p.1) .unwrap_or(line_to_render.chars().count()); + + let left_truncate_sign = if truncate_start_position == 0 { + "" + } else { + ".." + }; + let right_truncate_sign = if truncate_end_position == line_to_render.chars().count() { + "" + } else { + ".." + }; + + let max_width_for_visible_portion = max_width.saturating_sub(left_truncate_sign.chars().count()).saturating_sub(right_truncate_sign.chars().count()); let mut visible_portion = String::new(); + let mut visible_characters = String::new(); for (i, character) in line_to_render.chars().enumerate() { + if visible_characters.width() + character.width().unwrap_or(0) > max_width_for_visible_portion { + break; + } if i >= truncate_start_position && i <= truncate_end_position { if indices.contains(&i) { visible_portion.push_str(&index_character_style(&character.to_string())); } else { visible_portion.push_str(&non_index_character_style(&character.to_string())); } + visible_characters.push(character); } } if truncate_positions.is_some() { - let left_truncate_sign = if truncate_start_position == 0 { - "" - } else { - ".." - }; - let right_truncate_sign = if truncate_end_position == line_to_render.chars().count() { - "" - } else { - ".." - }; format!( "{}{}{}", non_index_character_style(left_truncate_sign), @@ -292,7 +300,7 @@ impl SearchResult { if i >= width_remaining { break; } - if string_start_position > 0 && string_end_position < line_to_render.chars().count() + if string_start_position > 0 && string_end_position < line_to_render.width() { let take_from_start = i % 2 == 0; if take_from_start { @@ -302,13 +310,13 @@ impl SearchResult { } } else { string_end_position += 1; - if string_end_position == line_to_render.chars().count() { + if string_end_position == line_to_render.width() { width_remaining += 2; // no need for truncating dots } } - } else if string_end_position < line_to_render.chars().count() { + } else if string_end_position < line_to_render.width() { string_end_position += 1; - if string_end_position == line_to_render.chars().count() { + if string_end_position == line_to_render.width() { width_remaining += 2; // no need for truncating dots } } else if string_start_position > 0 { From fb2daf5c6102438e4754eb929aaa5e7cd43ed5f6 Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Wed, 27 Mar 2024 18:39:15 +0100 Subject: [PATCH 4/4] always show results --- src/ui/controls_line.rs | 9 +-------- src/ui/mod.rs | 5 ++--- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/ui/controls_line.rs b/src/ui/controls_line.rs index 667539b..01f0728 100644 --- a/src/ui/controls_line.rs +++ b/src/ui/controls_line.rs @@ -23,14 +23,7 @@ impl ControlsLine { self.animation_offset = animation_offset; self } - pub fn render(&self, max_width: usize, show_controls: bool) -> String { - if show_controls { - self.render_controls(max_width) - } else { - self.render_empty_line(max_width) - } - } - pub fn render_controls(&self, max_width: usize) -> String { + pub fn render(&self, max_width: usize) -> String { let loading_animation = LoadingAnimation::new(&self.scanning_indication, self.animation_offset); let full_length = loading_animation.full_len() diff --git a/src/ui/mod.rs b/src/ui/mod.rs index dfda4b8..b97de96 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -71,7 +71,6 @@ impl State { } } pub fn render_controls_line(&self) -> String { - let has_results = !self.displayed_search_results.1.is_empty(); let tiled_floating_control = Control::new_floating_control("Ctrl f", self.should_open_floating); let names_contents_control = Control::new_filter_control("Ctrl r", &self.search_filter); @@ -86,10 +85,10 @@ impl State { Some(vec!["Scanning folder", "Scanning", "S"]), ) .with_animation_offset(self.loading_animation_offset) - .render(self.display_columns, has_results) + .render(self.display_columns) } else { ControlsLine::new(controls, None) - .render(self.display_columns, has_results) + .render(self.display_columns) } } }