style(core): fix formatting
This commit is contained in:
		
							parent
							
								
									5d7b13e0bc
								
							
						
					
					
						commit
						9e3742f273
					
				|  | @ -26,7 +26,7 @@ pub fn can_use_capabilities() -> bool { | ||||||
|     Err(err) => { |     Err(err) => { | ||||||
|       error!("error while checking if capabilities are enabled: {}", err); |       error!("error while checking if capabilities are enabled: {}", err); | ||||||
|       false |       false | ||||||
|     }, |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -39,4 +39,4 @@ pub fn clear_capabilities() -> Result<()> { | ||||||
|   caps::clear(None, CapSet::Effective)?; |   caps::clear(None, CapSet::Effective)?; | ||||||
|   caps::clear(None, CapSet::Permitted)?; |   caps::clear(None, CapSet::Permitted)?; | ||||||
|   Ok(()) |   Ok(()) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -26,4 +26,3 @@ pub use linux::*; | ||||||
| mod fallback; | mod fallback; | ||||||
| #[cfg(not(target_os = "linux"))] | #[cfg(not(target_os = "linux"))] | ||||||
| pub use fallback::*; | pub use fallback::*; | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ | ||||||
| 
 | 
 | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use crossbeam::channel::Sender; | use crossbeam::channel::Sender; | ||||||
| use log::{error, debug}; | use log::{debug, error}; | ||||||
| 
 | 
 | ||||||
| const WATCHER_INTERVAL: u64 = 1000; | const WATCHER_INTERVAL: u64 = 1000; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ use log::{error, info, warn}; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|   cli::util::CommandExt, |   cli::util::CommandExt, | ||||||
|   common_flags::{*}, |   common_flags::*, | ||||||
|   exit_code::{ |   exit_code::{ | ||||||
|     DAEMON_ALREADY_RUNNING, DAEMON_FATAL_CONFIG_ERROR, DAEMON_GENERAL_ERROR, |     DAEMON_ALREADY_RUNNING, DAEMON_FATAL_CONFIG_ERROR, DAEMON_GENERAL_ERROR, | ||||||
|     DAEMON_LEGACY_ALREADY_RUNNING, DAEMON_SUCCESS, WORKER_EXIT_ALL_PROCESSES, WORKER_RESTART, |     DAEMON_LEGACY_ALREADY_RUNNING, DAEMON_SUCCESS, WORKER_EXIT_ALL_PROCESSES, WORKER_RESTART, | ||||||
|  | @ -123,11 +123,7 @@ fn daemon_main(args: CliModuleArgs) -> i32 { | ||||||
| 
 | 
 | ||||||
|   // TODO: register signals to terminate the worker if the daemon terminates
 |   // TODO: register signals to terminate the worker if the daemon terminates
 | ||||||
| 
 | 
 | ||||||
|   spawn_worker( |   spawn_worker(&paths_overrides, exit_notify.clone(), None); | ||||||
|     &paths_overrides, |  | ||||||
|     exit_notify.clone(), |  | ||||||
|     None |  | ||||||
|   ); |  | ||||||
| 
 | 
 | ||||||
|   ipc::initialize_and_spawn(&paths.runtime, exit_notify.clone()) |   ipc::initialize_and_spawn(&paths.runtime, exit_notify.clone()) | ||||||
|     .expect("unable to initialize ipc server for daemon"); |     .expect("unable to initialize ipc server for daemon"); | ||||||
|  | @ -246,10 +242,7 @@ fn spawn_worker( | ||||||
| 
 | 
 | ||||||
|   let mut command = Command::new(&espanso_exe_path.to_string_lossy().to_string()); |   let mut command = Command::new(&espanso_exe_path.to_string_lossy().to_string()); | ||||||
| 
 | 
 | ||||||
|   let mut args = vec![ |   let mut args = vec!["worker", "--monitor-daemon"]; | ||||||
|     "worker", |  | ||||||
|     "--monitor-daemon", |  | ||||||
|   ]; |  | ||||||
|   if let Some(start_reason) = &start_reason { |   if let Some(start_reason) = &start_reason { | ||||||
|     args.push("--start-reason"); |     args.push("--start-reason"); | ||||||
|     args.push(start_reason); |     args.push(start_reason); | ||||||
|  | @ -312,11 +305,7 @@ fn restart_worker( | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if !has_timed_out { |   if !has_timed_out { | ||||||
|     spawn_worker( |     spawn_worker(paths_overrides, exit_notify, start_reason); | ||||||
|       paths_overrides, |  | ||||||
|       exit_notify, |  | ||||||
|       start_reason, |  | ||||||
|     ); |  | ||||||
|   } else { |   } else { | ||||||
|     error!("could not restart worker, as the exit process has timed out"); |     error!("could not restart worker, as the exit process has timed out"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -99,11 +99,9 @@ pub fn load_config_or_troubleshoot(paths: &Paths, paths_overrides: &PathsOverrid | ||||||
|         LoadResult::Warning(load_result, troubleshoot_handle) |         LoadResult::Warning(load_result, troubleshoot_handle) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     Err(_) => { |     Err(_) => LoadResult::Fatal( | ||||||
|       LoadResult::Fatal( |       launch_troubleshoot(paths_overrides).expect("unable to launch troubleshoot GUI"), | ||||||
|         launch_troubleshoot(paths_overrides).expect("unable to launch troubleshoot GUI"), |     ), | ||||||
|       ) |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -78,9 +78,9 @@ fn watcher_main(config_dir: &Path, watcher_notify: &Sender<()>) { | ||||||
|           if ["yml", "yaml"].iter().any(|ext| ext == &extension) { |           if ["yml", "yaml"].iter().any(|ext| ext == &extension) { | ||||||
|             // Only load non-hidden yml files
 |             // Only load non-hidden yml files
 | ||||||
|             !is_file_hidden(&path) |             !is_file_hidden(&path) | ||||||
|           } else { 
 |           } else { | ||||||
|             // If there is no extension, it's probably a folder 
 |             // If there is no extension, it's probably a folder
 | ||||||
|             extension.is_empty() 
 |             extension.is_empty() | ||||||
|           } |           } | ||||||
|         } else { |         } else { | ||||||
|           false |           false | ||||||
|  |  | ||||||
|  | @ -35,4 +35,4 @@ pub fn is_accessibility_enabled() -> bool { | ||||||
| #[cfg(target_os = "macos")] | #[cfg(target_os = "macos")] | ||||||
| pub fn prompt_enable_accessibility() -> bool { | pub fn prompt_enable_accessibility() -> bool { | ||||||
|   espanso_mac_utils::prompt_accessibility() |   espanso_mac_utils::prompt_accessibility() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -22,8 +22,8 @@ use std::process::Command; | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use thiserror::Error; | use thiserror::Error; | ||||||
| 
 | 
 | ||||||
| use crate::cli::PathsOverrides; |  | ||||||
| use crate::cli::util::CommandExt; | use crate::cli::util::CommandExt; | ||||||
|  | use crate::cli::PathsOverrides; | ||||||
| 
 | 
 | ||||||
| pub fn launch_daemon(paths_overrides: &PathsOverrides) -> Result<()> { | pub fn launch_daemon(paths_overrides: &PathsOverrides) -> Result<()> { | ||||||
|   let espanso_exe_path = std::env::current_exe()?; |   let espanso_exe_path = std::env::current_exe()?; | ||||||
|  |  | ||||||
|  | @ -18,8 +18,11 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use self::util::MigrationError; | use self::util::MigrationError; | ||||||
| use crate::{exit_code::{LAUNCHER_ALREADY_RUNNING, LAUNCHER_CONFIG_DIR_POPULATION_FAILURE, LAUNCHER_SUCCESS}, lock::acquire_daemon_lock}; |  | ||||||
| use crate::preferences::Preferences; | use crate::preferences::Preferences; | ||||||
|  | use crate::{ | ||||||
|  |   exit_code::{LAUNCHER_ALREADY_RUNNING, LAUNCHER_CONFIG_DIR_POPULATION_FAILURE, LAUNCHER_SUCCESS}, | ||||||
|  |   lock::acquire_daemon_lock, | ||||||
|  | }; | ||||||
| use log::error; | use log::error; | ||||||
| 
 | 
 | ||||||
| use super::{CliModule, CliModuleArgs}; | use super::{CliModule, CliModuleArgs}; | ||||||
|  | @ -75,8 +78,9 @@ fn launcher_main(args: CliModuleArgs) -> i32 { | ||||||
|   let runtime_dir_clone = paths.runtime.clone(); |   let runtime_dir_clone = paths.runtime.clone(); | ||||||
|   let is_legacy_version_running_handler = |   let is_legacy_version_running_handler = | ||||||
|     Box::new(move || util::is_legacy_version_running(&runtime_dir_clone)); |     Box::new(move || util::is_legacy_version_running(&runtime_dir_clone)); | ||||||
|   
 | 
 | ||||||
|   let (is_wrong_edition_page_enabled, wrong_edition_detected_os) = edition_check::is_wrong_edition(); |   let (is_wrong_edition_page_enabled, wrong_edition_detected_os) = | ||||||
|  |     edition_check::is_wrong_edition(); | ||||||
| 
 | 
 | ||||||
|   let is_migrate_page_enabled = espanso_config::is_legacy_config(&paths.config); |   let is_migrate_page_enabled = espanso_config::is_legacy_config(&paths.config); | ||||||
|   let paths_clone = paths.clone(); |   let paths_clone = paths.clone(); | ||||||
|  | @ -115,8 +119,7 @@ fn launcher_main(args: CliModuleArgs) -> i32 { | ||||||
|   } else { |   } else { | ||||||
|     false |     false | ||||||
|   }; |   }; | ||||||
|   let is_accessibility_enabled_handler = |   let is_accessibility_enabled_handler = Box::new(accessibility::is_accessibility_enabled); | ||||||
|     Box::new(accessibility::is_accessibility_enabled); |  | ||||||
|   let enable_accessibility_handler = Box::new(move || { |   let enable_accessibility_handler = Box::new(move || { | ||||||
|     accessibility::prompt_enable_accessibility(); |     accessibility::prompt_enable_accessibility(); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|  | @ -20,10 +20,13 @@ | ||||||
| use std::{path::Path, process::Command}; | use std::{path::Path, process::Command}; | ||||||
| 
 | 
 | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use thiserror::Error; |  | ||||||
| use espanso_path::Paths; | use espanso_path::Paths; | ||||||
|  | use thiserror::Error; | ||||||
| 
 | 
 | ||||||
| use crate::{exit_code::{MIGRATE_CLEAN_FAILURE, MIGRATE_DIRTY_FAILURE}, lock::acquire_legacy_lock}; | use crate::{ | ||||||
|  |   exit_code::{MIGRATE_CLEAN_FAILURE, MIGRATE_DIRTY_FAILURE}, | ||||||
|  |   lock::acquire_legacy_lock, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| pub fn is_legacy_version_running(runtime_path: &Path) -> bool { | pub fn is_legacy_version_running(runtime_path: &Path) -> bool { | ||||||
|   let legacy_lock_file = acquire_legacy_lock(runtime_path); |   let legacy_lock_file = acquire_legacy_lock(runtime_path); | ||||||
|  | @ -55,8 +58,8 @@ pub fn migrate_configuration(paths: &Paths) -> Result<()> { | ||||||
|   } else { |   } else { | ||||||
|     match result.code() { |     match result.code() { | ||||||
|       Some(code) if code == MIGRATE_CLEAN_FAILURE => Err(MigrationError::Clean.into()), |       Some(code) if code == MIGRATE_CLEAN_FAILURE => Err(MigrationError::Clean.into()), | ||||||
|       Some(code) if code == MIGRATE_DIRTY_FAILURE=> Err(MigrationError::Dirty.into()), |       Some(code) if code == MIGRATE_DIRTY_FAILURE => Err(MigrationError::Dirty.into()), | ||||||
|       _ => Err(MigrationError::Unexpected.into()) |       _ => Err(MigrationError::Unexpected.into()), | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,8 +17,8 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use std::{fs::File, io::BufReader}; |  | ||||||
| use std::io::BufRead; | use std::io::BufRead; | ||||||
|  | use std::{fs::File, io::BufReader}; | ||||||
| 
 | 
 | ||||||
| use super::{CliModule, CliModuleArgs}; | use super::{CliModule, CliModuleArgs}; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -17,9 +17,16 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use std::{path::PathBuf}; | use std::path::PathBuf; | ||||||
| 
 | 
 | ||||||
| use crate::{exit_code::{MIGRATE_ALREADY_NEW_FORMAT, MIGRATE_CLEAN_FAILURE, MIGRATE_DIRTY_FAILURE, MIGRATE_LEGACY_INSTANCE_RUNNING, MIGRATE_SUCCESS, MIGRATE_USER_ABORTED, configure_custom_panic_hook, update_panic_exit_code}, lock::acquire_legacy_lock}; | use crate::{ | ||||||
|  |   exit_code::{ | ||||||
|  |     configure_custom_panic_hook, update_panic_exit_code, MIGRATE_ALREADY_NEW_FORMAT, | ||||||
|  |     MIGRATE_CLEAN_FAILURE, MIGRATE_DIRTY_FAILURE, MIGRATE_LEGACY_INSTANCE_RUNNING, MIGRATE_SUCCESS, | ||||||
|  |     MIGRATE_USER_ABORTED, | ||||||
|  |   }, | ||||||
|  |   lock::acquire_legacy_lock, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| use super::{CliModule, CliModuleArgs}; | use super::{CliModule, CliModuleArgs}; | ||||||
| use colored::*; | use colored::*; | ||||||
|  | @ -91,11 +98,13 @@ fn migrate_main(args: CliModuleArgs) -> i32 { | ||||||
|     target_backup_dir.to_string_lossy() |     target_backup_dir.to_string_lossy() | ||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
|   if !cli_args.is_present("noconfirm") && !Confirm::new() |   if !cli_args.is_present("noconfirm") | ||||||
|  |     && !Confirm::new() | ||||||
|       .with_prompt("Do you want to proceed?") |       .with_prompt("Do you want to proceed?") | ||||||
|       .default(true) |       .default(true) | ||||||
|       .interact() |       .interact() | ||||||
|       .expect("unable to read choice") { |       .expect("unable to read choice") | ||||||
|  |   { | ||||||
|     return MIGRATE_USER_ABORTED; |     return MIGRATE_USER_ABORTED; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -132,7 +141,7 @@ fn migrate_main(args: CliModuleArgs) -> i32 { | ||||||
|     fs_extra::dir::get_dir_content(&paths.config).expect("unable to list legacy dir files"); |     fs_extra::dir::get_dir_content(&paths.config).expect("unable to list legacy dir files"); | ||||||
|   to_be_removed.extend(legacy_dir_content.files); |   to_be_removed.extend(legacy_dir_content.files); | ||||||
|   to_be_removed.extend(legacy_dir_content.directories); |   to_be_removed.extend(legacy_dir_content.directories); | ||||||
|   
 | 
 | ||||||
|   // Skip the config directory itself to preserve the symbolic link (if present)
 |   // Skip the config directory itself to preserve the symbolic link (if present)
 | ||||||
|   let config_dir_as_str = paths.config.to_string_lossy().to_string(); |   let config_dir_as_str = paths.config.to_string_lossy().to_string(); | ||||||
|   to_be_removed.retain(|path| path != &config_dir_as_str); |   to_be_removed.retain(|path| path != &config_dir_as_str); | ||||||
|  |  | ||||||
|  | @ -45,7 +45,7 @@ pub struct CliModule { | ||||||
|   pub subcommand: String, |   pub subcommand: String, | ||||||
|   pub show_in_dock: bool, |   pub show_in_dock: bool, | ||||||
|   pub requires_linux_capabilities: bool, |   pub requires_linux_capabilities: bool, | ||||||
|   pub entry: fn(CliModuleArgs)->i32, |   pub entry: fn(CliModuleArgs) -> i32, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Default for CliModule { | impl Default for CliModule { | ||||||
|  | @ -54,12 +54,12 @@ impl Default for CliModule { | ||||||
|       enable_logs: false, |       enable_logs: false, | ||||||
|       log_mode: LogMode::Read, |       log_mode: LogMode::Read, | ||||||
|       disable_logs_terminal_output: false, |       disable_logs_terminal_output: false, | ||||||
|       requires_paths: false, 
 |       requires_paths: false, | ||||||
|       requires_config: false, 
 |       requires_config: false, | ||||||
|       subcommand: "".to_string(), 
 |       subcommand: "".to_string(), | ||||||
|       show_in_dock: false, |       show_in_dock: false, | ||||||
|       requires_linux_capabilities: false, |       requires_linux_capabilities: false, | ||||||
|       entry: |_| {0}, |       entry: |_| 0, | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -104,4 +104,4 @@ pub struct PathsOverrides { | ||||||
| pub struct CliAlias { | pub struct CliAlias { | ||||||
|   pub subcommand: String, |   pub subcommand: String, | ||||||
|   pub forward_into: String, |   pub forward_into: String, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,9 +17,9 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use clap::{ArgMatches}; |  | ||||||
| use espanso_modulo::form::*; |  | ||||||
| use crate::icon::IconPaths; | use crate::icon::IconPaths; | ||||||
|  | use clap::ArgMatches; | ||||||
|  | use espanso_modulo::form::*; | ||||||
| 
 | 
 | ||||||
| pub fn form_main(matches: &ArgMatches, _icon_paths: &IconPaths) -> i32 { | pub fn form_main(matches: &ArgMatches, _icon_paths: &IconPaths) -> i32 { | ||||||
|   let as_json: bool = matches.is_present("json"); |   let as_json: bool = matches.is_present("json"); | ||||||
|  | @ -43,9 +43,12 @@ pub fn form_main(matches: &ArgMatches, _icon_paths: &IconPaths) -> i32 { | ||||||
|   } else { |   } else { | ||||||
|     serde_json::from_str(&data).expect("unable to parse form configuration") |     serde_json::from_str(&data).expect("unable to parse form configuration") | ||||||
|   }; |   }; | ||||||
|   
 | 
 | ||||||
|   // Overwrite the icon
 |   // Overwrite the icon
 | ||||||
|   config.icon = _icon_paths.form_icon.as_deref().map(|path| path.to_string_lossy().to_string()); |   config.icon = _icon_paths | ||||||
|  |     .form_icon | ||||||
|  |     .as_deref() | ||||||
|  |     .map(|path| path.to_string_lossy().to_string()); | ||||||
| 
 | 
 | ||||||
|   let form = generator::generate(config); |   let form = generator::generate(config); | ||||||
|   let values = show(form); |   let values = show(form); | ||||||
|  |  | ||||||
|  | @ -24,9 +24,9 @@ mod form; | ||||||
| #[cfg(feature = "modulo")] | #[cfg(feature = "modulo")] | ||||||
| mod search; | mod search; | ||||||
| #[cfg(feature = "modulo")] | #[cfg(feature = "modulo")] | ||||||
| mod welcome; |  | ||||||
| #[cfg(feature = "modulo")] |  | ||||||
| mod troubleshoot; | mod troubleshoot; | ||||||
|  | #[cfg(feature = "modulo")] | ||||||
|  | mod welcome; | ||||||
| 
 | 
 | ||||||
| pub fn new() -> CliModule { | pub fn new() -> CliModule { | ||||||
|   #[allow(clippy::needless_update)] |   #[allow(clippy::needless_update)] | ||||||
|  | @ -56,7 +56,7 @@ fn modulo_main(args: CliModuleArgs) -> i32 { | ||||||
|   if let Some(matches) = cli_args.subcommand_matches("welcome") { |   if let Some(matches) = cli_args.subcommand_matches("welcome") { | ||||||
|     return welcome::welcome_main(matches, &paths, &icon_paths); |     return welcome::welcome_main(matches, &paths, &icon_paths); | ||||||
|   } |   } | ||||||
|   
 | 
 | ||||||
|   if cli_args.subcommand_matches("troubleshoot").is_some() { |   if cli_args.subcommand_matches("troubleshoot").is_some() { | ||||||
|     return troubleshoot::troubleshoot_main(&paths, &icon_paths); |     return troubleshoot::troubleshoot_main(&paths, &icon_paths); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -17,10 +17,10 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use std::collections::HashMap; |  | ||||||
| use clap::{ArgMatches}; |  | ||||||
| use espanso_modulo::search::*; |  | ||||||
| use crate::icon::IconPaths; | use crate::icon::IconPaths; | ||||||
|  | use clap::ArgMatches; | ||||||
|  | use espanso_modulo::search::*; | ||||||
|  | use std::collections::HashMap; | ||||||
| 
 | 
 | ||||||
| pub fn search_main(matches: &ArgMatches, icon_paths: &IconPaths) -> i32 { | pub fn search_main(matches: &ArgMatches, icon_paths: &IconPaths) -> i32 { | ||||||
|   let as_json: bool = matches.is_present("json"); |   let as_json: bool = matches.is_present("json"); | ||||||
|  | @ -46,7 +46,10 @@ pub fn search_main(matches: &ArgMatches, icon_paths: &IconPaths) -> i32 { | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   // Overwrite the icon
 |   // Overwrite the icon
 | ||||||
|   config.icon = icon_paths.logo.as_deref().map(|path| path.to_string_lossy().to_string()); |   config.icon = icon_paths | ||||||
|  |     .logo | ||||||
|  |     .as_deref() | ||||||
|  |     .map(|path| path.to_string_lossy().to_string()); | ||||||
| 
 | 
 | ||||||
|   let algorithm = algorithm::get_algorithm(&config.algorithm, true); |   let algorithm = algorithm::get_algorithm(&config.algorithm, true); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use std::path::{Path}; | use std::path::Path; | ||||||
| 
 | 
 | ||||||
| use crate::icon::IconPaths; | use crate::icon::IconPaths; | ||||||
| use crate::preferences::Preferences; | use crate::preferences::Preferences; | ||||||
|  | @ -38,68 +38,69 @@ pub fn troubleshoot_main(paths: &Paths, icon_paths: &IconPaths) -> i32 { | ||||||
|     } |     } | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   let (is_fatal_error, error_sets) = match crate::config::load_config(&paths.config, &paths.packages) |   let (is_fatal_error, error_sets) = | ||||||
|   { |     match crate::config::load_config(&paths.config, &paths.packages) { | ||||||
|     Ok(config_result) => { |       Ok(config_result) => { | ||||||
|       let error_sets = config_result |         let error_sets = config_result | ||||||
|         .non_fatal_errors |           .non_fatal_errors | ||||||
|         .into_iter() |           .into_iter() | ||||||
|         .map(|error_set| espanso_modulo::troubleshooting::ErrorSet { |           .map(|error_set| espanso_modulo::troubleshooting::ErrorSet { | ||||||
|           file: Some(error_set.file), |             file: Some(error_set.file), | ||||||
|           errors: error_set |             errors: error_set | ||||||
|             .errors |               .errors | ||||||
|             .into_iter() |               .into_iter() | ||||||
|             .map(|error| espanso_modulo::troubleshooting::ErrorRecord { |               .map(|error| espanso_modulo::troubleshooting::ErrorRecord { | ||||||
|               level: match error.level { |                 level: match error.level { | ||||||
|                 espanso_config::error::ErrorLevel::Error => { |                   espanso_config::error::ErrorLevel::Error => { | ||||||
|                   espanso_modulo::troubleshooting::ErrorLevel::Error |                     espanso_modulo::troubleshooting::ErrorLevel::Error | ||||||
|                 } |                   } | ||||||
|                 espanso_config::error::ErrorLevel::Warning => { |                   espanso_config::error::ErrorLevel::Warning => { | ||||||
|                   espanso_modulo::troubleshooting::ErrorLevel::Warning |                     espanso_modulo::troubleshooting::ErrorLevel::Warning | ||||||
|                 } |                   } | ||||||
|               }, |                 }, | ||||||
|               message: format!("{:?}", error.error), |                 message: format!("{:?}", error.error), | ||||||
|             }) |               }) | ||||||
|             .collect(), |               .collect(), | ||||||
|         }) |           }) | ||||||
|         .collect(); |           .collect(); | ||||||
| 
 | 
 | ||||||
|       (false, error_sets) |         (false, error_sets) | ||||||
|     } |       } | ||||||
|     Err(err) => { |       Err(err) => { | ||||||
|       let message = format!("{:?}", err); |         let message = format!("{:?}", err); | ||||||
|       let file_path = if message.contains("default.yml") { |         let file_path = if message.contains("default.yml") { | ||||||
|         let default_file_path = paths.config.join("config").join("default.yml"); |           let default_file_path = paths.config.join("config").join("default.yml"); | ||||||
|         Some(default_file_path) |           Some(default_file_path) | ||||||
|       } else { |         } else { | ||||||
|         None |           None | ||||||
|       }; |         }; | ||||||
| 
 | 
 | ||||||
|       ( |         ( | ||||||
|         true, |           true, | ||||||
|         vec![espanso_modulo::troubleshooting::ErrorSet { |           vec![espanso_modulo::troubleshooting::ErrorSet { | ||||||
|           file: file_path, |             file: file_path, | ||||||
|           errors: vec![espanso_modulo::troubleshooting::ErrorRecord { |             errors: vec![espanso_modulo::troubleshooting::ErrorRecord { | ||||||
|             level: espanso_modulo::troubleshooting::ErrorLevel::Error, |               level: espanso_modulo::troubleshooting::ErrorLevel::Error, | ||||||
|             message: format!("{:?}", err), |               message: format!("{:?}", err), | ||||||
|  |             }], | ||||||
|           }], |           }], | ||||||
|         }], |         ) | ||||||
|       ) |       } | ||||||
|     } |     }; | ||||||
|   }; |  | ||||||
| 
 | 
 | ||||||
|   espanso_modulo::troubleshooting::show(TroubleshootingOptions { |   espanso_modulo::troubleshooting::show(TroubleshootingOptions { | ||||||
|     window_icon_path: icon_paths |     window_icon_path: icon_paths | ||||||
|       .wizard_icon |       .wizard_icon | ||||||
|       .as_ref() |       .as_ref() | ||||||
|       .map(|path| path.to_string_lossy().to_string()), |       .map(|path| path.to_string_lossy().to_string()), | ||||||
|     error_sets, 
 |     error_sets, | ||||||
|     is_fatal_error, |     is_fatal_error, | ||||||
|     handlers: TroubleshootingHandlers { |     handlers: TroubleshootingHandlers { | ||||||
|       dont_show_again_changed: Some(dont_show_again_handler), |       dont_show_again_changed: Some(dont_show_again_handler), | ||||||
|       open_file: Some(open_file_handler), |       open_file: Some(open_file_handler), | ||||||
|     }, |     }, | ||||||
|   }).expect("troubleshoot GUI returned error"); |   }) | ||||||
|  |   .expect("troubleshoot GUI returned error"); | ||||||
| 
 | 
 | ||||||
|   0 |   0 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,8 +17,8 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use clap::{ArgMatches}; |  | ||||||
| use crate::icon::IconPaths; | use crate::icon::IconPaths; | ||||||
|  | use clap::ArgMatches; | ||||||
| use espanso_modulo::welcome::*; | use espanso_modulo::welcome::*; | ||||||
| use espanso_path::Paths; | use espanso_path::Paths; | ||||||
| 
 | 
 | ||||||
|  | @ -30,7 +30,7 @@ pub fn welcome_main(matches: &ArgMatches, _: &Paths, icon_paths: &IconPaths) -> | ||||||
| 
 | 
 | ||||||
|   let is_already_running = matches.is_present("already-running"); |   let is_already_running = matches.is_present("already-running"); | ||||||
| 
 | 
 | ||||||
|   espanso_modulo::welcome::show(WelcomeOptions{ |   espanso_modulo::welcome::show(WelcomeOptions { | ||||||
|     window_icon_path: icon_paths |     window_icon_path: icon_paths | ||||||
|       .wizard_icon |       .wizard_icon | ||||||
|       .as_ref() |       .as_ref() | ||||||
|  |  | ||||||
|  | @ -70,8 +70,12 @@ pub fn install_package(paths: &Paths, matches: &ArgMatches) -> Result<()> { | ||||||
|     error_eprintln!("Error: the requested package is hosted on an external repository"); |     error_eprintln!("Error: the requested package is hosted on an external repository"); | ||||||
|     error_eprintln!("and its contents may not have been verified by the espanso team."); |     error_eprintln!("and its contents may not have been verified by the espanso team."); | ||||||
|     error_eprintln!(""); |     error_eprintln!(""); | ||||||
|     error_eprintln!("For security reasons, espanso blocks packages that are not verified by default."); |     error_eprintln!( | ||||||
|     error_eprintln!("If you want to install the package anyway, you can proceed with the installation"); |       "For security reasons, espanso blocks packages that are not verified by default." | ||||||
|  |     ); | ||||||
|  |     error_eprintln!( | ||||||
|  |       "If you want to install the package anyway, you can proceed with the installation" | ||||||
|  |     ); | ||||||
|     error_eprintln!("by passing the '--external' flag, but please do it only if you trust the"); |     error_eprintln!("by passing the '--external' flag, but please do it only if you trust the"); | ||||||
|     error_eprintln!("source or you verified the contents of the package yourself."); |     error_eprintln!("source or you verified the contents of the package yourself."); | ||||||
|     error_eprintln!(""); |     error_eprintln!(""); | ||||||
|  |  | ||||||
|  | @ -42,10 +42,15 @@ pub fn list_packages(paths: &Paths, _: &ArgMatches) -> Result<()> { | ||||||
|     match package { |     match package { | ||||||
|       StoredPackage::Legacy(legacy) => { |       StoredPackage::Legacy(legacy) => { | ||||||
|         info_println!("- {} (legacy)", legacy.name); |         info_println!("- {} (legacy)", legacy.name); | ||||||
|       }, |       } | ||||||
|       StoredPackage::Modern(package) => { |       StoredPackage::Modern(package) => { | ||||||
|         info_println!("- {} - version: {} ({})", package.manifest.name, package.manifest.version, package.source); |         info_println!( | ||||||
|       }, |           "- {} - version: {} ({})", | ||||||
|  |           package.manifest.name, | ||||||
|  |           package.manifest.version, | ||||||
|  |           package.source | ||||||
|  |         ); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -31,7 +31,9 @@ pub fn uninstall_package(paths: &Paths, matches: &ArgMatches) -> Result<()> { | ||||||
|   let archiver = |   let archiver = | ||||||
|     espanso_package::get_archiver(&paths.packages).context("unable to get package archiver")?; |     espanso_package::get_archiver(&paths.packages).context("unable to get package archiver")?; | ||||||
| 
 | 
 | ||||||
|   archiver.delete(package_name).context("unable to delete package")?; |   archiver | ||||||
|  |     .delete(package_name) | ||||||
|  |     .context("unable to delete package")?; | ||||||
| 
 | 
 | ||||||
|   info_println!("package '{}' uninstalled!", package_name); |   info_println!("package '{}' uninstalled!", package_name); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,25 +37,41 @@ fn path_main(args: CliModuleArgs) -> i32 { | ||||||
|     println!("{}", paths.config.to_string_lossy()); |     println!("{}", paths.config.to_string_lossy()); | ||||||
|   } else if cli_args.subcommand_matches("packages").is_some() { |   } else if cli_args.subcommand_matches("packages").is_some() { | ||||||
|     println!("{}", paths.packages.to_string_lossy()); |     println!("{}", paths.packages.to_string_lossy()); | ||||||
|   } else if cli_args.subcommand_matches("data").is_some() || cli_args.subcommand_matches("runtime").is_some() { |   } else if cli_args.subcommand_matches("data").is_some() | ||||||
|  |     || cli_args.subcommand_matches("runtime").is_some() | ||||||
|  |   { | ||||||
|     println!("{}", paths.runtime.to_string_lossy()); |     println!("{}", paths.runtime.to_string_lossy()); | ||||||
|   } else if cli_args.subcommand_matches("default").is_some() { |   } else if cli_args.subcommand_matches("default").is_some() { | ||||||
|     if args.is_legacy_config { |     if args.is_legacy_config { | ||||||
|       println!("{}", paths.config.join("default.yml").to_string_lossy()); |       println!("{}", paths.config.join("default.yml").to_string_lossy()); | ||||||
|     } else { |     } else { | ||||||
|       println!("{}", paths.config.join("config").join("default.yml").to_string_lossy()); |       println!( | ||||||
|  |         "{}", | ||||||
|  |         paths | ||||||
|  |           .config | ||||||
|  |           .join("config") | ||||||
|  |           .join("default.yml") | ||||||
|  |           .to_string_lossy() | ||||||
|  |       ); | ||||||
|     } |     } | ||||||
|   } else if cli_args.subcommand_matches("base").is_some() { |   } else if cli_args.subcommand_matches("base").is_some() { | ||||||
|     if args.is_legacy_config { |     if args.is_legacy_config { | ||||||
|       eprintln!("base config not available when using legacy configuration format"); |       eprintln!("base config not available when using legacy configuration format"); | ||||||
|     } else { |     } else { | ||||||
|       println!("{}", paths.config.join("match").join("base.yml").to_string_lossy()); |       println!( | ||||||
|  |         "{}", | ||||||
|  |         paths | ||||||
|  |           .config | ||||||
|  |           .join("match") | ||||||
|  |           .join("base.yml") | ||||||
|  |           .to_string_lossy() | ||||||
|  |       ); | ||||||
|     } |     } | ||||||
|   } else { |   } else { | ||||||
|     println!("Config: {}", paths.config.to_string_lossy()); |     println!("Config: {}", paths.config.to_string_lossy()); | ||||||
|     println!("Packages: {}", paths.packages.to_string_lossy()); |     println!("Packages: {}", paths.packages.to_string_lossy()); | ||||||
|     println!("Runtime: {}", paths.runtime.to_string_lossy()); |     println!("Runtime: {}", paths.runtime.to_string_lossy()); | ||||||
|   } |   } | ||||||
|   
 | 
 | ||||||
|   0 |   0 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -20,9 +20,9 @@ | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use const_format::formatcp; | use const_format::formatcp; | ||||||
| use regex::Regex; | use regex::Regex; | ||||||
|  | use std::fs::create_dir_all; | ||||||
| use std::path::PathBuf; | use std::path::PathBuf; | ||||||
| use std::process::{Command, Stdio}; | use std::process::{Command, Stdio}; | ||||||
| use std::{fs::create_dir_all}; |  | ||||||
| use thiserror::Error; | use thiserror::Error; | ||||||
| 
 | 
 | ||||||
| use crate::{error_eprintln, info_println, warn_eprintln}; | use crate::{error_eprintln, info_println, warn_eprintln}; | ||||||
|  | @ -143,8 +143,7 @@ pub fn is_registered() -> bool { | ||||||
|         if cmd_output.status.success() { |         if cmd_output.status.success() { | ||||||
|           let caps = EXEC_PATH_REGEX.captures(output).unwrap(); |           let caps = EXEC_PATH_REGEX.captures(output).unwrap(); | ||||||
|           let path = caps.get(1).map_or("", |m| m.as_str()); |           let path = caps.get(1).map_or("", |m| m.as_str()); | ||||||
|           let espanso_path = |           let espanso_path = get_binary_path().expect("unable to get espanso executable path"); | ||||||
|             get_binary_path().expect("unable to get espanso executable path"); |  | ||||||
| 
 | 
 | ||||||
|           if espanso_path.to_string_lossy() != path { |           if espanso_path.to_string_lossy() != path { | ||||||
|             error_eprintln!("Espanso is registered as a systemd service, but it points to another binary location:"); |             error_eprintln!("Espanso is registered as a systemd service, but it points to another binary location:"); | ||||||
|  | @ -195,8 +194,12 @@ pub fn start_service() -> Result<()> { | ||||||
|       ); |       ); | ||||||
|       error_eprintln!("You can run it in unmanaged mode with `espanso service start --unmanaged`"); |       error_eprintln!("You can run it in unmanaged mode with `espanso service start --unmanaged`"); | ||||||
|       error_eprintln!(""); |       error_eprintln!(""); | ||||||
|       error_eprintln!("NOTE: unmanaged mode means espanso does not rely on the system service manager"); |       error_eprintln!( | ||||||
|       error_eprintln!("      to run, but as a result, you are in charge of starting/stopping espanso"); |         "NOTE: unmanaged mode means espanso does not rely on the system service manager" | ||||||
|  |       ); | ||||||
|  |       error_eprintln!( | ||||||
|  |         "      to run, but as a result, you are in charge of starting/stopping espanso" | ||||||
|  |       ); | ||||||
|       error_eprintln!("      when needed."); |       error_eprintln!("      when needed."); | ||||||
|       return Err(StartError::SystemdNotFound.into()); |       return Err(StartError::SystemdNotFound.into()); | ||||||
|     } |     } | ||||||
|  | @ -207,8 +210,12 @@ pub fn start_service() -> Result<()> { | ||||||
|     error_eprintln!("You can either register it first with `espanso service register` or"); |     error_eprintln!("You can either register it first with `espanso service register` or"); | ||||||
|     error_eprintln!("you can run it in unmanaged mode with `espanso service start --unmanaged`"); |     error_eprintln!("you can run it in unmanaged mode with `espanso service start --unmanaged`"); | ||||||
|     error_eprintln!(""); |     error_eprintln!(""); | ||||||
|     error_eprintln!("NOTE: unmanaged mode means espanso does not rely on the system service manager"); |     error_eprintln!( | ||||||
|     error_eprintln!("      to run, but as a result, you are in charge of starting/stopping espanso"); |       "NOTE: unmanaged mode means espanso does not rely on the system service manager" | ||||||
|  |     ); | ||||||
|  |     error_eprintln!( | ||||||
|  |       "      to run, but as a result, you are in charge of starting/stopping espanso" | ||||||
|  |     ); | ||||||
|     error_eprintln!("      when needed."); |     error_eprintln!("      when needed."); | ||||||
|     return Err(StartError::NotRegistered.into()); |     return Err(StartError::NotRegistered.into()); | ||||||
|   } |   } | ||||||
|  | @ -274,4 +281,4 @@ fn get_binary_path() -> Result<PathBuf> { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Ok(std::env::current_exe()?) |   Ok(std::env::current_exe()?) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -18,7 +18,15 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use super::{CliModule, CliModuleArgs}; | use super::{CliModule, CliModuleArgs}; | ||||||
| use crate::{error_eprintln, exit_code::{SERVICE_ALREADY_RUNNING, SERVICE_FAILURE, SERVICE_NOT_REGISTERED, SERVICE_NOT_RUNNING, SERVICE_SUCCESS}, info_println, lock::acquire_worker_lock}; | use crate::{ | ||||||
|  |   error_eprintln, | ||||||
|  |   exit_code::{ | ||||||
|  |     SERVICE_ALREADY_RUNNING, SERVICE_FAILURE, SERVICE_NOT_REGISTERED, SERVICE_NOT_RUNNING, | ||||||
|  |     SERVICE_SUCCESS, | ||||||
|  |   }, | ||||||
|  |   info_println, | ||||||
|  |   lock::acquire_worker_lock, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| #[cfg(target_os = "macos")] | #[cfg(target_os = "macos")] | ||||||
| mod macos; | mod macos; | ||||||
|  | @ -123,7 +131,7 @@ fn service_main(args: CliModuleArgs) -> i32 { | ||||||
|       error_eprintln!("unable to stop espanso: {}", err); |       error_eprintln!("unable to stop espanso: {}", err); | ||||||
|       return SERVICE_FAILURE; |       return SERVICE_FAILURE; | ||||||
|     } |     } | ||||||
|   } 
 |   } | ||||||
| 
 | 
 | ||||||
|   SERVICE_SUCCESS |   SERVICE_SUCCESS | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,9 +17,9 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | use crate::cli::util::CommandExt; | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use thiserror::Error; | use thiserror::Error; | ||||||
| use crate::cli::util::CommandExt; |  | ||||||
| 
 | 
 | ||||||
| use crate::cli::PathsOverrides; | use crate::cli::PathsOverrides; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -18,11 +18,11 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
|  | use std::fs::create_dir_all; | ||||||
|  | use std::os::windows::process::CommandExt; | ||||||
| use std::path::{Path, PathBuf}; | use std::path::{Path, PathBuf}; | ||||||
| use std::process::Command; | use std::process::Command; | ||||||
| use std::{fs::create_dir_all}; |  | ||||||
| use thiserror::Error; | use thiserror::Error; | ||||||
| use std::os::windows::process::CommandExt; |  | ||||||
| 
 | 
 | ||||||
| use crate::{error_eprintln, warn_eprintln}; | use crate::{error_eprintln, warn_eprintln}; | ||||||
| 
 | 
 | ||||||
|  | @ -30,7 +30,7 @@ pub fn register() -> Result<()> { | ||||||
|   let current_path = std::env::current_exe().expect("unable to get exec path"); |   let current_path = std::env::current_exe().expect("unable to get exec path"); | ||||||
| 
 | 
 | ||||||
|   let shortcut_path = get_startup_shortcut_file()?; |   let shortcut_path = get_startup_shortcut_file()?; | ||||||
|   
 | 
 | ||||||
|   create_shortcut_target_file(&shortcut_path, ¤t_path, "launcher") |   create_shortcut_target_file(&shortcut_path, ¤t_path, "launcher") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -40,7 +40,7 @@ pub fn unregister() -> Result<()> { | ||||||
|     error_eprintln!("could not unregister espanso, as it's not registered"); |     error_eprintln!("could not unregister espanso, as it's not registered"); | ||||||
|     return Err(UnregisterError::EntryNotFound.into()); |     return Err(UnregisterError::EntryNotFound.into()); | ||||||
|   } |   } | ||||||
|   
 | 
 | ||||||
|   std::fs::remove_file(shortcut_path)?; |   std::fs::remove_file(shortcut_path)?; | ||||||
| 
 | 
 | ||||||
|   Ok(()) |   Ok(()) | ||||||
|  | @ -67,19 +67,21 @@ pub fn is_registered() -> bool { | ||||||
|           if current_path != target_path { |           if current_path != target_path { | ||||||
|             warn_eprintln!("WARNING: Espanso is already registered as a service, but it points to another executable,"); |             warn_eprintln!("WARNING: Espanso is already registered as a service, but it points to another executable,"); | ||||||
|             warn_eprintln!("which can create some inconsistencies."); |             warn_eprintln!("which can create some inconsistencies."); | ||||||
|             warn_eprintln!("To fix the problem, unregister and register espanso again with these commands:"); |             warn_eprintln!( | ||||||
|  |               "To fix the problem, unregister and register espanso again with these commands:" | ||||||
|  |             ); | ||||||
|             warn_eprintln!(""); |             warn_eprintln!(""); | ||||||
|             warn_eprintln!("   espanso service unregister"); |             warn_eprintln!("   espanso service unregister"); | ||||||
|             warn_eprintln!("   espanso service register"); |             warn_eprintln!("   espanso service register"); | ||||||
|             warn_eprintln!(""); |             warn_eprintln!(""); | ||||||
|           } |           } | ||||||
|           
 | 
 | ||||||
|           true |           true | ||||||
|         }, |         } | ||||||
|         Err(err) => { |         Err(err) => { | ||||||
|           error_eprintln!("unable to determine shortcut target path: {}", err); |           error_eprintln!("unable to determine shortcut target path: {}", err); | ||||||
|           false |           false | ||||||
|         }, |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     Err(err) => { |     Err(err) => { | ||||||
|  | @ -138,7 +140,11 @@ fn get_shortcut_target_file(shortcut_path: &Path) -> Result<PathBuf> { | ||||||
|   Ok(path) |   Ok(path) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn create_shortcut_target_file(shortcut_path: &Path, target_path: &Path, arguments: &str) -> Result<()> { | fn create_shortcut_target_file( | ||||||
|  |   shortcut_path: &Path, | ||||||
|  |   target_path: &Path, | ||||||
|  |   arguments: &str, | ||||||
|  | ) -> Result<()> { | ||||||
|   let output = Command::new("powershell") |   let output = Command::new("powershell") | ||||||
|             .arg("-c") |             .arg("-c") | ||||||
|             .arg("$WshShell = New-Object -comObject WScript.Shell; $Shortcut = $WshShell.CreateShortcut($env:SHORTCUT_PATH); $Shortcut.TargetPath = $env:TARGET_PATH; $Shortcut.Arguments = $env:TARGET_ARGS; $Shortcut.Save()") |             .arg("$WshShell = New-Object -comObject WScript.Shell; $Shortcut = $WshShell.CreateShortcut($env:SHORTCUT_PATH); $Shortcut.TargetPath = $env:TARGET_PATH; $Shortcut.Arguments = $env:TARGET_ARGS; $Shortcut.Save()") | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use super::{CliModule, CliModuleArgs}; | use super::{CliModule, CliModuleArgs}; | ||||||
| use crate::{error_eprintln, exit_code::{WORKAROUND_SUCCESS}}; | use crate::{error_eprintln, exit_code::WORKAROUND_SUCCESS}; | ||||||
| 
 | 
 | ||||||
| #[cfg(target_os = "macos")] | #[cfg(target_os = "macos")] | ||||||
| mod secure_input; | mod secure_input; | ||||||
|  |  | ||||||
|  | @ -27,11 +27,9 @@ use std::{ | ||||||
| const BLUR_CHROME_WINDOWS_SCRIPT: &str = | const BLUR_CHROME_WINDOWS_SCRIPT: &str = | ||||||
|   include_str!("../../res/macos/scripts/blur_chrome_windows.scpt"); |   include_str!("../../res/macos/scripts/blur_chrome_windows.scpt"); | ||||||
| 
 | 
 | ||||||
| const GET_RUNNING_APPS_SCRIPT: &str = | const GET_RUNNING_APPS_SCRIPT: &str = include_str!("../../res/macos/scripts/get_running_apps.scpt"); | ||||||
|   include_str!("../../res/macos/scripts/get_running_apps.scpt"); |  | ||||||
| 
 | 
 | ||||||
| const FOCUS_BITWARDEN_SCRIPT: &str = | const FOCUS_BITWARDEN_SCRIPT: &str = include_str!("../../res/macos/scripts/focus_bitwarden.scpt"); | ||||||
|   include_str!("../../res/macos/scripts/focus_bitwarden.scpt"); |  | ||||||
| 
 | 
 | ||||||
| const SECURE_INPUT_ASK_LOCK_SCREEN_SCRIPT: &str = | const SECURE_INPUT_ASK_LOCK_SCREEN_SCRIPT: &str = | ||||||
|   include_str!("../../res/macos/scripts/secure_input_ask_lock_screen.scpt"); |   include_str!("../../res/macos/scripts/secure_input_ask_lock_screen.scpt"); | ||||||
|  |  | ||||||
|  | @ -28,9 +28,7 @@ pub fn create_match_exit() -> BuiltInMatch { | ||||||
|     id: generate_next_builtin_id(), |     id: generate_next_builtin_id(), | ||||||
|     label: "Exit espanso", |     label: "Exit espanso", | ||||||
|     triggers: Vec::new(), |     triggers: Vec::new(), | ||||||
|     action: |_| { |     action: |_| EventType::ExitRequested(ExitMode::ExitAllProcesses), | ||||||
|       EventType::ExitRequested(ExitMode::ExitAllProcesses) |  | ||||||
|     }, |  | ||||||
|     ..Default::default() |     ..Default::default() | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -40,9 +38,7 @@ pub fn create_match_restart() -> BuiltInMatch { | ||||||
|     id: generate_next_builtin_id(), |     id: generate_next_builtin_id(), | ||||||
|     label: "Restart espanso", |     label: "Restart espanso", | ||||||
|     triggers: Vec::new(), |     triggers: Vec::new(), | ||||||
|     action: |_| { |     action: |_| EventType::ExitRequested(ExitMode::RestartWorker), | ||||||
|       EventType::ExitRequested(ExitMode::RestartWorker) |  | ||||||
|     }, |  | ||||||
|     ..Default::default() |     ..Default::default() | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -86,7 +86,8 @@ impl<'a> espanso_engine::process::MatchFilter for ConfigManager<'a> { | ||||||
| 
 | 
 | ||||||
|     let builtin_matches: Vec<i32> = matches_ids |     let builtin_matches: Vec<i32> = matches_ids | ||||||
|       .iter() |       .iter() | ||||||
|       .filter(|id| is_builtin_match(**id)).copied() |       .filter(|id| is_builtin_match(**id)) | ||||||
|  |       .copied() | ||||||
|       .collect(); |       .collect(); | ||||||
| 
 | 
 | ||||||
|     let mut output = active_user_defined_matches; |     let mut output = active_user_defined_matches; | ||||||
|  | @ -164,9 +165,9 @@ impl<'a> espanso_engine::process::UndoEnabledProvider for ConfigManager<'a> { | ||||||
|   fn is_undo_enabled(&self) -> bool { |   fn is_undo_enabled(&self) -> bool { | ||||||
|     // Disable undo_backspace on Wayland for now as it's not stable
 |     // Disable undo_backspace on Wayland for now as it's not stable
 | ||||||
|     if cfg!(feature = "wayland") { |     if cfg!(feature = "wayland") { | ||||||
|       return false |       return false; | ||||||
|     } |     } | ||||||
|     
 | 
 | ||||||
|     self.active().undo_backspace() |     self.active().undo_backspace() | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ use espanso_config::config::Config; | ||||||
| 
 | 
 | ||||||
| mod default; | mod default; | ||||||
| pub use default::DefaultContext; | pub use default::DefaultContext; | ||||||
| use espanso_info::{AppInfo}; | use espanso_info::AppInfo; | ||||||
| 
 | 
 | ||||||
| pub trait Context: ConfigContext + AppInfoContext {} | pub trait Context: ConfigContext + AppInfoContext {} | ||||||
| 
 | 
 | ||||||
|  | @ -34,4 +34,4 @@ pub trait ConfigContext { | ||||||
| 
 | 
 | ||||||
| pub trait AppInfoContext { | pub trait AppInfoContext { | ||||||
|   fn get_active_app_info(&self) -> AppInfo; |   fn get_active_app_info(&self) -> AppInfo; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,14 +17,17 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use std::{cell::RefCell, time::{Duration, Instant}}; | use std::{ | ||||||
|  |   cell::RefCell, | ||||||
|  |   time::{Duration, Instant}, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| use espanso_info::{AppInfo, AppInfoProvider}; | use espanso_info::{AppInfo, AppInfoProvider}; | ||||||
| 
 | 
 | ||||||
| pub struct CachedAppInfoProvider<'a> { | pub struct CachedAppInfoProvider<'a> { | ||||||
|   app_info_provider: &'a dyn AppInfoProvider, |   app_info_provider: &'a dyn AppInfoProvider, | ||||||
|   caching_interval: Duration, |   caching_interval: Duration, | ||||||
|   
 | 
 | ||||||
|   _cached_info: RefCell<Option<(Instant, AppInfo)>>, |   _cached_info: RefCell<Option<(Instant, AppInfo)>>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -50,7 +53,7 @@ impl<'a> AppInfoProvider for CachedAppInfoProvider<'a> { | ||||||
| 
 | 
 | ||||||
|     let info = self.app_info_provider.get_info(); |     let info = self.app_info_provider.get_info(); | ||||||
|     *cached_info = Some((Instant::now(), info.clone())); |     *cached_info = Some((Instant::now(), info.clone())); | ||||||
|     
 | 
 | ||||||
|     info |     info | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,4 +17,4 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| pub mod app_info_provider; | pub mod app_info_provider; | ||||||
|  |  | ||||||
|  | @ -89,7 +89,7 @@ impl<'a> ClipboardInjectorAdapter<'a> { | ||||||
|       InjectionOptions { |       InjectionOptions { | ||||||
|         delay: params.paste_shortcut_event_delay as i32, |         delay: params.paste_shortcut_event_delay as i32, | ||||||
|         disable_fast_inject: params.disable_x11_fast_inject, |         disable_fast_inject: params.disable_x11_fast_inject, | ||||||
|         ..Default::default() 
 |         ..Default::default() | ||||||
|       }, |       }, | ||||||
|     )?; |     )?; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -40,7 +40,7 @@ impl<'a> ContextMenuHandler for ContextMenuHandlerAdapter<'a> { | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     self.remote.show_context_menu(&ui_menu); |     self.remote.show_context_menu(&ui_menu); | ||||||
|     
 | 
 | ||||||
|     Ok(()) |     Ok(()) | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use espanso_ui::{UIRemote, icons::TrayIcon}; | use espanso_ui::{icons::TrayIcon, UIRemote}; | ||||||
| 
 | 
 | ||||||
| use espanso_engine::{dispatch::IconHandler, event::ui::IconStatus}; | use espanso_engine::{dispatch::IconHandler, event::ui::IconStatus}; | ||||||
| 
 | 
 | ||||||
|  | @ -35,12 +35,12 @@ impl<'a> IconHandler for IconHandlerAdapter<'a> { | ||||||
|   fn update_icon(&self, status: &IconStatus) -> anyhow::Result<()> { |   fn update_icon(&self, status: &IconStatus) -> anyhow::Result<()> { | ||||||
|     let icon = match status { |     let icon = match status { | ||||||
|       IconStatus::Enabled => TrayIcon::Normal, |       IconStatus::Enabled => TrayIcon::Normal, | ||||||
|       IconStatus::Disabled => TrayIcon::Disabled, 
 |       IconStatus::Disabled => TrayIcon::Disabled, | ||||||
|       IconStatus::SecureInputDisabled => TrayIcon::SystemDisabled, 
 |       IconStatus::SecureInputDisabled => TrayIcon::SystemDisabled, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     self.remote.update_tray_icon(icon); |     self.remote.update_tray_icon(icon); | ||||||
| 
 | 
 | ||||||
|     Ok(()) |     Ok(()) | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -33,4 +33,4 @@ pub struct InjectParams { | ||||||
|   pub key_delay: Option<usize>, |   pub key_delay: Option<usize>, | ||||||
|   pub disable_x11_fast_inject: bool, |   pub disable_x11_fast_inject: bool, | ||||||
|   pub evdev_modifier_delay: Option<usize>, |   pub evdev_modifier_delay: Option<usize>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,4 +17,4 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| pub mod executor; | pub mod executor; | ||||||
|  |  | ||||||
|  | @ -48,9 +48,7 @@ impl<'a> funnel::Source<'a> for DetectSource { | ||||||
|           key: convert_to_engine_key(keyboard_event.key), |           key: convert_to_engine_key(keyboard_event.key), | ||||||
|           value: keyboard_event.value, |           value: keyboard_event.value, | ||||||
|           status: convert_to_engine_status(keyboard_event.status), |           status: convert_to_engine_status(keyboard_event.status), | ||||||
|           variant: keyboard_event |           variant: keyboard_event.variant.map(convert_to_engine_variant), | ||||||
|             .variant |  | ||||||
|             .map(convert_to_engine_variant), |  | ||||||
|         }), |         }), | ||||||
|       }, |       }, | ||||||
|       InputEvent::Mouse(mouse_event) => Event { |       InputEvent::Mouse(mouse_event) => Event { | ||||||
|  |  | ||||||
|  | @ -19,7 +19,10 @@ | ||||||
| 
 | 
 | ||||||
| use crossbeam::channel::{Receiver, Select, SelectedOperation}; | use crossbeam::channel::{Receiver, Select, SelectedOperation}; | ||||||
| 
 | 
 | ||||||
| use espanso_engine::{event::{Event, EventType, ExitMode}, funnel}; | use espanso_engine::{ | ||||||
|  |   event::{Event, EventType, ExitMode}, | ||||||
|  |   funnel, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| use super::sequencer::Sequencer; | use super::sequencer::Sequencer; | ||||||
| 
 | 
 | ||||||
|  | @ -28,7 +31,7 @@ pub struct ExitSource<'a> { | ||||||
|   pub sequencer: &'a Sequencer, |   pub sequencer: &'a Sequencer, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl <'a> ExitSource<'a> { | impl<'a> ExitSource<'a> { | ||||||
|   pub fn new(exit_signal: Receiver<ExitMode>, sequencer: &'a Sequencer) -> Self { |   pub fn new(exit_signal: Receiver<ExitMode>, sequencer: &'a Sequencer) -> Self { | ||||||
|     ExitSource { |     ExitSource { | ||||||
|       exit_signal, |       exit_signal, | ||||||
|  | @ -51,4 +54,4 @@ impl<'a> funnel::Source<'a> for ExitSource<'a> { | ||||||
|       etype: EventType::ExitRequested(mode), |       etype: EventType::ExitRequested(mode), | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -29,7 +29,16 @@ use espanso_path::Paths; | ||||||
| use espanso_ui::{event::UIEvent, UIRemote}; | use espanso_ui::{event::UIEvent, UIRemote}; | ||||||
| use log::{debug, error, info, warn}; | use log::{debug, error, info, warn}; | ||||||
| 
 | 
 | ||||||
| use crate::{cli::worker::{context::Context, engine::{dispatch::executor::{clipboard_injector::ClipboardInjectorAdapter, context_menu::ContextMenuHandlerAdapter, event_injector::EventInjectorAdapter, icon::IconHandlerAdapter, key_injector::KeyInjectorAdapter, secure_input::SecureInputManagerAdapter}, process::middleware::{ | use crate::{ | ||||||
|  |   cli::worker::{ | ||||||
|  |     context::Context, | ||||||
|  |     engine::{ | ||||||
|  |       dispatch::executor::{ | ||||||
|  |         clipboard_injector::ClipboardInjectorAdapter, context_menu::ContextMenuHandlerAdapter, | ||||||
|  |         event_injector::EventInjectorAdapter, icon::IconHandlerAdapter, | ||||||
|  |         key_injector::KeyInjectorAdapter, secure_input::SecureInputManagerAdapter, | ||||||
|  |       }, | ||||||
|  |       process::middleware::{ | ||||||
|         image_resolve::PathProviderAdapter, |         image_resolve::PathProviderAdapter, | ||||||
|         match_select::MatchSelectorAdapter, |         match_select::MatchSelectorAdapter, | ||||||
|         matcher::{ |         matcher::{ | ||||||
|  | @ -42,15 +51,25 @@ use crate::{cli::worker::{context::Context, engine::{dispatch::executor::{clipbo | ||||||
|           extension::{clipboard::ClipboardAdapter, form::FormProviderAdapter}, |           extension::{clipboard::ClipboardAdapter, form::FormProviderAdapter}, | ||||||
|           RendererAdapter, |           RendererAdapter, | ||||||
|         }, |         }, | ||||||
|       }}, match_cache::{CombinedMatchCache, MatchCache}, ui::notification::NotificationManager}, common_flags::{WORKER_START_REASON_CONFIG_CHANGED, WORKER_START_REASON_KEYBOARD_LAYOUT_CHANGED, WORKER_START_REASON_MANUAL}, preferences::Preferences}; |       }, | ||||||
|  |     }, | ||||||
|  |     match_cache::{CombinedMatchCache, MatchCache}, | ||||||
|  |     ui::notification::NotificationManager, | ||||||
|  |   }, | ||||||
|  |   common_flags::{ | ||||||
|  |     WORKER_START_REASON_CONFIG_CHANGED, WORKER_START_REASON_KEYBOARD_LAYOUT_CHANGED, | ||||||
|  |     WORKER_START_REASON_MANUAL, | ||||||
|  |   }, | ||||||
|  |   preferences::Preferences, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| use super::secure_input::SecureInputEvent; | use super::secure_input::SecureInputEvent; | ||||||
| 
 | 
 | ||||||
|  | mod caches; | ||||||
| pub mod dispatch; | pub mod dispatch; | ||||||
| pub mod funnel; | pub mod funnel; | ||||||
| pub mod process; |  | ||||||
| mod caches; |  | ||||||
| mod keyboard_layout_util; | mod keyboard_layout_util; | ||||||
|  | pub mod process; | ||||||
| 
 | 
 | ||||||
| #[allow(clippy::too_many_arguments)] | #[allow(clippy::too_many_arguments)] | ||||||
| pub fn initialize_and_spawn( | pub fn initialize_and_spawn( | ||||||
|  | @ -68,12 +87,16 @@ pub fn initialize_and_spawn( | ||||||
|     .name("engine thread".to_string()) |     .name("engine thread".to_string()) | ||||||
|     .spawn(move || { |     .spawn(move || { | ||||||
|       // TODO: properly order the initializations if necessary
 |       // TODO: properly order the initializations if necessary
 | ||||||
|       let preferences = crate::preferences::get_default(&paths.runtime).expect("unable to load preferences"); |       let preferences = | ||||||
|  |         crate::preferences::get_default(&paths.runtime).expect("unable to load preferences"); | ||||||
| 
 | 
 | ||||||
|       let app_info_provider = |       let app_info_provider = | ||||||
|         espanso_info::get_provider().expect("unable to initialize app info provider"); |         espanso_info::get_provider().expect("unable to initialize app info provider"); | ||||||
|       // TODO: read interval from configs?
 |       // TODO: read interval from configs?
 | ||||||
|       let cached_app_info_provider = caches::app_info_provider::CachedAppInfoProvider::from(&*app_info_provider, std::time::Duration::from_millis(400)); |       let cached_app_info_provider = caches::app_info_provider::CachedAppInfoProvider::from( | ||||||
|  |         &*app_info_provider, | ||||||
|  |         std::time::Duration::from_millis(400), | ||||||
|  |       ); | ||||||
|       let config_manager = |       let config_manager = | ||||||
|         super::config::ConfigManager::new(&*config_store, &*match_store, &cached_app_info_provider); |         super::config::ConfigManager::new(&*config_store, &*match_store, &cached_app_info_provider); | ||||||
|       let match_cache = MatchCache::load(&*config_store, &*match_store); |       let match_cache = MatchCache::load(&*config_store, &*match_store); | ||||||
|  | @ -83,7 +106,10 @@ pub fn initialize_and_spawn( | ||||||
|       let modulo_form_ui = crate::gui::modulo::form::ModuloFormUI::new(&modulo_manager); |       let modulo_form_ui = crate::gui::modulo::form::ModuloFormUI::new(&modulo_manager); | ||||||
|       let modulo_search_ui = crate::gui::modulo::search::ModuloSearchUI::new(&modulo_manager); |       let modulo_search_ui = crate::gui::modulo::search::ModuloSearchUI::new(&modulo_manager); | ||||||
| 
 | 
 | ||||||
|       let context: Box<dyn Context> = Box::new(super::context::DefaultContext::new(&config_manager, &cached_app_info_provider)); |       let context: Box<dyn Context> = Box::new(super::context::DefaultContext::new( | ||||||
|  |         &config_manager, | ||||||
|  |         &cached_app_info_provider, | ||||||
|  |       )); | ||||||
|       let builtin_matches = super::builtin::get_builtin_matches(&*config_manager.default()); |       let builtin_matches = super::builtin::get_builtin_matches(&*config_manager.default()); | ||||||
|       let combined_match_cache = CombinedMatchCache::load(&match_cache, &builtin_matches); |       let combined_match_cache = CombinedMatchCache::load(&match_cache, &builtin_matches); | ||||||
| 
 | 
 | ||||||
|  | @ -95,7 +121,9 @@ pub fn initialize_and_spawn( | ||||||
|       let (detect_source, modifier_state_store, sequencer, key_state_store) = |       let (detect_source, modifier_state_store, sequencer, key_state_store) = | ||||||
|         super::engine::funnel::init_and_spawn(SourceCreationOptions { |         super::engine::funnel::init_and_spawn(SourceCreationOptions { | ||||||
|           use_evdev: use_evdev_backend, |           use_evdev: use_evdev_backend, | ||||||
|           evdev_keyboard_rmlvo: keyboard_layout_util::generate_detect_rmlvo(&*config_manager.default()), |           evdev_keyboard_rmlvo: keyboard_layout_util::generate_detect_rmlvo( | ||||||
|  |             &*config_manager.default(), | ||||||
|  |           ), | ||||||
|           hotkeys: match_converter.get_hotkeys(), |           hotkeys: match_converter.get_hotkeys(), | ||||||
|           win32_exclude_orphan_events: default_config.win32_exclude_orphan_events(), |           win32_exclude_orphan_events: default_config.win32_exclude_orphan_events(), | ||||||
|         }) |         }) | ||||||
|  | @ -136,8 +164,11 @@ pub fn initialize_and_spawn( | ||||||
| 
 | 
 | ||||||
|       let injector = espanso_inject::get_injector(InjectorCreationOptions { |       let injector = espanso_inject::get_injector(InjectorCreationOptions { | ||||||
|         use_evdev: use_evdev_backend, |         use_evdev: use_evdev_backend, | ||||||
|         keyboard_state_provider: key_state_store.map(|store| Box::new(store) as Box<dyn KeyboardStateProvider>), |         keyboard_state_provider: key_state_store | ||||||
|         evdev_keyboard_rmlvo: keyboard_layout_util::generate_inject_rmlvo(&*config_manager.default()), |           .map(|store| Box::new(store) as Box<dyn KeyboardStateProvider>), | ||||||
|  |         evdev_keyboard_rmlvo: keyboard_layout_util::generate_inject_rmlvo( | ||||||
|  |           &*config_manager.default(), | ||||||
|  |         ), | ||||||
|         ..Default::default() |         ..Default::default() | ||||||
|       }) |       }) | ||||||
|       .expect("failed to initialize injector module"); // TODO: handle the options
 |       .expect("failed to initialize injector module"); // TODO: handle the options
 | ||||||
|  | @ -234,7 +265,7 @@ pub fn initialize_and_spawn( | ||||||
|         } |         } | ||||||
|         _ => { |         _ => { | ||||||
|           notification_manager.notify_start(); |           notification_manager.notify_start(); | ||||||
|           
 | 
 | ||||||
|           if !preferences.has_displayed_welcome() { |           if !preferences.has_displayed_welcome() { | ||||||
|             super::ui::welcome::show_welcome_screen(); |             super::ui::welcome::show_welcome_screen(); | ||||||
|             preferences.set_has_displayed_welcome(true); |             preferences.set_has_displayed_welcome(true); | ||||||
|  |  | ||||||
|  | @ -65,7 +65,7 @@ impl<'a> MatchSelector for MatchSelectorAdapter<'a> { | ||||||
|         } |         } | ||||||
|       }) |       }) | ||||||
|       .collect(); |       .collect(); | ||||||
|     
 | 
 | ||||||
|     let hint = if is_search { |     let hint = if is_search { | ||||||
|       Some("Search matches by content or trigger (or type > to see commands)") |       Some("Search matches by content or trigger (or type > to see commands)") | ||||||
|     } else { |     } else { | ||||||
|  |  | ||||||
|  | @ -124,6 +124,8 @@ impl<'a> MatchConverter<'a> { | ||||||
| 
 | 
 | ||||||
|   fn global_match_set(&self) -> MatchSet { |   fn global_match_set(&self) -> MatchSet { | ||||||
|     let paths = self.config_store.get_all_match_paths(); |     let paths = self.config_store.get_all_match_paths(); | ||||||
|     self.match_store.query(&paths.into_iter().collect::<Vec<_>>()) |     self | ||||||
|  |       .match_store | ||||||
|  |       .query(&paths.into_iter().collect::<Vec<_>>()) | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ | ||||||
| 
 | 
 | ||||||
| pub mod disable; | pub mod disable; | ||||||
| pub mod image_resolve; | pub mod image_resolve; | ||||||
| pub mod matcher; |  | ||||||
| pub mod match_select; | pub mod match_select; | ||||||
|  | pub mod matcher; | ||||||
| pub mod multiplex; | pub mod multiplex; | ||||||
| pub mod render; | pub mod render; | ||||||
|  |  | ||||||
|  | @ -24,11 +24,9 @@ pub struct ClipboardAdapter<'a> { | ||||||
|   clipboard: &'a dyn Clipboard, |   clipboard: &'a dyn Clipboard, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl <'a> ClipboardAdapter<'a> { | impl<'a> ClipboardAdapter<'a> { | ||||||
|   pub fn new(clipboard: &'a dyn Clipboard) -> Self { |   pub fn new(clipboard: &'a dyn Clipboard) -> Self { | ||||||
|     Self { |     Self { clipboard } | ||||||
|       clipboard |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -18,4 +18,4 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| pub mod clipboard; | pub mod clipboard; | ||||||
| pub mod form; | pub mod form; | ||||||
|  |  | ||||||
|  | @ -86,7 +86,9 @@ fn generate_global_vars_map(config_provider: &dyn ConfigProvider) -> HashMap<i32 | ||||||
| 
 | 
 | ||||||
|   for (_, match_set) in config_provider.configs() { |   for (_, match_set) in config_provider.configs() { | ||||||
|     for var in match_set.global_vars.iter() { |     for var in match_set.global_vars.iter() { | ||||||
|       global_vars_map.entry(var.id).or_insert_with(|| convert_var((*var).clone())); |       global_vars_map | ||||||
|  |         .entry(var.id) | ||||||
|  |         .or_insert_with(|| convert_var((*var).clone())); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -17,4 +17,4 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| pub mod middleware; | pub mod middleware; | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use std::{collections::HashMap}; | use std::collections::HashMap; | ||||||
| 
 | 
 | ||||||
| use espanso_config::{ | use espanso_config::{ | ||||||
|   config::ConfigStore, |   config::ConfigStore, | ||||||
|  |  | ||||||
|  | @ -19,4 +19,4 @@ | ||||||
| 
 | 
 | ||||||
| pub mod notification; | pub mod notification; | ||||||
| pub mod util; | pub mod util; | ||||||
| pub mod welcome; | pub mod welcome; | ||||||
|  |  | ||||||
|  | @ -34,8 +34,11 @@ pub fn convert_icon_paths_to_tray_vec(icon_paths: &IconPaths) -> Vec<(TrayIcon, | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if let Some(system_disabled) = &icon_paths.tray_icon_system_disabled { |   if let Some(system_disabled) = &icon_paths.tray_icon_system_disabled { | ||||||
|     paths.push((TrayIcon::SystemDisabled, system_disabled.to_string_lossy().to_string())); |     paths.push(( | ||||||
|  |       TrayIcon::SystemDisabled, | ||||||
|  |       system_disabled.to_string_lossy().to_string(), | ||||||
|  |     )); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   paths |   paths | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,4 +19,4 @@ | ||||||
| 
 | 
 | ||||||
| pub const WORKER_START_REASON_MANUAL: &str = "manual_restart"; | pub const WORKER_START_REASON_MANUAL: &str = "manual_restart"; | ||||||
| pub const WORKER_START_REASON_CONFIG_CHANGED: &str = "config_changed"; | pub const WORKER_START_REASON_CONFIG_CHANGED: &str = "config_changed"; | ||||||
| pub const WORKER_START_REASON_KEYBOARD_LAYOUT_CHANGED: &str = "keyboard_layout_changed"; | pub const WORKER_START_REASON_KEYBOARD_LAYOUT_CHANGED: &str = "keyboard_layout_changed"; | ||||||
|  |  | ||||||
|  | @ -36,7 +36,11 @@ pub struct SearchItem { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub trait FormUI { | pub trait FormUI { | ||||||
|   fn show(&self, layout: &str, fields: &HashMap<String, FormField>) -> Result<Option<HashMap<String, String>>>; |   fn show( | ||||||
|  |     &self, | ||||||
|  |     layout: &str, | ||||||
|  |     fields: &HashMap<String, FormField>, | ||||||
|  |   ) -> Result<Option<HashMap<String, String>>>; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
|  | @ -52,5 +56,5 @@ pub enum FormField { | ||||||
|   List { |   List { | ||||||
|     default: Option<String>, |     default: Option<String>, | ||||||
|     values: Vec<String>, |     values: Vec<String>, | ||||||
|   } |   }, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ | ||||||
| 
 | 
 | ||||||
| use serde::Serialize; | use serde::Serialize; | ||||||
| use serde_json::{json, Map, Value}; | use serde_json::{json, Map, Value}; | ||||||
| use std::{collections::HashMap}; | use std::collections::HashMap; | ||||||
| 
 | 
 | ||||||
| use crate::gui::{FormField, FormUI}; | use crate::gui::{FormField, FormUI}; | ||||||
| 
 | 
 | ||||||
|  | @ -31,9 +31,7 @@ pub struct ModuloFormUI<'a> { | ||||||
| 
 | 
 | ||||||
| impl<'a> ModuloFormUI<'a> { | impl<'a> ModuloFormUI<'a> { | ||||||
|   pub fn new(manager: &'a ModuloManager) -> Self { |   pub fn new(manager: &'a ModuloManager) -> Self { | ||||||
|     Self { |     Self { manager } | ||||||
|       manager, |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -62,9 +60,7 @@ impl<'a> FormUI for ModuloFormUI<'a> { | ||||||
|           Ok(Some(json)) |           Ok(Some(json)) | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       Err(error) => { |       Err(error) => Err(error.into()), | ||||||
|         Err(error.into()) |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -77,22 +77,16 @@ impl ModuloManager { | ||||||
|                       Err(ModuloError::EmptyOutput.into()) |                       Err(ModuloError::EmptyOutput.into()) | ||||||
|                     } |                     } | ||||||
|                   } |                   } | ||||||
|                   Err(error) => { |                   Err(error) => Err(ModuloError::Error(error).into()), | ||||||
|                     Err(ModuloError::Error(error).into()) |  | ||||||
|                   } |  | ||||||
|                 } |                 } | ||||||
|               } |               } | ||||||
|               Err(error) => { |               Err(error) => Err(ModuloError::Error(error).into()), | ||||||
|                 Err(ModuloError::Error(error).into()) |  | ||||||
|               } |  | ||||||
|             } |             } | ||||||
|           } else { |           } else { | ||||||
|             Err(ModuloError::StdinError.into()) |             Err(ModuloError::StdinError.into()) | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         Err(error) => { |         Err(error) => Err(ModuloError::Error(error).into()), | ||||||
|           Err(ModuloError::Error(error).into()) |  | ||||||
|         } |  | ||||||
|       } |       } | ||||||
|     } else { |     } else { | ||||||
|       Err(ModuloError::MissingModulo.into()) |       Err(ModuloError::MissingModulo.into()) | ||||||
|  | @ -102,7 +96,9 @@ impl ModuloManager { | ||||||
| 
 | 
 | ||||||
| #[derive(Error, Debug)] | #[derive(Error, Debug)] | ||||||
| pub enum ModuloError { | pub enum ModuloError { | ||||||
|   #[error("attempt to invoke modulo, but this version of espanso is not compiled with support for it")] |   #[error(
 | ||||||
|  |     "attempt to invoke modulo, but this version of espanso is not compiled with support for it" | ||||||
|  |   )] | ||||||
|   MissingModulo, |   MissingModulo, | ||||||
| 
 | 
 | ||||||
|   #[error("modulo returned an empty output")] |   #[error("modulo returned an empty output")] | ||||||
|  |  | ||||||
|  | @ -19,4 +19,4 @@ | ||||||
| 
 | 
 | ||||||
| pub mod form; | pub mod form; | ||||||
| pub mod manager; | pub mod manager; | ||||||
| pub mod search; | pub mod search; | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ | ||||||
| 
 | 
 | ||||||
| use serde::Serialize; | use serde::Serialize; | ||||||
| use serde_json::Value; | use serde_json::Value; | ||||||
| use std::{collections::HashMap}; | use std::collections::HashMap; | ||||||
| 
 | 
 | ||||||
| use crate::gui::{SearchItem, SearchUI}; | use crate::gui::{SearchItem, SearchUI}; | ||||||
| 
 | 
 | ||||||
|  | @ -31,9 +31,7 @@ pub struct ModuloSearchUI<'a> { | ||||||
| 
 | 
 | ||||||
| impl<'a> ModuloSearchUI<'a> { | impl<'a> ModuloSearchUI<'a> { | ||||||
|   pub fn new(manager: &'a ModuloManager) -> Self { |   pub fn new(manager: &'a ModuloManager) -> Self { | ||||||
|     Self { |     Self { manager } | ||||||
|       manager, |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -58,9 +56,7 @@ impl<'a> SearchUI for ModuloSearchUI<'a> { | ||||||
|           Ok(None) |           Ok(None) | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       Err(error) => { |       Err(error) => Err(error.into()), | ||||||
|         Err(error.into()) |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -82,10 +78,13 @@ struct ModuloSearchItemConfig<'a> { | ||||||
| 
 | 
 | ||||||
| // TODO: test
 | // TODO: test
 | ||||||
| fn convert_items(items: &[SearchItem]) -> Vec<ModuloSearchItemConfig> { | fn convert_items(items: &[SearchItem]) -> Vec<ModuloSearchItemConfig> { | ||||||
|   items.iter().map(|item| ModuloSearchItemConfig { |   items | ||||||
|     id: &item.id, |     .iter() | ||||||
|     label: &item.label, 
 |     .map(|item| ModuloSearchItemConfig { | ||||||
|     trigger: item.tag.as_deref(), 
 |       id: &item.id, | ||||||
|     is_builtin: item.is_builtin, |       label: &item.label, | ||||||
|   }).collect() |       trigger: item.tag.as_deref(), | ||||||
|  |       is_builtin: item.is_builtin, | ||||||
|  |     }) | ||||||
|  |     .collect() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -33,7 +33,6 @@ const WINDOWS_LOGO_ICO_BINARY: &[u8] = include_bytes!("res/windows/logo.ico"); | ||||||
| #[cfg(target_os = "windows")] | #[cfg(target_os = "windows")] | ||||||
| const WINDOWS_TRAY_EXPLAIN_IMAGE: &[u8] = include_bytes!("res/windows/tray_explain_image.png"); | const WINDOWS_TRAY_EXPLAIN_IMAGE: &[u8] = include_bytes!("res/windows/tray_explain_image.png"); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| #[cfg(target_os = "macos")] | #[cfg(target_os = "macos")] | ||||||
| const MAC_BINARY: &[u8] = include_bytes!("res/macos/icon.png"); | const MAC_BINARY: &[u8] = include_bytes!("res/macos/icon.png"); | ||||||
| #[cfg(target_os = "macos")] | #[cfg(target_os = "macos")] | ||||||
|  | @ -61,21 +60,39 @@ pub struct IconPaths { | ||||||
|   pub accessibility_image_2: Option<PathBuf>, |   pub accessibility_image_2: Option<PathBuf>, | ||||||
|   pub tray_explain_image: Option<PathBuf>, |   pub tray_explain_image: Option<PathBuf>, | ||||||
| 
 | 
 | ||||||
|   pub logo: Option<PathBuf>, 
 |   pub logo: Option<PathBuf>, | ||||||
|   pub logo_no_background: Option<PathBuf>, |   pub logo_no_background: Option<PathBuf>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[cfg(target_os = "windows")] | #[cfg(target_os = "windows")] | ||||||
| pub fn load_icon_paths(runtime_dir: &Path) -> Result<IconPaths> { | pub fn load_icon_paths(runtime_dir: &Path) -> Result<IconPaths> { | ||||||
|   Ok(IconPaths { |   Ok(IconPaths { | ||||||
|     form_icon: Some(extract_icon(WINDOWS_LOGO_ICO_BINARY, &runtime_dir.join("form.ico"))?), |     form_icon: Some(extract_icon( | ||||||
|  |       WINDOWS_LOGO_ICO_BINARY, | ||||||
|  |       &runtime_dir.join("form.ico"), | ||||||
|  |     )?), | ||||||
|     search_icon: Some(extract_icon(ICON_BINARY, &runtime_dir.join("search.png"))?), |     search_icon: Some(extract_icon(ICON_BINARY, &runtime_dir.join("search.png"))?), | ||||||
|     wizard_icon: Some(extract_icon(WINDOWS_LOGO_ICO_BINARY, &runtime_dir.join("wizard.ico"))?), |     wizard_icon: Some(extract_icon( | ||||||
|     tray_icon_normal: Some(extract_icon(WINDOWS_NORMAL_DARK_ICO_BINARY, &runtime_dir.join("normal.ico"))?), |       WINDOWS_LOGO_ICO_BINARY, | ||||||
|     tray_icon_disabled: Some(extract_icon(WINDOWS_DISABLED_DARK_ICO_BINARY, &runtime_dir.join("disabled.ico"))?), |       &runtime_dir.join("wizard.ico"), | ||||||
|  |     )?), | ||||||
|  |     tray_icon_normal: Some(extract_icon( | ||||||
|  |       WINDOWS_NORMAL_DARK_ICO_BINARY, | ||||||
|  |       &runtime_dir.join("normal.ico"), | ||||||
|  |     )?), | ||||||
|  |     tray_icon_disabled: Some(extract_icon( | ||||||
|  |       WINDOWS_DISABLED_DARK_ICO_BINARY, | ||||||
|  |       &runtime_dir.join("disabled.ico"), | ||||||
|  |     )?), | ||||||
|     logo: Some(extract_icon(ICON_BINARY, &runtime_dir.join("icon.png"))?), |     logo: Some(extract_icon(ICON_BINARY, &runtime_dir.join("icon.png"))?), | ||||||
|     logo_no_background: Some(extract_icon(LOGO_NO_BACKGROUND_BINARY, &runtime_dir.join("icon_no_background.png"))?), |     logo_no_background: Some(extract_icon( | ||||||
|     tray_explain_image: Some(extract_icon(WINDOWS_TRAY_EXPLAIN_IMAGE, &runtime_dir.join("tray_explain_image.png"))?), |       LOGO_NO_BACKGROUND_BINARY, | ||||||
|  |       &runtime_dir.join("icon_no_background.png"), | ||||||
|  |     )?), | ||||||
|  |     tray_explain_image: Some(extract_icon( | ||||||
|  |       WINDOWS_TRAY_EXPLAIN_IMAGE, | ||||||
|  |       &runtime_dir.join("tray_explain_image.png"), | ||||||
|  |     )?), | ||||||
|     ..Default::default() |     ..Default::default() | ||||||
|   }) |   }) | ||||||
| } | } | ||||||
|  | @ -85,13 +102,31 @@ pub fn load_icon_paths(runtime_dir: &Path) -> Result<IconPaths> { | ||||||
|   Ok(IconPaths { |   Ok(IconPaths { | ||||||
|     search_icon: Some(extract_icon(ICON_BINARY, &runtime_dir.join("search.png"))?), |     search_icon: Some(extract_icon(ICON_BINARY, &runtime_dir.join("search.png"))?), | ||||||
|     tray_icon_normal: Some(extract_icon(MAC_BINARY, &runtime_dir.join("normal.png"))?), |     tray_icon_normal: Some(extract_icon(MAC_BINARY, &runtime_dir.join("normal.png"))?), | ||||||
|     tray_icon_disabled: Some(extract_icon(MAC_DISABLED_BINARY, &runtime_dir.join("disabled.png"))?), |     tray_icon_disabled: Some(extract_icon( | ||||||
|     tray_icon_system_disabled: Some(extract_icon(MAC_SYSTEM_DISABLED_BINARY, &runtime_dir.join("systemdisabled.png"))?), |       MAC_DISABLED_BINARY, | ||||||
|  |       &runtime_dir.join("disabled.png"), | ||||||
|  |     )?), | ||||||
|  |     tray_icon_system_disabled: Some(extract_icon( | ||||||
|  |       MAC_SYSTEM_DISABLED_BINARY, | ||||||
|  |       &runtime_dir.join("systemdisabled.png"), | ||||||
|  |     )?), | ||||||
|     logo: Some(extract_icon(ICON_BINARY, &runtime_dir.join("icon.png"))?), |     logo: Some(extract_icon(ICON_BINARY, &runtime_dir.join("icon.png"))?), | ||||||
|     logo_no_background: Some(extract_icon(LOGO_NO_BACKGROUND_BINARY, &runtime_dir.join("icon_no_background.png"))?), |     logo_no_background: Some(extract_icon( | ||||||
|     accessibility_image_1: Some(extract_icon(MAC_ACCESSIBILITY_1_BINARY, &runtime_dir.join("accessibility_1.png"))?), |       LOGO_NO_BACKGROUND_BINARY, | ||||||
|     accessibility_image_2: Some(extract_icon(MAC_ACCESSIBILITY_2_BINARY, &runtime_dir.join("accessibility_2.png"))?), |       &runtime_dir.join("icon_no_background.png"), | ||||||
|     tray_explain_image: Some(extract_icon(MAC_STATUS_ICON_EXPLAIN_IMAGE, &runtime_dir.join("icon_explain_image.png"))?), |     )?), | ||||||
|  |     accessibility_image_1: Some(extract_icon( | ||||||
|  |       MAC_ACCESSIBILITY_1_BINARY, | ||||||
|  |       &runtime_dir.join("accessibility_1.png"), | ||||||
|  |     )?), | ||||||
|  |     accessibility_image_2: Some(extract_icon( | ||||||
|  |       MAC_ACCESSIBILITY_2_BINARY, | ||||||
|  |       &runtime_dir.join("accessibility_2.png"), | ||||||
|  |     )?), | ||||||
|  |     tray_explain_image: Some(extract_icon( | ||||||
|  |       MAC_STATUS_ICON_EXPLAIN_IMAGE, | ||||||
|  |       &runtime_dir.join("icon_explain_image.png"), | ||||||
|  |     )?), | ||||||
|     ..Default::default() |     ..Default::default() | ||||||
|   }) |   }) | ||||||
| } | } | ||||||
|  | @ -101,7 +136,10 @@ pub fn load_icon_paths(runtime_dir: &Path) -> Result<IconPaths> { | ||||||
|   Ok(IconPaths { |   Ok(IconPaths { | ||||||
|     logo: Some(extract_icon(ICON_BINARY, &runtime_dir.join("iconv2.png"))?), |     logo: Some(extract_icon(ICON_BINARY, &runtime_dir.join("iconv2.png"))?), | ||||||
|     search_icon: Some(extract_icon(ICON_BINARY, &runtime_dir.join("search.png"))?), |     search_icon: Some(extract_icon(ICON_BINARY, &runtime_dir.join("search.png"))?), | ||||||
|     logo_no_background: Some(extract_icon(LOGO_NO_BACKGROUND_BINARY, &runtime_dir.join("icon_no_background.png"))?), |     logo_no_background: Some(extract_icon( | ||||||
|  |       LOGO_NO_BACKGROUND_BINARY, | ||||||
|  |       &runtime_dir.join("icon_no_background.png"), | ||||||
|  |     )?), | ||||||
|     ..Default::default() |     ..Default::default() | ||||||
|   }) |   }) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -18,9 +18,9 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use espanso_ipc::{IPCServer, IPCClient}; | use espanso_ipc::{IPCClient, IPCServer}; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
| use std::path::Path; | use std::path::Path; | ||||||
| use serde::{Serialize, Deserialize}; |  | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Serialize, Deserialize)] | #[derive(Debug, Serialize, Deserialize)] | ||||||
| pub enum IPCEvent { | pub enum IPCEvent { | ||||||
|  | @ -40,15 +40,11 @@ pub fn create_ipc_client_to_worker(runtime_dir: &Path) -> Result<impl IPCClient< | ||||||
|   create_ipc_client(runtime_dir, "workerv2") |   create_ipc_client(runtime_dir, "workerv2") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn create_ipc_server( | fn create_ipc_server(runtime_dir: &Path, name: &str) -> Result<impl IPCServer<IPCEvent>> { | ||||||
|   runtime_dir: &Path, |  | ||||||
|   name: &str, |  | ||||||
| ) -> Result<impl IPCServer<IPCEvent>> { |  | ||||||
|   espanso_ipc::server(&format!("espanso{}", name), runtime_dir) |   espanso_ipc::server(&format!("espanso{}", name), runtime_dir) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| fn create_ipc_client(runtime_dir: &Path, target_process: &str) -> Result<impl IPCClient<IPCEvent>> { | fn create_ipc_client(runtime_dir: &Path, target_process: &str) -> Result<impl IPCClient<IPCEvent>> { | ||||||
|   let client = espanso_ipc::client(&format!("espanso{}", target_process), runtime_dir)?; |   let client = espanso_ipc::client(&format!("espanso{}", target_process), runtime_dir)?; | ||||||
|   Ok(client) |   Ok(client) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -42,8 +42,12 @@ impl Lock { | ||||||
|       .write(true) |       .write(true) | ||||||
|       .create(true) |       .create(true) | ||||||
|       .open(&lock_file_path) |       .open(&lock_file_path) | ||||||
|       .unwrap_or_else(|_| panic!("unable to create reference to lock file: {:?}", |       .unwrap_or_else(|_| { | ||||||
|         lock_file_path)); |         panic!( | ||||||
|  |           "unable to create reference to lock file: {:?}", | ||||||
|  |           lock_file_path | ||||||
|  |         ) | ||||||
|  |       }); | ||||||
| 
 | 
 | ||||||
|     if lock_file.try_lock_exclusive().is_ok() { |     if lock_file.try_lock_exclusive().is_ok() { | ||||||
|       Some(Lock { lock_file }) |       Some(Lock { lock_file }) | ||||||
|  |  | ||||||
|  | @ -76,12 +76,8 @@ impl Write for FileProxy { | ||||||
|       Ok(mut lock) => { |       Ok(mut lock) => { | ||||||
|         match &mut (*lock) { |         match &mut (*lock) { | ||||||
|           // Write to the memory buffer until a file is ready
 |           // Write to the memory buffer until a file is ready
 | ||||||
|           Output::Memory(buffer) => { |           Output::Memory(buffer) => buffer.write(buf), | ||||||
|             buffer.write(buf) |           Output::File(output) => output.write(buf), | ||||||
|           } |  | ||||||
|           Output::File(output) => { |  | ||||||
|             output.write(buf) |  | ||||||
|           } |  | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       Err(_) => Err(std::io::Error::new( |       Err(_) => Err(std::io::Error::new( | ||||||
|  | @ -93,16 +89,10 @@ impl Write for FileProxy { | ||||||
| 
 | 
 | ||||||
|   fn flush(&mut self) -> std::io::Result<()> { |   fn flush(&mut self) -> std::io::Result<()> { | ||||||
|     match self.output.lock() { |     match self.output.lock() { | ||||||
|       Ok(mut lock) => { |       Ok(mut lock) => match &mut (*lock) { | ||||||
|         match &mut (*lock) { |         Output::Memory(buffer) => buffer.flush(), | ||||||
|           Output::Memory(buffer) => { |         Output::File(output) => output.flush(), | ||||||
|             buffer.flush() |       }, | ||||||
|           } |  | ||||||
|           Output::File(output) => { |  | ||||||
|             output.flush() |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       Err(_) => Err(std::io::Error::new( |       Err(_) => Err(std::io::Error::new( | ||||||
|         std::io::ErrorKind::Other, |         std::io::ErrorKind::Other, | ||||||
|         "lock poison error", |         "lock poison error", | ||||||
|  | @ -133,4 +123,4 @@ macro_rules! error_eprintln { | ||||||
|     eprintln!($($tts)*); |     eprintln!($($tts)*); | ||||||
|     log::error!($($tts)*); |     log::error!($($tts)*); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -478,10 +478,7 @@ fn main() { | ||||||
|       )]; |       )]; | ||||||
| 
 | 
 | ||||||
|       if !handler.disable_logs_terminal_output { |       if !handler.disable_logs_terminal_output { | ||||||
|         outputs.insert( |         outputs.insert(0, TermLogger::new(log_level, config, TerminalMode::Mixed)); | ||||||
|           0, |  | ||||||
|           TermLogger::new(log_level, config, TerminalMode::Mixed), |  | ||||||
|         ); |  | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       CombinedLogger::init(outputs).expect("unable to initialize logs"); |       CombinedLogger::init(outputs).expect("unable to initialize logs"); | ||||||
|  |  | ||||||
|  | @ -62,4 +62,4 @@ pub struct PatchDefinition { | ||||||
|   pub is_enabled: fn() -> bool, |   pub is_enabled: fn() -> bool, | ||||||
|   pub should_patch: fn(app: &AppProperties) -> bool, |   pub should_patch: fn(app: &AppProperties) -> bool, | ||||||
|   pub apply: fn(config: Arc<dyn Config>, name: &str) -> Arc<dyn Config>, |   pub apply: fn(config: Arc<dyn Config>, name: &str) -> Arc<dyn Config>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -23,8 +23,8 @@ pub mod generic_terminal_x11; | ||||||
| pub mod kitty_terminal_x11; | pub mod kitty_terminal_x11; | ||||||
| pub mod konsole_terminal_x11; | pub mod konsole_terminal_x11; | ||||||
| pub mod libreoffice_writer_x11; | pub mod libreoffice_writer_x11; | ||||||
| pub mod simple_terminal_x11; |  | ||||||
| pub mod simple_terminal_2_x11; | pub mod simple_terminal_2_x11; | ||||||
|  | pub mod simple_terminal_x11; | ||||||
| pub mod terminator_terminal_x11; | pub mod terminator_terminal_x11; | ||||||
| pub mod termite_terminal_x11; | pub mod termite_terminal_x11; | ||||||
| pub mod tilix_terminal_x11; | pub mod tilix_terminal_x11; | ||||||
|  | @ -32,4 +32,4 @@ pub mod urxvt_terminal_x11; | ||||||
| pub mod xterm_terminal_x11; | pub mod xterm_terminal_x11; | ||||||
| pub mod yakuake_terminal_x11; | pub mod yakuake_terminal_x11; | ||||||
| 
 | 
 | ||||||
| mod util; | mod util; | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,4 +19,4 @@ | ||||||
| 
 | 
 | ||||||
| pub fn is_wayland() -> bool { | pub fn is_wayland() -> bool { | ||||||
|   cfg!(feature = "wayland") |   cfg!(feature = "wayland") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -96,4 +96,4 @@ macro_rules! generate_patchable_config { | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
|  
 | 
 | ||||||
| use espanso_config::config::{Backend, RMLVOConfig, ToggleKey}; | use espanso_config::config::{Backend, RMLVOConfig, ToggleKey}; | ||||||
| 
 | 
 | ||||||
| #[cfg(target_os = "windows")] | #[cfg(target_os = "windows")] | ||||||
|  |  | ||||||
|  | @ -18,4 +18,4 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| pub mod onenote_for_windows_10; | pub mod onenote_for_windows_10; | ||||||
| pub mod vscode_win; | pub mod vscode_win; | ||||||
|  |  | ||||||
|  | @ -38,4 +38,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -41,4 +41,4 @@ pub fn patch() -> PatchDefinition { | ||||||
|       )) |       )) | ||||||
|     }, |     }, | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use std::{path::PathBuf}; | use std::path::PathBuf; | ||||||
| use thiserror::Error; | use thiserror::Error; | ||||||
| 
 | 
 | ||||||
| pub fn is_espanso_in_path() -> bool { | pub fn is_espanso_in_path() -> bool { | ||||||
|  |  | ||||||
|  | @ -50,11 +50,10 @@ pub fn add_espanso_to_path(prompt_when_necessary: bool) -> Result<()> { | ||||||
|             target_link_path.to_string_lossy(), |             target_link_path.to_string_lossy(), | ||||||
|           ); |           ); | ||||||
| 
 | 
 | ||||||
|           let mut child = std::process::Command::new("osascript").args(&[ |           let mut child = std::process::Command::new("osascript") | ||||||
|             "-e", |             .args(&["-e", ¶ms]) | ||||||
|             ¶ms, |             .spawn()?; | ||||||
|           ]).spawn()?; | 
 | ||||||
|           
 |  | ||||||
|           let result = child.wait()?; |           let result = child.wait()?; | ||||||
|           if !result.success() { |           if !result.success() { | ||||||
|             return Err(PathError::ElevationRequestFailure.into()); |             return Err(PathError::ElevationRequestFailure.into()); | ||||||
|  | @ -90,11 +89,10 @@ pub fn remove_espanso_from_path(prompt_when_necessary: bool) -> Result<()> { | ||||||
|             target_link_path.to_string_lossy(), |             target_link_path.to_string_lossy(), | ||||||
|           ); |           ); | ||||||
| 
 | 
 | ||||||
|           let mut child = std::process::Command::new("osascript").args(&[ |           let mut child = std::process::Command::new("osascript") | ||||||
|             "-e", |             .args(&["-e", ¶ms]) | ||||||
|             ¶ms, |             .spawn()?; | ||||||
|           ]).spawn()?; | 
 | ||||||
|           
 |  | ||||||
|           let result = child.wait()?; |           let result = child.wait()?; | ||||||
|           if !result.success() { |           if !result.success() { | ||||||
|             return Err(PathError::ElevationRequestFailure.into()); |             return Err(PathError::ElevationRequestFailure.into()); | ||||||
|  | @ -119,7 +117,7 @@ pub enum PathError { | ||||||
| 
 | 
 | ||||||
|   #[error("symlink error: `{0}`")] |   #[error("symlink error: `{0}`")] | ||||||
|   SymlinkError(std::io::Error), |   SymlinkError(std::io::Error), | ||||||
|   
 | 
 | ||||||
|   #[error("elevation request failed")] |   #[error("elevation request failed")] | ||||||
|   ElevationRequestFailure, |   ElevationRequestFailure, | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -22,24 +22,24 @@ mod macos; | ||||||
| #[cfg(target_os = "macos")] | #[cfg(target_os = "macos")] | ||||||
| pub use macos::add_espanso_to_path; | pub use macos::add_espanso_to_path; | ||||||
| #[cfg(target_os = "macos")] | #[cfg(target_os = "macos")] | ||||||
| pub use macos::remove_espanso_from_path; |  | ||||||
| #[cfg(target_os = "macos")] |  | ||||||
| pub use macos::is_espanso_in_path; | pub use macos::is_espanso_in_path; | ||||||
|  | #[cfg(target_os = "macos")] | ||||||
|  | pub use macos::remove_espanso_from_path; | ||||||
| 
 | 
 | ||||||
| #[cfg(target_os = "windows")] | #[cfg(target_os = "windows")] | ||||||
| mod win; | mod win; | ||||||
| #[cfg(target_os = "windows")] | #[cfg(target_os = "windows")] | ||||||
| pub use win::add_espanso_to_path; | pub use win::add_espanso_to_path; | ||||||
| #[cfg(target_os = "windows")] | #[cfg(target_os = "windows")] | ||||||
| pub use win::remove_espanso_from_path; |  | ||||||
| #[cfg(target_os = "windows")] |  | ||||||
| pub use win::is_espanso_in_path; | pub use win::is_espanso_in_path; | ||||||
|  | #[cfg(target_os = "windows")] | ||||||
|  | pub use win::remove_espanso_from_path; | ||||||
| 
 | 
 | ||||||
| #[cfg(target_os = "linux")] | #[cfg(target_os = "linux")] | ||||||
| mod linux; | mod linux; | ||||||
| #[cfg(target_os = "linux")] | #[cfg(target_os = "linux")] | ||||||
| pub use linux::add_espanso_to_path; | pub use linux::add_espanso_to_path; | ||||||
| #[cfg(target_os = "linux")] | #[cfg(target_os = "linux")] | ||||||
| pub use linux::remove_espanso_from_path; |  | ||||||
| #[cfg(target_os = "linux")] |  | ||||||
| pub use linux::is_espanso_in_path; | pub use linux::is_espanso_in_path; | ||||||
|  | #[cfg(target_os = "linux")] | ||||||
|  | pub use linux::remove_espanso_from_path; | ||||||
|  |  | ||||||
|  | @ -72,7 +72,9 @@ impl<KVSType: KVS> Preferences for DefaultPreferences<KVSType> { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   fn should_display_troubleshoot_for_non_fatal_errors(&self) -> bool { |   fn should_display_troubleshoot_for_non_fatal_errors(&self) -> bool { | ||||||
|     self.get(SHOULD_DISPLAY_TROUBLESHOOT_FOR_NON_FATAL_ERRORS).unwrap_or(true) |     self | ||||||
|  |       .get(SHOULD_DISPLAY_TROUBLESHOOT_FOR_NON_FATAL_ERRORS) | ||||||
|  |       .unwrap_or(true) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   fn set_should_display_troubleshoot_for_non_fatal_errors(&self, value: bool) { |   fn set_should_display_troubleshoot_for_non_fatal_errors(&self, value: bool) { | ||||||
|  |  | ||||||
|  | @ -17,8 +17,8 @@ | ||||||
|  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| use std::path::Path; |  | ||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
|  | use std::path::Path; | ||||||
| 
 | 
 | ||||||
| mod default; | mod default; | ||||||
| 
 | 
 | ||||||
|  | @ -36,4 +36,4 @@ pub trait Preferences: Send + Sync + Clone { | ||||||
| pub fn get_default(runtime_dir: &Path) -> Result<impl Preferences> { | pub fn get_default(runtime_dir: &Path) -> Result<impl Preferences> { | ||||||
|   let kvs = espanso_kvs::get_persistent(runtime_dir)?; |   let kvs = espanso_kvs::get_persistent(runtime_dir)?; | ||||||
|   default::DefaultPreferences::new(kvs) |   default::DefaultPreferences::new(kvs) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -42,4 +42,4 @@ pub fn attach_console() { | ||||||
| #[cfg(not(target_os = "windows"))] | #[cfg(not(target_os = "windows"))] | ||||||
| pub fn attach_console() { | pub fn attach_console() { | ||||||
|   // Not necessary on Linux and macOS
 |   // Not necessary on Linux and macOS
 | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user