diff --git a/waycast-core/src/lib.rs b/waycast-core/src/lib.rs index a64491e..2f24e5b 100644 --- a/waycast-core/src/lib.rs +++ b/waycast-core/src/lib.rs @@ -26,7 +26,10 @@ pub trait LauncherPlugin { // Only search/use this plugin if the prefix was typed fn by_prefix_only(&self) -> bool; // Actual item searching functions - fn default_list(&self) -> Vec>; + fn default_list(&self) -> Vec> { + // Default empty list - plugins can override this + Vec::new() + } fn filter(&self, query: &str) -> Vec>; } diff --git a/waycast-macros/src/lib.rs b/waycast-macros/src/lib.rs index f717aed..711774b 100644 --- a/waycast-macros/src/lib.rs +++ b/waycast-macros/src/lib.rs @@ -154,7 +154,7 @@ impl PluginConfig { quote! {} }; - // Generate default_list method + // Generate default_list method only if explicitly specified in config let default_list_method = if let Some(ref default_list_fn) = self.default_list_fn { quote! { fn default_list(&self) -> Vec> { @@ -162,14 +162,11 @@ impl PluginConfig { } } } else { - quote! { - fn default_list(&self) -> Vec> { - Vec::new() - } - } + // Don't generate default_list method - user must implement it themselves + quote! {} }; - // Generate filter method + // Generate filter method only if explicitly specified in config let filter_method = if let Some(ref filter_fn) = self.filter_fn { quote! { fn filter(&self, query: &str) -> Vec> { @@ -177,11 +174,8 @@ impl PluginConfig { } } } else { - quote! { - fn filter(&self, query: &str) -> Vec> { - Vec::new() - } - } + // Don't generate filter method - user must implement it themselves + quote! {} }; quote! { diff --git a/waycast-plugins/src/drun.rs b/waycast-plugins/src/drun.rs index a85e9d1..5e79d4b 100644 --- a/waycast-plugins/src/drun.rs +++ b/waycast-plugins/src/drun.rs @@ -79,32 +79,7 @@ pub fn get_desktop_entries() -> Vec { entries } -fn drun_default_list(_plugin: &DrunPlugin) -> Vec> { - let mut entries: Vec> = Vec::new(); - for e in get_desktop_entries() { - entries.push(Box::new(e)); - } - - entries -} - -fn drun_filter(plugin: &DrunPlugin, query: &str) -> Vec> { - if query.is_empty() { - return drun_default_list(plugin); - } - - let query_lower = query.to_lowercase(); - let mut entries: Vec> = Vec::new(); - for entry in drun_default_list(plugin) { - let title_lower = entry.title().to_lowercase(); - if title_lower.contains(&query_lower) { - entries.push(entry); - } - } - - entries -} pub struct DrunPlugin; @@ -119,9 +94,34 @@ impl LauncherPlugin for DrunPlugin { name: "drun", priority: 1000, description: "List and launch an installed application", - prefix: "app", - default_list: drun_default_list, - filter: drun_filter + prefix: "app" + } + + fn default_list(&self) -> Vec> { + let mut entries: Vec> = Vec::new(); + + for e in get_desktop_entries() { + entries.push(Box::new(e)); + } + + entries + } + + fn filter(&self, query: &str) -> Vec> { + if query.is_empty() { + return self.default_list(); + } + + let query_lower = query.to_lowercase(); + let mut entries: Vec> = Vec::new(); + for entry in self.default_list() { + let title_lower = entry.title().to_lowercase(); + if title_lower.contains(&query_lower) { + entries.push(entry); + } + } + + entries } } diff --git a/waycast-plugins/src/file_search.rs b/waycast-plugins/src/file_search.rs index 2dd2813..db99826 100644 --- a/waycast-plugins/src/file_search.rs +++ b/waycast-plugins/src/file_search.rs @@ -192,9 +192,7 @@ impl LauncherPlugin for FileSearchPlugin { name: "Files", priority: 500, description: "Search and open files", - prefix: "f", - default_list: file_search_default_list, - filter: file_search_filter + prefix: "f" } fn init(&self) { @@ -214,35 +212,33 @@ impl LauncherPlugin for FileSearchPlugin { }); }); } -} -fn file_search_default_list(_plugin: &FileSearchPlugin) -> Vec> { - Vec::new() -} + fn filter(&self, query: &str) -> Vec> { + if query.is_empty() { + return self.default_list(); + } -fn file_search_filter(plugin: &FileSearchPlugin, query: &str) -> Vec> { - if query.is_empty() { - return file_search_default_list(plugin); - } + let mut entries: Vec> = Vec::new(); - let mut entries: Vec> = Vec::new(); - - // Try to get files without blocking - if indexing is still in progress, return empty - if let Ok(files) = plugin.files.try_lock() { - for f in files.iter() { - if let Some(file_name) = f.path.file_name() { - let cmp = file_name.to_string_lossy().to_lowercase(); - if cmp.contains(&query.to_lowercase()) { - entries.push(Box::new(f.clone())); + // Try to get files without blocking - if indexing is still in progress, return empty + if let Ok(files) = self.files.try_lock() { + for f in files.iter() { + if let Some(file_name) = f.path.file_name() { + let cmp = file_name.to_string_lossy().to_lowercase(); + if cmp.contains(&query.to_lowercase()) { + entries.push(Box::new(f.clone())); + } } } } - } - entries + entries + } } + + pub fn new() -> FileSearchPlugin { FileSearchPlugin::new() } \ No newline at end of file diff --git a/waycast-plugins/src/projects.rs b/waycast-plugins/src/projects.rs index ca199e4..6727066 100644 --- a/waycast-plugins/src/projects.rs +++ b/waycast-plugins/src/projects.rs @@ -81,28 +81,26 @@ impl LauncherPlugin for ProjectsPlugin { name: "Projects", priority: 800, description: "Search and open code projects", - prefix: "proj", - default_list: projects_default_list, - filter: projects_filter + prefix: "proj" } - + fn init(&self) { let files_clone = Arc::clone(&self.files); let search_paths = self.search_paths.clone(); let skip_dirs = self.skip_dirs.clone(); - + std::thread::spawn(move || { let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { let mut project_entries = Vec::new(); - + for search_path in &search_paths { if let Ok(entries) = fs::read_dir(search_path) { for entry in entries.flatten() { if let Ok(file_type) = entry.file_type() { if file_type.is_dir() { let path = entry.path(); - + // Skip hidden directories (starting with .) if let Some(file_name) = path.file_name() { if let Some(name_str) = file_name.to_str() { @@ -110,12 +108,12 @@ impl LauncherPlugin for ProjectsPlugin { if name_str.starts_with('.') { continue; } - + // Skip directories in skip list if should_skip_dir(name_str, &skip_dirs) { continue; } - + project_entries.push(ProjectEntry { path }); } } @@ -124,44 +122,39 @@ impl LauncherPlugin for ProjectsPlugin { } } } - + // Update the shared files collection let mut files_guard = files_clone.lock().await; *files_guard = project_entries; - + println!("Projects plugin: Found {} projects", files_guard.len()); }); }); } -} -fn projects_default_list(_plugin: &ProjectsPlugin) -> Vec> { - Vec::new() -} + fn filter(&self, query: &str) -> Vec> { + if query.is_empty() { + return self.default_list(); + } -fn projects_filter(plugin: &ProjectsPlugin, query: &str) -> Vec> { - if query.is_empty() { - return projects_default_list(plugin); - } + let mut entries: Vec> = Vec::new(); - let mut entries: Vec> = Vec::new(); - - // Try to get files without blocking - if indexing is still in progress, return empty - if let Ok(files) = plugin.files.try_lock() { - for f in files.iter() { - if let Some(file_name) = f.path.file_name() { - let cmp = file_name.to_string_lossy().to_lowercase(); - if cmp.contains(&query.to_lowercase()) { - entries.push(Box::new(f.clone())); + // Try to get files without blocking - if indexing is still in progress, return empty + if let Ok(files) = self.files.try_lock() { + for f in files.iter() { + if let Some(file_name) = f.path.file_name() { + let cmp = file_name.to_string_lossy().to_lowercase(); + if cmp.contains(&query.to_lowercase()) { + entries.push(Box::new(f.clone())); + } } } } + + entries } - - entries } - pub fn new() -> ProjectsPlugin { ProjectsPlugin { search_paths: Vec::new(),