support custom cache file, fixes 26
This commit is contained in:
parent
184c9a2b77
commit
74594d688d
7 changed files with 68 additions and 79 deletions
|
@ -5,6 +5,7 @@ use hyprland::{
|
|||
};
|
||||
use rayon::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::{env, fs, sync::Arc, thread};
|
||||
use sysinfo::{Pid, System};
|
||||
use worf::{
|
||||
|
@ -115,7 +116,7 @@ impl ItemProvider<Window> for WindowProvider {
|
|||
}
|
||||
}
|
||||
|
||||
fn load_icon_cache(cache_path: &String) -> Result<HashMap<String, String>, Error> {
|
||||
fn load_icon_cache(cache_path: &PathBuf) -> Result<HashMap<String, String>, Error> {
|
||||
let toml_content =
|
||||
fs::read_to_string(cache_path).map_err(|e| Error::UpdateCacheError(format!("{e}")))?;
|
||||
let cache: HashMap<String, String> = toml::from_str(&toml_content)
|
||||
|
@ -123,15 +124,6 @@ fn load_icon_cache(cache_path: &String) -> Result<HashMap<String, String>, Error
|
|||
Ok(cache)
|
||||
}
|
||||
|
||||
fn cache_path() -> Result<String, Error> {
|
||||
let path = dirs::cache_dir()
|
||||
.map(|x| x.join("worf-hyprswitch"))
|
||||
.ok_or_else(|| Error::UpdateCacheError("cannot read cache file".to_owned()))?;
|
||||
|
||||
desktop::create_file_if_not_exists(&path)?;
|
||||
Ok(path.to_string_lossy().into_owned())
|
||||
}
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
env_logger::Builder::new()
|
||||
.parse_filters(&env::var("RUST_LOG").unwrap_or_else(|_| "error".to_owned()))
|
||||
|
@ -141,7 +133,8 @@ fn main() -> Result<(), String> {
|
|||
let args = config::parse_args();
|
||||
let config = config::load_config(Some(&args)).unwrap_or(args);
|
||||
|
||||
let cache_path = cache_path().map_err(|err| err.to_string())?;
|
||||
let cache_path =
|
||||
desktop::cache_file_path(&config, "worf-hyprswitch").map_err(|err| err.to_string())?;
|
||||
let mut cache = load_icon_cache(&cache_path).map_err(|e| e.to_string())?;
|
||||
|
||||
let provider = WindowProvider::new(&config, &cache)?;
|
||||
|
|
|
@ -245,7 +245,7 @@ pub struct Config {
|
|||
allow_markup: Option<bool>,
|
||||
|
||||
#[clap(short = 'k', long = "cache-file")]
|
||||
cache_file: Option<String>, // todo support this
|
||||
cache_file: Option<String>,
|
||||
|
||||
/// Defines which terminal to use. defaults to the first one found:
|
||||
/// * kitty
|
||||
|
@ -291,6 +291,7 @@ pub struct Config {
|
|||
)]
|
||||
location: Option<Vec<Anchor>>,
|
||||
|
||||
/// If set to `true` sub actions will be disabled
|
||||
#[clap(short = 'a', long = "no-actions")]
|
||||
no_actions: Option<bool>,
|
||||
|
||||
|
@ -621,6 +622,11 @@ impl Config {
|
|||
self.allow_markup.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn cache_file(&self) -> Option<String> {
|
||||
self.cache_file.clone()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn password(&self) -> Option<String> {
|
||||
self.password.clone()
|
||||
|
|
|
@ -219,6 +219,22 @@ fn start_forked_cmd(mut cmd: Command) -> Result<(), Error> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the path of a given cache file
|
||||
/// # Errors
|
||||
/// Will return Error if the cache file cannot be created or not found.
|
||||
pub fn cache_file_path(config: &Config, name: &str) -> Result<PathBuf, Error> {
|
||||
let path = if let Some(cfg) = config.cache_file() {
|
||||
PathBuf::from(cfg)
|
||||
} else {
|
||||
dirs::cache_dir()
|
||||
.map(|x| x.join(name))
|
||||
.ok_or_else(|| Error::UpdateCacheError("cannot read cache file".to_owned()))?
|
||||
};
|
||||
|
||||
create_file_if_not_exists(&path)?;
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
/// Parse a simple toml cache file from the format below
|
||||
/// "Key"=score
|
||||
/// i.e.
|
||||
|
@ -227,13 +243,9 @@ fn start_forked_cmd(mut cmd: Command) -> Result<(), Error> {
|
|||
/// "Files"=50
|
||||
/// # Errors
|
||||
/// Returns an Error when the given file is not found or did not parse.
|
||||
pub fn load_cache_file(cache_path: Option<&PathBuf>) -> Result<HashMap<String, i64>, Error> {
|
||||
let Some(path) = cache_path else {
|
||||
return Err(Error::MissingFile);
|
||||
};
|
||||
|
||||
pub fn load_cache_file(cache_path: &PathBuf) -> Result<HashMap<String, i64>, Error> {
|
||||
let toml_content =
|
||||
fs::read_to_string(path).map_err(|e| Error::UpdateCacheError(format!("{e}")))?;
|
||||
fs::read_to_string(cache_path).map_err(|e| Error::UpdateCacheError(format!("{e}")))?;
|
||||
let parsed: toml::Value = toml_content
|
||||
.parse()
|
||||
.map_err(|_| Error::ParsingError("failed to parse cache".to_owned()))?;
|
||||
|
|
|
@ -37,12 +37,7 @@ struct AutoItemProvider {
|
|||
impl AutoItemProvider {
|
||||
fn new(config: &Config) -> Self {
|
||||
AutoItemProvider {
|
||||
drun: DRunProvider::new(
|
||||
AutoRunType::DRun,
|
||||
config.no_actions(),
|
||||
config.sort_order(),
|
||||
config.term(),
|
||||
),
|
||||
drun: DRunProvider::new(AutoRunType::DRun, config),
|
||||
file: FileItemProvider::new(AutoRunType::File, config.sort_order()),
|
||||
math: MathProvider::new(AutoRunType::Math),
|
||||
ssh: SshProvider::new(AutoRunType::Ssh, &config.sort_order()),
|
||||
|
@ -157,7 +152,7 @@ pub fn show(config: &Config) -> Result<(), Error> {
|
|||
provider.math.elements.push(selection_result);
|
||||
}
|
||||
AutoRunType::DRun => {
|
||||
update_drun_cache_and_run(cache_path, &mut cache, selection_result)?;
|
||||
update_drun_cache_and_run(&cache_path, &mut cache, selection_result)?;
|
||||
break;
|
||||
}
|
||||
AutoRunType::File => {
|
||||
|
|
|
@ -28,7 +28,7 @@ struct DRunCache {
|
|||
#[derive(Clone)]
|
||||
pub(crate) struct DRunProvider<T: Clone> {
|
||||
items: Option<Vec<MenuItem<T>>>,
|
||||
pub(crate) cache_path: Option<PathBuf>,
|
||||
pub(crate) cache_path: PathBuf,
|
||||
pub(crate) cache: HashMap<String, i64>,
|
||||
data: T,
|
||||
no_actions: bool,
|
||||
|
@ -50,21 +50,16 @@ impl<T: Clone + Send + Sync> ItemProvider<T> for DRunProvider<T> {
|
|||
}
|
||||
|
||||
impl<T: Clone + Send + Sync> DRunProvider<T> {
|
||||
pub(crate) fn new(
|
||||
menu_item_data: T,
|
||||
no_actions: bool,
|
||||
sort_order: SortOrder,
|
||||
terminal: Option<String>,
|
||||
) -> Self {
|
||||
let (cache_path, d_run_cache) = load_d_run_cache();
|
||||
pub(crate) fn new(menu_item_data: T, config: &Config) -> Self {
|
||||
let (cache_path, d_run_cache) = load_cache("drun_cache", config).unwrap();
|
||||
DRunProvider {
|
||||
items: None,
|
||||
cache_path,
|
||||
cache: d_run_cache,
|
||||
data: menu_item_data,
|
||||
no_actions,
|
||||
sort_order,
|
||||
terminal,
|
||||
no_actions: config.no_actions(),
|
||||
sort_order: config.sort_order(),
|
||||
terminal: config.term(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,21 +190,14 @@ impl<T: Clone + Send + Sync> DRunProvider<T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn load_d_run_cache() -> (Option<PathBuf>, HashMap<String, i64>) {
|
||||
let cache_path = dirs::cache_dir().map(|x| x.join("worf-drun"));
|
||||
load_cache(cache_path)
|
||||
}
|
||||
|
||||
pub(crate) fn update_drun_cache_and_run<T: Clone>(
|
||||
cache_path: Option<PathBuf>,
|
||||
cache_path: &PathBuf,
|
||||
cache: &mut HashMap<String, i64>,
|
||||
selection_result: MenuItem<T>,
|
||||
) -> Result<(), Error> {
|
||||
if let Some(cache_path) = cache_path {
|
||||
*cache.entry(selection_result.label).or_insert(0) += 1;
|
||||
if let Err(e) = save_cache_file(&cache_path, cache) {
|
||||
log::warn!("cannot save drun cache {e:?}");
|
||||
}
|
||||
) -> Result<(), crate::Error> {
|
||||
*cache.entry(selection_result.label).or_insert(0) += 1;
|
||||
if let Err(e) = save_cache_file(cache_path, cache) {
|
||||
log::warn!("cannot save drun cache {e:?}");
|
||||
}
|
||||
|
||||
if let Some(action) = selection_result.action {
|
||||
|
@ -224,14 +212,14 @@ pub(crate) fn update_drun_cache_and_run<T: Clone>(
|
|||
///
|
||||
/// Will return `Err` if it was not able to spawn the process
|
||||
pub fn show(config: &Config) -> Result<(), Error> {
|
||||
let provider = DRunProvider::new(0, config.no_actions(), config.sort_order(), config.term());
|
||||
let provider = DRunProvider::new(0, config);
|
||||
let cache_path = provider.cache_path.clone();
|
||||
let mut cache = provider.cache.clone();
|
||||
|
||||
// todo ues a arc instead of cloning the config
|
||||
let selection_result = gui::show(config.clone(), provider, false, None, None);
|
||||
match selection_result {
|
||||
Ok(s) => update_drun_cache_and_run(cache_path, &mut cache, s.menu)?,
|
||||
Ok(s) => update_drun_cache_and_run(&cache_path, &mut cache, s.menu)?,
|
||||
Err(_) => {
|
||||
log::error!("No item selected");
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use crate::Error;
|
||||
use crate::config::Config;
|
||||
use crate::desktop::{cache_file_path, create_file_if_not_exists, load_cache_file};
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use crate::desktop::{create_file_if_not_exists, load_cache_file};
|
||||
|
||||
pub mod auto;
|
||||
pub mod dmenu;
|
||||
pub mod drun;
|
||||
|
@ -12,15 +13,17 @@ pub mod run;
|
|||
pub mod search;
|
||||
pub mod ssh;
|
||||
|
||||
pub(crate) fn load_cache(cache_path: Option<PathBuf>) -> (Option<PathBuf>, HashMap<String, i64>) {
|
||||
pub(crate) fn load_cache(
|
||||
name: &str,
|
||||
config: &Config,
|
||||
) -> Result<(PathBuf, HashMap<String, i64>), Error> {
|
||||
let cache_path = cache_file_path(config, name)?;
|
||||
let cache = {
|
||||
if let Some(ref cache_path) = cache_path {
|
||||
if let Err(e) = create_file_if_not_exists(cache_path) {
|
||||
log::warn!("No drun cache file and cannot create: {e:?}");
|
||||
}
|
||||
if let Err(e) = create_file_if_not_exists(&cache_path) {
|
||||
log::warn!("No drun cache file and cannot create: {e:?}");
|
||||
}
|
||||
|
||||
load_cache_file(cache_path.as_ref()).unwrap_or_default()
|
||||
load_cache_file(&cache_path).unwrap_or_default()
|
||||
};
|
||||
(cache_path, cache)
|
||||
Ok((cache_path, cache))
|
||||
}
|
||||
|
|
|
@ -30,20 +30,20 @@ impl ItemProvider<i32> for RunProvider {
|
|||
#[derive(Clone)]
|
||||
struct RunProvider {
|
||||
items: Option<Vec<MenuItem<i32>>>,
|
||||
cache_path: Option<PathBuf>,
|
||||
cache_path: PathBuf,
|
||||
cache: HashMap<String, i64>,
|
||||
sort_order: SortOrder,
|
||||
}
|
||||
|
||||
impl RunProvider {
|
||||
fn new(sort_order: SortOrder) -> Self {
|
||||
let (cache_path, d_run_cache) = load_run_cache();
|
||||
RunProvider {
|
||||
fn new(config: &Config) -> Result<Self, Error> {
|
||||
let (cache_path, d_run_cache) = load_cache("worf-run", config)?;
|
||||
Ok(RunProvider {
|
||||
items: None,
|
||||
cache_path,
|
||||
cache: d_run_cache,
|
||||
sort_order,
|
||||
}
|
||||
sort_order: config.sort_order(),
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
|
@ -98,21 +98,14 @@ impl RunProvider {
|
|||
}
|
||||
}
|
||||
|
||||
fn load_run_cache() -> (Option<PathBuf>, HashMap<String, i64>) {
|
||||
let cache_path = dirs::cache_dir().map(|x| x.join("worf-run"));
|
||||
load_cache(cache_path)
|
||||
}
|
||||
|
||||
fn update_run_cache_and_run<T: Clone>(
|
||||
cache_path: Option<PathBuf>,
|
||||
cache_path: &PathBuf,
|
||||
cache: &mut HashMap<String, i64>,
|
||||
selection_result: MenuItem<T>,
|
||||
) -> Result<(), Error> {
|
||||
if let Some(cache_path) = cache_path {
|
||||
*cache.entry(selection_result.label).or_insert(0) += 1;
|
||||
if let Err(e) = save_cache_file(&cache_path, cache) {
|
||||
log::warn!("cannot save run cache {e:?}");
|
||||
}
|
||||
*cache.entry(selection_result.label).or_insert(0) += 1;
|
||||
if let Err(e) = save_cache_file(cache_path, cache) {
|
||||
log::warn!("cannot save run cache {e:?}");
|
||||
}
|
||||
|
||||
if let Some(action) = selection_result.action {
|
||||
|
@ -132,13 +125,12 @@ fn update_run_cache_and_run<T: Clone>(
|
|||
///
|
||||
/// Will return `Err` if it was not able to spawn the process
|
||||
pub fn show(config: &Config) -> Result<(), Error> {
|
||||
let provider = RunProvider::new(config.sort_order());
|
||||
let provider = RunProvider::new(config)?;
|
||||
let cache_path = provider.cache_path.clone();
|
||||
let mut cache = provider.cache.clone();
|
||||
|
||||
let selection_result = gui::show(config.clone(), provider, false, None, None);
|
||||
match selection_result {
|
||||
Ok(s) => update_run_cache_and_run(cache_path, &mut cache, s.menu)?,
|
||||
Ok(s) => update_run_cache_and_run(&cache_path, &mut cache, s.menu)?,
|
||||
Err(_) => {
|
||||
log::error!("No item selected");
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue