From dfe8a2eaf2adbb086ea43baa615f76af8d95583c Mon Sep 17 00:00:00 2001 From: multiplex55 <6619098+multiplex55@users.noreply.github.com> Date: Thu, 28 Aug 2025 18:41:26 -0400 Subject: [PATCH 1/2] Add WezTerm option for external note editing --- src/gui/mod.rs | 18 ++++++++++++------ src/gui/note_panel.rs | 21 +++++++++++++++++++++ src/plugins/note.rs | 14 ++++++++------ src/settings.rs | 2 +- src/settings_editor.rs | 24 ++++++++++++++++-------- tests/wezterm_command.rs | 14 ++++++++++++++ 6 files changed, 72 insertions(+), 21 deletions(-) create mode 100644 tests/wezterm_command.rs diff --git a/src/gui/mod.rs b/src/gui/mod.rs index 83cb150d..28f8e1b7 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -8,10 +8,10 @@ mod convert_panel; mod cpu_list_dialog; mod fav_dialog; mod image_panel; -mod screenshot_editor; mod macro_dialog; mod note_panel; mod notes_dialog; +mod screenshot_editor; mod shell_cmd_dialog; mod snippet_dialog; mod tempfile_alias_dialog; @@ -34,10 +34,12 @@ pub use convert_panel::ConvertPanel; pub use cpu_list_dialog::CpuListDialog; pub use fav_dialog::FavDialog; pub use image_panel::ImagePanel; -pub use screenshot_editor::ScreenshotEditor; pub use macro_dialog::MacroDialog; -pub use note_panel::{build_nvim_command, extract_links, show_wiki_link, NotePanel}; +pub use note_panel::{ + build_nvim_command, build_wezterm_command, extract_links, show_wiki_link, NotePanel, +}; pub use notes_dialog::NotesDialog; +pub use screenshot_editor::ScreenshotEditor; pub use shell_cmd_dialog::ShellCmdDialog; pub use snippet_dialog::SnippetDialog; pub use tempfile_alias_dialog::TempfileAliasDialog; @@ -781,7 +783,7 @@ impl LauncherApp { .get("note") .and_then(|v| serde_json::from_value::(v.clone()).ok()) .map(|s| s.external_open) - .unwrap_or(NoteExternalOpen::Neither); + .unwrap_or(NoteExternalOpen::Wezterm); let settings_editor = SettingsEditor::new_with_plugins(&settings); let plugin_editor = PluginEditor::new(&settings); @@ -3517,8 +3519,12 @@ impl LauncherApp { Local::now().format("%Y%m%d_%H%M%S") ); let path = dir.join(filename); - self.screenshot_editors - .push(ScreenshotEditor::new(img, path, clip, self.screenshot_auto_save)); + self.screenshot_editors.push(ScreenshotEditor::new( + img, + path, + clip, + self.screenshot_auto_save, + )); self.update_panel_stack(); } diff --git a/src/gui/note_panel.rs b/src/gui/note_panel.rs index feca615a..8d5f1164 100644 --- a/src/gui/note_panel.rs +++ b/src/gui/note_panel.rs @@ -145,6 +145,10 @@ impl NotePanel { self.save(app); self.open_external(app, NoteExternalOpen::Notepad); } + NoteExternalOpen::Wezterm => { + self.save(app); + self.open_external(app, NoteExternalOpen::Wezterm); + } NoteExternalOpen::Neither => { self.show_open_with_menu = true; ui.memory_mut(|m| m.open_popup(popup_id)); @@ -159,6 +163,11 @@ impl NotePanel { self.open_external(app, NoteExternalOpen::Powershell); close = true; } + if ui.button("WezTerm").clicked() { + self.save(app); + self.open_external(app, NoteExternalOpen::Wezterm); + close = true; + } if ui.button("Notepad").clicked() { self.save(app); self.open_external(app, NoteExternalOpen::Notepad); @@ -959,6 +968,11 @@ impl NotePanel { let (mut cmd, _cmd_str) = build_nvim_command(&path); cmd.spawn() } + NoteExternalOpen::Wezterm => { + let editor = app.note_external_editor.as_deref().unwrap_or("nvim"); + let (mut cmd, _cmd_str) = build_wezterm_command(&path, editor); + cmd.spawn() + } NoteExternalOpen::Notepad => Command::new("notepad.exe").arg(&path).spawn(), NoteExternalOpen::Neither => return, }; @@ -1070,6 +1084,13 @@ pub fn build_nvim_command(note_path: &Path) -> (Command, String) { (cmd, cmd_str) } +pub fn build_wezterm_command(note_path: &Path, editor: &str) -> (Command, String) { + let mut cmd = Command::new("wezterm"); + cmd.arg("start").arg("--").arg(editor).arg(note_path); + let cmd_str = format!("{:?}", cmd); + (cmd, cmd_str) +} + fn extract_tags(content: &str) -> Vec { static TAG_RE: Lazy = Lazy::new(|| Regex::new(r"#([A-Za-z0-9_]+)").unwrap()); let mut tags: Vec = Vec::new(); diff --git a/src/plugins/note.rs b/src/plugins/note.rs index 7dd22f03..afc60549 100644 --- a/src/plugins/note.rs +++ b/src/plugins/note.rs @@ -1,13 +1,13 @@ use crate::actions::Action; use crate::common::slug::{register_slug, reset_slug_lookup, slugify, unique_slug}; use crate::plugin::Plugin; -use eframe::egui; -use serde::{Deserialize, Serialize}; use chrono::Local; +use eframe::egui; use fuzzy_matcher::skim::SkimMatcherV2; use fuzzy_matcher::FuzzyMatcher; use once_cell::sync::Lazy; use regex::Regex; +use serde::{Deserialize, Serialize}; use std::collections::{HashMap, HashSet}; use std::path::PathBuf; use std::sync::{Arc, Mutex}; @@ -17,6 +17,7 @@ pub enum NoteExternalOpen { Neither, Powershell, Notepad, + Wezterm, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -27,7 +28,7 @@ pub struct NotePluginSettings { impl Default for NotePluginSettings { fn default() -> Self { Self { - external_open: NoteExternalOpen::Neither, + external_open: NoteExternalOpen::Wezterm, } } } @@ -454,7 +455,7 @@ impl NotePlugin { matcher: SkimMatcherV2::default(), data: CACHE.clone(), templates: TEMPLATE_CACHE.clone(), - external_open: NoteExternalOpen::Neither, + external_open: NoteExternalOpen::Wezterm, } } } @@ -921,13 +922,13 @@ impl Plugin for NotePlugin { } fn settings_ui(&mut self, ui: &mut egui::Ui, value: &mut serde_json::Value) { - let mut cfg: NotePluginSettings = - serde_json::from_value(value.clone()).unwrap_or_default(); + let mut cfg: NotePluginSettings = serde_json::from_value(value.clone()).unwrap_or_default(); egui::ComboBox::from_label("Open externally") .selected_text(match cfg.external_open { NoteExternalOpen::Neither => "Neither", NoteExternalOpen::Powershell => "Powershell", NoteExternalOpen::Notepad => "Notepad", + NoteExternalOpen::Wezterm => "WezTerm", }) .show_ui(ui, |ui| { ui.selectable_value(&mut cfg.external_open, NoteExternalOpen::Neither, "Neither"); @@ -937,6 +938,7 @@ impl Plugin for NotePlugin { "Powershell", ); ui.selectable_value(&mut cfg.external_open, NoteExternalOpen::Notepad, "Notepad"); + ui.selectable_value(&mut cfg.external_open, NoteExternalOpen::Wezterm, "WezTerm"); }); match serde_json::to_value(&cfg) { Ok(v) => *value = v, diff --git a/src/settings.rs b/src/settings.rs index da3dc138..baf1d335 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -276,7 +276,7 @@ impl Default for Settings { note_save_on_close: default_note_save_on_close(), note_always_overwrite: false, note_images_as_links: false, - note_external_editor: None, + note_external_editor: Some("wezterm".to_string()), note_more_limit: default_note_more_limit(), enable_toasts: true, toast_duration: default_toast_duration(), diff --git a/src/settings_editor.rs b/src/settings_editor.rs index f79d1182..d6d75d7b 100644 --- a/src/settings_editor.rs +++ b/src/settings_editor.rs @@ -154,14 +154,16 @@ impl SettingsEditor { plugins_expanded: false, expand_request: None, }; - s.plugin_settings.entry("screenshot".into()).or_insert_with(|| { - serde_json::json!({ - "screenshot_dir": s.screenshot_dir.clone(), - "screenshot_save_file": s.screenshot_save_file, - "screenshot_auto_save": s.screenshot_auto_save, - "screenshot_use_editor": s.screenshot_use_editor, - }) - }); + s.plugin_settings + .entry("screenshot".into()) + .or_insert_with(|| { + serde_json::json!({ + "screenshot_dir": s.screenshot_dir.clone(), + "screenshot_save_file": s.screenshot_save_file, + "screenshot_auto_save": s.screenshot_auto_save, + "screenshot_use_editor": s.screenshot_use_editor, + }) + }); s } @@ -554,6 +556,7 @@ impl SettingsEditor { NoteExternalOpen::Neither => "Neither", NoteExternalOpen::Powershell => "Powershell", NoteExternalOpen::Notepad => "Notepad", + NoteExternalOpen::Wezterm => "WezTerm", }) .show_ui(ui, |ui| { ui.selectable_value( @@ -571,6 +574,11 @@ impl SettingsEditor { NoteExternalOpen::Notepad, "Notepad", ); + ui.selectable_value( + &mut cfg.external_open, + NoteExternalOpen::Wezterm, + "WezTerm", + ); }); self.plugin_settings.insert( "note".into(), diff --git a/tests/wezterm_command.rs b/tests/wezterm_command.rs new file mode 100644 index 00000000..083992d0 --- /dev/null +++ b/tests/wezterm_command.rs @@ -0,0 +1,14 @@ +use multi_launcher::gui::build_wezterm_command; +use std::path::Path; + +#[test] +fn builds_wezterm_command() { + let note = Path::new("note.txt"); + let (cmd, _cmd_str) = build_wezterm_command(note, "nvim"); + assert_eq!(cmd.get_program().to_string_lossy(), "wezterm"); + let args: Vec<_> = cmd + .get_args() + .map(|a| a.to_string_lossy().into_owned()) + .collect(); + assert_eq!(args, ["start", "--", "nvim", "note.txt"]); +} From ae10495220ad97bbd3f4383f098ecae8d19ef1e9 Mon Sep 17 00:00:00 2001 From: multiplex55 <6619098+multiplex55@users.noreply.github.com> Date: Thu, 28 Aug 2025 19:05:14 -0400 Subject: [PATCH 2/2] Hide extra console when launching WezTerm --- src/gui/note_panel.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/note_panel.rs b/src/gui/note_panel.rs index 8d5f1164..b4044e6f 100644 --- a/src/gui/note_panel.rs +++ b/src/gui/note_panel.rs @@ -17,6 +17,8 @@ use regex::Regex; use rfd::FileDialog; use std::collections::HashMap; use std::process::Command; +#[cfg(windows)] +use std::os::windows::process::CommandExt; use std::{ env, path::{Path, PathBuf}, @@ -1087,6 +1089,10 @@ pub fn build_nvim_command(note_path: &Path) -> (Command, String) { pub fn build_wezterm_command(note_path: &Path, editor: &str) -> (Command, String) { let mut cmd = Command::new("wezterm"); cmd.arg("start").arg("--").arg(editor).arg(note_path); + #[cfg(windows)] + { + cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW + } let cmd_str = format!("{:?}", cmd); (cmd, cmd_str) }