Skip to content

Commit

Permalink
feat: add case_sensitive_ext option for mimetype, theme and icons (#…
Browse files Browse the repository at this point in the history
…497)

* feat: add `case_sensitive_ext` option for mimetype, theme and icons

* Clone `CONFIG_T` instead of initializing it twice

* Reimplement without `CONFIG_T` as static ref

* Clippy & fmt
  • Loading branch information
Akmadan23 authored Mar 11, 2024
1 parent 4267cb5 commit cd93314
Show file tree
Hide file tree
Showing 21 changed files with 138 additions and 60 deletions.
1 change: 1 addition & 0 deletions config/joshuto.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use_trash = true
watch_files = true
xdg_open = false
xdg_open_fork = false
case_sensitive_ext = false

custom_commands = []

Expand Down
4 changes: 4 additions & 0 deletions docs/configuration/joshuto.toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ xdg_open = false
# Fork xdg_open so you can continue using joshuto with application open
xdg_open_fork = false

# If true, all file extensions checks will be case sensitive.
# Applies to `[extension]` in `mimetype.toml` and `[ext]` in `theme.toml` and `icons.toml`
case_sensitive_ext = false

# Use system trash can instead of permanently removing files
use_trash = true

Expand Down
9 changes: 8 additions & 1 deletion src/commands/change_directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub fn change_directory(context: &mut AppContext, mut path: &path::Path) -> AppR
};

cd(new_cwd.as_path(), context)?;
let config = context.config_ref().clone();
let options = context.config_ref().display_options_ref().clone();
let ui_context = context.ui_context_ref().clone();
let tab_options = context
Expand All @@ -39,7 +40,13 @@ pub fn change_directory(context: &mut AppContext, mut path: &path::Path) -> AppR
.tab_context_mut()
.curr_tab_mut()
.history_mut()
.populate_to_root(new_cwd.as_path(), &ui_context, &options, &tab_options)?;
.populate_to_root(
new_cwd.as_path(),
&config,
&ui_context,
&options,
&tab_options,
)?;
Ok(())
}

Expand Down
3 changes: 2 additions & 1 deletion src/commands/delete_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,13 @@ pub fn delete_selected_files(
}

let curr_tab = context.tab_context_ref().curr_tab_ref();
let config = context.config_ref().clone();
let options = context.config_ref().display_options_ref().clone();
let curr_path = curr_tab.cwd().to_path_buf();
for (_, tab) in context.tab_context_mut().iter_mut() {
let tab_options = tab.option_ref().clone();
tab.history_mut()
.reload(&curr_path, &options, &tab_options)?;
.reload(&curr_path, &config, &options, &tab_options)?;
}
Ok(())
}
3 changes: 2 additions & 1 deletion src/commands/new_directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ use crate::history::DirectoryHistory;

