feat(core): implement basic cli handler structure and path handler
This commit is contained in:
parent
b375518730
commit
1f0fe74ac1
76
Cargo.lock
generated
76
Cargo.lock
generated
|
@ -9,6 +9,15 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.38"
|
||||
|
@ -27,6 +36,17 @@ version = "0.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
|
@ -93,6 +113,21 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags 1.2.1",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_fn"
|
||||
version = "0.4.5"
|
||||
|
@ -250,6 +285,8 @@ dependencies = [
|
|||
name = "espanso"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"espanso-clipboard",
|
||||
"espanso-config",
|
||||
"espanso-detect",
|
||||
|
@ -258,8 +295,11 @@ dependencies = [
|
|||
"espanso-match",
|
||||
"espanso-path",
|
||||
"espanso-ui",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"maplit",
|
||||
"simplelog",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -448,6 +488,15 @@ dependencies = [
|
|||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.0"
|
||||
|
@ -867,6 +916,12 @@ dependencies = [
|
|||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.8.0"
|
||||
|
@ -947,6 +1002,15 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.23"
|
||||
|
@ -993,6 +1057,12 @@ version = "1.7.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.0.4"
|
||||
|
@ -1005,6 +1075,12 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.2"
|
||||
|
|
|
@ -23,4 +23,9 @@ espanso-clipboard = { path = "../espanso-clipboard" }
|
|||
espanso-info = { path = "../espanso-info" }
|
||||
espanso-path = { path = "../espanso-path" }
|
||||
maplit = "1.0.2"
|
||||
simplelog = "0.9.0"
|
||||
simplelog = "0.9.0"
|
||||
log = "0.4.14"
|
||||
anyhow = "1.0.38"
|
||||
thiserror = "1.0.23"
|
||||
clap = "2.33.3"
|
||||
lazy_static = "1.4.0"
|
65
espanso/src/cli/mod.rs
Normal file
65
espanso/src/cli/mod.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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 clap::ArgMatches;
|
||||
use espanso_config::{config::ConfigStore, matches::store::MatchStore};
|
||||
use espanso_path::Paths;
|
||||
|
||||
pub mod log;
|
||||
pub mod path;
|
||||
|
||||
pub struct CliModule {
|
||||
pub enable_logs: bool,
|
||||
pub requires_paths: bool,
|
||||
pub requires_config: bool,
|
||||
pub subcommand: String,
|
||||
pub entry: fn(CliModuleArgs),
|
||||
}
|
||||
|
||||
impl Default for CliModule {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enable_logs: false,
|
||||
requires_paths: false,
|
||||
requires_config: false,
|
||||
subcommand: "".to_string(),
|
||||
entry: |_| {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CliModuleArgs {
|
||||
pub config_store: Option<Box<dyn ConfigStore>>,
|
||||
pub match_store: Option<Box<dyn MatchStore>>,
|
||||
pub is_legacy_config: bool,
|
||||
pub paths: Option<Paths>,
|
||||
pub cli_args: Option<ArgMatches<'static>>,
|
||||
}
|
||||
|
||||
impl Default for CliModuleArgs {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
config_store: None,
|
||||
match_store: None,
|
||||
is_legacy_config: false,
|
||||
paths: None,
|
||||
cli_args: None,
|
||||
}
|
||||
}
|
||||
}
|
59
espanso/src/cli/path.rs
Normal file
59
espanso/src/cli/path.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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};
|
||||
|
||||
pub fn new() -> CliModule {
|
||||
CliModule {
|
||||
requires_paths: true,
|
||||
requires_config: true,
|
||||
subcommand: "path".to_string(),
|
||||
entry: path_main,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn path_main(args: CliModuleArgs) {
|
||||
let paths = args.paths.expect("missing paths argument");
|
||||
let cli_args = args.cli_args.expect("missing cli_args argument");
|
||||
|
||||
if cli_args.subcommand_matches("config").is_some() {
|
||||
println!("{}", paths.config.to_string_lossy());
|
||||
} else if cli_args.subcommand_matches("packages").is_some() {
|
||||
println!("{}", paths.packages.to_string_lossy());
|
||||
} else if cli_args.subcommand_matches("data").is_some() || cli_args.subcommand_matches("runtime").is_some() {
|
||||
println!("{}", paths.runtime.to_string_lossy());
|
||||
} else if cli_args.subcommand_matches("default").is_some() {
|
||||
if args.is_legacy_config {
|
||||
println!("{}", paths.config.join("default.yml").to_string_lossy());
|
||||
} else {
|
||||
println!("{}", paths.config.join("config").join("default.yml").to_string_lossy());
|
||||
}
|
||||
} else if cli_args.subcommand_matches("base").is_some() {
|
||||
if args.is_legacy_config {
|
||||
eprintln!("base config not available when using legacy configuration format");
|
||||
} else {
|
||||
println!("{}", paths.config.join("match").join("base.yml").to_string_lossy());
|
||||
}
|
||||
} else {
|
||||
println!("Config: {}", paths.config.to_string_lossy());
|
||||
println!("Packages: {}", paths.packages.to_string_lossy());
|
||||
println!("Runtime: {}", paths.runtime.to_string_lossy());
|
||||
}
|
||||
}
|
89
espanso/src/logging/mod.rs
Normal file
89
espanso/src/logging/mod.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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 std::{
|
||||
fs::{File, OpenOptions},
|
||||
path::Path,
|
||||
};
|
||||
use std::{
|
||||
io::Write,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
/// This struct can be passed as an output to the logger to "defer" the
|
||||
/// decision of the output file
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct FileProxy {
|
||||
output: Arc<Mutex<Option<File>>>,
|
||||
}
|
||||
|
||||
impl FileProxy {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
output: Arc::new(Mutex::new(None)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_output_file(&self, path: &Path) -> Result<()> {
|
||||
let log_file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.create(true)
|
||||
.append(true)
|
||||
.open(path)?;
|
||||
let mut lock = self.output.lock().expect("unable to obtain FileProxy lock");
|
||||
*lock = Some(log_file);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for FileProxy {
|
||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||
match self.output.lock() {
|
||||
Ok(lock) => {
|
||||
if let Some(mut output) = lock.as_ref() {
|
||||
output.write(buf)
|
||||
} else {
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
Err(_) => Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"lock poison error",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> std::io::Result<()> {
|
||||
match self.output.lock() {
|
||||
Ok(lock) => {
|
||||
if let Some(mut output) = lock.as_ref() {
|
||||
output.flush()
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Err(_) => Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"lock poison error",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,144 +1,264 @@
|
|||
use std::{path::PathBuf, time::Duration};
|
||||
/*
|
||||
* 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 espanso_detect::{
|
||||
event::{InputEvent, Status},
|
||||
get_source,
|
||||
hotkey::HotKey,
|
||||
SourceCreationOptions,
|
||||
};
|
||||
use espanso_inject::{get_injector, keys, Injector};
|
||||
use espanso_ui::{event::UIEvent::*, icons::TrayIcon, menu::*};
|
||||
use simplelog::{CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode};
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
use clap::{App, AppSettings, Arg, SubCommand};
|
||||
use cli::{CliModule, CliModuleArgs};
|
||||
use logging::FileProxy;
|
||||
use simplelog::{CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode, WriteLogger};
|
||||
|
||||
mod cli;
|
||||
mod engine;
|
||||
mod logging;
|
||||
mod util;
|
||||
|
||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
const LOG_FILE_NAME: &str = "espanso.log";
|
||||
|
||||
lazy_static! {
|
||||
static ref CLI_HANDLERS: Vec<CliModule> = vec![
|
||||
cli::path::new(),
|
||||
];
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!z");
|
||||
// TODO: attach console
|
||||
|
||||
CombinedLogger::init(vec![
|
||||
TermLogger::new(LevelFilter::Debug, Config::default(), TerminalMode::Mixed),
|
||||
// WriteLogger::new(
|
||||
// LevelFilter::Info,
|
||||
// Config::default(),
|
||||
// File::create("my_rust_binary.log").unwrap(),
|
||||
// ),
|
||||
])
|
||||
.unwrap();
|
||||
|
||||
let paths = espanso_path::resolve_paths();
|
||||
println!("paths: {:?}", paths);
|
||||
let config = espanso_config::load_legacy(&paths.config, &paths.packages).unwrap();
|
||||
let install_subcommand = SubCommand::with_name("install")
|
||||
.about("Install a package. Equivalent to 'espanso package install'")
|
||||
.arg(
|
||||
Arg::with_name("external")
|
||||
.short("e")
|
||||
.long("external")
|
||||
.required(false)
|
||||
.takes_value(false)
|
||||
.help("Allow installing packages from non-verified repositories."),
|
||||
)
|
||||
.arg(Arg::with_name("package_name").help("Package name"))
|
||||
.arg(
|
||||
Arg::with_name("repository_url")
|
||||
.help("(Optional) Link to GitHub repository")
|
||||
.required(false)
|
||||
.default_value("hub"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("proxy")
|
||||
.help("Use a proxy, should be used as --proxy=https://proxy:1234")
|
||||
.required(false)
|
||||
.long("proxy")
|
||||
.takes_value(true),
|
||||
);
|
||||
|
||||
// let icon_paths = vec![
|
||||
// (
|
||||
// espanso_ui::icons::TrayIcon::Normal,
|
||||
// r"C:\Users\Freddy\AppData\Local\espanso\espanso.ico".to_string(),
|
||||
// ),
|
||||
// (
|
||||
// espanso_ui::icons::TrayIcon::Disabled,
|
||||
// r"C:\Users\Freddy\AppData\Local\espanso\espansored.ico".to_string(),
|
||||
// ),
|
||||
// ];
|
||||
let icon_paths = vec![
|
||||
(
|
||||
espanso_ui::icons::TrayIcon::Normal,
|
||||
r"/Users/freddy/Library/Application Support/espanso/icon.png".to_string(),
|
||||
),
|
||||
(
|
||||
espanso_ui::icons::TrayIcon::Disabled,
|
||||
r"/Users/freddy/Library/Application Support/espanso/icondisabled.png".to_string(),
|
||||
),
|
||||
];
|
||||
let uninstall_subcommand = SubCommand::with_name("uninstall")
|
||||
.about("Remove an installed package. Equivalent to 'espanso package uninstall'")
|
||||
.arg(Arg::with_name("package_name").help("Package name"));
|
||||
|
||||
// let (remote, mut eventloop) = espanso_ui::win32::create(espanso_ui::win32::Win32UIOptions {
|
||||
// show_icon: true,
|
||||
// icon_paths: &icon_paths,
|
||||
// notification_icon_path: r"C:\Users\Freddy\Insync\Development\Espanso\Images\icongreensmall.png"
|
||||
// .to_string(),
|
||||
// });
|
||||
// let (remote, mut eventloop) = espanso_ui::mac::create(espanso_ui::mac::MacUIOptions {
|
||||
// show_icon: true,
|
||||
// icon_paths: &icon_paths,
|
||||
// });
|
||||
let (remote, mut eventloop) = espanso_ui::create_ui(espanso_ui::UIOptions {
|
||||
notification_icon_path: Some(
|
||||
r"C:\Users\Freddy\Insync\Development\Espanso\Images\icongreensmall.png".to_string(),
|
||||
),
|
||||
..Default::default()
|
||||
})
|
||||
.unwrap();
|
||||
let mut clap_instance = App::new("espanso")
|
||||
.version(VERSION)
|
||||
.author("Federico Terzi")
|
||||
.about("A Privacy-first, Cross-platform Text Expander")
|
||||
.arg(Arg::with_name("v")
|
||||
.short("v")
|
||||
.multiple(true)
|
||||
.help("Sets the level of verbosity"))
|
||||
.subcommand(SubCommand::with_name("cmd")
|
||||
.about("Send a command to the espanso daemon.")
|
||||
.subcommand(SubCommand::with_name("exit")
|
||||
.about("Terminate the daemon."))
|
||||
.subcommand(SubCommand::with_name("enable")
|
||||
.about("Enable the espanso replacement engine."))
|
||||
.subcommand(SubCommand::with_name("disable")
|
||||
.about("Disable the espanso replacement engine."))
|
||||
.subcommand(SubCommand::with_name("toggle")
|
||||
.about("Toggle the status of the espanso replacement engine."))
|
||||
)
|
||||
.subcommand(SubCommand::with_name("edit")
|
||||
.about("Open the default text editor to edit config files and reload them automatically when exiting")
|
||||
.arg(Arg::with_name("config")
|
||||
.help("Defaults to \"default\". The configuration file name to edit (without the .yml extension)."))
|
||||
.arg(Arg::with_name("norestart")
|
||||
.short("n")
|
||||
.long("norestart")
|
||||
.required(false)
|
||||
.takes_value(false)
|
||||
.help("Avoid restarting espanso after editing the file"))
|
||||
)
|
||||
.subcommand(SubCommand::with_name("detect")
|
||||
.about("Tool to detect current window properties, to simplify filters creation."))
|
||||
.subcommand(SubCommand::with_name("daemon")
|
||||
.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("log")
|
||||
.about("Print the latest daemon logs."))
|
||||
.subcommand(SubCommand::with_name("start")
|
||||
.about("Start the daemon spawning a new process in the background."))
|
||||
.subcommand(SubCommand::with_name("stop")
|
||||
.about("Stop the espanso daemon."))
|
||||
.subcommand(SubCommand::with_name("restart")
|
||||
.about("Restart the espanso daemon."))
|
||||
.subcommand(SubCommand::with_name("status")
|
||||
.about("Check if the espanso daemon is running or not."))
|
||||
.subcommand(SubCommand::with_name("path")
|
||||
.about("Prints all the espanso directory paths to easily locate configuration and matches.")
|
||||
.subcommand(SubCommand::with_name("config")
|
||||
.about("Print the current config folder path."))
|
||||
.subcommand(SubCommand::with_name("packages")
|
||||
.about("Print the current packages folder path."))
|
||||
.subcommand(SubCommand::with_name("data")
|
||||
.about("Print the current data folder path.")
|
||||
.setting(AppSettings::Hidden)) // Legacy path
|
||||
.subcommand(SubCommand::with_name("runtime")
|
||||
.about("Print the current runtime folder path."))
|
||||
.subcommand(SubCommand::with_name("default")
|
||||
.about("Print the default configuration file path."))
|
||||
.subcommand(SubCommand::with_name("base")
|
||||
.about("Print the default match file path."))
|
||||
)
|
||||
.subcommand(SubCommand::with_name("match")
|
||||
.about("List and execute matches from the CLI")
|
||||
.subcommand(SubCommand::with_name("list")
|
||||
.about("Print all matches to standard output")
|
||||
.arg(Arg::with_name("json")
|
||||
.short("j")
|
||||
.long("json")
|
||||
.help("Return the matches as json")
|
||||
.required(false)
|
||||
.takes_value(false)
|
||||
)
|
||||
.arg(Arg::with_name("onlytriggers")
|
||||
.short("t")
|
||||
.long("onlytriggers")
|
||||
.help("Print only triggers without replacement")
|
||||
.required(false)
|
||||
.takes_value(false)
|
||||
)
|
||||
.arg(Arg::with_name("preservenewlines")
|
||||
.short("n")
|
||||
.long("preservenewlines")
|
||||
.help("Preserve newlines when printing replacements")
|
||||
.required(false)
|
||||
.takes_value(false)
|
||||
)
|
||||
)
|
||||
.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")
|
||||
)
|
||||
)
|
||||
)
|
||||
// Package manager
|
||||
.subcommand(SubCommand::with_name("package")
|
||||
.about("Espanso package manager commands")
|
||||
.subcommand(install_subcommand.clone())
|
||||
.subcommand(uninstall_subcommand.clone())
|
||||
.subcommand(SubCommand::with_name("list")
|
||||
.about("List all installed packages")
|
||||
.arg(Arg::with_name("full")
|
||||
.help("Print all package info")
|
||||
.long("full")))
|
||||
|
||||
eventloop.initialize().unwrap();
|
||||
.subcommand(SubCommand::with_name("refresh")
|
||||
.about("Update espanso package index"))
|
||||
)
|
||||
.subcommand(SubCommand::with_name("worker")
|
||||
.setting(AppSettings::Hidden)
|
||||
.arg(Arg::with_name("reload")
|
||||
.short("r")
|
||||
.long("reload")
|
||||
.required(false)
|
||||
.takes_value(false))
|
||||
)
|
||||
.subcommand(install_subcommand)
|
||||
.subcommand(uninstall_subcommand);
|
||||
|
||||
let handle = std::thread::spawn(move || {
|
||||
let injector = get_injector(Default::default()).unwrap();
|
||||
let mut source = get_source(SourceCreationOptions {
|
||||
//use_evdev: true,
|
||||
hotkeys: vec![
|
||||
HotKey::new(1, "CTRL+SPACE").unwrap(),
|
||||
//HotKey::new(1, "OPTION+SPACE").unwrap(),
|
||||
HotKey::new(2, "CTRL+OPTION+3").unwrap(),
|
||||
],
|
||||
..Default::default()
|
||||
})
|
||||
.unwrap();
|
||||
let clipboard = espanso_clipboard::get_clipboard(Default::default()).unwrap();
|
||||
let provider = espanso_info::get_provider().unwrap();
|
||||
source.initialize().unwrap();
|
||||
source
|
||||
.eventloop(Box::new(move |event: InputEvent| {
|
||||
println!("ev {:?}", event);
|
||||
match event {
|
||||
InputEvent::Mouse(_) => {}
|
||||
InputEvent::Keyboard(evt) => {
|
||||
if evt.key == espanso_detect::event::Key::Escape && evt.status == Status::Released {
|
||||
//remote.update_tray_icon(espanso_ui::icons::TrayIcon::Disabled);
|
||||
//remote.show_notification("Espanso is running!");
|
||||
injector
|
||||
.send_string("Hey guys! @", Default::default())
|
||||
.expect("error");
|
||||
//std::thread::sleep(std::time::Duration::from_secs(2));
|
||||
//injector.send_key_combination(&[keys::Key::Control, keys::Key::V], Default::default()).unwrap();
|
||||
}
|
||||
if evt.key == espanso_detect::event::Key::Shift && evt.status == Status::Released {
|
||||
println!("info {:?}", provider.get_info());
|
||||
}
|
||||
}
|
||||
InputEvent::HotKey(hotkey) => {
|
||||
if hotkey.hotkey_id == 2 {
|
||||
println!("clip {:?}", clipboard.get_text());
|
||||
} else if hotkey.hotkey_id == 1 {
|
||||
//clipboard.set_text("test text").unwrap();
|
||||
clipboard.set_html("<i>test text</i>", Some("test text fallback")).unwrap();
|
||||
//clipboard.set_image(&PathBuf::from(r"C:\Users\Freddy\Insync\Development\Espanso\Images\icongreen.png")).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
.unwrap();
|
||||
});
|
||||
// TODO: explain that the start and restart commands are only meaningful
|
||||
// when using the system daemon manager on macOS and Linux
|
||||
|
||||
eventloop.run(Box::new(move |event| {
|
||||
println!("ui {:?}", event);
|
||||
let menu = Menu::from(vec![
|
||||
MenuItem::Simple(SimpleMenuItem::new("open", "Open")),
|
||||
MenuItem::Separator,
|
||||
MenuItem::Sub(SubMenuItem::new(
|
||||
"Sub",
|
||||
vec![
|
||||
MenuItem::Simple(SimpleMenuItem::new("sub1", "Sub 1")),
|
||||
MenuItem::Simple(SimpleMenuItem::new("sub2", "Sub 2")),
|
||||
],
|
||||
)),
|
||||
])
|
||||
.unwrap();
|
||||
match event {
|
||||
TrayIconClick => {
|
||||
remote.show_context_menu(&menu);
|
||||
}
|
||||
ContextMenuClick(raw_id) => {
|
||||
//remote.update_tray_icon(TrayIcon::Disabled);
|
||||
remote.show_notification("Hello there!");
|
||||
println!("item {:?}", menu.get_item_id(raw_id));
|
||||
}
|
||||
let matches = clap_instance.clone().get_matches();
|
||||
let log_level = match matches.occurrences_of("v") {
|
||||
0 => LevelFilter::Warn,
|
||||
1 => LevelFilter::Info,
|
||||
_ => LevelFilter::Debug,
|
||||
};
|
||||
|
||||
let handler = CLI_HANDLERS
|
||||
.iter()
|
||||
.find(|cli| matches.subcommand_matches(&cli.subcommand).is_some());
|
||||
|
||||
if let Some(handler) = handler {
|
||||
let log_proxy = FileProxy::new();
|
||||
if handler.enable_logs {
|
||||
CombinedLogger::init(vec![
|
||||
TermLogger::new(log_level, Config::default(), TerminalMode::Mixed),
|
||||
WriteLogger::new(log_level, Config::default(), log_proxy.clone()),
|
||||
])
|
||||
.expect("unable to initialize logs");
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
let mut cli_args: CliModuleArgs = CliModuleArgs::default();
|
||||
|
||||
if handler.requires_paths || handler.requires_config {
|
||||
// TODO: here take into account env variable and/or command line flag
|
||||
let paths = espanso_path::resolve_paths();
|
||||
|
||||
if handler.requires_config {
|
||||
let (config_store, match_store, is_legacy_config) =
|
||||
if espanso_config::is_legacy_config(&paths.config) {
|
||||
let (config_store, match_store) =
|
||||
espanso_config::load_legacy(&paths.config, &paths.packages)
|
||||
.expect("unable to load legacy config");
|
||||
(config_store, match_store, true)
|
||||
} else {
|
||||
let (config_store, match_store) =
|
||||
espanso_config::load(&paths.config).expect("unable to load config");
|
||||
(config_store, match_store, false)
|
||||
};
|
||||
|
||||
cli_args.is_legacy_config = is_legacy_config;
|
||||
cli_args.config_store = Some(config_store);
|
||||
cli_args.match_store = Some(match_store);
|
||||
}
|
||||
|
||||
if handler.enable_logs {
|
||||
log_proxy
|
||||
.set_output_file(&paths.runtime.join(LOG_FILE_NAME))
|
||||
.expect("unable to set up log output file");
|
||||
}
|
||||
|
||||
cli_args.paths = Some(paths);
|
||||
}
|
||||
|
||||
if let Some(args) = matches.subcommand_matches(&handler.subcommand) {
|
||||
cli_args.cli_args = Some(args.clone());
|
||||
}
|
||||
|
||||
(handler.entry)(cli_args)
|
||||
} else {
|
||||
clap_instance
|
||||
.print_long_help()
|
||||
.expect("unable to print help");
|
||||
println!();
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
use espanso_detect::event::{InputEvent, Status};
|
||||
use espanso_ui::{linux::LinuxUIOptions, menu::*};
|
||||
use simplelog::{CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode};
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!z");
|
||||
CombinedLogger::init(vec![
|
||||
TermLogger::new(LevelFilter::Debug, Config::default(), TerminalMode::Mixed),
|
||||
// WriteLogger::new(
|
||||
// LevelFilter::Info,
|
||||
// Config::default(),
|
||||
// File::create("my_rust_binary.log").unwrap(),
|
||||
// ),
|
||||
])
|
||||
.unwrap();
|
||||
|
||||
let icon_paths = vec![
|
||||
(
|
||||
espanso_ui::icons::TrayIcon::Normal,
|
||||
r"C:\Users\Freddy\AppData\Local\espanso\espanso.ico".to_string(),
|
||||
),
|
||||
(
|
||||
espanso_ui::icons::TrayIcon::Disabled,
|
||||
r"C:\Users\Freddy\AppData\Local\espanso\espansored.ico".to_string(),
|
||||
),
|
||||
];
|
||||
|
||||
|
||||
// let (remote, mut eventloop) = espanso_ui::win32::create(espanso_ui::win32::Win32UIOptions {
|
||||
// show_icon: true,
|
||||
// icon_paths: &icon_paths,
|
||||
// notification_icon_path: r"C:\Users\Freddy\Insync\Development\Espanso\Images\icongreensmall.png"
|
||||
// .to_string(),
|
||||
// });
|
||||
let (remote, mut eventloop) = espanso_ui::linux::create(LinuxUIOptions {
|
||||
notification_icon_path: r"/home/freddy/insync/Development/Espanso/Images/icongreensmall.png".to_owned(),
|
||||
});
|
||||
|
||||
let handle = std::thread::spawn(move || {
|
||||
//let mut source = espanso_detect::win32::Win32Source::new();
|
||||
let mut source = espanso_detect::evdev::EVDEVSource::new();
|
||||
source.initialize();
|
||||
source.eventloop(Box::new(move |event: InputEvent| {
|
||||
println!("ev {:?}", event);
|
||||
match event {
|
||||
InputEvent::Mouse(_) => {}
|
||||
InputEvent::Keyboard(evt) => {
|
||||
if evt.key == espanso_detect::event::Key::Shift && evt.status == Status::Pressed {
|
||||
//remote.update_tray_icon(espanso_ui::icons::TrayIcon::Disabled);
|
||||
remote.show_notification("Espanso is running!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
// eventloop.initialize();
|
||||
// eventloop.run(Box::new(move |event| {
|
||||
// println!("ui {:?}", event);
|
||||
// let menu = Menu::from(vec![
|
||||
// MenuItem::Simple(SimpleMenuItem::new("open", "Open")),
|
||||
// MenuItem::Separator,
|
||||
// MenuItem::Sub(SubMenuItem::new(
|
||||
// "Sub",
|
||||
// vec![
|
||||
// MenuItem::Simple(SimpleMenuItem::new("sub1", "Sub 1")),
|
||||
// MenuItem::Simple(SimpleMenuItem::new("sub2", "Sub 2")),
|
||||
// ],
|
||||
// )),
|
||||
// ])
|
||||
// .unwrap();
|
||||
// remote.show_context_menu(&menu);
|
||||
// }))
|
||||
eventloop.run();
|
||||
}
|
Loading…
Reference in New Issue
Block a user