feat(core): implement 'espanso cmd' subcommand. Fix #832
This commit is contained in:
parent
70d97bf90d
commit
4ca35ea14d
72
espanso/src/cli/cmd.rs
Normal file
72
espanso/src/cli/cmd.rs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* This file is part of espanso.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2021 Federico Terzi
|
||||||
|
*
|
||||||
|
* espanso is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* espanso is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
ipc::{create_ipc_client_to_worker, IPCEvent},
|
||||||
|
lock::acquire_worker_lock,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{CliModule, CliModuleArgs};
|
||||||
|
use anyhow::{bail, Result};
|
||||||
|
use espanso_ipc::IPCClient;
|
||||||
|
|
||||||
|
pub fn new() -> CliModule {
|
||||||
|
CliModule {
|
||||||
|
requires_paths: true,
|
||||||
|
subcommand: "cmd".to_string(),
|
||||||
|
entry: cmd_main,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cmd_main(args: CliModuleArgs) -> i32 {
|
||||||
|
let cli_args = args.cli_args.expect("missing cli_args");
|
||||||
|
let paths = args.paths.expect("missing paths");
|
||||||
|
|
||||||
|
let event = if cli_args.subcommand_matches("enable").is_some() {
|
||||||
|
IPCEvent::EnableRequest
|
||||||
|
} else if cli_args.subcommand_matches("disable").is_some() {
|
||||||
|
IPCEvent::DisableRequest
|
||||||
|
} else if cli_args.subcommand_matches("toggle").is_some() {
|
||||||
|
IPCEvent::ToggleRequest
|
||||||
|
} else if cli_args.subcommand_matches("search").is_some() {
|
||||||
|
IPCEvent::OpenSearchBar
|
||||||
|
} else {
|
||||||
|
eprintln!("unknown command, please run `espanso cmd --help` to see a list of valid ones.");
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(error) = send_event_to_worker(&paths.runtime, event) {
|
||||||
|
eprintln!("unable to send command, error: {:?}", error);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_event_to_worker(runtime_path: &Path, event: IPCEvent) -> Result<()> {
|
||||||
|
if acquire_worker_lock(runtime_path).is_some() {
|
||||||
|
bail!("Worker process is not running, please start Espanso first.")
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut client = create_ipc_client_to_worker(runtime_path)?;
|
||||||
|
client.send_async(event)
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ use clap::ArgMatches;
|
||||||
use espanso_config::{config::ConfigStore, error::NonFatalErrorSet, matches::store::MatchStore};
|
use espanso_config::{config::ConfigStore, error::NonFatalErrorSet, matches::store::MatchStore};
|
||||||
use espanso_path::Paths;
|
use espanso_path::Paths;
|
||||||
|
|
||||||
|
pub mod cmd;
|
||||||
pub mod daemon;
|
pub mod daemon;
|
||||||
pub mod edit;
|
pub mod edit;
|
||||||
pub mod env_path;
|
pub mod env_path;
|
||||||
|
|
|
@ -68,5 +68,12 @@ impl<'a> funnel::Source<'a> for IpcEventSource<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_event_type_allowed(event: &EventType) -> bool {
|
fn is_event_type_allowed(event: &EventType) -> bool {
|
||||||
matches!(event, EventType::MatchExecRequest(_))
|
matches!(
|
||||||
|
event,
|
||||||
|
EventType::MatchExecRequest(_)
|
||||||
|
| EventType::ShowSearchBar
|
||||||
|
| EventType::DisableRequest
|
||||||
|
| EventType::EnableRequest
|
||||||
|
| EventType::ToggleRequest
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,21 +59,17 @@ pub fn initialize_and_spawn(
|
||||||
|
|
||||||
EventHandlerResponse::NoResponse
|
EventHandlerResponse::NoResponse
|
||||||
}
|
}
|
||||||
IPCEvent::RequestMatchExpansion(payload) => {
|
IPCEvent::DisableRequest => send_event(&event_notify, EventType::DisableRequest),
|
||||||
if let Err(err) =
|
IPCEvent::EnableRequest => send_event(&event_notify, EventType::EnableRequest),
|
||||||
event_notify.send(EventType::MatchExecRequest(MatchExecRequestEvent {
|
IPCEvent::ToggleRequest => send_event(&event_notify, EventType::ToggleRequest),
|
||||||
|
IPCEvent::OpenSearchBar => send_event(&event_notify, EventType::ShowSearchBar),
|
||||||
|
IPCEvent::RequestMatchExpansion(payload) => send_event(
|
||||||
|
&event_notify,
|
||||||
|
EventType::MatchExecRequest(MatchExecRequestEvent {
|
||||||
trigger: payload.trigger,
|
trigger: payload.trigger,
|
||||||
args: payload.args,
|
args: payload.args,
|
||||||
}))
|
}),
|
||||||
{
|
),
|
||||||
error!(
|
|
||||||
"experienced error while sending event signal from worker ipc handler: {}",
|
|
||||||
err
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
EventHandlerResponse::NoResponse
|
|
||||||
}
|
|
||||||
#[allow(unreachable_patterns)]
|
#[allow(unreachable_patterns)]
|
||||||
unexpected_event => {
|
unexpected_event => {
|
||||||
warn!(
|
warn!(
|
||||||
|
@ -89,3 +85,17 @@ pub fn initialize_and_spawn(
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_event(
|
||||||
|
event_notify: &Sender<EventType>,
|
||||||
|
event: EventType,
|
||||||
|
) -> EventHandlerResponse<IPCEvent> {
|
||||||
|
if let Err(err) = event_notify.send(event) {
|
||||||
|
error!(
|
||||||
|
"experienced error while sending event signal from worker ipc handler: {}",
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
EventHandlerResponse::NoResponse
|
||||||
|
}
|
||||||
|
|
|
@ -27,6 +27,11 @@ pub enum IPCEvent {
|
||||||
Exit,
|
Exit,
|
||||||
ExitAllProcesses,
|
ExitAllProcesses,
|
||||||
|
|
||||||
|
EnableRequest,
|
||||||
|
DisableRequest,
|
||||||
|
ToggleRequest,
|
||||||
|
OpenSearchBar,
|
||||||
|
|
||||||
RequestMatchExpansion(RequestMatchExpansionPayload),
|
RequestMatchExpansion(RequestMatchExpansionPayload),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@ lazy_static! {
|
||||||
cli::workaround::new(),
|
cli::workaround::new(),
|
||||||
cli::package::new(),
|
cli::package::new(),
|
||||||
cli::match_cli::new(),
|
cli::match_cli::new(),
|
||||||
|
cli::cmd::new(),
|
||||||
];
|
];
|
||||||
static ref ALIASES: Vec<CliAlias> = vec![
|
static ref ALIASES: Vec<CliAlias> = vec![
|
||||||
CliAlias {
|
CliAlias {
|
||||||
|
@ -220,17 +221,17 @@ fn main() {
|
||||||
.subcommand(SubCommand::with_name("unregister").about("Remove 'espanso' command from PATH"))
|
.subcommand(SubCommand::with_name("unregister").about("Remove 'espanso' command from PATH"))
|
||||||
.about("Add or remove the 'espanso' command from the PATH"),
|
.about("Add or remove the 'espanso' command from the PATH"),
|
||||||
)
|
)
|
||||||
// .subcommand(SubCommand::with_name("cmd")
|
.subcommand(SubCommand::with_name("cmd")
|
||||||
// .about("Send a command to the espanso daemon.")
|
.about("Send a command to the espanso daemon.")
|
||||||
// .subcommand(SubCommand::with_name("exit")
|
.subcommand(SubCommand::with_name("enable")
|
||||||
// .about("Terminate the daemon."))
|
.about("Enable expansions."))
|
||||||
// .subcommand(SubCommand::with_name("enable")
|
.subcommand(SubCommand::with_name("disable")
|
||||||
// .about("Enable the espanso replacement engine."))
|
.about("Disable expansions."))
|
||||||
// .subcommand(SubCommand::with_name("disable")
|
.subcommand(SubCommand::with_name("toggle")
|
||||||
// .about("Disable the espanso replacement engine."))
|
.about("Enable/Disable expansions."))
|
||||||
// .subcommand(SubCommand::with_name("toggle")
|
.subcommand(SubCommand::with_name("search")
|
||||||
// .about("Toggle the status of the espanso replacement engine."))
|
.about("Open the Espanso's search bar."))
|
||||||
// )
|
)
|
||||||
.subcommand(SubCommand::with_name("edit")
|
.subcommand(SubCommand::with_name("edit")
|
||||||
.about("Shortcut to open the default text editor to edit config files")
|
.about("Shortcut to open the default text editor to edit config files")
|
||||||
.arg(Arg::with_name("target_file")
|
.arg(Arg::with_name("target_file")
|
||||||
|
@ -252,10 +253,6 @@ For example, specifying 'email' is equivalent to 'match/email.yml'."#))
|
||||||
.setting(AppSettings::Hidden)
|
.setting(AppSettings::Hidden)
|
||||||
.about("Start the daemon without spawning a new process."),
|
.about("Start the daemon without spawning a new process."),
|
||||||
)
|
)
|
||||||
// .subcommand(SubCommand::with_name("register")
|
|
||||||
// .about("MacOS and Linux only. Register espanso in the system daemon manager."))
|
|
||||||
// .subcommand(SubCommand::with_name("unregister")
|
|
||||||
// .about("MacOS and Linux only. Unregister espanso from the system daemon manager."))
|
|
||||||
.subcommand(SubCommand::with_name("launcher").setting(AppSettings::Hidden))
|
.subcommand(SubCommand::with_name("launcher").setting(AppSettings::Hidden))
|
||||||
.subcommand(SubCommand::with_name("log").about("Print the daemon logs."))
|
.subcommand(SubCommand::with_name("log").about("Print the daemon logs."))
|
||||||
.subcommand(
|
.subcommand(
|
||||||
|
@ -306,8 +303,6 @@ For example, specifying 'email' is equivalent to 'match/email.yml'."#))
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
// .subcommand(SubCommand::with_name("status")
|
|
||||||
// .about("Check if the espanso daemon is running or not."))
|
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("path")
|
SubCommand::with_name("path")
|
||||||
.about("Prints all the espanso directory paths to easily locate configuration and matches.")
|
.about("Prints all the espanso directory paths to easily locate configuration and matches.")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user