fix clippy

This commit is contained in:
Alexander Mohr 2025-04-21 20:07:47 +02:00
parent 2453bbaf72
commit 6cbdc96f87
5 changed files with 138 additions and 113 deletions

View file

@ -17,8 +17,7 @@ pub enum ConfigurationError {
impl fmt::Display for ConfigurationError { impl fmt::Display for ConfigurationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
ConfigurationError::Open(e) => write!(f, "{e}"), ConfigurationError::Open(e) | ConfigurationError::Parse(e) => write!(f, "{e}"),
ConfigurationError::Parse(e) => write!(f, "{e}"),
} }
} }
} }
@ -102,7 +101,7 @@ impl FromStr for Anchor {
"left" => Ok(Anchor::Left), "left" => Ok(Anchor::Left),
"bottom" => Ok(Anchor::Bottom), "bottom" => Ok(Anchor::Bottom),
"right" => Ok(Anchor::Right), "right" => Ok(Anchor::Right),
other => Err(format!("Invalid anchor: {}", other)), other => Err(format!("Invalid anchor: {other}")),
} }
} }
} }
@ -705,7 +704,7 @@ pub fn resolve_path(
/// * no config file exists /// * no config file exists
/// * config file and args cannot be merged /// * config file and args cannot be merged
pub fn load_config(args_opt: Option<Config>) -> Result<Config, ConfigurationError> { pub fn load_config(args_opt: Option<Config>) -> Result<Config, ConfigurationError> {
let config_path = conf_path(args_opt.as_ref().map(|c| c.config.clone()).flatten()); let config_path = conf_path(args_opt.as_ref().and_then(|c| c.config.clone()));
match config_path { match config_path {
Ok(path) => { Ok(path) => {
let toml_content = let toml_content =
@ -740,20 +739,22 @@ pub fn load_config(args_opt: Option<Config>) -> Result<Config, ConfigurationErro
Err(e) => Err(ConfigurationError::Open(format!("{e}"))), Err(e) => Err(ConfigurationError::Open(format!("{e}"))),
} }
} }
#[must_use]
pub fn expand_path(input: &str) -> PathBuf { pub fn expand_path(input: &str) -> PathBuf {
let mut path = input.to_string(); let mut path = input.to_string();
// Expand ~ to home directory // Expand ~ to home directory
if path.starts_with("~") { if path.starts_with('~') {
if let Some(home_dir) = dirs::home_dir() { if let Some(home_dir) = dirs::home_dir() {
path = path.replacen("~", home_dir.to_str().unwrap_or(""), 1); path = path.replacen('~', home_dir.to_str().unwrap_or(""), 1);
} }
} }
// Expand $VAR style environment variables // Expand $VAR style environment variables
if path.contains('$') { if path.contains('$') {
for (key, value) in env::vars() { for (key, value) in env::vars() {
let var_pattern = format!("${}", key); let var_pattern = format!("${key}");
if path.contains(&var_pattern) { if path.contains(&var_pattern) {
path = path.replace(&var_pattern, &value); path = path.replace(&var_pattern, &value);
} }

View file

@ -14,6 +14,7 @@ use regex::Regex;
#[derive(Debug)] #[derive(Debug)]
pub enum DesktopError { pub enum DesktopError {
MissingIcon, MissingIcon,
ParsingError(String),
} }
/// # Errors /// # Errors
@ -60,6 +61,10 @@ fn fetch_icon_from_theme(icon_name: &str) -> Result<String, DesktopError> {
} }
} }
/// # Errors
///
/// Will return `Err`
/// * if it was not able to find any icon
pub fn fetch_icon_from_common_dirs(icon_name: &str) -> Result<String, DesktopError> { pub fn fetch_icon_from_common_dirs(icon_name: &str) -> Result<String, DesktopError> {
let mut paths = vec![ let mut paths = vec![
PathBuf::from("/usr/local/share/icons"), PathBuf::from("/usr/local/share/icons"),
@ -72,16 +77,22 @@ pub fn fetch_icon_from_common_dirs(icon_name: &str) -> Result<String, DesktopErr
} }
let extensions = ["png", "jpg", "gif", "svg"].join("|"); // Create regex group for extensions let extensions = ["png", "jpg", "gif", "svg"].join("|"); // Create regex group for extensions
let formatted_name = Regex::new(&format!(r"(?i){icon_name}\.({extensions})$")).unwrap(); let formatted_name = Regex::new(&format!(r"(?i){icon_name}\.({extensions})$"));
if let Ok(formatted_name) = formatted_name {
paths paths
.into_iter() .into_iter()
.filter(|dir| dir.exists()) .filter(|dir| dir.exists())
.find_map(|dir| { .find_map(|dir| {
find_file_case_insensitive(dir.as_path(), &formatted_name) find_file_case_insensitive(dir.as_path(), &formatted_name)
.and_then(|files| files.first().map(|f| f.to_string_lossy().into_owned())) .and_then(|files| files.first().map(|f| f.to_string_lossy().into_owned()))
}) })
.ok_or_else(|| DesktopError::MissingIcon) .ok_or(DesktopError::MissingIcon)
} else {
Err(DesktopError::ParsingError(
"Failed to get formatted icon, likely the internal regex did not parse properly"
.to_string(),
))
}
} }
fn find_file_case_insensitive(folder: &Path, file_name: &Regex) -> Option<Vec<PathBuf>> { fn find_file_case_insensitive(folder: &Path, file_name: &Regex) -> Option<Vec<PathBuf>> {
@ -102,9 +113,10 @@ fn find_file_case_insensitive(folder: &Path, file_name: &Regex) -> Option<Vec<Pa
}) })
} }
/// # Errors /// # Panics
/// ///
/// Will return Err when it cannot parse the internal regex /// When it cannot parse the internal regex
#[must_use]
pub fn find_desktop_files() -> Vec<DesktopFile> { pub fn find_desktop_files() -> Vec<DesktopFile> {
let mut paths = vec![ let mut paths = vec![
PathBuf::from("/usr/share/applications"), PathBuf::from("/usr/share/applications"),

View file

@ -155,11 +155,11 @@ fn build_ui<T, P>(
window.set_namespace(Some("worf")); window.set_namespace(Some("worf"));
} }
config.location.as_ref().map(|location| { if let Some(location) = config.location.as_ref() {
for anchor in location { for anchor in location {
window.set_anchor(anchor.into(), true); window.set_anchor(anchor.into(), true);
} }
}); }
let outer_box = gtk4::Box::new(config.orientation.unwrap().into(), 0); let outer_box = gtk4::Box::new(config.orientation.unwrap().into(), 0);
outer_box.set_widget_name("outer-box"); outer_box.set_widget_name("outer-box");
@ -210,16 +210,15 @@ fn build_ui<T, P>(
&item_provider.lock().unwrap().get_elements(None), &item_provider.lock().unwrap().get_elements(None),
&list_items, &list_items,
&inner_box, &inner_box,
&config, config,
&sender, sender,
&app, app,
&window, &window,
); );
let items_sort = ArcMenuMap::clone(&list_items); let items_sort = ArcMenuMap::clone(&list_items);
inner_box.set_sort_func(move |child1, child2| { inner_box
sort_menu_items_by_score(child1, child2, items_sort.clone()) .set_sort_func(move |child1, child2| sort_menu_items_by_score(child1, child2, &items_sort));
});
let items_focus = ArcMenuMap::clone(&list_items); let items_focus = ArcMenuMap::clone(&list_items);
inner_box.connect_map(move |fb| { inner_box.connect_map(move |fb| {
@ -235,7 +234,7 @@ fn build_ui<T, P>(
setup_key_event_handler( setup_key_event_handler(
&window, &window,
entry.clone(), &entry,
inner_box, inner_box,
app.clone(), app.clone(),
sender.clone(), sender.clone(),
@ -246,7 +245,7 @@ fn build_ui<T, P>(
window.set_child(Widget::NONE); window.set_child(Widget::NONE);
window.show(); window.show();
animate_window_show(config.clone(), window.clone(), outer_box); animate_window_show(config, window.clone(), outer_box);
} }
fn build_ui_from_menu_items<T: Clone + 'static>( fn build_ui_from_menu_items<T: Clone + 'static>(
@ -262,30 +261,26 @@ fn build_ui_from_menu_items<T: Clone + 'static>(
let mut arc_lock = list_items.lock().unwrap(); let mut arc_lock = list_items.lock().unwrap();
inner_box.unset_sort_func(); inner_box.unset_sort_func();
loop { while let Some(b) = inner_box.child_at_index(0) {
if let Some(b) = inner_box.child_at_index(0) { inner_box.remove(&b);
inner_box.remove(&b);
} else {
break;
}
} }
for entry in items { for entry in items {
arc_lock.insert( arc_lock.insert(
add_menu_item(&inner_box, entry, config, sender, &list_items, app, window), add_menu_item(inner_box, entry, config, sender, list_items, app, window),
(*entry).clone(), (*entry).clone(),
); );
} }
} }
let lic = list_items.clone(); let lic = ArcMenuMap::clone(list_items);
inner_box inner_box.set_sort_func(move |child2, child1| sort_menu_items_by_score(child1, child2, &lic));
.set_sort_func(move |child2, child1| sort_menu_items_by_score(child1, child2, lic.clone()));
inner_box.invalidate_sort(); inner_box.invalidate_sort();
} }
#[allow(clippy::too_many_arguments)] // todo fix this
fn setup_key_event_handler<T: Clone + 'static>( fn setup_key_event_handler<T: Clone + 'static>(
window: &ApplicationWindow, window: &ApplicationWindow,
entry: SearchEntry, entry: &SearchEntry,
inner_box: FlowBox, inner_box: FlowBox,
app: Application, app: Application,
sender: MenuItemSender<T>, sender: MenuItemSender<T>,
@ -307,13 +302,14 @@ fn setup_key_event_handler<T: Clone + 'static>(
&config, &config,
&item_provider, &item_provider,
&window_clone, &window_clone,
&key_value, key_value,
) )
}); });
window.add_controller(key_controller); window.add_controller(key_controller);
} }
#[allow(clippy::too_many_arguments)] // todo refactor this?
fn handle_key_press<T: Clone + 'static>( fn handle_key_press<T: Clone + 'static>(
search_entry: &SearchEntry, search_entry: &SearchEntry,
inner_box: &FlowBox, inner_box: &FlowBox,
@ -323,54 +319,54 @@ fn handle_key_press<T: Clone + 'static>(
config: &Config, config: &Config,
item_provider: &ArcProvider<T>, item_provider: &ArcProvider<T>,
window_clone: &ApplicationWindow, window_clone: &ApplicationWindow,
keyboard_key: &Key, keyboard_key: Key,
) -> Propagation { ) -> Propagation {
let update_view = |query: &String, items: Vec<MenuItem<T>>| { let update_view = |query: &String, items: Vec<MenuItem<T>>| {
build_ui_from_menu_items( build_ui_from_menu_items(
&items, &items,
&list_items, list_items,
&inner_box, inner_box,
&config, config,
&sender, sender,
&app, app,
&window_clone, window_clone,
); );
filter_widgets(query, list_items, &config, &inner_box); filter_widgets(query, list_items, config, inner_box);
select_first_visible_child(&list_items, &inner_box); select_first_visible_child(list_items, inner_box);
}; };
let update_view_from_provider = |query: &String| { let update_view_from_provider = |query: &String| {
let filtered_list = item_provider.lock().unwrap().get_elements(Some(&query)); let filtered_list = item_provider.lock().unwrap().get_elements(Some(query));
update_view(query, filtered_list) update_view(query, filtered_list);
}; };
match keyboard_key { match keyboard_key {
&Key::Escape => { Key::Escape => {
if let Err(e) = sender.send(Err(anyhow!("No item selected"))) { if let Err(e) = sender.send(Err(anyhow!("No item selected"))) {
log::error!("failed to send message {e}"); log::error!("failed to send message {e}");
} }
close_gui(app.clone(), window_clone.clone(), &config); close_gui(app.clone(), window_clone.clone(), config);
} }
&Key::Return => { Key::Return => {
if let Err(e) = handle_selected_item( if let Err(e) = handle_selected_item(
&sender, sender,
app.clone(), app.clone(),
window_clone.clone(), window_clone.clone(),
&config, config,
&inner_box, inner_box,
&list_items, list_items,
) { ) {
log::error!("{e}"); log::error!("{e}");
} }
} }
&Key::BackSpace => { Key::BackSpace => {
let mut query = search_entry.text().to_string(); let mut query = search_entry.text().to_string();
query.pop(); query.pop();
search_entry.set_text(&query); search_entry.set_text(&query);
update_view_from_provider(&query); update_view_from_provider(&query);
} }
&Key::Tab => { Key::Tab => {
if let Some(fb) = inner_box.selected_children().first() { if let Some(fb) = inner_box.selected_children().first() {
if let Some(child) = fb.child() { if let Some(child) = fb.child() {
let expander = child.downcast::<Expander>().ok(); let expander = child.downcast::<Expander>().ok();
@ -381,7 +377,7 @@ fn handle_key_press<T: Clone + 'static>(
let menu_item = lock.get(fb); let menu_item = lock.get(fb);
if let Some(menu_item) = menu_item { if let Some(menu_item) = menu_item {
if let Some(new_items) = if let Some(new_items) =
item_provider.lock().unwrap().get_sub_elements(&menu_item) item_provider.lock().unwrap().get_sub_elements(menu_item)
{ {
let query = menu_item.label.clone(); let query = menu_item.label.clone();
drop(lock); drop(lock);
@ -411,7 +407,7 @@ fn handle_key_press<T: Clone + 'static>(
fn sort_menu_items_by_score<T: std::clone::Clone>( fn sort_menu_items_by_score<T: std::clone::Clone>(
child1: &FlowBoxChild, child1: &FlowBoxChild,
child2: &FlowBoxChild, child2: &FlowBoxChild,
items_lock: ArcMenuMap<T>, items_lock: &ArcMenuMap<T>,
) -> Ordering { ) -> Ordering {
let lock = items_lock.lock().unwrap(); let lock = items_lock.lock().unwrap();
let m1 = lock.get(child1); let m1 = lock.get(child1);
@ -444,7 +440,7 @@ fn sort_menu_items_by_score<T: std::clone::Clone>(
} }
} }
fn animate_window_show(config: Config, window: ApplicationWindow, outer_box: gtk4::Box) { fn animate_window_show(config: &Config, window: ApplicationWindow, outer_box: gtk4::Box) {
let display = window.display(); let display = window.display();
if let Some(surface) = window.surface() { if let Some(surface) = window.surface() {
// todo this does not work for multi monitor systems // todo this does not work for multi monitor systems

View file

@ -1,5 +1,5 @@
use std::os::unix::prelude::CommandExt; use std::os::unix::prelude::CommandExt;
use std::path::PathBuf; use std::path::{Path, PathBuf};
use std::process::{Command, Stdio}; use std::process::{Command, Stdio};
use std::{env, fmt, fs, io}; use std::{env, fmt, fs, io};
@ -89,7 +89,7 @@ impl<T: Clone> DRunProvider<T> {
"Skipping desktop entry for {name:?} because action {action:?} does not exist" "Skipping desktop entry for {name:?} because action {action:?} does not exist"
); );
continue; continue;
}; }
let icon = file let icon = file
.entry .entry
@ -176,13 +176,13 @@ impl<T: Clone> FileItemProvider<T> {
} }
} }
fn resolve_icon_for_name(&self, path: PathBuf) -> String { fn resolve_icon_for_name(path: &Path) -> String {
let result = tree_magic_mini::from_filepath(&path); let result = tree_magic_mini::from_filepath(path);
if let Some(result) = result { if let Some(result) = result {
if result.starts_with("image") { if result.starts_with("image") {
"image-x-generic".to_owned() "image-x-generic".to_owned()
} else if result.starts_with("inode") { } else if result.starts_with("inode") {
return result.replace("/", "-"); return result.replace('/', "-");
} else if result.starts_with("text") { } else if result.starts_with("text") {
if result.contains("plain") { if result.contains("plain") {
"text-x-generic".to_owned() "text-x-generic".to_owned()
@ -225,7 +225,7 @@ impl<T: Clone> ItemProvider<T> for FileItemProvider<T> {
}; };
let mut trimmed_search = search.unwrap_or(&default_path).to_owned(); let mut trimmed_search = search.unwrap_or(&default_path).to_owned();
if !trimmed_search.starts_with("/") && !trimmed_search.starts_with("~") { if !trimmed_search.starts_with('/') && !trimmed_search.starts_with('~') {
trimmed_search = format!("{default_path}/{trimmed_search}"); trimmed_search = format!("{default_path}/{trimmed_search}");
} }
@ -241,38 +241,45 @@ impl<T: Clone> ItemProvider<T> for FileItemProvider<T> {
} }
if path.is_dir() { if path.is_dir() {
for entry in path.read_dir().unwrap() { if let Ok(entries) = path.read_dir() {
if let Ok(entry) = entry { for entry in entries.flatten() {
let mut path_str = entry.path().to_str().unwrap_or("").to_string(); if let Some(mut path_str) =
if trimmed_search.starts_with("~") { entry.path().to_str().map(std::string::ToString::to_string)
if let Some(home_dir) = dirs::home_dir() { {
path_str = path_str.replace(home_dir.to_str().unwrap_or(""), "~"); if trimmed_search.starts_with('~') {
if let Some(home_dir) = dirs::home_dir() {
if let Some(home_str) = home_dir.to_str() {
path_str = path_str.replace(home_str, "~");
}
}
} }
}
if entry.path().is_dir() { if entry.path().is_dir() {
path_str += "/"; path_str.push('/');
} }
items.push({ items.push(MenuItem {
MenuItem {
label: path_str.clone(), label: path_str.clone(),
icon_path: Some(self.resolve_icon_for_name(entry.path())), icon_path: Some(FileItemProvider::<T>::resolve_icon_for_name(
&entry.path(),
)),
action: Some(format!("xdg-open {path_str}")), action: Some(format!("xdg-open {path_str}")),
sub_elements: vec![], sub_elements: vec![],
working_dir: None, working_dir: None,
initial_sort_score: 0, initial_sort_score: 0,
search_sort_score: 0.0, search_sort_score: 0.0,
data: Some(self.menu_item_data.clone()), data: Some(self.menu_item_data.clone()),
} });
}); }
} }
} }
} else { } else {
items.push({ items.push({
MenuItem { MenuItem {
label: trimmed_search.to_owned(), label: trimmed_search.clone(),
icon_path: Some(self.resolve_icon_for_name(PathBuf::from(&trimmed_search))), icon_path: Some(FileItemProvider::<T>::resolve_icon_for_name(
&PathBuf::from(&trimmed_search),
)),
action: Some(format!("xdg-open {trimmed_search}")), action: Some(format!("xdg-open {trimmed_search}")),
sub_elements: vec![], sub_elements: vec![],
working_dir: None, working_dir: None,
@ -329,7 +336,7 @@ impl<T: Clone> ItemProvider<T> for MathProvider<T> {
let item = MenuItem { let item = MenuItem {
label: result, label: result,
icon_path: None, icon_path: None,
action: search.map(|s| s.to_string()), action: search.map(String::from),
sub_elements: vec![], sub_elements: vec![],
working_dir: None, working_dir: None,
initial_sort_score: 0, initial_sort_score: 0,
@ -361,17 +368,17 @@ enum AutoRunType {
#[derive(Clone)] #[derive(Clone)]
struct AutoItemProvider { struct AutoItemProvider {
drun_provider: DRunProvider<AutoRunType>, drun: DRunProvider<AutoRunType>,
file_provider: FileItemProvider<AutoRunType>, file: FileItemProvider<AutoRunType>,
math_provider: MathProvider<AutoRunType>, math: MathProvider<AutoRunType>,
} }
impl AutoItemProvider { impl AutoItemProvider {
fn new() -> Self { fn new() -> Self {
AutoItemProvider { AutoItemProvider {
drun_provider: DRunProvider::new(AutoRunType::DRun), drun: DRunProvider::new(AutoRunType::DRun),
file_provider: FileItemProvider::new(AutoRunType::File), file: FileItemProvider::new(AutoRunType::File),
math_provider: MathProvider::new(AutoRunType::Math), math: MathProvider::new(AutoRunType::Math),
} }
} }
} }
@ -381,21 +388,21 @@ impl ItemProvider<AutoRunType> for AutoItemProvider {
if let Some(search) = search_opt { if let Some(search) = search_opt {
let trimmed_search = search.trim(); let trimmed_search = search.trim();
if trimmed_search.is_empty() { if trimmed_search.is_empty() {
self.drun_provider.get_elements(search_opt) self.drun.get_elements(search_opt)
} else if MathProvider::<AutoRunType>::contains_math_functions_or_starts_with_number( } else if MathProvider::<AutoRunType>::contains_math_functions_or_starts_with_number(
trimmed_search, trimmed_search,
) { ) {
self.math_provider.get_elements(search_opt) self.math.get_elements(search_opt)
} else if trimmed_search.starts_with("$") } else if trimmed_search.starts_with('$')
|| trimmed_search.starts_with("/") || trimmed_search.starts_with('/')
|| trimmed_search.starts_with("~") || trimmed_search.starts_with('~')
{ {
self.file_provider.get_elements(search_opt) self.file.get_elements(search_opt)
} else { } else {
self.drun_provider.get_elements(search_opt) self.drun.get_elements(search_opt)
} }
} else { } else {
self.drun_provider.get_elements(search_opt) self.drun.get_elements(search_opt)
} }
} }
@ -411,7 +418,7 @@ impl ItemProvider<AutoRunType> for AutoItemProvider {
/// ///
/// Will return `Err` if it was not able to spawn the process /// Will return `Err` if it was not able to spawn the process
pub fn d_run(config: &Config) -> Result<(), ModeError> { pub fn d_run(config: &Config) -> Result<(), ModeError> {
let provider = DRunProvider::new("".to_owned()); let provider = DRunProvider::new(String::new());
let cache_path = provider.cache_path.clone(); let cache_path = provider.cache_path.clone();
let mut cache = provider.cache.clone(); let mut cache = provider.cache.clone();
@ -427,10 +434,14 @@ pub fn d_run(config: &Config) -> Result<(), ModeError> {
Ok(()) Ok(())
} }
/// # Errors
///
/// Will return `Err`
/// * if it was not able to spawn the process
pub fn auto(config: &Config) -> Result<(), ModeError> { pub fn auto(config: &Config) -> Result<(), ModeError> {
let provider = AutoItemProvider::new(); let provider = AutoItemProvider::new();
let cache_path = provider.drun_provider.cache_path.clone(); let cache_path = provider.drun.cache_path.clone();
let mut cache = provider.drun_provider.cache.clone(); let mut cache = provider.drun.cache.clone();
// todo ues a arc instead of cloning the config // todo ues a arc instead of cloning the config
let selection_result = gui::show(config.clone(), provider); let selection_result = gui::show(config.clone(), provider);
@ -459,8 +470,12 @@ pub fn auto(config: &Config) -> Result<(), ModeError> {
Ok(()) Ok(())
} }
/// # Errors
///
/// Will return `Err`
/// * if it was not able to spawn the process
pub fn file(config: &Config) -> Result<(), ModeError> { pub fn file(config: &Config) -> Result<(), ModeError> {
let provider = FileItemProvider::new("".to_owned()); let provider = FileItemProvider::new(String::new());
// todo ues a arc instead of cloning the config // todo ues a arc instead of cloning the config
let selection_result = gui::show(config.clone(), provider); let selection_result = gui::show(config.clone(), provider);
@ -478,8 +493,8 @@ pub fn file(config: &Config) -> Result<(), ModeError> {
Ok(()) Ok(())
} }
pub fn math(config: &Config) -> Result<(), ModeError> { pub fn math(config: &Config) {
let provider = MathProvider::new("".to_owned()); let provider = MathProvider::new(String::new);
// todo ues a arc instead of cloning the config // todo ues a arc instead of cloning the config
let selection_result = gui::show(config.clone(), provider); let selection_result = gui::show(config.clone(), provider);
@ -489,10 +504,11 @@ pub fn math(config: &Config) -> Result<(), ModeError> {
log::error!("No item selected"); log::error!("No item selected");
} }
} }
Ok(())
} }
/// # Errors
///
/// todo
pub fn dmenu(_: &Config) -> Result<(), ModeError> { pub fn dmenu(_: &Config) -> Result<(), ModeError> {
Ok(()) Ok(())
} }
@ -504,7 +520,7 @@ fn update_drun_cache_and_run<T: Clone>(
) -> Result<(), ModeError> { ) -> Result<(), ModeError> {
if let Some(cache_path) = cache_path { if let Some(cache_path) = cache_path {
*cache.entry(selection_result.label).or_insert(0) += 1; *cache.entry(selection_result.label).or_insert(0) += 1;
if let Err(e) = save_cache_file(&cache_path, &cache) { if let Err(e) = save_cache_file(&cache_path, cache) {
log::warn!("cannot save drun cache {e:?}"); log::warn!("cannot save drun cache {e:?}");
} }
} }
@ -583,7 +599,7 @@ fn spawn_fork(cmd: &str, working_dir: Option<&String>) -> Result<(), ModeError>
if let Some(dir) = working_dir { if let Some(dir) = working_dir {
env::set_current_dir(dir) env::set_current_dir(dir)
.map_err(|e| ModeError::RunError(format!("cannot set workdir {e}")))? .map_err(|e| ModeError::RunError(format!("cannot set workdir {e}")))?;
} }
let exec = parts[0].replace('"', ""); let exec = parts[0].replace('"', "");

View file

@ -30,7 +30,7 @@ fn main() -> anyhow::Result<()> {
mode::file(&config).map_err(|e| anyhow!(e))?; mode::file(&config).map_err(|e| anyhow!(e))?;
} }
Mode::Math => { Mode::Math => {
mode::math(&config).map_err(|e| anyhow!(e))?; mode::math(&config);
} }
Mode::Auto => { Mode::Auto => {
mode::auto(&config).map_err(|e| anyhow!(e))?; mode::auto(&config).map_err(|e| anyhow!(e))?;