From 44d1b37d7a88a1ce40a02ebb783b158eb72c5e6b Mon Sep 17 00:00:00 2001 From: multiplex55 <6619098+multiplex55@users.noreply.github.com> Date: Sat, 7 Feb 2026 16:37:32 -0500 Subject: [PATCH 1/2] Add action metadata preview pane and preview settings --- benches/omni_search.rs | 3 + benches/search.rs | 3 + src/actions/mod.rs | 15 +++ src/dashboard/widgets/active_timers.rs | 6 + src/dashboard/widgets/calendar.rs | 9 ++ src/dashboard/widgets/clipboard_recent.rs | 3 + src/dashboard/widgets/clipboard_snippets.rs | 6 + src/dashboard/widgets/command_history.rs | 36 +++++ src/dashboard/widgets/frequent_commands.rs | 3 + src/dashboard/widgets/gesture_health.rs | 3 + src/dashboard/widgets/layouts.rs | 3 + src/dashboard/widgets/mod.rs | 6 + src/dashboard/widgets/notes_graph.rs | 3 + src/dashboard/widgets/notes_recent.rs | 3 + src/dashboard/widgets/notes_tags.rs | 3 + src/dashboard/widgets/now_playing.rs | 3 + src/dashboard/widgets/pinned_commands.rs | 9 ++ src/dashboard/widgets/pinned_query_results.rs | 3 + src/dashboard/widgets/quick_tools.rs | 3 + src/dashboard/widgets/recent_notes.rs | 9 ++ src/dashboard/widgets/recycle_bin.rs | 3 + src/dashboard/widgets/snippets_favorites.rs | 3 + src/dashboard/widgets/stopwatch.rs | 3 + src/dashboard/widgets/system_controls.rs | 3 + src/dashboard/widgets/tempfiles.rs | 12 ++ src/dashboard/widgets/todo.rs | 6 + src/dashboard/widgets/todo_focus.rs | 3 + src/dashboard/widgets/volume.rs | 3 + src/dashboard/widgets/weather_site.rs | 3 + src/gui/add_action_dialog.rs | 12 ++ src/gui/brightness_dialog.rs | 3 + src/gui/mod.rs | 81 ++++++++++- src/gui/note_panel.rs | 3 + src/gui/volume_dialog.rs | 12 ++ src/history.rs | 27 ++++ src/indexer.rs | 3 + src/launcher.rs | 30 +++++ src/mouse_gestures/db.rs | 12 ++ src/plugins/asciiart.rs | 6 + src/plugins/base_convert.rs | 9 ++ src/plugins/bookmarks.rs | 27 ++++ src/plugins/brightness.rs | 12 ++ src/plugins/browser_tabs.rs | 18 +++ src/plugins/calendar.rs | 54 ++++++++ src/plugins/clipboard.rs | 21 +++ src/plugins/color_picker.rs | 15 +++ src/plugins/convert_panel.rs | 9 ++ src/plugins/dropcalc.rs | 6 + src/plugins/emoji.rs | 12 ++ src/plugins/fav.rs | 36 +++++ src/plugins/folders.rs | 21 +++ src/plugins/help.rs | 6 + src/plugins/history.rs | 12 ++ src/plugins/ip.rs | 9 ++ src/plugins/keys.rs | 9 ++ src/plugins/layout.rs | 53 +++++++- src/plugins/lorem.rs | 12 ++ src/plugins/macros.rs | 15 +++ src/plugins/media.rs | 15 +++ src/plugins/missing.rs | 15 +++ src/plugins/mouse_gestures.rs | 45 +++++++ src/plugins/network.rs | 6 + src/plugins/note.rs | 126 ++++++++++++++++++ src/plugins/omni_search.rs | 6 + src/plugins/processes.rs | 15 +++ src/plugins/random.rs | 18 +++ src/plugins/recycle.rs | 8 +- src/plugins/reddit.rs | 6 + src/plugins/runescape.rs | 12 ++ src/plugins/screenshot.rs | 30 +++++ src/plugins/settings.rs | 18 +++ src/plugins/shell.rs | 36 +++++ src/plugins/snippets.rs | 36 +++++ src/plugins/stopwatch.rs | 45 +++++++ src/plugins/sysinfo.rs | 24 ++++ src/plugins/system.rs | 12 +- src/plugins/task_manager.rs | 10 +- src/plugins/tempfile.rs | 45 +++++++ src/plugins/text_case.rs | 81 +++++++++++ src/plugins/timer.rs | 57 ++++++++ src/plugins/timestamp.rs | 18 +++ src/plugins/todo.rs | 99 ++++++++++++++ src/plugins/unit_convert.rs | 9 ++ src/plugins/volume.rs | 21 +++ src/plugins/weather.rs | 6 + src/plugins/wikipedia.rs | 6 + src/plugins/windows.rs | 9 ++ src/plugins/youtube.rs | 6 + src/plugins_builtin.rs | 24 ++++ src/settings.rs | 10 ++ src/settings_editor.rs | 11 ++ tests/dashboard_config.rs | 3 + tests/gui_visibility.rs | 7 + tests/hide_after_run.rs | 3 + tests/history.rs | 9 ++ tests/layout_plugin.rs | 13 ++ tests/mouse_gestures_db.rs | 54 ++++++++ tests/omni_search_plugin.rs | 9 ++ tests/plugin_commands.rs | 3 + tests/preserve_command.rs | 15 +++ tests/ranking.rs | 12 ++ tests/recycle_plugin.rs | 9 ++ tests/resilience.rs | 3 + tests/selection.rs | 38 ++++++ tests/settings_plugin.rs | 6 + tests/shell_plugin.rs | 27 ++++ tests/snippets_plugin.rs | 3 + tests/system_plugin.rs | 9 ++ tests/task_manager_plugin.rs | 9 ++ tests/tempfile_plugin.rs | 3 + tests/trigger_visibility.rs | 3 + tests/watchers.rs | 3 + tests/web_search_prefix.rs | 3 + 113 files changed, 1837 insertions(+), 8 deletions(-) create mode 100644 tests/layout_plugin.rs diff --git a/benches/omni_search.rs b/benches/omni_search.rs index f8a293ed..13951cc4 100644 --- a/benches/omni_search.rs +++ b/benches/omni_search.rs @@ -28,6 +28,9 @@ fn bench_omni_search(c: &mut Criterion) { desc: format!("Description {i}"), action: i.to_string(), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); let index = build_index(&actions); diff --git a/benches/search.rs b/benches/search.rs index 401fc1c9..1f48d13e 100644 --- a/benches/search.rs +++ b/benches/search.rs @@ -13,6 +13,9 @@ fn bench_search(c: &mut Criterion) { desc: String::new(), action: format!("{i}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); let actions_arc = Arc::new(actions); diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 7b5c6291..eb8f716e 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -10,6 +10,21 @@ pub struct Action { pub action: String, // Path to folder or exe #[serde(skip_serializing_if = "Option::is_none")] pub args: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub preview_text: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub risk_level: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub icon: Option, +} + +#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] +pub enum ActionRiskLevel { + Low, + Medium, + High, + Critical, } pub fn load_actions(path: &str) -> anyhow::Result> { diff --git a/src/dashboard/widgets/active_timers.rs b/src/dashboard/widgets/active_timers.rs index e082e8d3..16fce440 100644 --- a/src/dashboard/widgets/active_timers.rs +++ b/src/dashboard/widgets/active_timers.rs @@ -110,6 +110,9 @@ impl Widget for ActiveTimersWidget { desc: "Timer".into(), action: format!("timer:pause:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some("timer pause".into()), }); @@ -121,6 +124,9 @@ impl Widget for ActiveTimersWidget { desc: "Timer".into(), action: format!("timer:cancel:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some("timer cancel".into()), }); diff --git a/src/dashboard/widgets/calendar.rs b/src/dashboard/widgets/calendar.rs index f1ece7d7..f0845dcf 100644 --- a/src/dashboard/widgets/calendar.rs +++ b/src/dashboard/widgets/calendar.rs @@ -267,6 +267,9 @@ impl CalendarWidget { desc: "Calendar".into(), action: format!("calendar:add:{input}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some("cal add".into()), }); @@ -283,6 +286,9 @@ impl CalendarWidget { desc: "Calendar".into(), action: format!("calendar:open:{view}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: None, }); @@ -376,6 +382,9 @@ impl CalendarWidget { desc: "Calendar".into(), action: "calendar:open".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: None, }); diff --git a/src/dashboard/widgets/clipboard_recent.rs b/src/dashboard/widgets/clipboard_recent.rs index d6b58153..e638be2c 100644 --- a/src/dashboard/widgets/clipboard_recent.rs +++ b/src/dashboard/widgets/clipboard_recent.rs @@ -108,6 +108,9 @@ impl Widget for ClipboardRecentWidget { desc: "Clipboard".into(), action: format!("clipboard:copy:{idx}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some("cb list".into()), }); diff --git a/src/dashboard/widgets/clipboard_snippets.rs b/src/dashboard/widgets/clipboard_snippets.rs index dd9cc7ff..96b16ba9 100644 --- a/src/dashboard/widgets/clipboard_snippets.rs +++ b/src/dashboard/widgets/clipboard_snippets.rs @@ -138,6 +138,9 @@ impl Widget for ClipboardSnippetsWidget { desc: "Clipboard".into(), action: format!("clipboard:copy:{idx}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some("cb list".into()), }); @@ -165,6 +168,9 @@ impl Widget for ClipboardSnippetsWidget { desc: "Snippet".into(), action: format!("clipboard:{}", snippet.text), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some(format!("cs {}", snippet.alias)), }); diff --git a/src/dashboard/widgets/command_history.rs b/src/dashboard/widgets/command_history.rs index 0fa0f45e..79eceef4 100644 --- a/src/dashboard/widgets/command_history.rs +++ b/src/dashboard/widgets/command_history.rs @@ -121,6 +121,9 @@ impl CommandHistoryWidget { ctx: &DashboardContext<'_>, action_id: &str, args: Option<&str>, + preview_text: None, + risk_level: None, + icon: None, ) -> Option { if let Some(action) = ctx.actions_by_id.get(action_id) { return Some(action.clone()); @@ -153,6 +156,9 @@ impl CommandHistoryWidget { desc: "Fav".into(), action: fav.action.clone(), args: fav.args.clone(), + preview_text: None, + risk_level: None, + icon: None, }); } @@ -163,6 +169,9 @@ impl CommandHistoryWidget { desc: "Note".into(), action: action_id.to_string(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -177,6 +186,9 @@ impl CommandHistoryWidget { desc: "Clipboard".into(), action: action_id.to_string(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -191,6 +203,9 @@ impl CommandHistoryWidget { desc: "Todo".into(), action: action_id.to_string(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -205,6 +220,9 @@ impl CommandHistoryWidget { desc: "Todo".into(), action: action_id.to_string(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -219,6 +237,9 @@ impl CommandHistoryWidget { desc: "Todo".into(), action: action_id.to_string(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -230,6 +251,9 @@ impl CommandHistoryWidget { desc: "Snippet".into(), action: action_id.to_string(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -241,6 +265,9 @@ impl CommandHistoryWidget { desc: "Snippet".into(), action: action_id.to_string(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -252,6 +279,9 @@ impl CommandHistoryWidget { desc: "Snippet".into(), action: action_id.to_string(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -279,6 +309,9 @@ impl CommandHistoryWidget { desc: pin.desc.clone(), action: pin.action_id.clone(), args: pin.args.clone(), + preview_text: None, + risk_level: None, + icon: None, }; let resolved = Self::resolve_action(ctx, &pin.action_id, pin.args.as_deref()); let action = resolved.clone().unwrap_or(fallback); @@ -370,6 +403,9 @@ impl Widget for CommandHistoryWidget { label: entry.action.label.clone(), desc: entry.action.desc.clone(), args: entry.action.args.clone(), + preview_text: None, + risk_level: None, + icon: None, query: entry.query.clone(), timestamp: entry.timestamp, }; diff --git a/src/dashboard/widgets/frequent_commands.rs b/src/dashboard/widgets/frequent_commands.rs index 2b6d967a..7c4119f7 100644 --- a/src/dashboard/widgets/frequent_commands.rs +++ b/src/dashboard/widgets/frequent_commands.rs @@ -66,6 +66,9 @@ impl FrequentCommandsWidget { desc: "Command".into(), action: key.to_string(), args: None, + preview_text: None, + risk_level: None, + icon: None, }) }) } diff --git a/src/dashboard/widgets/gesture_health.rs b/src/dashboard/widgets/gesture_health.rs index eb14e0bc..70456182 100644 --- a/src/dashboard/widgets/gesture_health.rs +++ b/src/dashboard/widgets/gesture_health.rs @@ -19,6 +19,9 @@ impl GestureHealthWidget { desc: "Mouse gestures".into(), action: action.into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: None, } diff --git a/src/dashboard/widgets/layouts.rs b/src/dashboard/widgets/layouts.rs index 296ea79a..043fcc07 100644 --- a/src/dashboard/widgets/layouts.rs +++ b/src/dashboard/widgets/layouts.rs @@ -396,6 +396,9 @@ impl LayoutsWidget { desc: "Layout".into(), action, args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: None, } diff --git a/src/dashboard/widgets/mod.rs b/src/dashboard/widgets/mod.rs index f4823e28..261e284d 100644 --- a/src/dashboard/widgets/mod.rs +++ b/src/dashboard/widgets/mod.rs @@ -574,6 +574,9 @@ pub(crate) fn gesture_focus_action( desc: "Mouse gestures".into(), action: "mg:dialog:focus".into(), args: serde_json::to_string(&args).ok(), + preview_text: None, + risk_level: None, + icon: None, }, query_override: None, } @@ -597,6 +600,9 @@ pub(crate) fn gesture_toggle_action( desc: "Mouse gestures".into(), action: "mg:toggle".into(), args: serde_json::to_string(&args).ok(), + preview_text: None, + risk_level: None, + icon: None, }, query_override: None, } diff --git a/src/dashboard/widgets/notes_graph.rs b/src/dashboard/widgets/notes_graph.rs index 409a9685..75cc1426 100644 --- a/src/dashboard/widgets/notes_graph.rs +++ b/src/dashboard/widgets/notes_graph.rs @@ -115,6 +115,9 @@ impl Widget for NotesGraphWidget { desc: "Note".into(), action: format!("note:open:{slug}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some(format!("note open {slug}")), }); diff --git a/src/dashboard/widgets/notes_recent.rs b/src/dashboard/widgets/notes_recent.rs index 1c1fbef3..db9ba964 100644 --- a/src/dashboard/widgets/notes_recent.rs +++ b/src/dashboard/widgets/notes_recent.rs @@ -188,6 +188,9 @@ impl Widget for NotesRecentWidget { desc: "Note".into(), action: format!("note:open:{}", note.slug), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some(format!("note open {}", note.slug)), }); diff --git a/src/dashboard/widgets/notes_tags.rs b/src/dashboard/widgets/notes_tags.rs index 8172fdf3..cbcb5727 100644 --- a/src/dashboard/widgets/notes_tags.rs +++ b/src/dashboard/widgets/notes_tags.rs @@ -119,6 +119,9 @@ impl Widget for NotesTagsWidget { desc: "Note".into(), action: format!("query:note list #{tag}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some(format!("note list #{tag}")), }); diff --git a/src/dashboard/widgets/now_playing.rs b/src/dashboard/widgets/now_playing.rs index f5d5c807..b1d5aec9 100644 --- a/src/dashboard/widgets/now_playing.rs +++ b/src/dashboard/widgets/now_playing.rs @@ -65,6 +65,9 @@ impl NowPlayingWidget { desc: "Media".into(), action: action.into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some(query.into()), } diff --git a/src/dashboard/widgets/pinned_commands.rs b/src/dashboard/widgets/pinned_commands.rs index 0fa3bfdc..4ae3ebc7 100644 --- a/src/dashboard/widgets/pinned_commands.rs +++ b/src/dashboard/widgets/pinned_commands.rs @@ -130,6 +130,9 @@ impl PinnedCommandsWidget { desc: "Fav".into(), action: f.action.clone(), args: f.args.clone(), + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -140,6 +143,9 @@ impl PinnedCommandsWidget { desc: "Fav".into(), action: fav.action.clone(), args: fav.args.clone(), + preview_text: None, + risk_level: None, + icon: None, }) }) } @@ -272,6 +278,9 @@ mod tests { desc: "desc".into(), action: id.into(), args: None, + preview_text: None, + risk_level: None, + icon: None, } } diff --git a/src/dashboard/widgets/pinned_query_results.rs b/src/dashboard/widgets/pinned_query_results.rs index e5fcabd5..df0750e4 100644 --- a/src/dashboard/widgets/pinned_query_results.rs +++ b/src/dashboard/widgets/pinned_query_results.rs @@ -334,6 +334,9 @@ impl PinnedQueryResultsWidget { desc: action.desc.clone(), action: format!("query:{}", action.label), args: None, + preview_text: None, + risk_level: None, + icon: None, }, }, } diff --git a/src/dashboard/widgets/quick_tools.rs b/src/dashboard/widgets/quick_tools.rs index f4cf0468..472e167b 100644 --- a/src/dashboard/widgets/quick_tools.rs +++ b/src/dashboard/widgets/quick_tools.rs @@ -75,6 +75,9 @@ impl QuickToolsWidget { desc: "Tool".into(), action: format!("query:{query}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some(query.to_string()), } diff --git a/src/dashboard/widgets/recent_notes.rs b/src/dashboard/widgets/recent_notes.rs index 6c45e5bf..2333cd0b 100644 --- a/src/dashboard/widgets/recent_notes.rs +++ b/src/dashboard/widgets/recent_notes.rs @@ -140,6 +140,9 @@ impl RecentNotesWidget { desc: "Note".into(), action: format!("note:open:{}", note.slug), args: None, + preview_text: None, + risk_level: None, + icon: None, }, None, ), @@ -149,6 +152,9 @@ impl RecentNotesWidget { desc: "Note".into(), action: "note:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Some(format!("note open {}", note.slug)), ), @@ -158,6 +164,9 @@ impl RecentNotesWidget { desc: "Note".into(), action: "query:note open ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Some(format!( "note open {}", diff --git a/src/dashboard/widgets/recycle_bin.rs b/src/dashboard/widgets/recycle_bin.rs index 0fa5eeea..d8cf764e 100644 --- a/src/dashboard/widgets/recycle_bin.rs +++ b/src/dashboard/widgets/recycle_bin.rs @@ -98,6 +98,9 @@ impl RecycleBinWidget { desc: "Recycle Bin".into(), action: "recycle:clean".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, } } } diff --git a/src/dashboard/widgets/snippets_favorites.rs b/src/dashboard/widgets/snippets_favorites.rs index af9e52de..2eb7ff9a 100644 --- a/src/dashboard/widgets/snippets_favorites.rs +++ b/src/dashboard/widgets/snippets_favorites.rs @@ -101,6 +101,9 @@ impl Widget for SnippetsFavoritesWidget { desc: "Fav".into(), action: entry.action.clone(), args: entry.args.clone(), + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some("fav".into()), }); diff --git a/src/dashboard/widgets/stopwatch.rs b/src/dashboard/widgets/stopwatch.rs index c01bd482..67dcbfac 100644 --- a/src/dashboard/widgets/stopwatch.rs +++ b/src/dashboard/widgets/stopwatch.rs @@ -117,6 +117,9 @@ impl StopwatchWidget { desc: "Stopwatch".into(), action: action.to_string(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some(query.to_string()), } diff --git a/src/dashboard/widgets/system_controls.rs b/src/dashboard/widgets/system_controls.rs index b8efa242..a719cf45 100644 --- a/src/dashboard/widgets/system_controls.rs +++ b/src/dashboard/widgets/system_controls.rs @@ -170,6 +170,9 @@ impl SystemControlsWidget { desc: "System controls".into(), action, args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: None, } diff --git a/src/dashboard/widgets/tempfiles.rs b/src/dashboard/widgets/tempfiles.rs index 235a528c..15dde82d 100644 --- a/src/dashboard/widgets/tempfiles.rs +++ b/src/dashboard/widgets/tempfiles.rs @@ -196,6 +196,9 @@ impl TempfilesWidget { desc: "Tempfile".into(), action: "tempfile:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, } } @@ -205,6 +208,9 @@ impl TempfilesWidget { desc: "Tempfile".into(), action: "tempfile:clear".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, } } @@ -214,6 +220,9 @@ impl TempfilesWidget { desc: "Tempfile".into(), action: format!("tempfile:remove:{}", path.to_string_lossy()), args: None, + preview_text: None, + risk_level: None, + icon: None, } } @@ -223,6 +232,9 @@ impl TempfilesWidget { desc: "Tempfile".into(), action: format!("tempfile:open:{}", path.to_string_lossy()), args: None, + preview_text: None, + risk_level: None, + icon: None, } } } diff --git a/src/dashboard/widgets/todo.rs b/src/dashboard/widgets/todo.rs index a1c86cd2..04724b53 100644 --- a/src/dashboard/widgets/todo.rs +++ b/src/dashboard/widgets/todo.rs @@ -351,6 +351,9 @@ impl TodoWidget { desc: "Todo".into(), action: "todo:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: self.cfg.query.clone().or_else(|| Some("todo".into())), }); @@ -427,6 +430,9 @@ impl TodoWidget { desc: "Todo".into(), action: format!("todo:edit:{idx}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some(format!("todo edit {}", entry.text)), }); diff --git a/src/dashboard/widgets/todo_focus.rs b/src/dashboard/widgets/todo_focus.rs index edde875f..2f4ed34f 100644 --- a/src/dashboard/widgets/todo_focus.rs +++ b/src/dashboard/widgets/todo_focus.rs @@ -201,6 +201,9 @@ impl Widget for TodoFocusWidget { desc: "Todo".into(), action: format!("todo:edit:{idx}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: self .cfg diff --git a/src/dashboard/widgets/volume.rs b/src/dashboard/widgets/volume.rs index 9c20650f..18264628 100644 --- a/src/dashboard/widgets/volume.rs +++ b/src/dashboard/widgets/volume.rs @@ -120,6 +120,9 @@ impl VolumeWidget { desc: "Volume".into(), action, args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: None, } diff --git a/src/dashboard/widgets/weather_site.rs b/src/dashboard/widgets/weather_site.rs index b00cbe4f..aa3483b2 100644 --- a/src/dashboard/widgets/weather_site.rs +++ b/src/dashboard/widgets/weather_site.rs @@ -118,6 +118,9 @@ impl Widget for WeatherSiteWidget { desc: "Weather".into(), action: url, args: None, + preview_text: None, + risk_level: None, + icon: None, }, query_override: Some(format!("weather {loc}")), }); diff --git a/src/gui/add_action_dialog.rs b/src/gui/add_action_dialog.rs index 1232c51e..2c41790e 100644 --- a/src/gui/add_action_dialog.rs +++ b/src/gui/add_action_dialog.rs @@ -19,8 +19,14 @@ pub struct AddActionDialog { path: String, /// Whether the arguments field is visible. show_args: bool, + preview_text: None, + risk_level: None, + icon: None, /// Additional arguments to pass when launching. args: String, + preview_text: None, + risk_level: None, + icon: None, /// Current dialog mode (add or edit existing command). mode: DialogMode, } @@ -47,7 +53,13 @@ impl Default for AddActionDialog { desc: String::new(), path: String::new(), show_args: false, + preview_text: None, + risk_level: None, + icon: None, args: String::new(), + preview_text: None, + risk_level: None, + icon: None, mode: DialogMode::Add, } } diff --git a/src/gui/brightness_dialog.rs b/src/gui/brightness_dialog.rs index 07336bc2..7f2c2eda 100644 --- a/src/gui/brightness_dialog.rs +++ b/src/gui/brightness_dialog.rs @@ -40,6 +40,9 @@ impl BrightnessDialog { desc: "Brightness".into(), action: format!("brightness:set:{}", self.value), args: None, + preview_text: None, + risk_level: None, + icon: None, }); close = true; app.focus_input(); diff --git a/src/gui/mod.rs b/src/gui/mod.rs index 45350991..49871e8d 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -481,6 +481,8 @@ pub struct LauncherApp { pub help_hotkey_str: Option, pub query_scale: f32, pub list_scale: f32, + pub preview_enabled: bool, + pub preview_compact_mode: bool, /// Number of user defined commands at the start of `actions`. pub custom_len: usize, pub history_limit: usize, @@ -1326,6 +1328,8 @@ impl LauncherApp { help_hotkey_str: settings.help_hotkey.clone(), query_scale, list_scale, + preview_enabled: settings.preview_enabled, + preview_compact_mode: settings.preview_compact_mode, custom_len, history_limit: settings.history_limit, clipboard_limit: settings.clipboard_limit, @@ -1439,6 +1443,9 @@ impl LauncherApp { desc: a.desc.clone(), action: a.action.clone(), args: a.args.clone(), + preview_text: None, + risk_level: None, + icon: None, }); } self.results = res; @@ -1801,6 +1808,9 @@ impl LauncherApp { desc: "Fav".into(), action: fav.action.clone(), args: fav.args.clone(), + preview_text: None, + risk_level: None, + icon: None, }); } @@ -1811,6 +1821,9 @@ impl LauncherApp { desc: "Note".into(), action: pin.action_id.clone(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -1826,6 +1839,9 @@ impl LauncherApp { desc: "Clipboard".into(), action: pin.action_id.clone(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -1841,6 +1857,9 @@ impl LauncherApp { desc: "Todo".into(), action: pin.action_id.clone(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -1856,6 +1875,9 @@ impl LauncherApp { desc: "Todo".into(), action: pin.action_id.clone(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -1871,6 +1893,9 @@ impl LauncherApp { desc: "Todo".into(), action: pin.action_id.clone(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -1882,6 +1907,9 @@ impl LauncherApp { desc: "Snippet".into(), action: pin.action_id.clone(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -1893,6 +1921,9 @@ impl LauncherApp { desc: "Snippet".into(), action: pin.action_id.clone(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -1904,6 +1935,9 @@ impl LauncherApp { desc: "Snippet".into(), action: pin.action_id.clone(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -1920,6 +1954,9 @@ impl LauncherApp { label: action.label.clone(), desc: action.desc.clone(), args: action.args.clone(), + preview_text: None, + risk_level: None, + icon: None, query: self.query.clone(), timestamp: chrono::Utc::now().timestamp(), }; @@ -2339,6 +2376,9 @@ impl LauncherApp { desc: "Calendar".into(), action: format!("calendar:jump:{}", event.start.format("%Y-%m-%d")), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); self.query = format!("cal find {input}"); @@ -2408,6 +2448,9 @@ impl LauncherApp { desc: "Calendar".into(), action: format!("calendar:jump:{}", instance.start.format("%Y-%m-%d")), args: None, + preview_text: None, + risk_level: None, + icon: None, } }) .collect(); @@ -3899,10 +3942,14 @@ impl eframe::App for LauncherApp { } } else { let area_height = ui.available_height(); - ScrollArea::vertical() - .max_height(area_height) - .show(ui, |ui| { - scale_ui(ui, self.list_scale, |ui| { + ui.horizontal(|ui| { + let show_preview_pane = self.preview_enabled && self.selected.is_some(); + let list_width = if show_preview_pane { ui.available_width() * 0.62 } else { ui.available_width() }; + ui.set_width(list_width); + ScrollArea::vertical() + .max_height(area_height) + .show(ui, |ui| { + scale_ui(ui, self.list_scale, |ui| { let mut refresh = false; let mut set_focus = false; let show_full = self @@ -4398,6 +4445,32 @@ impl eframe::App for LauncherApp { } }); }); + if show_preview_pane { + ui.separator(); + ui.vertical(|ui| { + if let Some(idx) = self.selected { + if let Some(action) = self.results.get(idx) { + ui.heading(&action.label); + if !self.preview_compact_mode { + ui.label(&action.desc); + } + if let Some(icon) = &action.icon { + ui.small(format!("Icon: {icon}")); + } + if let Some(level) = action.risk_level { + ui.colored_label(egui::Color32::from_rgb(230, 170, 70), format!("Risk: {:?}", level)); + } + ui.separator(); + if let Some(text) = &action.preview_text { + ui.label(text); + } else { + ui.weak(action.action.clone()); + } + } + } + }); + } + }); } }); let show_editor = self.show_editor; diff --git a/src/gui/note_panel.rs b/src/gui/note_panel.rs index 2afb9b09..ac014b8a 100644 --- a/src/gui/note_panel.rs +++ b/src/gui/note_panel.rs @@ -1531,6 +1531,9 @@ mod tests { desc: String::new(), action: "query:changed".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; app.selected = Some(0); diff --git a/src/gui/volume_dialog.rs b/src/gui/volume_dialog.rs index 9e69c948..c9a2cf3d 100644 --- a/src/gui/volume_dialog.rs +++ b/src/gui/volume_dialog.rs @@ -44,6 +44,9 @@ impl VolumeDialog { desc: "Volume".into(), action: format!("volume:set:{}", self.value), args: None, + preview_text: None, + risk_level: None, + icon: None, }); close = true; app.focus_input(); @@ -65,6 +68,9 @@ impl VolumeDialog { desc: "Volume".into(), action, args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -74,6 +80,9 @@ impl VolumeDialog { desc: "Volume".into(), action: format!("volume:pid:{}:{}", proc.pid, proc.value), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } if ui.button("Mute").clicked() { @@ -82,6 +91,9 @@ impl VolumeDialog { desc: "Volume".into(), action: format!("volume:pid_toggle_mute:{}", proc.pid), args: None, + preview_text: None, + risk_level: None, + icon: None, }); proc.muted = !proc.muted; } diff --git a/src/history.rs b/src/history.rs index 150be439..10b64c93 100644 --- a/src/history.rs +++ b/src/history.rs @@ -25,6 +25,9 @@ pub struct HistoryPin { pub label: String, pub desc: String, pub args: Option, + preview_text: None, + risk_level: None, + icon: None, pub query: String, #[serde(default)] pub timestamp: i64, @@ -37,6 +40,9 @@ impl HistoryPin { label: entry.action.label.clone(), desc: entry.action.desc.clone(), args: entry.action.args.clone(), + preview_text: None, + risk_level: None, + icon: None, query: entry.query.clone(), timestamp: entry.timestamp, } @@ -265,6 +271,9 @@ mod tests { label: "One".into(), desc: "Test".into(), args: Some("--flag".into()), + preview_text: None, + risk_level: None, + icon: None, query: "one".into(), timestamp: 123, }; @@ -291,6 +300,9 @@ mod tests { label: "One".into(), desc: "Test".into(), args: Some("--flag".into()), + preview_text: None, + risk_level: None, + icon: None, query: "one".into(), timestamp: 1, }; @@ -299,6 +311,9 @@ mod tests { label: "One Updated".into(), desc: "Other".into(), args: Some("--flag".into()), + preview_text: None, + risk_level: None, + icon: None, query: "two".into(), timestamp: 2, }; @@ -307,6 +322,9 @@ mod tests { label: "One".into(), desc: "Test".into(), args: Some("--other".into()), + preview_text: None, + risk_level: None, + icon: None, query: "one".into(), timestamp: 1, }; @@ -323,6 +341,9 @@ mod tests { label: "One".into(), desc: "Old".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, query: "one".into(), timestamp: 10, }; @@ -334,6 +355,9 @@ mod tests { label: "One Updated".into(), desc: "New".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, query: "two".into(), timestamp: 11, }; @@ -347,6 +371,9 @@ mod tests { desc: "Fresh".into(), action: pin.action_id.clone(), args: None, + preview_text: None, + risk_level: None, + icon: None, }) } else { None diff --git a/src/indexer.rs b/src/indexer.rs index c66f5a69..4fa9eae7 100644 --- a/src/indexer.rs +++ b/src/indexer.rs @@ -23,6 +23,9 @@ pub fn index_paths(paths: &[String]) -> anyhow::Result> { desc: entry.path().display().to_string(), action: entry.path().display().to_string(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } diff --git a/src/launcher.rs b/src/launcher.rs index e95005b4..980998fb 100644 --- a/src/launcher.rs +++ b/src/launcher.rs @@ -63,6 +63,9 @@ mod tests { desc: String::new(), action: "volume:pid_toggle_mute:42".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }; assert_eq!( parse_action_kind(&action), @@ -77,6 +80,9 @@ mod tests { desc: String::new(), action: "volume:toggle_mute".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }; assert_eq!(parse_action_kind(&action), ActionKind::VolumeToggleMute); } @@ -88,6 +94,9 @@ mod tests { desc: String::new(), action: "power:plan:set:balanced".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }; assert_eq!( parse_action_kind(&action), @@ -109,6 +118,9 @@ mod tests { desc: String::new(), action: format!("todo:add:{encoded}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }; assert_eq!( @@ -134,6 +146,9 @@ mod tests { desc: String::new(), action: format!("todo:tag:{encoded}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }; assert_eq!( @@ -395,6 +410,9 @@ enum ActionKind<'a> { ShellAdd { name: &'a str, args: &'a str, + preview_text: None, + risk_level: None, + icon: None, }, ShellRemove(&'a str), ClipboardClear, @@ -459,6 +477,9 @@ enum ActionKind<'a> { label: &'a str, command: &'a str, args: Option<&'a str>, + preview_text: None, + risk_level: None, + icon: None, }, FavRemove(&'a str), BrightnessSet(u32), @@ -523,6 +544,9 @@ enum ActionKind<'a> { ExecPath { path: &'a str, args: Option<&'a str>, + preview_text: None, + risk_level: None, + icon: None, }, Macro(&'a str), } @@ -807,6 +831,9 @@ fn parse_action_kind(action: &Action) -> ActionKind<'_> { _ => ActionKind::ExecPath { path: s, args: action.args.as_deref(), + preview_text: None, + risk_level: None, + icon: None, }, }; } @@ -898,6 +925,9 @@ fn parse_action_kind(action: &Action) -> ActionKind<'_> { ActionKind::ExecPath { path: s, args: action.args.as_deref(), + preview_text: None, + risk_level: None, + icon: None, } } diff --git a/src/mouse_gestures/db.rs b/src/mouse_gestures/db.rs index 980d47c5..fd80414c 100644 --- a/src/mouse_gestures/db.rs +++ b/src/mouse_gestures/db.rs @@ -32,6 +32,9 @@ pub struct BindingEntry { pub action: String, #[serde(default, skip_serializing_if = "Option::is_none")] pub args: Option, + preview_text: None, + risk_level: None, + icon: None, #[serde(default = "default_enabled")] pub enabled: bool, } @@ -631,6 +634,9 @@ struct LegacyBindingEntry { action: String, #[serde(default, skip_serializing_if = "Option::is_none")] args: Option, + preview_text: None, + risk_level: None, + icon: None, #[serde(default = "default_enabled")] enabled: bool, #[serde(default)] @@ -646,6 +652,9 @@ impl LegacyBindingEntry { kind: BindingKind::ToggleLauncher, action: String::new(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: self.enabled, }; } @@ -664,6 +673,9 @@ impl LegacyBindingEntry { kind, action, args: self.args, + preview_text: None, + risk_level: None, + icon: None, enabled: self.enabled, } } diff --git a/src/plugins/asciiart.rs b/src/plugins/asciiart.rs index 8b1ba2c8..f5fb9d03 100644 --- a/src/plugins/asciiart.rs +++ b/src/plugins/asciiart.rs @@ -40,6 +40,9 @@ impl Plugin for AsciiArtPlugin { desc: "AsciiArt".into(), action: format!("clipboard:{}", art), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -66,6 +69,9 @@ impl Plugin for AsciiArtPlugin { desc: "AsciiArt".into(), action: "query:ascii ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } diff --git a/src/plugins/base_convert.rs b/src/plugins/base_convert.rs index d156fb26..b02edb64 100644 --- a/src/plugins/base_convert.rs +++ b/src/plugins/base_convert.rs @@ -131,6 +131,9 @@ impl Plugin for BaseConvertPlugin { desc: "Base Convert".into(), action: format!("clipboard:{res}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -156,12 +159,18 @@ impl Plugin for BaseConvertPlugin { desc: "Base Convert".into(), action: "query:conv ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "convert".into(), desc: "Base Convert".into(), action: "query:convert ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/bookmarks.rs b/src/plugins/bookmarks.rs index b9b5ba3a..cd78614a 100644 --- a/src/plugins/bookmarks.rs +++ b/src/plugins/bookmarks.rs @@ -91,6 +91,9 @@ impl BookmarksPlugin { desc: "Bookmark".into(), action: "bookmark:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -105,6 +108,9 @@ impl BookmarksPlugin { desc: "Bookmark".into(), action: format!("bookmark:add:{norm}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -129,6 +135,9 @@ impl BookmarksPlugin { desc: "Bookmark".into(), action: format!("bookmark:remove:{}", b.url.clone()), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -155,6 +164,9 @@ impl BookmarksPlugin { desc: "Bookmark".into(), action: b.url.clone(), args: None, + preview_text: None, + risk_level: None, + icon: None, } }) .collect(); @@ -185,6 +197,9 @@ impl BookmarksPlugin { desc: "Bookmark".into(), action: b.url.clone(), args: None, + preview_text: None, + risk_level: None, + icon: None, } }) .collect() @@ -332,24 +347,36 @@ impl Plugin for BookmarksPlugin { desc: "Bookmark".into(), action: "query:bm ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "bm add".into(), desc: "Bookmark".into(), action: "query:bm add ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "bm rm".into(), desc: "Bookmark".into(), action: "query:bm rm ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "bm list".into(), desc: "Bookmark".into(), action: "query:bm list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/brightness.rs b/src/plugins/brightness.rs index cb7f9fb1..b23fe372 100644 --- a/src/plugins/brightness.rs +++ b/src/plugins/brightness.rs @@ -12,6 +12,9 @@ fn usage_action(usage: &str) -> Action { desc: "Brightness".into(), action: "query:bright ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, } } @@ -30,6 +33,9 @@ impl Plugin for BrightnessPlugin { desc: "Brightness".into(), action: "brightness:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, usage_action(BRIGHT_USAGE), ]; @@ -49,6 +55,9 @@ impl Plugin for BrightnessPlugin { desc: "Brightness".into(), action: format!("brightness:set:{val}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } ParseArgsResult::Usage(usage) => { @@ -77,6 +86,9 @@ impl Plugin for BrightnessPlugin { desc: "Brightness".into(), action: "query:bright ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } diff --git a/src/plugins/browser_tabs.rs b/src/plugins/browser_tabs.rs index d17d0c41..9824097c 100644 --- a/src/plugins/browser_tabs.rs +++ b/src/plugins/browser_tabs.rs @@ -320,6 +320,9 @@ mod imp { }, action: format!("tab:switch:{id_str}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -414,6 +417,9 @@ impl Plugin for BrowserTabsPlugin { desc: "Remove cached browser tabs".into(), action: "tab:clear".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } if rest.eq_ignore_ascii_case("cache") { @@ -422,6 +428,9 @@ impl Plugin for BrowserTabsPlugin { desc: "Enumerate browser tabs".into(), action: "tab:cache".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } @@ -449,18 +458,27 @@ impl Plugin for BrowserTabsPlugin { desc: "Browser tabs".into(), action: "query:tab ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "tab cache".into(), desc: "Rebuild browser tab cache".into(), action: "tab:cache".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "tab clear".into(), desc: "Clear browser tab cache".into(), action: "tab:clear".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/calendar.rs b/src/plugins/calendar.rs index efe73bd1..2cd35253 100644 --- a/src/plugins/calendar.rs +++ b/src/plugins/calendar.rs @@ -1146,6 +1146,9 @@ impl Plugin for CalendarPlugin { desc: "Calendar".into(), action: "calendar:open".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } let rest_lc = rest.to_lowercase(); @@ -1155,6 +1158,9 @@ impl Plugin for CalendarPlugin { desc: "Calendar".into(), action: format!("calendar:open:{rest_lc}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } if rest_lc == "upcoming" { @@ -1163,6 +1169,9 @@ impl Plugin for CalendarPlugin { desc: "Calendar".into(), action: "calendar:upcoming".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } if let Some(find) = strip_prefix_ci(rest, "find") { @@ -1175,6 +1184,9 @@ impl Plugin for CalendarPlugin { desc: "Calendar".into(), action: format!("calendar:search:{query}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } if let Some(add) = strip_prefix_ci(rest, "add") { @@ -1206,6 +1218,9 @@ impl Plugin for CalendarPlugin { desc: "Calendar".into(), action: format!("calendar:add:{input}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } if let Some(snooze) = strip_prefix_ci(rest, "snooze") { @@ -1218,6 +1233,9 @@ impl Plugin for CalendarPlugin { desc: "Calendar".into(), action: format!("calendar:snooze:{input}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } if let Some(date) = parse_date_reference(rest, chrono::Local::now().naive_local().date()) { @@ -1226,6 +1244,9 @@ impl Plugin for CalendarPlugin { desc: "Calendar".into(), action: format!("calendar:jump:{rest}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } Vec::new() @@ -1250,66 +1271,99 @@ impl Plugin for CalendarPlugin { desc: "Calendar".into(), action: "query:cal".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cal day".into(), desc: "Calendar".into(), action: "query:cal day".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cal week".into(), desc: "Calendar".into(), action: "query:cal week".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cal month".into(), desc: "Calendar".into(), action: "query:cal month".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cal today".into(), desc: "Calendar".into(), action: "query:cal today".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cal tomorrow".into(), desc: "Calendar".into(), action: "query:cal tomorrow".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cal next mon".into(), desc: "Calendar".into(), action: "query:cal next mon".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cal add".into(), desc: "Calendar".into(), action: "query:cal add ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cal find".into(), desc: "Calendar".into(), action: "query:cal find ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cal upcoming".into(), desc: "Calendar".into(), action: "query:cal upcoming".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cal snooze".into(), desc: "Calendar".into(), action: "query:cal snooze ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/clipboard.rs b/src/plugins/clipboard.rs index 2fa3e1d8..2ce12d43 100644 --- a/src/plugins/clipboard.rs +++ b/src/plugins/clipboard.rs @@ -178,6 +178,9 @@ impl Plugin for ClipboardPlugin { desc: "Clipboard".into(), action: "clipboard:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -189,6 +192,9 @@ impl Plugin for ClipboardPlugin { desc: "Clipboard".into(), action: "clipboard:clear".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -204,6 +210,9 @@ impl Plugin for ClipboardPlugin { desc: "Clipboard".into(), action: format!("clipboard:copy:{idx}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -220,6 +229,9 @@ impl Plugin for ClipboardPlugin { desc: "Clipboard".into(), action: format!("clipboard:copy:{idx}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect() } @@ -243,18 +255,27 @@ impl Plugin for ClipboardPlugin { desc: "Clipboard".into(), action: "query:cb".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cb list".into(), desc: "Clipboard".into(), action: "query:cb list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cb clear".into(), desc: "Clipboard".into(), action: "query:cb clear".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/color_picker.rs b/src/plugins/color_picker.rs index 46170116..495a0908 100644 --- a/src/plugins/color_picker.rs +++ b/src/plugins/color_picker.rs @@ -49,18 +49,27 @@ impl Plugin for ColorPickerPlugin { desc: "Color hex".into(), action: format!("clipboard:{hex}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: rgb.clone(), desc: "Color rgb".into(), action: format!("clipboard:{rgb}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: hsl.clone(), desc: "Color hsl".into(), action: format!("clipboard:{hsl}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } @@ -84,12 +93,18 @@ impl Plugin for ColorPickerPlugin { desc: "Color picker".into(), action: "query:color ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "color #ff0000".into(), desc: "Color picker".into(), action: "query:color #ff0000".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/convert_panel.rs b/src/plugins/convert_panel.rs index d7a543ed..1bbf7c67 100644 --- a/src/plugins/convert_panel.rs +++ b/src/plugins/convert_panel.rs @@ -15,6 +15,9 @@ impl Plugin for ConvertPanelPlugin { desc: "Convert".into(), action: "convert:panel".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } Vec::new() @@ -39,12 +42,18 @@ impl Plugin for ConvertPanelPlugin { desc: "Convert".into(), action: "query:conv ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "convert".into(), desc: "Convert".into(), action: "query:convert ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/dropcalc.rs b/src/plugins/dropcalc.rs index 4d21c49c..a11b4335 100644 --- a/src/plugins/dropcalc.rs +++ b/src/plugins/dropcalc.rs @@ -47,6 +47,9 @@ impl Plugin for DropCalcPlugin { desc: "DropCalc".into(), action: format!("calc:{percent:.2}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } @@ -68,6 +71,9 @@ impl Plugin for DropCalcPlugin { desc: "DropCalc".into(), action: "query:drop ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } diff --git a/src/plugins/emoji.rs b/src/plugins/emoji.rs index 8ebad2a1..4c1324c7 100644 --- a/src/plugins/emoji.rs +++ b/src/plugins/emoji.rs @@ -134,6 +134,9 @@ impl Plugin for EmojiPlugin { desc: "Emoji".into(), action: format!("clipboard:{emoji}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -150,6 +153,9 @@ impl Plugin for EmojiPlugin { desc: "Emoji".into(), action: format!("clipboard:{emoji}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -176,12 +182,18 @@ impl Plugin for EmojiPlugin { desc: "Emoji".into(), action: "query:emoji ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "emoji list".into(), desc: "Emoji".into(), action: "query:emoji list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/fav.rs b/src/plugins/fav.rs index 02aafef1..a46a386a 100644 --- a/src/plugins/fav.rs +++ b/src/plugins/fav.rs @@ -20,6 +20,9 @@ pub struct FavEntry { pub action: String, #[serde(skip_serializing_if = "Option::is_none")] pub args: Option, + preview_text: None, + risk_level: None, + icon: None, } pub fn load_favs(path: &str) -> anyhow::Result> { @@ -51,6 +54,9 @@ pub fn set_fav(path: &str, label: &str, action: &str, args: Option<&str>) -> any label: label.to_string(), action: action.to_string(), args: args.map(|s| s.to_string()), + preview_text: None, + risk_level: None, + icon: None, }); } save_favs(path, &list) @@ -85,6 +91,9 @@ pub fn resolve_with_plugin( plugin: &dyn Plugin, command: &str, args: Option<&str>, + preview_text: None, + risk_level: None, + icon: None, ) -> (String, Option) { let mut query = command.to_string(); if let Some(a) = args { @@ -105,6 +114,9 @@ pub fn run_fav(label: &str) -> anyhow::Result<()> { desc: String::new(), action: entry.action.clone(), args: entry.args.clone(), + preview_text: None, + risk_level: None, + icon: None, }; launch_action(&act)?; } @@ -156,6 +168,9 @@ impl FavPlugin { desc: "Fav".into(), action: f.action.clone(), args: f.args.clone(), + preview_text: None, + risk_level: None, + icon: None, }) .collect() } @@ -176,6 +191,9 @@ impl Plugin for FavPlugin { desc: "Fav".into(), action: "fav:dialog:".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } @@ -190,6 +208,9 @@ impl Plugin for FavPlugin { desc: "Fav".into(), action: format!("fav:dialog:{label}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } @@ -207,6 +228,9 @@ impl Plugin for FavPlugin { desc: "Fav".into(), action: format!("fav:remove:{}", f.label), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -241,24 +265,36 @@ impl Plugin for FavPlugin { desc: "Fav".into(), action: "query:fav ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "fav add".into(), desc: "Fav".into(), action: "query:fav add ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "fav rm".into(), desc: "Fav".into(), action: "query:fav rm ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "fav list".into(), desc: "Fav".into(), action: "query:fav list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/folders.rs b/src/plugins/folders.rs index ed7ff542..cf8e4907 100644 --- a/src/plugins/folders.rs +++ b/src/plugins/folders.rs @@ -186,6 +186,9 @@ impl FoldersPlugin { desc: f.path.clone(), action: f.path.clone(), args: None, + preview_text: None, + risk_level: None, + icon: None, } }) .collect() @@ -209,6 +212,9 @@ impl Plugin for FoldersPlugin { desc: "Folder".into(), action: format!("folder:add:{path}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -235,6 +241,9 @@ impl Plugin for FoldersPlugin { desc: f.path.clone(), action: format!("folder:remove:{}", f.path.clone()), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -272,24 +281,36 @@ impl Plugin for FoldersPlugin { desc: "Folder".into(), action: "query:f ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "f list".into(), desc: "Folder".into(), action: "query:f list ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "f add".into(), desc: "Folder".into(), action: "query:f add ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "f rm".into(), desc: "Folder".into(), action: "query:f rm ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/help.rs b/src/plugins/help.rs index 76d23207..943468a4 100644 --- a/src/plugins/help.rs +++ b/src/plugins/help.rs @@ -13,6 +13,9 @@ impl Plugin for HelpPlugin { desc: "Display available command prefixes".into(), action: "help:show".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -37,6 +40,9 @@ impl Plugin for HelpPlugin { desc: "Help".into(), action: "query:help".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } diff --git a/src/plugins/history.rs b/src/plugins/history.rs index 48ac70d6..0db6fff9 100644 --- a/src/plugins/history.rs +++ b/src/plugins/history.rs @@ -32,6 +32,9 @@ impl Plugin for HistoryPlugin { desc: "History".into(), action: "history:clear".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -46,6 +49,9 @@ impl Plugin for HistoryPlugin { desc: "History".into(), action: format!("history:{idx}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect() }) @@ -71,12 +77,18 @@ impl Plugin for HistoryPlugin { desc: "History".into(), action: "query:hi".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "hi clear".into(), desc: "History".into(), action: "query:hi clear".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/ip.rs b/src/plugins/ip.rs index 19033dd0..023ed8ba 100644 --- a/src/plugins/ip.rs +++ b/src/plugins/ip.rs @@ -18,6 +18,9 @@ impl Plugin for IpPlugin { desc: "IP".into(), action: format!("clipboard:{ip}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -31,6 +34,9 @@ impl Plugin for IpPlugin { desc: "IP".into(), action: format!("clipboard:{ip}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -56,6 +62,9 @@ impl Plugin for IpPlugin { desc: "IP".into(), action: "query:ip".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } diff --git a/src/plugins/keys.rs b/src/plugins/keys.rs index e60b13cd..ed7be5b2 100644 --- a/src/plugins/keys.rs +++ b/src/plugins/keys.rs @@ -24,6 +24,9 @@ impl Plugin for KeysPlugin { desc: "Keys".into(), action: "query:keys ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } @@ -32,6 +35,9 @@ impl Plugin for KeysPlugin { desc: "Keys".into(), action: format!("keys:{spec}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } @@ -53,6 +59,9 @@ impl Plugin for KeysPlugin { desc: "Keys".into(), action: "query:keys ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } diff --git a/src/plugins/layout.rs b/src/plugins/layout.rs index b53a16fe..58b14035 100644 --- a/src/plugins/layout.rs +++ b/src/plugins/layout.rs @@ -1,4 +1,4 @@ -use crate::actions::Action; +use crate::actions::{Action, ActionRiskLevel}; use crate::plugin::Plugin; use crate::plugins::layouts_storage::{get_layout, layouts_config_path, load_layouts, LayoutMatch}; @@ -172,36 +172,54 @@ impl Plugin for LayoutPlugin { desc: "Layout".into(), action: "query:layout list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "layout save ".into(), desc: "Layout".into(), action: "query:layout save ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "layout load ".into(), desc: "Layout".into(), action: "query:layout load ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "layout show ".into(), desc: "Layout".into(), action: "query:layout show ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: format!("{config_label} ({config_desc})"), desc: "Layout config".into(), action: "layout:edit".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "layout rm ".into(), desc: "Layout".into(), action: "query:layout rm ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ]; } @@ -223,6 +241,11 @@ impl Plugin for LayoutPlugin { &LayoutFlags::default(), ), args: None, + preview_text: Some( + "Repositions and resizes windows based on the saved layout.".into(), + ), + risk_level: Some(ActionRiskLevel::High), + icon: Some("layout".into()), }) .collect(); } @@ -239,6 +262,11 @@ impl Plugin for LayoutPlugin { desc: "Layout".into(), action: build_action(format!("layout:save:{name}"), &flags), args: None, + preview_text: Some( + "Captures current window placements into a named layout.".into(), + ), + risk_level: Some(ActionRiskLevel::Medium), + icon: Some("layout".into()), }]; } @@ -252,6 +280,11 @@ impl Plugin for LayoutPlugin { desc: "Layout".into(), action: build_action(format!("layout:load:{name}"), &flags), args: None, + preview_text: Some( + "Repositions and resizes windows based on the saved layout.".into(), + ), + risk_level: Some(ActionRiskLevel::High), + icon: Some("layout".into()), }]; } @@ -292,6 +325,12 @@ impl Plugin for LayoutPlugin { desc: format!("Layout preview: {layout_name}"), action: action.clone(), args: None, + preview_text: Some( + "Preview entry for this matched window inside the selected layout." + .into(), + ), + risk_level: Some(ActionRiskLevel::Low), + icon: Some("layout".into()), } }) .collect(); @@ -310,6 +349,9 @@ impl Plugin for LayoutPlugin { desc: "Layout".into(), action: format!("query:layout show {}", layout.name), args: None, + preview_text: Some("Shows window matches for the selected layout.".into()), + risk_level: Some(ActionRiskLevel::Low), + icon: Some("layout".into()), }) .collect(); } @@ -323,6 +365,9 @@ impl Plugin for LayoutPlugin { desc: "Layout config".into(), action: "layout:edit".into(), args: None, + preview_text: Some("Opens the layouts configuration file for editing.".into()), + risk_level: Some(ActionRiskLevel::Low), + icon: Some("layout".into()), }]; } } @@ -337,6 +382,9 @@ impl Plugin for LayoutPlugin { desc: "Layout".into(), action: build_action(format!("layout:rm:{name}"), &flags), args: None, + preview_text: Some("Deletes the saved layout definition from disk.".into()), + risk_level: Some(ActionRiskLevel::High), + icon: Some("layout".into()), }]; } @@ -361,6 +409,9 @@ impl Plugin for LayoutPlugin { desc: "Layout".into(), action: "query:layout ".into(), args: None, + preview_text: Some("Layout operation".into()), + risk_level: Some(ActionRiskLevel::Low), + icon: Some("layout".into()), }] } } diff --git a/src/plugins/lorem.rs b/src/plugins/lorem.rs index 74fc895a..c11c5e7d 100644 --- a/src/plugins/lorem.rs +++ b/src/plugins/lorem.rs @@ -40,6 +40,9 @@ impl Plugin for LoremPlugin { desc: "Lorem".into(), action: format!("clipboard:{text}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -66,18 +69,27 @@ impl Plugin for LoremPlugin { desc: "Lorem words".into(), action: "query:lorem w ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "lorem s ".into(), desc: "Lorem sentences".into(), action: "query:lorem s ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "lorem p ".into(), desc: "Lorem paragraphs".into(), action: "query:lorem p ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/macros.rs b/src/plugins/macros.rs index 844d430d..5d116bab 100644 --- a/src/plugins/macros.rs +++ b/src/plugins/macros.rs @@ -36,6 +36,9 @@ pub struct MacroStep { pub command: String, #[serde(skip_serializing_if = "Option::is_none")] pub args: Option, + preview_text: None, + risk_level: None, + icon: None, /// Delay in milliseconds after this step when using manual delays. #[serde(default)] pub delay_ms: u64, @@ -260,6 +263,9 @@ impl MacrosPlugin { desc: "Macro".into(), action: format!("macro:{}", m.label), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect() } @@ -280,6 +286,9 @@ impl Plugin for MacrosPlugin { desc: "Macro".into(), action: "macro:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } @@ -315,12 +324,18 @@ impl Plugin for MacrosPlugin { desc: "Macro".into(), action: "query:macro ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "macro list".into(), desc: "Macro".into(), action: "query:macro list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/media.rs b/src/plugins/media.rs index a5bbe4c9..95c4790d 100644 --- a/src/plugins/media.rs +++ b/src/plugins/media.rs @@ -19,6 +19,9 @@ impl Plugin for MediaPlugin { desc: "Media".into(), action: format!("media:{}", op), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect() } @@ -42,24 +45,36 @@ impl Plugin for MediaPlugin { desc: "Media".into(), action: "query:media play".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "media pause".into(), desc: "Media".into(), action: "query:media pause".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "media next".into(), desc: "Media".into(), action: "query:media next".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "media prev".into(), desc: "Media".into(), action: "query:media prev".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/missing.rs b/src/plugins/missing.rs index b93edbd4..888ba301 100644 --- a/src/plugins/missing.rs +++ b/src/plugins/missing.rs @@ -26,6 +26,9 @@ impl Plugin for MissingPlugin { desc: "Maintenance".into(), action: format!("folder:remove:{}", f.path), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -39,6 +42,9 @@ impl Plugin for MissingPlugin { desc: "Maintenance".into(), action: format!("bookmark:remove:{}", b.url), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -64,6 +70,9 @@ impl Plugin for MissingPlugin { desc: "Maintenance".into(), action: format!("fav:remove:{}", f.label), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -75,6 +84,9 @@ impl Plugin for MissingPlugin { desc: "Maintenance".into(), action: "noop:".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } @@ -99,6 +111,9 @@ impl Plugin for MissingPlugin { desc: "Maintenance".into(), action: "query:check miss".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } diff --git a/src/plugins/mouse_gestures.rs b/src/plugins/mouse_gestures.rs index 6ddf5c55..6ddf3184 100644 --- a/src/plugins/mouse_gestures.rs +++ b/src/plugins/mouse_gestures.rs @@ -300,48 +300,72 @@ impl MouseGesturesPlugin { desc: "Mouse gestures".into(), action: "query:mg ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "mg settings".into(), desc: "Mouse gestures".into(), action: "mg:dialog:settings".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "mg edit".into(), desc: "Mouse gestures".into(), action: "mg:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "mg add".into(), desc: "Mouse gestures".into(), action: "mg:dialog:binding".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "mg list".into(), desc: "Mouse gestures".into(), action: "query:mg list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "mg find".into(), desc: "Mouse gestures".into(), action: "query:mg find ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "mg where".into(), desc: "Mouse gestures".into(), action: "query:mg where ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "mg conflicts".into(), desc: "Mouse gestures".into(), action: "query:mg conflicts".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } @@ -364,6 +388,9 @@ impl MouseGesturesPlugin { desc: "Mouse gestures".into(), action: "mg:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect() } @@ -401,6 +428,9 @@ impl Plugin for MouseGesturesPlugin { desc: "Mouse gestures".into(), action: "mg:dialog:settings".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } if strip_prefix_ci(trimmed, "mg edit").is_some() { @@ -409,6 +439,9 @@ impl Plugin for MouseGesturesPlugin { desc: "Mouse gestures".into(), action: "mg:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } if strip_prefix_ci(trimmed, "mg add").is_some() { @@ -417,6 +450,9 @@ impl Plugin for MouseGesturesPlugin { desc: "Mouse gestures".into(), action: "mg:dialog:binding".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } if let Some(rest) = strip_prefix_ci(trimmed, "mg find") { @@ -430,6 +466,9 @@ impl Plugin for MouseGesturesPlugin { desc: Self::format_match_desc(&context), action: "mg:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -444,6 +483,9 @@ impl Plugin for MouseGesturesPlugin { desc: "Mouse gestures".into(), action: "mg:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -474,6 +516,9 @@ impl Plugin for MouseGesturesPlugin { desc: conflict_desc.into(), action: "mg:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } diff --git a/src/plugins/network.rs b/src/plugins/network.rs index c4089b3a..c8d18ef1 100644 --- a/src/plugins/network.rs +++ b/src/plugins/network.rs @@ -173,6 +173,9 @@ impl Plugin for NetworkPlugin { desc: "Network".into(), action: format!("net:{name}"), args: None, + preview_text: None, + risk_level: None, + icon: None, } }) .collect() @@ -196,6 +199,9 @@ impl Plugin for NetworkPlugin { desc: "Network".into(), action: "query:net".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } diff --git a/src/plugins/note.rs b/src/plugins/note.rs index 603559f0..d60c52e1 100644 --- a/src/plugins/note.rs +++ b/src/plugins/note.rs @@ -745,6 +745,9 @@ impl Plugin for NotePlugin { desc: "Note".into(), action: "note:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; actions.extend([ Action { @@ -752,72 +755,108 @@ impl Plugin for NotePlugin { desc: "Note".into(), action: "query:note search ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note list".into(), desc: "Note".into(), action: "query:note list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note tag".into(), desc: "Note".into(), action: "query:note tag".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note templates".into(), desc: "Note".into(), action: "query:note templates".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note new".into(), desc: "Note".into(), action: "query:note new ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note add".into(), desc: "Note".into(), action: "query:note add ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note open".into(), desc: "Note".into(), action: "query:note open ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note today".into(), desc: "Note".into(), action: "query:note today".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note link".into(), desc: "Note".into(), action: "query:note link ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note rm".into(), desc: "Note".into(), action: "query:note rm ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note reload".into(), desc: "Note".into(), action: "note:reload".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "notes unused".into(), desc: "Note".into(), action: "note:unused_assets".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ]); return actions; @@ -840,6 +879,9 @@ impl Plugin for NotePlugin { desc: "Note".into(), action: "note:reload".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -867,6 +909,9 @@ impl Plugin for NotePlugin { desc: "Note".into(), action, args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -888,6 +933,9 @@ impl Plugin for NotePlugin { desc: "Note".into(), action: format!("note:open:{}", n.slug), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -942,6 +990,9 @@ impl Plugin for NotePlugin { desc: "Note".into(), action: format!("note:open:{}", n.slug), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -957,6 +1008,9 @@ impl Plugin for NotePlugin { desc: "Note".into(), action: format!("note:open:{}", n.slug), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -999,6 +1053,9 @@ impl Plugin for NotePlugin { desc: "Note".into(), action: format!("query:note list #{t}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -1024,6 +1081,9 @@ impl Plugin for NotePlugin { desc: "Note".into(), action, args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } "link" => { @@ -1033,6 +1093,9 @@ impl Plugin for NotePlugin { desc: "Usage".into(), action: "query:note link ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; actions.extend(guard.notes.iter().map(|n| Action { label: format!( @@ -1045,6 +1108,9 @@ impl Plugin for NotePlugin { n.alias.as_ref().unwrap_or(&n.title) ), args: None, + preview_text: None, + risk_level: None, + icon: None, })); return actions; } @@ -1057,6 +1123,9 @@ impl Plugin for NotePlugin { desc: "Backlinks".into(), action: "query:note link ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } }; @@ -1074,6 +1143,9 @@ impl Plugin for NotePlugin { desc: format!("Backlinks to {}", note.title), action: format!("note:open:{}", linked_note.slug), args: None, + preview_text: None, + risk_level: None, + icon: None, } }) .collect(); @@ -1084,6 +1156,9 @@ impl Plugin for NotePlugin { desc: "Backlinks".into(), action: format!("note:open:{}", note.slug), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } @@ -1106,6 +1181,9 @@ impl Plugin for NotePlugin { desc: "Note".into(), action: format!("note:remove:{}", n.slug), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -1116,6 +1194,9 @@ impl Plugin for NotePlugin { desc: "Note".into(), action: "note:unused_assets".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -1136,6 +1217,9 @@ impl Plugin for NotePlugin { desc: "Note".into(), action: format!("query:note new --template {name} "), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -1166,84 +1250,126 @@ impl Plugin for NotePlugin { desc: "Note".into(), action: "query:note".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note new".into(), desc: "Note".into(), action: "query:note new ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note add".into(), desc: "Note".into(), action: "query:note add ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note create".into(), desc: "Note".into(), action: "query:note create ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note open".into(), desc: "Note".into(), action: "query:note open ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note list".into(), desc: "Note".into(), action: "query:note list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note search".into(), desc: "Note".into(), action: "query:note search ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note tag".into(), desc: "Note".into(), action: "query:note tag".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note templates".into(), desc: "Note".into(), action: "query:note templates".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note today".into(), desc: "Note".into(), action: "query:note today".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note link".into(), desc: "Note".into(), action: "query:note link ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note rm".into(), desc: "Note".into(), action: "query:note rm ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "note reload".into(), desc: "Note".into(), action: "note:reload".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "notes unused".into(), desc: "Note".into(), action: "note:unused_assets".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/omni_search.rs b/src/plugins/omni_search.rs index 3498e440..1edbd341 100644 --- a/src/plugins/omni_search.rs +++ b/src/plugins/omni_search.rs @@ -101,12 +101,18 @@ impl Plugin for OmniSearchPlugin { desc: "Omni".into(), action: "query:o ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "o list".into(), desc: "Omni".into(), action: "query:o list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/processes.rs b/src/plugins/processes.rs index a5b58989..c393ccb4 100644 --- a/src/plugins/processes.rs +++ b/src/plugins/processes.rs @@ -42,12 +42,18 @@ impl Plugin for ProcessesPlugin { desc: format!("PID {pid}"), action: format!("process:switch:{pid}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }; let kill_action = Action { label: format!("Kill {name}"), desc: format!("PID {pid}"), action: format!("process:kill:{pid}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }; match mode { Mode::Both => vec![switch_action, kill_action], @@ -77,18 +83,27 @@ impl Plugin for ProcessesPlugin { desc: "Processes".into(), action: "query:ps ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "psk".into(), desc: "Kill process".into(), action: "query:psk ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "pss".into(), desc: "Switch process".into(), action: "query:pss ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/random.rs b/src/plugins/random.rs index 8a50498f..85d314ca 100644 --- a/src/plugins/random.rs +++ b/src/plugins/random.rs @@ -58,6 +58,9 @@ impl Plugin for RandomPlugin { desc: "Random number".into(), action: format!("clipboard:{value}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -69,6 +72,9 @@ impl Plugin for RandomPlugin { desc: "Dice roll".into(), action: format!("clipboard:{value}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } "pw" | "password" => { @@ -87,6 +93,9 @@ impl Plugin for RandomPlugin { desc: "Random password".into(), action: format!("clipboard:{pw}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -114,18 +123,27 @@ impl Plugin for RandomPlugin { desc: "Random number".into(), action: "query:rand number ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "rand dice".into(), desc: "Dice".into(), action: "query:rand dice".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "rand pw ".into(), desc: "Random password".into(), action: "query:rand pw ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/recycle.rs b/src/plugins/recycle.rs index b7db1173..f1107419 100644 --- a/src/plugins/recycle.rs +++ b/src/plugins/recycle.rs @@ -1,4 +1,4 @@ -use crate::actions::Action; +use crate::actions::{Action, ActionRiskLevel}; use crate::plugin::Plugin; pub struct RecyclePlugin; @@ -13,6 +13,9 @@ impl Plugin for RecyclePlugin { desc: "Recycle Bin".into(), action: "recycle:clean".into(), args: None, + preview_text: Some("Empties all items currently in the recycle bin.".into()), + risk_level: Some(ActionRiskLevel::High), + icon: Some("recycle".into()), }]; } Vec::new() @@ -36,6 +39,9 @@ impl Plugin for RecyclePlugin { desc: "Recycle".into(), action: "query:rec".into(), args: None, + preview_text: Some("Query shortcut for recycle-bin operations.".into()), + risk_level: Some(ActionRiskLevel::Low), + icon: Some("recycle".into()), }] } } diff --git a/src/plugins/reddit.rs b/src/plugins/reddit.rs index 381ac3fb..a1c6eeb3 100644 --- a/src/plugins/reddit.rs +++ b/src/plugins/reddit.rs @@ -15,6 +15,9 @@ impl Plugin for RedditPlugin { desc: "Web search".into(), action: format!("https://www.reddit.com/search/?q={}", encode(q)), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -39,6 +42,9 @@ impl Plugin for RedditPlugin { desc: "Reddit".into(), action: "query:red ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } diff --git a/src/plugins/runescape.rs b/src/plugins/runescape.rs index 745bd6bd..65a0c204 100644 --- a/src/plugins/runescape.rs +++ b/src/plugins/runescape.rs @@ -15,6 +15,9 @@ impl Plugin for RunescapeSearchPlugin { desc: "Web search".into(), action: format!("https://runescape.wiki/?search={}", encode(q)), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -27,6 +30,9 @@ impl Plugin for RunescapeSearchPlugin { desc: "Web search".into(), action: format!("https://oldschool.runescape.wiki/?search={}", encode(q)), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -52,12 +58,18 @@ impl Plugin for RunescapeSearchPlugin { desc: "Runescape".into(), action: "query:rs ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "osrs".into(), desc: "Runescape".into(), action: "query:osrs ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/screenshot.rs b/src/plugins/screenshot.rs index 25f1de35..e62655b2 100644 --- a/src/plugins/screenshot.rs +++ b/src/plugins/screenshot.rs @@ -99,42 +99,63 @@ impl Plugin for ScreenshotPlugin { desc: "Screenshot".into(), action: "screenshot:window".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "Screenshot region".into(), desc: "Screenshot".into(), action: "screenshot:region".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "Screenshot region (markup pen)".into(), desc: "Screenshot".into(), action: "screenshot:region_markup".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "Screenshot desktop".into(), desc: "Screenshot".into(), action: "screenshot:desktop".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "Screenshot active window to clipboard".into(), desc: "Screenshot".into(), action: "screenshot:window_clip".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "Screenshot region to clipboard".into(), desc: "Screenshot".into(), action: "screenshot:region_clip".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "Screenshot desktop to clipboard".into(), desc: "Screenshot".into(), action: "screenshot:desktop_clip".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } @@ -158,18 +179,27 @@ impl Plugin for ScreenshotPlugin { desc: "Screenshot".into(), action: "query:ss ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "shot clip".into(), desc: "Screenshot".into(), action: "query:ss clip".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "shot region markup".into(), desc: "Screenshot".into(), action: "screenshot:region_markup".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/settings.rs b/src/plugins/settings.rs index f7f5bbb1..4ddcb1b1 100644 --- a/src/plugins/settings.rs +++ b/src/plugins/settings.rs @@ -14,6 +14,9 @@ impl Plugin for SettingsPlugin { desc: "Show settings panel".into(), action: "settings:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -24,6 +27,9 @@ impl Plugin for SettingsPlugin { desc: "Configure dashboard layout and widgets".into(), action: "dashboard:settings".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -34,6 +40,9 @@ impl Plugin for SettingsPlugin { desc: "Configure launcher theme colors".into(), action: "theme:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -59,18 +68,27 @@ impl Plugin for SettingsPlugin { desc: "Settings".into(), action: "settings:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "Dashboard Settings".into(), desc: "Dashboard settings".into(), action: "dashboard:settings".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "Theme settings".into(), desc: "Configure launcher theme colors".into(), action: "theme:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/shell.rs b/src/plugins/shell.rs index 3616c834..edb47d40 100644 --- a/src/plugins/shell.rs +++ b/src/plugins/shell.rs @@ -12,6 +12,9 @@ pub const SHELL_CMDS_FILE: &str = "shell_cmds.json"; pub struct ShellCmdEntry { pub name: String, pub args: String, + preview_text: None, + risk_level: None, + icon: None, /// When false this command will not be suggested when typing `sh `. #[serde(default = "default_autocomplete")] pub autocomplete: bool, @@ -66,6 +69,9 @@ pub fn append_shell_cmd(path: &str, name: &str, args: &str) -> anyhow::Result<() list.push(ShellCmdEntry { name: name.to_string(), args: args.to_string(), + preview_text: None, + risk_level: None, + icon: None, autocomplete: true, keep_open: false, }); @@ -96,6 +102,9 @@ impl Plugin for ShellPlugin { desc: "Shell".into(), action: "shell:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -111,6 +120,9 @@ impl Plugin for ShellPlugin { desc: "Shell".into(), action: format!("shell:add:{name}|{args}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -132,6 +144,9 @@ impl Plugin for ShellPlugin { desc: "Shell".into(), action: format!("shell:remove:{}", c.name), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -155,6 +170,9 @@ impl Plugin for ShellPlugin { desc: "Shell".into(), action: format!("{}{}", prefix, c.args), args: None, + preview_text: None, + risk_level: None, + icon: None, } }) .collect(); @@ -188,6 +206,9 @@ impl Plugin for ShellPlugin { desc: "Shell".into(), action: format!("{}{}", prefix, entry.args), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -196,6 +217,9 @@ impl Plugin for ShellPlugin { desc: "Shell".into(), action: format!("shell:{}", arg), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } Vec::new() @@ -220,24 +244,36 @@ impl Plugin for ShellPlugin { desc: "Shell".into(), action: "query:sh".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "sh add".into(), desc: "Shell".into(), action: "query:sh add ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "sh rm".into(), desc: "Shell".into(), action: "query:sh rm ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "sh list".into(), desc: "Shell".into(), action: "query:sh list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/snippets.rs b/src/plugins/snippets.rs index f3cf641d..8499771a 100644 --- a/src/plugins/snippets.rs +++ b/src/plugins/snippets.rs @@ -135,6 +135,9 @@ impl Plugin for SnippetsPlugin { desc: "Snippet".into(), action: "snippet:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -156,6 +159,9 @@ impl Plugin for SnippetsPlugin { desc: "Snippet".into(), action: format!("snippet:remove:{}", s.alias.clone()), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -170,6 +176,9 @@ impl Plugin for SnippetsPlugin { desc: "Snippet".into(), action: format!("snippet:add:{alias}|{text}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -185,6 +194,9 @@ impl Plugin for SnippetsPlugin { desc: "Snippet".into(), action: format!("snippet:add:{alias}|{text}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -205,6 +217,9 @@ impl Plugin for SnippetsPlugin { desc: "Snippet".into(), action: format!("snippet:edit:{}", s.alias.clone()), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -226,6 +241,9 @@ impl Plugin for SnippetsPlugin { desc: "Snippet".into(), action: format!("clipboard:{}", s.text.clone()), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -247,6 +265,9 @@ impl Plugin for SnippetsPlugin { desc: "Snippet".into(), action: format!("clipboard:{}", s.text.clone()), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -272,30 +293,45 @@ impl Plugin for SnippetsPlugin { desc: "Snippet".into(), action: "query:cs".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cs add".into(), desc: "Snippet".into(), action: "query:cs add ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cs rm".into(), desc: "Snippet".into(), action: "query:cs rm ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cs list".into(), desc: "Snippet".into(), action: "query:cs list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "cs edit".into(), desc: "Snippet".into(), action: "query:cs edit".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/stopwatch.rs b/src/plugins/stopwatch.rs index e77efb92..f1c48223 100644 --- a/src/plugins/stopwatch.rs +++ b/src/plugins/stopwatch.rs @@ -224,6 +224,9 @@ impl Plugin for StopwatchPlugin { desc: "Stopwatch".into(), action, args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } if crate::common::strip_prefix_ci(rest, "list").is_some() || rest.is_empty() { @@ -241,6 +244,9 @@ impl Plugin for StopwatchPlugin { desc: "Stopwatch".into(), action: format!("stopwatch:show:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, } }) .collect(); @@ -255,6 +261,9 @@ impl Plugin for StopwatchPlugin { desc: "Stopwatch".into(), action: format!("stopwatch:pause:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } else if let Ok(id) = tail.parse::() { @@ -263,6 +272,9 @@ impl Plugin for StopwatchPlugin { desc: "Stopwatch".into(), action: format!("stopwatch:pause:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -276,6 +288,9 @@ impl Plugin for StopwatchPlugin { desc: "Stopwatch".into(), action: format!("stopwatch:resume:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } else if let Ok(id) = tail.parse::() { @@ -284,6 +299,9 @@ impl Plugin for StopwatchPlugin { desc: "Stopwatch".into(), action: format!("stopwatch:resume:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -297,6 +315,9 @@ impl Plugin for StopwatchPlugin { desc: "Stopwatch".into(), action: format!("stopwatch:stop:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } else if let Ok(id) = tail.parse::() { @@ -305,6 +326,9 @@ impl Plugin for StopwatchPlugin { desc: "Stopwatch".into(), action: format!("stopwatch:stop:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -325,6 +349,9 @@ impl Plugin for StopwatchPlugin { desc: "Stopwatch".into(), action: format!("stopwatch:show:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, } }) .collect(); @@ -335,6 +362,9 @@ impl Plugin for StopwatchPlugin { desc: "Stopwatch".into(), action: format!("stopwatch:show:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -361,30 +391,45 @@ impl Plugin for StopwatchPlugin { desc: "Stopwatch".into(), action: "query:sw start ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "sw list".into(), desc: "Stopwatch".into(), action: "query:sw list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "sw pause".into(), desc: "Stopwatch".into(), action: "query:sw pause".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "sw resume".into(), desc: "Stopwatch".into(), action: "query:sw resume".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "sw stop".into(), desc: "Stopwatch".into(), action: "query:sw stop".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/sysinfo.rs b/src/plugins/sysinfo.rs index 380941d9..3fbdcdd8 100644 --- a/src/plugins/sysinfo.rs +++ b/src/plugins/sysinfo.rs @@ -13,6 +13,9 @@ impl SysInfoPlugin { desc: "SysInfo".into(), action: "sysinfo:cpu".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, } } @@ -29,6 +32,9 @@ impl SysInfoPlugin { desc: "SysInfo".into(), action: "sysinfo:mem".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, } } @@ -51,6 +57,9 @@ impl SysInfoPlugin { desc: "SysInfo".into(), action: "sysinfo:disk".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, } } @@ -60,6 +69,9 @@ impl SysInfoPlugin { desc: "SysInfo".into(), action: format!("sysinfo:cpu_list:{count}"), args: None, + preview_text: None, + risk_level: None, + icon: None, } } } @@ -113,24 +125,36 @@ impl Plugin for SysInfoPlugin { desc: "SysInfo".into(), action: "query:info".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "info cpu".into(), desc: "SysInfo".into(), action: "query:info cpu".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "info mem".into(), desc: "SysInfo".into(), action: "query:info mem".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "info disk".into(), desc: "SysInfo".into(), action: "query:info disk".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/system.rs b/src/plugins/system.rs index cfef8e8f..4d4ea9c2 100644 --- a/src/plugins/system.rs +++ b/src/plugins/system.rs @@ -1,4 +1,4 @@ -use crate::actions::Action; +use crate::actions::{Action, ActionRiskLevel}; use crate::plugin::Plugin; pub struct SystemPlugin; @@ -20,6 +20,13 @@ impl Plugin for SystemPlugin { desc: "System".into(), action: format!("system:{}", o), args: None, + preview_text: Some(format!("Performs a system-level {o} operation.")), + risk_level: Some(match *o { + "shutdown" | "reboot" => ActionRiskLevel::Critical, + "logoff" => ActionRiskLevel::High, + _ => ActionRiskLevel::Medium, + }), + icon: Some("power".into()), }) .collect() } @@ -42,6 +49,9 @@ impl Plugin for SystemPlugin { desc: "System".into(), action: "query:sys ".into(), args: None, + preview_text: Some("Search system power actions.".into()), + risk_level: Some(ActionRiskLevel::Low), + icon: Some("power".into()), }] } } diff --git a/src/plugins/task_manager.rs b/src/plugins/task_manager.rs index 31643cc8..e4c0ce69 100644 --- a/src/plugins/task_manager.rs +++ b/src/plugins/task_manager.rs @@ -1,4 +1,4 @@ -use crate::actions::Action; +use crate::actions::{Action, ActionRiskLevel}; use crate::plugin::Plugin; pub struct TaskManagerPlugin; @@ -12,6 +12,11 @@ impl Plugin for TaskManagerPlugin { desc: "Task Manager".into(), action: "shell:taskmgr".into(), args: None, + preview_text: Some( + "Opens Windows Task Manager to inspect and end running tasks.".into(), + ), + risk_level: Some(ActionRiskLevel::Medium), + icon: Some("task_manager".into()), }]; } Vec::new() @@ -35,6 +40,9 @@ impl Plugin for TaskManagerPlugin { desc: "Task Manager".into(), action: "query:tm".into(), args: None, + preview_text: Some("Query shortcut for Task Manager commands.".into()), + risk_level: Some(ActionRiskLevel::Low), + icon: Some("task_manager".into()), }] } } diff --git a/src/plugins/tempfile.rs b/src/plugins/tempfile.rs index 7db88ae0..5811c222 100644 --- a/src/plugins/tempfile.rs +++ b/src/plugins/tempfile.rs @@ -143,6 +143,9 @@ impl Plugin for TempfilePlugin { desc: "Tempfile".into(), action: "tempfile:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -158,6 +161,9 @@ impl Plugin for TempfilePlugin { desc: "Tempfile".into(), action: format!("tempfile:new:{alias}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } else if let Some(rest) = crate::common::strip_prefix_ci(trimmed, "tmp new") @@ -169,6 +175,9 @@ impl Plugin for TempfilePlugin { desc: "Tempfile".into(), action: "tempfile:new".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -179,6 +188,9 @@ impl Plugin for TempfilePlugin { desc: "Tempfile".into(), action: "tempfile:open".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -189,6 +201,9 @@ impl Plugin for TempfilePlugin { desc: "Tempfile".into(), action: "tempfile:clear".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -215,6 +230,9 @@ impl Plugin for TempfilePlugin { desc: "Tempfile".into(), action: format!("tempfile:remove:{}", p.to_string_lossy()), args: None, + preview_text: None, + risk_level: None, + icon: None, } }) .collect(); @@ -238,6 +256,9 @@ impl Plugin for TempfilePlugin { desc: "Tempfile".into(), action: format!("tempfile:alias:{}|{}", p.to_string_lossy(), alias), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -267,6 +288,9 @@ impl Plugin for TempfilePlugin { desc: "Tempfile".into(), action: p.to_string_lossy().into(), args: None, + preview_text: None, + risk_level: None, + icon: None, } }) .collect(); @@ -293,42 +317,63 @@ impl Plugin for TempfilePlugin { desc: "Tempfile".into(), action: "query:tmp".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "tmp new".into(), desc: "Tempfile".into(), action: "query:tmp new ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "tmp create".into(), desc: "Tempfile".into(), action: "query:tmp create ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "tmp open".into(), desc: "Tempfile".into(), action: "query:tmp open".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "tmp clear".into(), desc: "Tempfile".into(), action: "query:tmp clear".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "tmp list".into(), desc: "Tempfile".into(), action: "query:tmp list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "tmp rm".into(), desc: "Tempfile".into(), action: "query:tmp rm ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/text_case.rs b/src/plugins/text_case.rs index 57dbe11d..4e2280bb 100644 --- a/src/plugins/text_case.rs +++ b/src/plugins/text_case.rs @@ -319,6 +319,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Uppercase".into(), action: format!("clipboard:{}", upper), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -328,6 +331,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Lowercase".into(), action: format!("clipboard:{}", lower), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -337,6 +343,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Capitalized".into(), action: format!("clipboard:{}", capitalized), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -346,6 +355,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Camel".into(), action: format!("clipboard:{}", camel), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -355,6 +367,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Pascal".into(), action: format!("clipboard:{}", pascal), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -364,6 +379,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Snake".into(), action: format!("clipboard:{}", snake), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -373,6 +391,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Screaming".into(), action: format!("clipboard:{}", screaming), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -382,6 +403,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Kebab".into(), action: format!("clipboard:{}", kebab), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -391,6 +415,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Train".into(), action: format!("clipboard:{}", train), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -400,6 +427,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Dot".into(), action: format!("clipboard:{}", dot), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -409,6 +439,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Alternating".into(), action: format!("clipboard:{}", alt_case), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -418,6 +451,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Mocking".into(), action: format!("clipboard:{}", mocking), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -427,6 +463,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Inverse".into(), action: format!("clipboard:{}", inverse), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -436,6 +475,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Backwards".into(), action: format!("clipboard:{}", backwards), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -445,6 +487,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Acronym".into(), action: format!("clipboard:{}", acronym), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -454,6 +499,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Initials".into(), action: format!("clipboard:{}", initial_caps), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -463,6 +511,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Title".into(), action: format!("clipboard:{}", title_case), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -472,6 +523,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Sentence".into(), action: format!("clipboard:{}", sentence), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -481,6 +535,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Base64".into(), action: format!("clipboard:{}", b64), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -490,6 +547,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Hex".into(), action: format!("clipboard:{}", hex_enc), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -499,6 +559,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Binary".into(), action: format!("clipboard:{}", binary), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -508,6 +571,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-ROT13".into(), action: format!("clipboard:{}", rot13), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -517,6 +583,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Clap".into(), action: format!("clipboard:{}", clap), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -526,6 +595,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Emoji".into(), action: format!("clipboard:{}", emoji_case), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -535,6 +607,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Custom".into(), action: format!("clipboard:{}", custom), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ( @@ -544,6 +619,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case-Morse".into(), action: format!("clipboard:{}", morse), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ), ]; @@ -578,6 +656,9 @@ impl Plugin for TextCasePlugin { desc: "Text Case".into(), action: "query:case ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } diff --git a/src/plugins/timer.rs b/src/plugins/timer.rs index 182c9a95..0a632d56 100644 --- a/src/plugins/timer.rs +++ b/src/plugins/timer.rs @@ -664,6 +664,9 @@ impl Plugin for TimerPlugin { desc: "Timer".into(), action: "timer:dialog:timer".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -674,6 +677,9 @@ impl Plugin for TimerPlugin { desc: "Timer".into(), action: "timer:dialog:alarm".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -687,6 +693,9 @@ impl Plugin for TimerPlugin { desc: "Timer".into(), action: format!("timer:show:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -698,6 +707,9 @@ impl Plugin for TimerPlugin { desc: "Timer".into(), action: format!("timer:cancel:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -709,6 +721,9 @@ impl Plugin for TimerPlugin { desc: "Timer".into(), action: format!("timer:cancel:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -722,6 +737,9 @@ impl Plugin for TimerPlugin { desc: "Timer".into(), action: format!("timer:pause:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } else if let Ok(id) = tail.parse::() { @@ -730,6 +748,9 @@ impl Plugin for TimerPlugin { desc: "Timer".into(), action: format!("timer:pause:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -743,6 +764,9 @@ impl Plugin for TimerPlugin { desc: "Timer".into(), action: format!("timer:resume:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } else if let Ok(id) = tail.parse::() { @@ -751,6 +775,9 @@ impl Plugin for TimerPlugin { desc: "Timer".into(), action: format!("timer:resume:{id}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -775,6 +802,9 @@ impl Plugin for TimerPlugin { desc: "Timer".into(), action, args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -799,6 +829,9 @@ impl Plugin for TimerPlugin { desc: "Timer".into(), action, args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -824,48 +857,72 @@ impl Plugin for TimerPlugin { desc: "Timer".into(), action: "query:timer".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "timer add".into(), desc: "Timer".into(), action: "query:timer add ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "timer list".into(), desc: "Timer".into(), action: "query:timer list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "timer pause".into(), desc: "Timer".into(), action: "query:timer pause".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "timer resume".into(), desc: "Timer".into(), action: "query:timer resume".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "timer cancel".into(), desc: "Timer".into(), action: "query:timer cancel".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "timer rm".into(), desc: "Timer".into(), action: "query:timer rm".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "alarm".into(), desc: "Timer".into(), action: "query:alarm".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/timestamp.rs b/src/plugins/timestamp.rs index fc017614..4c407798 100644 --- a/src/plugins/timestamp.rs +++ b/src/plugins/timestamp.rs @@ -64,6 +64,9 @@ impl Plugin for TimestampPlugin { desc: "Midnight TS".into(), action: format!("clipboard:{out}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } else if let Some(ms) = Self::string_to_ms(arg) { @@ -73,6 +76,9 @@ impl Plugin for TimestampPlugin { desc: "Midnight TS".into(), action: format!("clipboard:{out}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } else if let Some(rest) = crate::common::strip_prefix_ci(trimmed, PREFIX) { @@ -97,6 +103,9 @@ impl Plugin for TimestampPlugin { desc: "Timestamp".into(), action: format!("clipboard:{out}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } else { @@ -110,6 +119,9 @@ impl Plugin for TimestampPlugin { desc: "Timestamp".into(), action: format!("clipboard:{ts}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -137,12 +149,18 @@ impl Plugin for TimestampPlugin { desc: "Timestamp".into(), action: "query:ts ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "tsm ".into(), desc: "Midnight TS".into(), action: "query:tsm ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/todo.rs b/src/plugins/todo.rs index fdc362bd..f33b1ad1 100644 --- a/src/plugins/todo.rs +++ b/src/plugins/todo.rs @@ -41,6 +41,9 @@ fn usage_action(usage: &str, query: &str) -> Action { desc: "Todo".into(), action: format!("query:{query}"), args: None, + preview_text: None, + risk_level: None, + icon: None, } } @@ -263,6 +266,9 @@ impl TodoPlugin { desc: "Todo".into(), action: "todo:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } if rest.trim().is_empty() { @@ -271,6 +277,9 @@ impl TodoPlugin { desc: "Todo".into(), action: "todo:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; actions.extend([ Action { @@ -278,54 +287,81 @@ impl TodoPlugin { desc: "Todo".into(), action: "query:todo edit".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo list".into(), desc: "Todo".into(), action: "query:todo list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo tag".into(), desc: "Todo".into(), action: "query:todo tag ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo view".into(), desc: "Todo".into(), action: "query:todo view ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo add".into(), desc: "Todo".into(), action: "query:todo add ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo rm".into(), desc: "Todo".into(), action: "query:todo rm ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo clear".into(), desc: "Todo".into(), action: "query:todo clear".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo pset".into(), desc: "Todo".into(), action: "query:todo pset ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo export".into(), desc: "Todo".into(), action: "query:todo export".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ]); return actions; @@ -366,6 +402,9 @@ impl TodoPlugin { desc: "Todo".into(), action: format!("todo:edit:{idx}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -377,6 +416,9 @@ impl TodoPlugin { desc: "Todo".into(), action: "todo:view".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } return vec![usage_action(TODO_VIEW_USAGE, "todo view")]; @@ -389,6 +431,9 @@ impl TodoPlugin { desc: "Todo".into(), action: "todo:export".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } return vec![usage_action(TODO_EXPORT_USAGE, "todo export")]; @@ -401,6 +446,9 @@ impl TodoPlugin { desc: "Todo".into(), action: "todo:clear".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } return vec![usage_action(TODO_CLEAR_USAGE, "todo clear")]; @@ -413,6 +461,9 @@ impl TodoPlugin { desc: "Todo".into(), action: "todo:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, usage_action(TODO_ADD_USAGE, "todo add "), ]; @@ -473,6 +524,9 @@ impl TodoPlugin { desc: "Todo".into(), action: format!("todo:add:{encoded_payload}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } ParseArgsResult::Usage(usage) => { @@ -497,6 +551,9 @@ impl TodoPlugin { desc: "Todo".into(), action: format!("todo:pset:{idx}|{priority}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } ParseArgsResult::Usage(usage) => { @@ -530,6 +587,9 @@ impl TodoPlugin { desc: "Todo".into(), action: format!("todo:tag:{encoded_payload}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } @@ -590,6 +650,9 @@ impl TodoPlugin { desc: "Todo".into(), action: format!("query:todo list #{tag}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -613,6 +676,9 @@ impl TodoPlugin { desc: "Todo".into(), action: format!("todo:remove:{idx}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -676,6 +742,9 @@ impl TodoPlugin { desc: "Todo".into(), action: format!("todo:done:{idx}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -732,60 +801,90 @@ impl Plugin for TodoPlugin { desc: "Todo".into(), action: "query:todo".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo add".into(), desc: "Todo".into(), action: "query:todo add ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo list".into(), desc: "Todo".into(), action: "query:todo list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo rm".into(), desc: "Todo".into(), action: "query:todo rm ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo clear".into(), desc: "Todo".into(), action: "query:todo clear".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo pset".into(), desc: "Todo".into(), action: "query:todo pset ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo tag".into(), desc: "Todo".into(), action: "query:todo tag ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo edit".into(), desc: "Todo".into(), action: "query:todo edit".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo view".into(), desc: "Todo".into(), action: "query:todo view ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "todo export".into(), desc: "Todo".into(), action: "query:todo export".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/unit_convert.rs b/src/plugins/unit_convert.rs index 45c6d94a..d9748ada 100644 --- a/src/plugins/unit_convert.rs +++ b/src/plugins/unit_convert.rs @@ -369,6 +369,9 @@ impl Plugin for UnitConvertPlugin { desc: "Unit convert".into(), action, args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -394,12 +397,18 @@ impl Plugin for UnitConvertPlugin { desc: "Unit convert".into(), action: "query:conv ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "convert".into(), desc: "Unit convert".into(), action: "query:convert ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/volume.rs b/src/plugins/volume.rs index 34e778c5..8aebe778 100644 --- a/src/plugins/volume.rs +++ b/src/plugins/volume.rs @@ -20,6 +20,9 @@ impl Plugin for VolumePlugin { desc: "Volume".into(), action: "volume:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -32,6 +35,9 @@ impl Plugin for VolumePlugin { desc: "Volume".into(), action: "volume:mute_active".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } [level] => { @@ -42,6 +48,9 @@ impl Plugin for VolumePlugin { desc: "Volume".into(), action: format!("volume:set:{val}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -55,6 +64,9 @@ impl Plugin for VolumePlugin { desc: "Volume".into(), action: format!("volume:pid:{pid}:{level}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -81,6 +93,9 @@ impl Plugin for VolumePlugin { desc: format!("PID {pid}"), action: format!("volume:pid:{pid}:{level}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -111,12 +126,18 @@ impl Plugin for VolumePlugin { desc: "Volume".into(), action: "query:vol ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "vol ma".into(), desc: "Volume".into(), action: "query:vol ma".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/plugins/weather.rs b/src/plugins/weather.rs index 5e860a67..933d6629 100644 --- a/src/plugins/weather.rs +++ b/src/plugins/weather.rs @@ -17,6 +17,9 @@ impl Plugin for WeatherPlugin { desc: "Web search".into(), action: format!("https://www.weather.com/weather/today/l/{}", encode(q)), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -41,6 +44,9 @@ impl Plugin for WeatherPlugin { desc: "Weather".into(), action: "query:weather ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } diff --git a/src/plugins/wikipedia.rs b/src/plugins/wikipedia.rs index 03a963bd..d74ae401 100644 --- a/src/plugins/wikipedia.rs +++ b/src/plugins/wikipedia.rs @@ -19,6 +19,9 @@ impl Plugin for WikipediaPlugin { encode(q) ), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -43,6 +46,9 @@ impl Plugin for WikipediaPlugin { desc: "Wikipedia".into(), action: "query:wiki ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } diff --git a/src/plugins/windows.rs b/src/plugins/windows.rs index a66e2e5a..c6cc3a9f 100644 --- a/src/plugins/windows.rs +++ b/src/plugins/windows.rs @@ -36,12 +36,18 @@ impl Plugin for WindowsPlugin { desc: "Windows".into(), action: format!("window:switch:{}", hwnd.0 as usize), args: None, + preview_text: None, + risk_level: None, + icon: None, }); ctx.out.push(Action { label: format!("Close {title}"), desc: "Windows".into(), action: format!("window:close:{}", hwnd.0 as usize), args: None, + preview_text: None, + risk_level: None, + icon: None, }); } } @@ -77,6 +83,9 @@ impl Plugin for WindowsPlugin { desc: "Windows".into(), action: "query:win ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } diff --git a/src/plugins/youtube.rs b/src/plugins/youtube.rs index fc436e9d..f9c038f2 100644 --- a/src/plugins/youtube.rs +++ b/src/plugins/youtube.rs @@ -16,6 +16,9 @@ impl Plugin for YoutubePlugin { desc: "Web search".into(), action: format!("https://www.youtube.com/results?search_query={}", encode(q)), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; } } @@ -40,6 +43,9 @@ impl Plugin for YoutubePlugin { desc: "YouTube".into(), action: "query:yt ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } diff --git a/src/plugins_builtin.rs b/src/plugins_builtin.rs index a5c4a5a8..e3234a74 100644 --- a/src/plugins_builtin.rs +++ b/src/plugins_builtin.rs @@ -16,6 +16,9 @@ impl Plugin for WebSearchPlugin { desc: "Web search".into(), action: format!("https://www.google.com/search?q={}", encode(q)), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } else { Vec::new() @@ -40,6 +43,9 @@ impl Plugin for WebSearchPlugin { desc: "Web search".into(), action: "query:g ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } @@ -71,6 +77,9 @@ impl Plugin for CalculatorPlugin { desc: "Calculator".into(), action: format!("calc:history:{idx}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); } @@ -89,6 +98,9 @@ impl Plugin for CalculatorPlugin { desc: "Calculator".into(), action: format!("calc:{}", result), args: Some(expr.to_string()), + preview_text: None, + risk_level: None, + icon: None, }] } else { let entry = CalcHistoryEntry { @@ -101,6 +113,9 @@ impl Plugin for CalculatorPlugin { desc: "Calculator".into(), action: format!("calc:{}", result), args: None, + preview_text: None, + risk_level: None, + icon: None, }] } } @@ -130,18 +145,27 @@ impl Plugin for CalculatorPlugin { desc: "Calculator".into(), action: "query:= ".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "= history".into(), desc: "Calculator".into(), action: "query:= history".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "calc list".into(), desc: "Calculator".into(), action: "query:calc list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ] } diff --git a/src/settings.rs b/src/settings.rs index 078e8d86..cae661c8 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -296,6 +296,10 @@ pub struct Settings { /// Scale factor for the action list. Defaults to `1.0`. #[serde(default = "default_scale")] pub list_scale: Option, + #[serde(default = "default_preview_enabled")] + pub preview_enabled: bool, + #[serde(default)] + pub preview_compact_mode: bool, /// Weight of the fuzzy match score when ranking results. #[serde(default = "default_fuzzy_weight")] pub fuzzy_weight: f32, @@ -476,6 +480,10 @@ fn default_log_path() -> PathBuf { .unwrap_or_else(|| PathBuf::from("launcher.log")) } +fn default_preview_enabled() -> bool { + true +} + fn default_launcher_hotkey() -> Option { if std::env::var("ML_DEFAULT_HOTKEY_NONE").is_ok() { None @@ -507,6 +515,8 @@ impl Default for Settings { toast_duration: default_toast_duration(), query_scale: Some(1.0), list_scale: Some(1.0), + preview_enabled: default_preview_enabled(), + preview_compact_mode: false, fuzzy_weight: default_fuzzy_weight(), usage_weight: default_usage_weight(), query_autocomplete: default_query_autocomplete(), diff --git a/src/settings_editor.rs b/src/settings_editor.rs index e25aa6a8..81489c83 100644 --- a/src/settings_editor.rs +++ b/src/settings_editor.rs @@ -36,6 +36,8 @@ pub struct SettingsEditor { note_more_limit: usize, query_scale: f32, list_scale: f32, + preview_enabled: bool, + preview_compact_mode: bool, history_limit: usize, clipboard_limit: usize, fuzzy_weight: f32, @@ -133,6 +135,8 @@ impl SettingsEditor { note_more_limit: settings.note_more_limit, query_scale: settings.query_scale.unwrap_or(1.0), list_scale: settings.list_scale.unwrap_or(1.0), + preview_enabled: settings.preview_enabled, + preview_compact_mode: settings.preview_compact_mode, history_limit: settings.history_limit, clipboard_limit: settings.clipboard_limit, fuzzy_weight: settings.fuzzy_weight, @@ -274,6 +278,8 @@ impl SettingsEditor { note_more_limit: self.note_more_limit, query_scale: Some(self.query_scale), list_scale: Some(self.list_scale), + preview_enabled: self.preview_enabled, + preview_compact_mode: self.preview_compact_mode, history_limit: self.history_limit, clipboard_limit: self.clipboard_limit, fuzzy_weight: self.fuzzy_weight, @@ -449,6 +455,8 @@ impl SettingsEditor { ui.label("List scale"); ui.add(egui::Slider::new(&mut self.list_scale, 0.5..=5.0).text("")); }); + ui.checkbox(&mut self.preview_enabled, "Enable action preview panel"); + ui.checkbox(&mut self.preview_compact_mode, "Use compact preview mode"); if ui.button("Open Theme Settings...").clicked() { app.open_theme_settings_dialog(); } @@ -795,6 +803,9 @@ impl SettingsEditor { new_settings.query_scale.unwrap_or(1.0).min(5.0); app.list_scale = new_settings.list_scale.unwrap_or(1.0).min(5.0); + app.preview_enabled = new_settings.preview_enabled; + app.preview_compact_mode = + new_settings.preview_compact_mode; app.history_limit = new_settings.history_limit; app.clipboard_limit = new_settings.clipboard_limit; app.page_jump = new_settings.page_jump; diff --git a/tests/dashboard_config.rs b/tests/dashboard_config.rs index 9c8575ed..43ba41fc 100644 --- a/tests/dashboard_config.rs +++ b/tests/dashboard_config.rs @@ -140,6 +140,9 @@ fn activation_applies_query_override_first() { desc: "".into(), action: "query:after".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }; app.activate_action(action, Some("override".into()), ActivationSource::Dashboard); assert_eq!(app.query, "after"); diff --git a/tests/gui_visibility.rs b/tests/gui_visibility.rs index 0b764e2c..d44ce550 100644 --- a/tests/gui_visibility.rs +++ b/tests/gui_visibility.rs @@ -80,3 +80,10 @@ fn queued_visibility_applies_when_context_available() { _ => panic!("unexpected command"), } } + +#[test] +fn settings_default_enable_preview_panel() { + let settings = multi_launcher::settings::Settings::default(); + assert!(settings.preview_enabled); + assert!(!settings.preview_compact_mode); +} diff --git a/tests/hide_after_run.rs b/tests/hide_after_run.rs index a3194196..efbff2f4 100644 --- a/tests/hide_after_run.rs +++ b/tests/hide_after_run.rs @@ -44,6 +44,9 @@ fn run_action(action: &str) -> bool { desc: "".into(), action: action.into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; let (mut app, flag) = new_app_with_settings(&ctx, actions, Settings::default()); app.update_paths( diff --git a/tests/history.rs b/tests/history.rs index 0466457d..c0c9c872 100644 --- a/tests/history.rs +++ b/tests/history.rs @@ -40,6 +40,9 @@ fn clear_history_empties_file() { desc: "".into(), action: "run".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, source: None, timestamp: 0, @@ -80,6 +83,9 @@ fn gesture_activation_increments_history() { desc: "".into(), action: "history:clear".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }; app.activate_action(action, None, ActivationSource::Gesture); @@ -104,6 +110,9 @@ fn gesture_query_action_sets_query_without_execution() { desc: "".into(), action: "query:hello".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }; app.activate_action(action, None, ActivationSource::Gesture); diff --git a/tests/layout_plugin.rs b/tests/layout_plugin.rs new file mode 100644 index 00000000..b495fd03 --- /dev/null +++ b/tests/layout_plugin.rs @@ -0,0 +1,13 @@ +use multi_launcher::plugin::Plugin; +use multi_launcher::plugins::layout::LayoutPlugin; + +#[test] +fn layout_command_has_metadata() { + let plugin = LayoutPlugin; + let results = plugin.commands(); + assert!(!results.is_empty()); + let action = &results[0]; + assert!(action.preview_text.is_some()); + assert!(action.risk_level.is_some()); + assert!(action.icon.is_some()); +} diff --git a/tests/mouse_gestures_db.rs b/tests/mouse_gestures_db.rs index 69813747..8821a620 100644 --- a/tests/mouse_gestures_db.rs +++ b/tests/mouse_gestures_db.rs @@ -56,6 +56,9 @@ fn gesture_db_round_trip_serialization() { kind: BindingKind::Execute, action: "stopwatch:show:1".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }], }], @@ -152,6 +155,9 @@ fn matching_skips_disabled_gestures_and_bindings() { kind: BindingKind::Execute, action: "stopwatch:show:1".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }], }, @@ -166,6 +172,9 @@ fn matching_skips_disabled_gestures_and_bindings() { kind: BindingKind::Execute, action: "stopwatch:show:2".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: false, }], }, @@ -193,6 +202,9 @@ fn binding_resolution_is_deterministic() { kind: BindingKind::Execute, action: "stopwatch:show:1".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }, BindingEntry { @@ -200,6 +212,9 @@ fn binding_resolution_is_deterministic() { kind: BindingKind::Execute, action: "stopwatch:show:2".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }, ], @@ -215,6 +230,9 @@ fn binding_resolution_is_deterministic() { kind: BindingKind::Execute, action: "stopwatch:show:3".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }], }, @@ -243,6 +261,9 @@ fn binding_enabled_state_persists_and_controls_matching() { kind: BindingKind::Execute, action: "stopwatch:show:1".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: false, }], }], @@ -275,6 +296,9 @@ fn candidate_matching_ranks_exact_over_prefix_over_fuzzy() { kind: BindingKind::Execute, action: "stopwatch:show:1".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }], }, @@ -289,6 +313,9 @@ fn candidate_matching_ranks_exact_over_prefix_over_fuzzy() { kind: BindingKind::Execute, action: "stopwatch:show:2".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }], }, @@ -303,6 +330,9 @@ fn candidate_matching_ranks_exact_over_prefix_over_fuzzy() { kind: BindingKind::Execute, action: "stopwatch:show:3".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }], }, @@ -331,6 +361,9 @@ fn search_bindings_matches_across_fields() { kind: BindingKind::Execute, action: "browser:open".into(), args: Some("profile=work".into()), + preview_text: None, + risk_level: None, + icon: None, enabled: true, }], }], @@ -371,6 +404,9 @@ fn find_by_action_matches_prefixes() { kind: BindingKind::Execute, action: "browser:open".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }], }], @@ -398,6 +434,9 @@ fn find_conflicts_groups_duplicates_and_prefixes() { kind: BindingKind::Execute, action: "browser:open".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }], }, @@ -412,6 +451,9 @@ fn find_conflicts_groups_duplicates_and_prefixes() { kind: BindingKind::Execute, action: "mail:open".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }], }, @@ -426,6 +468,9 @@ fn find_conflicts_groups_duplicates_and_prefixes() { kind: BindingKind::Execute, action: "settings:open".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }], }, @@ -440,6 +485,9 @@ fn find_conflicts_groups_duplicates_and_prefixes() { kind: BindingKind::Execute, action: "other:open".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }], }, @@ -501,6 +549,9 @@ fn watch_event_executes_action() { desc: "".into(), action: "query:after".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, })); app.process_watch_events(); assert_eq!(app.query, "after"); @@ -524,6 +575,9 @@ fn set_query_binding_avoids_execute_action() { kind: BindingKind::SetQuery, action: "timer list".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, enabled: true, }; let action = binding.to_action("Gesture"); diff --git a/tests/omni_search_plugin.rs b/tests/omni_search_plugin.rs index 8d2f13dc..24bb3c0f 100644 --- a/tests/omni_search_plugin.rs +++ b/tests/omni_search_plugin.rs @@ -39,6 +39,9 @@ fn o_list_combines_all_sources() { desc: "app".into(), action: "myapp".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]); let plugin = OmniSearchPlugin::new(actions); @@ -78,6 +81,9 @@ fn o_list_filters_results() { desc: "app".into(), action: "bar".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]); let plugin = OmniSearchPlugin::new(actions); @@ -98,6 +104,9 @@ fn label_and_desc_same_returns_action() { desc: "dup".into(), action: "dup_action".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }; let actions = Arc::new(vec![action]); diff --git a/tests/plugin_commands.rs b/tests/plugin_commands.rs index 93b3b100..7523f118 100644 --- a/tests/plugin_commands.rs +++ b/tests/plugin_commands.rs @@ -81,6 +81,9 @@ fn empty_query_lists_commands() { desc: "web".into(), action: "chrome".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; let mut app = new_app(&ctx, actions); app.query.clear(); diff --git a/tests/preserve_command.rs b/tests/preserve_command.rs index e623c55f..160d9672 100644 --- a/tests/preserve_command.rs +++ b/tests/preserve_command.rs @@ -67,6 +67,9 @@ fn bookmark_add_preserves_prefix() { desc: "".into(), action: format!("bookmark:add:{url}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; let mut app = new_app(&ctx, actions, true); app.query = format!("bm add {url}"); @@ -87,6 +90,9 @@ fn bookmark_add_clears_without_setting() { desc: "".into(), action: format!("bookmark:add:{url}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; let mut app = new_app(&ctx, actions, false); app.query = format!("bm add {url}"); @@ -106,6 +112,9 @@ fn timer_add_preserves_prefix() { desc: "".into(), action: "timer:start:1s".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; let mut app = new_app(&ctx, actions, true); app.query = "timer add 1s".into(); @@ -134,6 +143,9 @@ fn todo_add_preserves_prefix() { desc: "".into(), action: "todo:add:test|0|".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; let mut app = new_app(&ctx, actions, true); let _cwd_guard = CurrentDirGuard::new(); @@ -157,6 +169,9 @@ fn tmp_new_preserves_prefix() { desc: "".into(), action: "tempfile:new".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; let mut app = new_app(&ctx, actions, true); let _cwd_guard = CurrentDirGuard::new(); diff --git a/tests/ranking.rs b/tests/ranking.rs index ab49e04b..bd44b976 100644 --- a/tests/ranking.rs +++ b/tests/ranking.rs @@ -38,12 +38,18 @@ fn usage_ranking() { desc: "".into(), action: "a".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "foo".into(), desc: "".into(), action: "b".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ]; let settings = Settings::default(); @@ -63,12 +69,18 @@ fn fuzzy_vs_usage_weight() { desc: "".into(), action: "a".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "defabc".into(), desc: "".into(), action: "b".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ]; let mut settings = Settings::default(); diff --git a/tests/recycle_plugin.rs b/tests/recycle_plugin.rs index 9dd13ac6..e89ba640 100644 --- a/tests/recycle_plugin.rs +++ b/tests/recycle_plugin.rs @@ -78,3 +78,12 @@ fn command_returns_immediately_and_cleans() { } } } + +#[test] +fn search_has_metadata() { + let plugin = RecyclePlugin; + let results = plugin.search("rec"); + assert!(results[0].preview_text.is_some()); + assert!(results[0].risk_level.is_some()); + assert!(results[0].icon.is_some()); +} diff --git a/tests/resilience.rs b/tests/resilience.rs index 9fbe9bc1..fd673eaa 100644 --- a/tests/resilience.rs +++ b/tests/resilience.rs @@ -43,6 +43,9 @@ fn history_poisoned_lock_does_not_panic() { desc: "d".into(), action: "a".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }; let entry = HistoryEntry { query: "q".into(), diff --git a/tests/selection.rs b/tests/selection.rs index 04c8e194..261de18b 100644 --- a/tests/selection.rs +++ b/tests/selection.rs @@ -34,12 +34,18 @@ fn arrow_keys_update_selection() { desc: "".into(), action: "one".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "two".into(), desc: "".into(), action: "two".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ]; let mut app = new_app(&ctx, acts); @@ -63,12 +69,18 @@ fn enter_returns_selected_index() { desc: "".into(), action: "one".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, Action { label: "two".into(), desc: "".into(), action: "two".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, ]; let mut app = new_app(&ctx, acts); @@ -88,6 +100,9 @@ fn page_keys_update_selection() { desc: "".into(), action: format!("act{i}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); let mut app = new_app(&ctx, acts); @@ -117,6 +132,9 @@ fn page_keys_respect_setting() { desc: "".into(), action: format!("act{i}"), args: None, + preview_text: None, + risk_level: None, + icon: None, }) .collect(); let mut settings = Settings::default(); @@ -148,3 +166,23 @@ fn page_keys_respect_setting() { app.handle_key(egui::Key::PageUp); assert_eq!(app.selected, Some(0)); } + +#[test] +fn selected_action_exposes_preview_metadata() { + let ctx = egui::Context::default(); + let acts = vec![Action { + label: "danger".into(), + desc: "System".into(), + action: "system:shutdown".into(), + args: None, + preview_text: Some("Will shutdown".into()), + risk_level: Some(multi_launcher::actions::ActionRiskLevel::Critical), + icon: Some("power".into()), + }]; + let mut app = new_app(&ctx, acts); + app.query = APP_PREFIX.into(); + app.search(); + app.handle_key(egui::Key::ArrowDown); + let selected = app.selected.and_then(|i| app.results.get(i)); + assert!(selected.and_then(|a| a.preview_text.as_ref()).is_some()); +} diff --git a/tests/settings_plugin.rs b/tests/settings_plugin.rs index 936e2dd1..36350472 100644 --- a/tests/settings_plugin.rs +++ b/tests/settings_plugin.rs @@ -83,6 +83,9 @@ fn dashboard_settings_action_opens_editor() { desc: "Configure dashboard layout and widgets".into(), action: "dashboard:settings".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }; assert!(!app.dashboard_editor.open); assert!(!app.show_dashboard_editor); @@ -113,6 +116,9 @@ fn theme_action_is_discoverable_and_opens_dialog() { desc: "Configure launcher theme colors".into(), action: "theme:dialog".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }, None, ActivationSource::Enter, diff --git a/tests/shell_plugin.rs b/tests/shell_plugin.rs index 35866bb7..c99dbbd4 100644 --- a/tests/shell_plugin.rs +++ b/tests/shell_plugin.rs @@ -18,6 +18,9 @@ fn load_shell_cmds_roundtrip() { let entries = vec![ShellCmdEntry { name: "test".into(), args: "echo hi".into(), + preview_text: None, + risk_level: None, + icon: None, autocomplete: true, keep_open: false, }]; @@ -39,6 +42,9 @@ fn search_named_command_returns_action() { let entries = vec![ShellCmdEntry { name: "demo".into(), args: "dir".into(), + preview_text: None, + risk_level: None, + icon: None, autocomplete: true, keep_open: false, }]; @@ -59,6 +65,9 @@ fn search_respects_autocomplete_flag() { let entries = vec![ShellCmdEntry { name: "demo".into(), args: "dir".into(), + preview_text: None, + risk_level: None, + icon: None, autocomplete: false, keep_open: false, }]; @@ -79,6 +88,9 @@ fn search_keep_open_uses_shell_keep_prefix() { let entries = vec![ShellCmdEntry { name: "demo".into(), args: "dir".into(), + preview_text: None, + risk_level: None, + icon: None, autocomplete: true, keep_open: true, }]; @@ -121,12 +133,18 @@ fn rm_lists_matching_commands() { ShellCmdEntry { name: "a".into(), args: "cmd_a".into(), + preview_text: None, + risk_level: None, + icon: None, autocomplete: true, keep_open: false, }, ShellCmdEntry { name: "b".into(), args: "cmd_b".into(), + preview_text: None, + risk_level: None, + icon: None, autocomplete: true, keep_open: false, }, @@ -148,6 +166,9 @@ fn list_returns_saved_commands() { let entries = vec![ShellCmdEntry { name: "x".into(), args: "dir".into(), + preview_text: None, + risk_level: None, + icon: None, autocomplete: true, keep_open: false, }]; @@ -172,6 +193,9 @@ fn launch_actions_modify_file() { desc: String::new(), action: "shell:add:test|dir".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }; launch_action(&add).unwrap(); let list = load_shell_cmds(SHELL_CMDS_FILE).unwrap(); @@ -183,6 +207,9 @@ fn launch_actions_modify_file() { desc: String::new(), action: "shell:remove:test".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }; launch_action(&rm).unwrap(); let list = load_shell_cmds(SHELL_CMDS_FILE).unwrap(); diff --git a/tests/snippets_plugin.rs b/tests/snippets_plugin.rs index f7a83e0b..b67d8180 100644 --- a/tests/snippets_plugin.rs +++ b/tests/snippets_plugin.rs @@ -126,6 +126,9 @@ fn launch_action_add_saves_snippet() { desc: String::new(), action: "snippet:add:alias|text".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }; launch_action(&action).unwrap(); let list = load_snippets(SNIPPETS_FILE).unwrap(); diff --git a/tests/system_plugin.rs b/tests/system_plugin.rs index 429de6be..11d4bc5c 100644 --- a/tests/system_plugin.rs +++ b/tests/system_plugin.rs @@ -8,3 +8,12 @@ fn search_shutdown_returns_action() { assert_eq!(results.len(), 1); assert_eq!(results[0].action, "system:shutdown"); } + +#[test] +fn search_shutdown_has_metadata() { + let plugin = SystemPlugin; + let results = plugin.search("sys shutdown"); + assert!(results[0].preview_text.is_some()); + assert!(results[0].risk_level.is_some()); + assert!(results[0].icon.is_some()); +} diff --git a/tests/task_manager_plugin.rs b/tests/task_manager_plugin.rs index 4fe73c85..8bbc7051 100644 --- a/tests/task_manager_plugin.rs +++ b/tests/task_manager_plugin.rs @@ -8,3 +8,12 @@ fn search_returns_action() { assert_eq!(results.len(), 1); assert_eq!(results[0].action, "shell:taskmgr"); } + +#[test] +fn search_has_metadata() { + let plugin = TaskManagerPlugin; + let results = plugin.search("tm"); + assert!(results[0].preview_text.is_some()); + assert!(results[0].risk_level.is_some()); + assert!(results[0].icon.is_some()); +} diff --git a/tests/tempfile_plugin.rs b/tests/tempfile_plugin.rs index 143daff1..6ac12fd4 100644 --- a/tests/tempfile_plugin.rs +++ b/tests/tempfile_plugin.rs @@ -124,6 +124,9 @@ fn launch_action_remove_deletes_file() { desc: "".into(), action: format!("tempfile:remove:{}", file.to_string_lossy()), args: None, + preview_text: None, + risk_level: None, + icon: None, }; launch_action(&action).unwrap(); assert!(!file.exists()); diff --git a/tests/trigger_visibility.rs b/tests/trigger_visibility.rs index 21d0343d..55b1b7b3 100644 --- a/tests/trigger_visibility.rs +++ b/tests/trigger_visibility.rs @@ -95,6 +95,9 @@ fn launcher_toggle_action_sets_visibility_and_restore() { desc: "".into(), action: "launcher:toggle".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }; app.activate_action(action, None, ActivationSource::Enter); diff --git a/tests/watchers.rs b/tests/watchers.rs index 57a5bb1f..de83069a 100644 --- a/tests/watchers.rs +++ b/tests/watchers.rs @@ -44,6 +44,9 @@ fn actions_watcher_sends_event() { desc: "".into(), action: "a".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; save_actions("actions.json", &acts).unwrap(); save_folders(FOLDERS_FILE, &[]).unwrap(); diff --git a/tests/web_search_prefix.rs b/tests/web_search_prefix.rs index 85b1fbed..e2fde8f9 100644 --- a/tests/web_search_prefix.rs +++ b/tests/web_search_prefix.rs @@ -44,6 +44,9 @@ fn g_prefix_filters_web_search() { desc: "test".into(), action: "custom".into(), args: None, + preview_text: None, + risk_level: None, + icon: None, }]; let mut app = new_app_with_plugins(&ctx, actions); app.query = "g hello".into(); From 5a12b4c0dbb95d8982627232b24c485701b3c56f Mon Sep 17 00:00:00 2001 From: multiplex55 <6619098+multiplex55@users.noreply.github.com> Date: Sat, 7 Feb 2026 17:23:18 -0500 Subject: [PATCH 2/2] Fix preview metadata rollout and restore compile-safe structs --- src/dashboard/widgets/command_history.rs | 6 --- src/gui/add_action_dialog.rs | 15 ++----- src/gui/mod.rs | 16 +++++--- src/history.rs | 24 ----------- src/launcher.rs | 15 ------- src/mouse_gestures/db.rs | 15 ++----- src/plugins/fav.rs | 9 ----- src/plugins/layout.rs | 51 +++++++++++------------- src/plugins/macros.rs | 6 +-- src/plugins/shell.rs | 6 --- src/settings.rs | 10 +++-- tests/mouse_gestures_db.rs | 51 ------------------------ tests/selection.rs | 4 +- tests/shell_plugin.rs | 21 ---------- 14 files changed, 50 insertions(+), 199 deletions(-) diff --git a/src/dashboard/widgets/command_history.rs b/src/dashboard/widgets/command_history.rs index 79eceef4..85bfb1d6 100644 --- a/src/dashboard/widgets/command_history.rs +++ b/src/dashboard/widgets/command_history.rs @@ -121,9 +121,6 @@ impl CommandHistoryWidget { ctx: &DashboardContext<'_>, action_id: &str, args: Option<&str>, - preview_text: None, - risk_level: None, - icon: None, ) -> Option { if let Some(action) = ctx.actions_by_id.get(action_id) { return Some(action.clone()); @@ -403,9 +400,6 @@ impl Widget for CommandHistoryWidget { label: entry.action.label.clone(), desc: entry.action.desc.clone(), args: entry.action.args.clone(), - preview_text: None, - risk_level: None, - icon: None, query: entry.query.clone(), timestamp: entry.timestamp, }; diff --git a/src/gui/add_action_dialog.rs b/src/gui/add_action_dialog.rs index 2c41790e..bab2bc8a 100644 --- a/src/gui/add_action_dialog.rs +++ b/src/gui/add_action_dialog.rs @@ -19,14 +19,8 @@ pub struct AddActionDialog { path: String, /// Whether the arguments field is visible. show_args: bool, - preview_text: None, - risk_level: None, - icon: None, /// Additional arguments to pass when launching. args: String, - preview_text: None, - risk_level: None, - icon: None, /// Current dialog mode (add or edit existing command). mode: DialogMode, } @@ -53,13 +47,7 @@ impl Default for AddActionDialog { desc: String::new(), path: String::new(), show_args: false, - preview_text: None, - risk_level: None, - icon: None, args: String::new(), - preview_text: None, - risk_level: None, - icon: None, mode: DialogMode::Add, } } @@ -162,6 +150,9 @@ impl AddActionDialog { } else { None }, + preview_text: None, + risk_level: None, + icon: None, }); app.custom_len += 1; app.actions = Arc::new(new_actions); diff --git a/src/gui/mod.rs b/src/gui/mod.rs index 49871e8d..6af676e5 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -1954,9 +1954,6 @@ impl LauncherApp { label: action.label.clone(), desc: action.desc.clone(), args: action.args.clone(), - preview_text: None, - risk_level: None, - icon: None, query: self.query.clone(), timestamp: chrono::Utc::now().timestamp(), }; @@ -3944,7 +3941,11 @@ impl eframe::App for LauncherApp { let area_height = ui.available_height(); ui.horizontal(|ui| { let show_preview_pane = self.preview_enabled && self.selected.is_some(); - let list_width = if show_preview_pane { ui.available_width() * 0.62 } else { ui.available_width() }; + let list_width = if show_preview_pane { + ui.available_width() * 0.62 + } else { + ui.available_width() + }; ui.set_width(list_width); ScrollArea::vertical() .max_height(area_height) @@ -4443,8 +4444,8 @@ impl eframe::App for LauncherApp { { self.focus_input(); } + }); }); - }); if show_preview_pane { ui.separator(); ui.vertical(|ui| { @@ -4458,7 +4459,10 @@ impl eframe::App for LauncherApp { ui.small(format!("Icon: {icon}")); } if let Some(level) = action.risk_level { - ui.colored_label(egui::Color32::from_rgb(230, 170, 70), format!("Risk: {:?}", level)); + ui.colored_label( + egui::Color32::from_rgb(230, 170, 70), + format!("Risk: {:?}", level), + ); } ui.separator(); if let Some(text) = &action.preview_text { diff --git a/src/history.rs b/src/history.rs index 10b64c93..216f310d 100644 --- a/src/history.rs +++ b/src/history.rs @@ -25,9 +25,6 @@ pub struct HistoryPin { pub label: String, pub desc: String, pub args: Option, - preview_text: None, - risk_level: None, - icon: None, pub query: String, #[serde(default)] pub timestamp: i64, @@ -40,9 +37,6 @@ impl HistoryPin { label: entry.action.label.clone(), desc: entry.action.desc.clone(), args: entry.action.args.clone(), - preview_text: None, - risk_level: None, - icon: None, query: entry.query.clone(), timestamp: entry.timestamp, } @@ -271,9 +265,6 @@ mod tests { label: "One".into(), desc: "Test".into(), args: Some("--flag".into()), - preview_text: None, - risk_level: None, - icon: None, query: "one".into(), timestamp: 123, }; @@ -300,9 +291,6 @@ mod tests { label: "One".into(), desc: "Test".into(), args: Some("--flag".into()), - preview_text: None, - risk_level: None, - icon: None, query: "one".into(), timestamp: 1, }; @@ -311,9 +299,6 @@ mod tests { label: "One Updated".into(), desc: "Other".into(), args: Some("--flag".into()), - preview_text: None, - risk_level: None, - icon: None, query: "two".into(), timestamp: 2, }; @@ -322,9 +307,6 @@ mod tests { label: "One".into(), desc: "Test".into(), args: Some("--other".into()), - preview_text: None, - risk_level: None, - icon: None, query: "one".into(), timestamp: 1, }; @@ -341,9 +323,6 @@ mod tests { label: "One".into(), desc: "Old".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, query: "one".into(), timestamp: 10, }; @@ -355,9 +334,6 @@ mod tests { label: "One Updated".into(), desc: "New".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, query: "two".into(), timestamp: 11, }; diff --git a/src/launcher.rs b/src/launcher.rs index 980998fb..6606edbd 100644 --- a/src/launcher.rs +++ b/src/launcher.rs @@ -410,9 +410,6 @@ enum ActionKind<'a> { ShellAdd { name: &'a str, args: &'a str, - preview_text: None, - risk_level: None, - icon: None, }, ShellRemove(&'a str), ClipboardClear, @@ -477,9 +474,6 @@ enum ActionKind<'a> { label: &'a str, command: &'a str, args: Option<&'a str>, - preview_text: None, - risk_level: None, - icon: None, }, FavRemove(&'a str), BrightnessSet(u32), @@ -544,9 +538,6 @@ enum ActionKind<'a> { ExecPath { path: &'a str, args: Option<&'a str>, - preview_text: None, - risk_level: None, - icon: None, }, Macro(&'a str), } @@ -831,9 +822,6 @@ fn parse_action_kind(action: &Action) -> ActionKind<'_> { _ => ActionKind::ExecPath { path: s, args: action.args.as_deref(), - preview_text: None, - risk_level: None, - icon: None, }, }; } @@ -925,9 +913,6 @@ fn parse_action_kind(action: &Action) -> ActionKind<'_> { ActionKind::ExecPath { path: s, args: action.args.as_deref(), - preview_text: None, - risk_level: None, - icon: None, } } diff --git a/src/mouse_gestures/db.rs b/src/mouse_gestures/db.rs index fd80414c..f4bff12c 100644 --- a/src/mouse_gestures/db.rs +++ b/src/mouse_gestures/db.rs @@ -32,9 +32,6 @@ pub struct BindingEntry { pub action: String, #[serde(default, skip_serializing_if = "Option::is_none")] pub args: Option, - preview_text: None, - risk_level: None, - icon: None, #[serde(default = "default_enabled")] pub enabled: bool, } @@ -483,6 +480,9 @@ impl BindingEntry { desc: format!("Mouse gesture: {gesture_label}"), action, args, + preview_text: None, + risk_level: None, + icon: None, } } } @@ -634,9 +634,6 @@ struct LegacyBindingEntry { action: String, #[serde(default, skip_serializing_if = "Option::is_none")] args: Option, - preview_text: None, - risk_level: None, - icon: None, #[serde(default = "default_enabled")] enabled: bool, #[serde(default)] @@ -652,9 +649,6 @@ impl LegacyBindingEntry { kind: BindingKind::ToggleLauncher, action: String::new(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: self.enabled, }; } @@ -673,9 +667,6 @@ impl LegacyBindingEntry { kind, action, args: self.args, - preview_text: None, - risk_level: None, - icon: None, enabled: self.enabled, } } diff --git a/src/plugins/fav.rs b/src/plugins/fav.rs index a46a386a..4db46799 100644 --- a/src/plugins/fav.rs +++ b/src/plugins/fav.rs @@ -20,9 +20,6 @@ pub struct FavEntry { pub action: String, #[serde(skip_serializing_if = "Option::is_none")] pub args: Option, - preview_text: None, - risk_level: None, - icon: None, } pub fn load_favs(path: &str) -> anyhow::Result> { @@ -54,9 +51,6 @@ pub fn set_fav(path: &str, label: &str, action: &str, args: Option<&str>) -> any label: label.to_string(), action: action.to_string(), args: args.map(|s| s.to_string()), - preview_text: None, - risk_level: None, - icon: None, }); } save_favs(path, &list) @@ -91,9 +85,6 @@ pub fn resolve_with_plugin( plugin: &dyn Plugin, command: &str, args: Option<&str>, - preview_text: None, - risk_level: None, - icon: None, ) -> (String, Option) { let mut query = command.to_string(); if let Some(a) = args { diff --git a/src/plugins/layout.rs b/src/plugins/layout.rs index 58b14035..b8ba7978 100644 --- a/src/plugins/layout.rs +++ b/src/plugins/layout.rs @@ -172,54 +172,54 @@ impl Plugin for LayoutPlugin { desc: "Layout".into(), action: "query:layout list".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, + preview_text: Some("Query shortcut for layout operations.".into()), + risk_level: Some(ActionRiskLevel::Low), + icon: Some("layout".into()), }, Action { label: "layout save ".into(), desc: "Layout".into(), action: "query:layout save ".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, + preview_text: Some("Layout command shortcut.".into()), + risk_level: Some(ActionRiskLevel::Low), + icon: Some("layout".into()), }, Action { label: "layout load ".into(), desc: "Layout".into(), action: "query:layout load ".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, + preview_text: Some("Layout command shortcut.".into()), + risk_level: Some(ActionRiskLevel::Low), + icon: Some("layout".into()), }, Action { label: "layout show ".into(), desc: "Layout".into(), action: "query:layout show ".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, + preview_text: Some("Layout command shortcut.".into()), + risk_level: Some(ActionRiskLevel::Low), + icon: Some("layout".into()), }, Action { label: format!("{config_label} ({config_desc})"), desc: "Layout config".into(), action: "layout:edit".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, + preview_text: Some("Layout command shortcut.".into()), + risk_level: Some(ActionRiskLevel::Low), + icon: Some("layout".into()), }, Action { label: "layout rm ".into(), desc: "Layout".into(), action: "query:layout rm ".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, + preview_text: Some("Layout command shortcut.".into()), + risk_level: Some(ActionRiskLevel::Low), + icon: Some("layout".into()), }, ]; } @@ -241,9 +241,7 @@ impl Plugin for LayoutPlugin { &LayoutFlags::default(), ), args: None, - preview_text: Some( - "Repositions and resizes windows based on the saved layout.".into(), - ), + preview_text: Some("Repositions windows based on the saved layout.".into()), risk_level: Some(ActionRiskLevel::High), icon: Some("layout".into()), }) @@ -280,9 +278,7 @@ impl Plugin for LayoutPlugin { desc: "Layout".into(), action: build_action(format!("layout:load:{name}"), &flags), args: None, - preview_text: Some( - "Repositions and resizes windows based on the saved layout.".into(), - ), + preview_text: Some("Repositions windows based on the saved layout.".into()), risk_level: Some(ActionRiskLevel::High), icon: Some("layout".into()), }]; @@ -326,8 +322,7 @@ impl Plugin for LayoutPlugin { action: action.clone(), args: None, preview_text: Some( - "Preview entry for this matched window inside the selected layout." - .into(), + "Preview row for a window match inside this layout.".into(), ), risk_level: Some(ActionRiskLevel::Low), icon: Some("layout".into()), @@ -349,7 +344,7 @@ impl Plugin for LayoutPlugin { desc: "Layout".into(), action: format!("query:layout show {}", layout.name), args: None, - preview_text: Some("Shows window matches for the selected layout.".into()), + preview_text: Some("Shows the windows included in this layout.".into()), risk_level: Some(ActionRiskLevel::Low), icon: Some("layout".into()), }) @@ -409,7 +404,7 @@ impl Plugin for LayoutPlugin { desc: "Layout".into(), action: "query:layout ".into(), args: None, - preview_text: Some("Layout operation".into()), + preview_text: Some("Query shortcut for layout operations.".into()), risk_level: Some(ActionRiskLevel::Low), icon: Some("layout".into()), }] diff --git a/src/plugins/macros.rs b/src/plugins/macros.rs index 5d116bab..87175444 100644 --- a/src/plugins/macros.rs +++ b/src/plugins/macros.rs @@ -36,9 +36,6 @@ pub struct MacroStep { pub command: String, #[serde(skip_serializing_if = "Option::is_none")] pub args: Option, - preview_text: None, - risk_level: None, - icon: None, /// Delay in milliseconds after this step when using manual delays. #[serde(default)] pub delay_ms: u64, @@ -193,6 +190,9 @@ pub fn run_macro(name: &str) -> anyhow::Result<()> { desc: String::new(), action: command, args, + preview_text: None, + risk_level: None, + icon: None, }; if let Err(e) = launch_action(&act) { tracing::error!(?e, "failed to run macro step"); diff --git a/src/plugins/shell.rs b/src/plugins/shell.rs index edb47d40..11321afe 100644 --- a/src/plugins/shell.rs +++ b/src/plugins/shell.rs @@ -12,9 +12,6 @@ pub const SHELL_CMDS_FILE: &str = "shell_cmds.json"; pub struct ShellCmdEntry { pub name: String, pub args: String, - preview_text: None, - risk_level: None, - icon: None, /// When false this command will not be suggested when typing `sh `. #[serde(default = "default_autocomplete")] pub autocomplete: bool, @@ -69,9 +66,6 @@ pub fn append_shell_cmd(path: &str, name: &str, args: &str) -> anyhow::Result<() list.push(ShellCmdEntry { name: name.to_string(), args: args.to_string(), - preview_text: None, - risk_level: None, - icon: None, autocomplete: true, keep_open: false, }); diff --git a/src/settings.rs b/src/settings.rs index cae661c8..dd55d3ae 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -296,8 +296,10 @@ pub struct Settings { /// Scale factor for the action list. Defaults to `1.0`. #[serde(default = "default_scale")] pub list_scale: Option, + /// Show preview pane for selected action in launcher results. #[serde(default = "default_preview_enabled")] pub preview_enabled: bool, + /// Use compact preview presentation in the preview pane. #[serde(default)] pub preview_compact_mode: bool, /// Weight of the fuzzy match score when ranking results. @@ -480,10 +482,6 @@ fn default_log_path() -> PathBuf { .unwrap_or_else(|| PathBuf::from("launcher.log")) } -fn default_preview_enabled() -> bool { - true -} - fn default_launcher_hotkey() -> Option { if std::env::var("ML_DEFAULT_HOTKEY_NONE").is_ok() { None @@ -492,6 +490,10 @@ fn default_launcher_hotkey() -> Option { } } +fn default_preview_enabled() -> bool { + true +} + impl Default for Settings { fn default() -> Self { Self { diff --git a/tests/mouse_gestures_db.rs b/tests/mouse_gestures_db.rs index 8821a620..790e6ce1 100644 --- a/tests/mouse_gestures_db.rs +++ b/tests/mouse_gestures_db.rs @@ -56,9 +56,6 @@ fn gesture_db_round_trip_serialization() { kind: BindingKind::Execute, action: "stopwatch:show:1".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }], }], @@ -155,9 +152,6 @@ fn matching_skips_disabled_gestures_and_bindings() { kind: BindingKind::Execute, action: "stopwatch:show:1".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }], }, @@ -172,9 +166,6 @@ fn matching_skips_disabled_gestures_and_bindings() { kind: BindingKind::Execute, action: "stopwatch:show:2".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: false, }], }, @@ -202,9 +193,6 @@ fn binding_resolution_is_deterministic() { kind: BindingKind::Execute, action: "stopwatch:show:1".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }, BindingEntry { @@ -212,9 +200,6 @@ fn binding_resolution_is_deterministic() { kind: BindingKind::Execute, action: "stopwatch:show:2".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }, ], @@ -230,9 +215,6 @@ fn binding_resolution_is_deterministic() { kind: BindingKind::Execute, action: "stopwatch:show:3".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }], }, @@ -261,9 +243,6 @@ fn binding_enabled_state_persists_and_controls_matching() { kind: BindingKind::Execute, action: "stopwatch:show:1".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: false, }], }], @@ -296,9 +275,6 @@ fn candidate_matching_ranks_exact_over_prefix_over_fuzzy() { kind: BindingKind::Execute, action: "stopwatch:show:1".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }], }, @@ -313,9 +289,6 @@ fn candidate_matching_ranks_exact_over_prefix_over_fuzzy() { kind: BindingKind::Execute, action: "stopwatch:show:2".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }], }, @@ -330,9 +303,6 @@ fn candidate_matching_ranks_exact_over_prefix_over_fuzzy() { kind: BindingKind::Execute, action: "stopwatch:show:3".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }], }, @@ -361,9 +331,6 @@ fn search_bindings_matches_across_fields() { kind: BindingKind::Execute, action: "browser:open".into(), args: Some("profile=work".into()), - preview_text: None, - risk_level: None, - icon: None, enabled: true, }], }], @@ -404,9 +371,6 @@ fn find_by_action_matches_prefixes() { kind: BindingKind::Execute, action: "browser:open".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }], }], @@ -434,9 +398,6 @@ fn find_conflicts_groups_duplicates_and_prefixes() { kind: BindingKind::Execute, action: "browser:open".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }], }, @@ -451,9 +412,6 @@ fn find_conflicts_groups_duplicates_and_prefixes() { kind: BindingKind::Execute, action: "mail:open".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }], }, @@ -468,9 +426,6 @@ fn find_conflicts_groups_duplicates_and_prefixes() { kind: BindingKind::Execute, action: "settings:open".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }], }, @@ -485,9 +440,6 @@ fn find_conflicts_groups_duplicates_and_prefixes() { kind: BindingKind::Execute, action: "other:open".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }], }, @@ -575,9 +527,6 @@ fn set_query_binding_avoids_execute_action() { kind: BindingKind::SetQuery, action: "timer list".into(), args: None, - preview_text: None, - risk_level: None, - icon: None, enabled: true, }; let action = binding.to_action("Gesture"); diff --git a/tests/selection.rs b/tests/selection.rs index 261de18b..6b785ca4 100644 --- a/tests/selection.rs +++ b/tests/selection.rs @@ -1,5 +1,5 @@ use eframe::egui; -use multi_launcher::actions::Action; +use multi_launcher::actions::{Action, ActionRiskLevel}; use multi_launcher::gui::{LauncherApp, APP_PREFIX}; use multi_launcher::plugin::PluginManager; use multi_launcher::settings::Settings; @@ -176,7 +176,7 @@ fn selected_action_exposes_preview_metadata() { action: "system:shutdown".into(), args: None, preview_text: Some("Will shutdown".into()), - risk_level: Some(multi_launcher::actions::ActionRiskLevel::Critical), + risk_level: Some(ActionRiskLevel::Critical), icon: Some("power".into()), }]; let mut app = new_app(&ctx, acts); diff --git a/tests/shell_plugin.rs b/tests/shell_plugin.rs index c99dbbd4..635215e1 100644 --- a/tests/shell_plugin.rs +++ b/tests/shell_plugin.rs @@ -18,9 +18,6 @@ fn load_shell_cmds_roundtrip() { let entries = vec![ShellCmdEntry { name: "test".into(), args: "echo hi".into(), - preview_text: None, - risk_level: None, - icon: None, autocomplete: true, keep_open: false, }]; @@ -42,9 +39,6 @@ fn search_named_command_returns_action() { let entries = vec![ShellCmdEntry { name: "demo".into(), args: "dir".into(), - preview_text: None, - risk_level: None, - icon: None, autocomplete: true, keep_open: false, }]; @@ -65,9 +59,6 @@ fn search_respects_autocomplete_flag() { let entries = vec![ShellCmdEntry { name: "demo".into(), args: "dir".into(), - preview_text: None, - risk_level: None, - icon: None, autocomplete: false, keep_open: false, }]; @@ -88,9 +79,6 @@ fn search_keep_open_uses_shell_keep_prefix() { let entries = vec![ShellCmdEntry { name: "demo".into(), args: "dir".into(), - preview_text: None, - risk_level: None, - icon: None, autocomplete: true, keep_open: true, }]; @@ -133,18 +121,12 @@ fn rm_lists_matching_commands() { ShellCmdEntry { name: "a".into(), args: "cmd_a".into(), - preview_text: None, - risk_level: None, - icon: None, autocomplete: true, keep_open: false, }, ShellCmdEntry { name: "b".into(), args: "cmd_b".into(), - preview_text: None, - risk_level: None, - icon: None, autocomplete: true, keep_open: false, }, @@ -166,9 +148,6 @@ fn list_returns_saved_commands() { let entries = vec![ShellCmdEntry { name: "x".into(), args: "dir".into(), - preview_text: None, - risk_level: None, - icon: None, autocomplete: true, keep_open: false, }];