feat(core): implement 'match list' command. Fix #786
This commit is contained in:
parent
382f708a02
commit
119d537fb7
102
espanso/src/cli/match_cli/list.rs
Normal file
102
espanso/src/cli/match_cli/list.rs
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* 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 anyhow::Result;
|
||||||
|
use clap::ArgMatches;
|
||||||
|
use espanso_config::{
|
||||||
|
config::{AppProperties, ConfigStore},
|
||||||
|
matches::{store::MatchStore, Match, MatchCause},
|
||||||
|
};
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
pub fn list_main(
|
||||||
|
cli_args: &ArgMatches,
|
||||||
|
config_store: Box<dyn ConfigStore>,
|
||||||
|
match_store: Box<dyn MatchStore>,
|
||||||
|
) -> Result<()> {
|
||||||
|
let only_triggers = cli_args.is_present("onlytriggers");
|
||||||
|
let preserve_newlines = cli_args.is_present("preservenewlines");
|
||||||
|
|
||||||
|
let class = cli_args.value_of("class");
|
||||||
|
let title = cli_args.value_of("title");
|
||||||
|
let exec = cli_args.value_of("exec");
|
||||||
|
|
||||||
|
let config = config_store.active(&AppProperties { title, class, exec });
|
||||||
|
let match_set = match_store.query(config.match_paths());
|
||||||
|
|
||||||
|
if cli_args.is_present("json") {
|
||||||
|
print_matches_as_json(&match_set.matches)?;
|
||||||
|
} else {
|
||||||
|
print_matches_as_plain(&match_set.matches, only_triggers, preserve_newlines)
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_matches_as_plain(match_list: &[&Match], only_triggers: bool, preserve_newlines: bool) {
|
||||||
|
for m in match_list {
|
||||||
|
let triggers = match &m.cause {
|
||||||
|
MatchCause::None => vec!["(none)".to_string()],
|
||||||
|
MatchCause::Trigger(trigger_cause) => trigger_cause.triggers.clone(),
|
||||||
|
MatchCause::Regex(regex_cause) => vec![regex_cause.regex.clone()],
|
||||||
|
};
|
||||||
|
|
||||||
|
for trigger in triggers {
|
||||||
|
if only_triggers {
|
||||||
|
println!("{}", trigger);
|
||||||
|
} else {
|
||||||
|
let description = m.description();
|
||||||
|
|
||||||
|
if preserve_newlines {
|
||||||
|
println!("{} - {}", trigger, description)
|
||||||
|
} else {
|
||||||
|
println!("{} - {}", trigger, description.replace('\n', " "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct JsonMatchEntry {
|
||||||
|
triggers: Vec<String>,
|
||||||
|
replace: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_matches_as_json(match_list: &[&Match]) -> Result<()> {
|
||||||
|
let mut entries = Vec::new();
|
||||||
|
for m in match_list {
|
||||||
|
let triggers = match &m.cause {
|
||||||
|
MatchCause::None => vec!["(none)".to_string()],
|
||||||
|
MatchCause::Trigger(trigger_cause) => trigger_cause.triggers.clone(),
|
||||||
|
MatchCause::Regex(regex_cause) => vec![regex_cause.regex.clone()],
|
||||||
|
};
|
||||||
|
|
||||||
|
entries.push(JsonMatchEntry {
|
||||||
|
triggers,
|
||||||
|
replace: m.description().to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let json = serde_json::to_string_pretty(&entries)?;
|
||||||
|
|
||||||
|
println!("{}", json);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
51
espanso/src/cli/match_cli/mod.rs
Normal file
51
espanso/src/cli/match_cli/mod.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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 super::{CliModule, CliModuleArgs};
|
||||||
|
|
||||||
|
mod list;
|
||||||
|
|
||||||
|
pub fn new() -> CliModule {
|
||||||
|
CliModule {
|
||||||
|
requires_config: true,
|
||||||
|
subcommand: "match".to_string(),
|
||||||
|
entry: match_main,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_main(args: CliModuleArgs) -> i32 {
|
||||||
|
let cli_args = args.cli_args.expect("missing cli_args");
|
||||||
|
let config_store = args.config_store.expect("missing config_store");
|
||||||
|
let match_store = args.match_store.expect("missing match_store");
|
||||||
|
|
||||||
|
if let Some(sub_args) = cli_args.subcommand_matches("list") {
|
||||||
|
if let Err(err) = list::list_main(sub_args, config_store, match_store) {
|
||||||
|
eprintln!("unable to list matches: {:?}", err);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if let Some(_sub_args) = cli_args.subcommand_matches("exec") {
|
||||||
|
todo!();
|
||||||
|
} else {
|
||||||
|
eprintln!("Invalid use, please run 'espanso match --help' to get more information.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ pub mod edit;
|
||||||
pub mod env_path;
|
pub mod env_path;
|
||||||
pub mod launcher;
|
pub mod launcher;
|
||||||
pub mod log;
|
pub mod log;
|
||||||
|
pub mod match_cli;
|
||||||
pub mod migrate;
|
pub mod migrate;
|
||||||
pub mod modulo;
|
pub mod modulo;
|
||||||
pub mod package;
|
pub mod package;
|
||||||
|
|
|
@ -71,6 +71,7 @@ lazy_static! {
|
||||||
cli::service::new(),
|
cli::service::new(),
|
||||||
cli::workaround::new(),
|
cli::workaround::new(),
|
||||||
cli::package::new(),
|
cli::package::new(),
|
||||||
|
cli::match_cli::new(),
|
||||||
];
|
];
|
||||||
static ref ALIASES: Vec<CliAlias> = vec![
|
static ref ALIASES: Vec<CliAlias> = vec![
|
||||||
CliAlias {
|
CliAlias {
|
||||||
|
@ -353,39 +354,57 @@ For example, specifying 'email' is equivalent to 'match/email.yml'."#))
|
||||||
.subcommand(restart_subcommand)
|
.subcommand(restart_subcommand)
|
||||||
.subcommand(stop_subcommand)
|
.subcommand(stop_subcommand)
|
||||||
.subcommand(status_subcommand)
|
.subcommand(status_subcommand)
|
||||||
// .subcommand(SubCommand::with_name("match")
|
.subcommand(SubCommand::with_name("match")
|
||||||
// .about("List and execute matches from the CLI")
|
.about("List and execute matches from the CLI")
|
||||||
// .subcommand(SubCommand::with_name("list")
|
.subcommand(SubCommand::with_name("list")
|
||||||
// .about("Print all matches to standard output")
|
.about("Print matches to standard output")
|
||||||
// .arg(Arg::with_name("json")
|
.arg(Arg::with_name("json")
|
||||||
// .short("j")
|
.short("j")
|
||||||
// .long("json")
|
.long("json")
|
||||||
// .help("Return the matches as json")
|
.help("Output matches to the JSON format")
|
||||||
// .required(false)
|
.required(false)
|
||||||
// .takes_value(false)
|
.takes_value(false)
|
||||||
// )
|
)
|
||||||
// .arg(Arg::with_name("onlytriggers")
|
.arg(Arg::with_name("onlytriggers")
|
||||||
// .short("t")
|
.short("t")
|
||||||
// .long("onlytriggers")
|
.long("only-triggers")
|
||||||
// .help("Print only triggers without replacement")
|
.help("Print only triggers without replacement")
|
||||||
// .required(false)
|
.required(false)
|
||||||
// .takes_value(false)
|
.takes_value(false)
|
||||||
// )
|
)
|
||||||
// .arg(Arg::with_name("preservenewlines")
|
.arg(Arg::with_name("preservenewlines")
|
||||||
// .short("n")
|
.short("n")
|
||||||
// .long("preservenewlines")
|
.long("preserve-newlines")
|
||||||
// .help("Preserve newlines when printing replacements")
|
.help("Preserve newlines when printing replacements. Does nothing when using JSON format.")
|
||||||
// .required(false)
|
.required(false)
|
||||||
// .takes_value(false)
|
.takes_value(false)
|
||||||
// )
|
)
|
||||||
// )
|
.arg(Arg::with_name("class")
|
||||||
// .subcommand(SubCommand::with_name("exec")
|
.long("class")
|
||||||
// .about("Triggers the expansion of the given match")
|
.help("Only return matches that would be active with the given class. This is relevant if you want to list matches only active inside an app-specific config.")
|
||||||
// .arg(Arg::with_name("trigger")
|
.required(false)
|
||||||
// .help("The trigger of the match to be expanded")
|
.takes_value(true)
|
||||||
// )
|
)
|
||||||
// )
|
.arg(Arg::with_name("title")
|
||||||
// )
|
.long("title")
|
||||||
|
.help("Only return matches that would be active with the given title. This is relevant if you want to list matches only active inside an app-specific config.")
|
||||||
|
.required(false)
|
||||||
|
.takes_value(true)
|
||||||
|
)
|
||||||
|
.arg(Arg::with_name("exec")
|
||||||
|
.long("exec")
|
||||||
|
.help("Only return matches that would be active with the given exec. This is relevant if you want to list matches only active inside an app-specific config.")
|
||||||
|
.required(false)
|
||||||
|
.takes_value(true)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// .subcommand(SubCommand::with_name("exec")
|
||||||
|
// .about("Triggers the expansion of the given match")
|
||||||
|
// .arg(Arg::with_name("trigger")
|
||||||
|
// .help("The trigger of the match to be expanded")
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("package")
|
SubCommand::with_name("package")
|
||||||
.about("package-management commands")
|
.about("package-management commands")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user