pub fn new_directory(context: &mut AppContext, p: &path::Path) -> AppResult {
std::fs::create_dir_all(p)?;
let config = context.config_ref().clone();
let options = context.config_ref().display_options_ref().clone();
let curr_path = context.tab_context_ref().curr_tab_ref().cwd().to_path_buf();
for (_, tab) in context.tab_context_mut().iter_mut() {
let tab_options = tab.option_ref().clone();
tab.history_mut()
.reload(&curr_path, &options, &tab_options)?;
.reload(&curr_path, &config, &options, &tab_options)?;
}

if context.config_ref().focus_on_create {
Expand Down
17 changes: 12 additions & 5 deletions src/commands/open_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::io;
use std::path;

use crate::commands::{quit, reload};
use crate::config::clean::app::AppConfig;
use crate::config::clean::mimetype::ProgramEntry;
use crate::context::AppContext;
use crate::error::{AppError, AppErrorKind, AppResult};
Expand All @@ -15,13 +16,19 @@ use super::change_directory;

use crate::MIMETYPE_T;

fn _get_options<'a>(path: &path::Path) -> Vec<&'a ProgramEntry> {
fn _get_options<'a>(path: &path::Path, config: &AppConfig) -> Vec<&'a ProgramEntry> {
let mut options: Vec<&ProgramEntry> = Vec::new();

if let Some(entries) = path
.extension()
.and_then(|ext| ext.to_str())
.and_then(|file_ext| MIMETYPE_T.app_list_for_ext(file_ext))
.and_then(|ext| {
if config.case_sensitive_ext {
MIMETYPE_T.app_list_for_ext(ext)
} else {
MIMETYPE_T.app_list_for_ext(&ext.to_lowercase())
}
})
{
options.extend(entries);
return options;
Expand Down Expand Up @@ -172,7 +179,7 @@ pub fn open(context: &mut AppContext, backend: &mut AppBackend) -> AppResult {
paths.iter().map(|e| e.file_name()).collect(),
)
};
let options = _get_options(path);
let options = _get_options(path, context.config_ref());
let option = options.iter().find(|option| option.program_exists());

let config = context.config_ref();
Expand Down Expand Up @@ -207,7 +214,7 @@ pub fn open_with_index(
));
}
let files: Vec<&str> = paths.iter().map(|e| e.file_name()).collect();
let options = _get_options(paths[0].file_path());
let options = _get_options(paths[0].file_path(), context.config_ref());

if index >= options.len() {
return Err(AppError::new(
Expand Down Expand Up @@ -240,7 +247,7 @@ pub fn open_with_interactive(context: &mut AppContext, backend: &mut AppBackend)
);
}
let files: Vec<&str> = paths.iter().map(|e| e.file_name()).collect();
let options = _get_options(paths[0].file_path());
let options = _get_options(paths[0].file_path(), context.config_ref());

_open_with_helper(context, backend, options, &files)?;
Ok(())
Expand Down
20 changes: 16 additions & 4 deletions src/commands/reload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub fn soft_reload(context: &mut AppContext, id: &Uuid) -> std::io::Result<()> {
}

if !paths.is_empty() {
let config = context.config_ref().clone();
let options = context.config_ref().display_options_ref().clone();
let tab_options = context
.tab_context_ref()
Expand All @@ -38,8 +39,13 @@ pub fn soft_reload(context: &mut AppContext, id: &Uuid) -> std::io::Result<()> {
.map(|t| t.history_mut())
{
for path in paths {
let new_dirlist =
create_dirlist_with_history(history, path.as_path(), &options, &tab_options)?;
let new_dirlist = create_dirlist_with_history(
history,
path.as_path(),
&config,
&options,
&tab_options,
)?;
history.insert(path, new_dirlist);
}
}
Expand Down Expand Up @@ -67,6 +73,7 @@ pub fn reload(context: &mut AppContext, id: &Uuid) -> std::io::Result<()> {
}

if !paths.is_empty() {
let config = context.config_ref().clone();
let options = context.config_ref().display_options_ref().clone();
let tab_options = context
.tab_context_ref()
Expand All @@ -79,8 +86,13 @@ pub fn reload(context: &mut AppContext, id: &Uuid) -> std::io::Result<()> {
.map(|t| t.history_mut())
{
for path in paths {
let new_dirlist =
create_dirlist_with_history(history, path.as_path(), &options, &tab_options)?;
let new_dirlist = create_dirlist_with_history(
history,
path.as_path(),
&config,
&options,
&tab_options,
)?;
history.insert(path, new_dirlist);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/commands/rename_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub fn _rename_file(
.map(|lst| lst.file_path().to_path_buf());

if let Some(path) = path {
let config = context.config_ref().clone();
let options = context.config_ref().display_options_ref().clone();
let tab_options = context
.tab_context_ref()
Expand All @@ -35,7 +36,7 @@ pub fn _rename_file(
.clone();
let history = context.tab_context_mut().curr_tab_mut().history_mut();
let new_dirlist =
create_dirlist_with_history(history, path.as_path(), &options, &tab_options)?;
create_dirlist_with_history(history, path.as_path(), &config, &options, &tab_options)?;
history.insert(path, new_dirlist);
}
Ok(())
Expand Down
8 changes: 5 additions & 3 deletions src/commands/tab_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ fn _tab_switch(new_index: usize, context: &mut AppContext) -> std::io::Result<()
None => None,
};

let config = context.config_ref().clone();
let options = context.config_ref().display_options_ref().clone();
let tab_options = context
.tab_context_ref()
Expand All @@ -44,15 +45,15 @@ fn _tab_switch(new_index: usize, context: &mut AppContext) -> std::io::Result<()

let history = context.tab_context_mut().curr_tab_mut().history_mut();
if history
.create_or_soft_update(cwd.as_path(), &options, &tab_options)
.create_or_soft_update(cwd.as_path(), &config, &options, &tab_options)
.is_err()
{
history.remove(cwd.as_path());
}

if let Some(cwd_parent) = cwd.parent() {
if history
.create_or_soft_update(cwd_parent, &options, &tab_options)
.create_or_soft_update(cwd_parent, &config, &options, &tab_options)
.is_err()
{
history.remove(cwd_parent);
Expand All @@ -61,7 +62,7 @@ fn _tab_switch(new_index: usize, context: &mut AppContext) -> std::io::Result<()

if let Some(file_path) = entry_path {
if history
.create_or_soft_update(file_path.as_path(), &options, &tab_options)
.create_or_soft_update(file_path.as_path(), &config, &options, &tab_options)
.is_err()
{
history.remove(file_path.as_path());
Expand Down Expand Up @@ -141,6 +142,7 @@ pub fn new_tab(context: &mut AppContext, mode: &NewTabMode) -> AppResult {
let id = Uuid::new_v4();
let tab = JoshutoTab::new(
new_tab_path,
context.config_ref(),
context.ui_context_ref(),
context.config_ref().display_options_ref(),
)?;
Expand Down
3 changes: 2 additions & 1 deletion src/commands/touch_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub fn touch_file(context: &mut AppContext, arg: &str) -> AppResult {
.map(|lst| lst.file_path().to_path_buf());

if let Some(path) = path {
let config = context.config_ref().clone();
let options = context.config_ref().display_options_ref().clone();
let tab_options = context
.tab_context_ref()
Expand All @@ -56,7 +57,7 @@ pub fn touch_file(context: &mut AppContext, arg: &str) -> AppResult {
.clone();
let history = context.tab_context_mut().curr_tab_mut().history_mut();
let new_dirlist =
create_dirlist_with_history(history, path.as_path(), &options, &tab_options)?;
create_dirlist_with_history(history, path.as_path(), &config, &options, &tab_options)?;
history.insert(path, new_dirlist);
}

Expand Down
2 changes: 2 additions & 0 deletions src/config/clean/app/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub struct AppConfig {
pub use_trash: bool,
pub xdg_open: bool,
pub xdg_open_fork: bool,
pub case_sensitive_ext: bool,
pub watch_files: bool,
pub custom_commands: Vec<CustomCommand>,
pub focus_on_create: bool,
Expand Down Expand Up @@ -84,6 +85,7 @@ impl From<AppConfigRaw> for AppConfig {
use_trash: raw.use_trash,
xdg_open: raw.xdg_open,
xdg_open_fork: raw.xdg_open_fork,
case_sensitive_ext: raw.case_sensitive_ext,
watch_files: raw.watch_files,
cmd_aliases: raw.cmd_aliases,
focus_on_create: raw.focus_on_create,
Expand Down
4 changes: 2 additions & 2 deletions src/config/clean/app/display/sort_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ fn size_sort(file1: &JoshutoDirEntry, file2: &JoshutoDirEntry) -> cmp::Ordering
}

fn ext_sort(file1: &JoshutoDirEntry, file2: &JoshutoDirEntry) -> cmp::Ordering {
let f1_ext = file1.get_ext();
let f2_ext = file2.get_ext();
let f1_ext = file1.ext().unwrap_or_default();
let f2_ext = file2.ext().unwrap_or_default();
alphanumeric_sort::compare_str(f1_ext, f2_ext)
}

Expand Down
2 changes: 2 additions & 0 deletions src/config/raw/app/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pub struct AppConfigRaw {
#[serde(default)]
pub xdg_open: bool,
#[serde(default)]
pub case_sensitive_ext: bool,
#[serde(default)]
pub xdg_open_fork: bool,
#[serde(default = "default_true")]
pub watch_files: bool,
Expand Down
5 changes: 3 additions & 2 deletions src/event/process_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,21 @@ pub fn process_worker_progress(context: &mut AppContext, res: FileOperationProgr
pub fn process_finished_worker(context: &mut AppContext, res: AppResult<FileOperationProgress>) {
let worker_context = context.worker_context_mut();
let observer = worker_context.remove_worker().unwrap();
let config = context.config_ref().clone();
let options = context.config_ref().display_options_ref().clone();
for (_, tab) in context.tab_context_mut().iter_mut() {
let tab_options = tab.option_ref().clone();
if observer.dest_path().exists() {
let _ = tab
.history_mut()
.reload(observer.dest_path(), &options, &tab_options);
.reload(observer.dest_path(), &config, &options, &tab_options);
} else {
tab.history_mut().remove(observer.dest_path());
}
if observer.src_path().exists() {
let _ = tab
.history_mut()
.reload(observer.src_path(), &options, &tab_options);
.reload(observer.src_path(), &config, &options, &tab_options);
} else {
tab.history_mut().remove(observer.src_path());
}
Expand Down
5 changes: 4 additions & 1 deletion src/fs/dirlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{io, path};

use crate::config::clean::app::display::tab::TabDisplayOption;
use crate::config::clean::app::display::DisplayOption;
use crate::config::clean::app::AppConfig;
use crate::context::UiContext;
use crate::fs::{JoshutoDirEntry, JoshutoMetadata};
use crate::history::read_directory;
Expand Down Expand Up @@ -43,11 +44,13 @@ impl JoshutoDirList {

pub fn from_path(
path: path::PathBuf,
config: &AppConfig,
options: &DisplayOption,
tab_options: &TabDisplayOption,
) -> io::Result<Self> {
let filter_func = options.filter_func();
let mut contents = read_directory(path.as_path(), filter_func, options, tab_options)?;
let mut contents =
read_directory(path.as_path(), filter_func, config, options, tab_options)?;

contents.sort_by(|f1, f2| tab_options.sort_options_ref().compare(f1, f2));

Expand Down
Loading

0 comments on commit cd93314

Please sign in to comment.