fix(review): bugs, arch violations, design smells

P1 bugs:
- unix_launcher: shell_split respects quoted args (was split_whitespace)
- plugin-host: 5s timeout on external plugin search
- ui: handle engine init panic, wire error state
- ui-egui: read window config instead of always using defaults
- plugin-url: use OpenPath action instead of SpawnProcess+xdg-open

Architecture:
- remove WindowConfig (mirror of WindowCfg); use WindowCfg directly
- remove on_select closure from SearchResult (domain leakage)
- remove LaunchAction::Custom; add Plugin::on_selected + SearchEngine::on_selected
- apps: record frecency via on_selected instead of embedded closure

Design smells:
- frecency: extract decay_factor helper, write outside mutex
- apps: remove cfg(test) cache_path hack; add new_for_test ctor
- apps: stable ResultId using name+exec to prevent collision
- files: stable ResultId using full path instead of index
- plugin-host: remove k-launcher-os-bridge dep (WindowConfig gone)
This commit is contained in:
2026-03-18 13:45:48 +01:00
parent 38860762c0
commit ff9b2b5712
18 changed files with 189 additions and 133 deletions

View File

@@ -71,21 +71,19 @@ impl Plugin for FilesPlugin {
.unwrap_or(false)
})
.take(20)
.enumerate()
.map(|(i, entry)| {
.map(|entry| {
let full_path = entry.path();
let name = entry.file_name().to_string_lossy().to_string();
let is_dir = full_path.is_dir();
let title = if is_dir { format!("{name}/") } else { name };
let path_str = full_path.to_string_lossy().to_string();
SearchResult {
id: ResultId::new(format!("file-{i}")),
id: ResultId::new(&path_str),
title: ResultTitle::new(title),
description: Some(path_str.clone()),
icon: None,
score: Score::new(50),
action: LaunchAction::OpenPath(path_str),
on_select: None,
}
})
.collect()