diff --git a/config/joshuto.toml b/config/joshuto.toml index 455210d68..054324122 100644 --- a/config/joshuto.toml +++ b/config/joshuto.toml @@ -1,5 +1,6 @@ numbered_command = false +focus_on_create = true use_trash = true watch_files = true xdg_open = false diff --git a/docs/configuration/joshuto.toml.md b/docs/configuration/joshuto.toml.md index ee88c33de..1fc6e6e7e 100644 --- a/docs/configuration/joshuto.toml.md +++ b/docs/configuration/joshuto.toml.md @@ -20,6 +20,13 @@ use_trash = true # Watch for filesystem changes and update directory listings accordingly watch_files = true +# If true the cursor will focus newly created files or directories with `:touch` or `:mkdir` +# Even if true, the behavior can be avoided prefixing the new file/dir with "./" +# E.g.: +# - `:mkdir a` moves the cursor to the new directory `a` +# - `:mkdir ./b` keeps the cursor where it was +focus_on_create = true + # The maximum file size to show a preview for max_preview_size = 2097152 # 2MB diff --git a/src/commands/cursor_move.rs b/src/commands/cursor_move.rs index 1f6e5ff8f..2d7688f73 100644 --- a/src/commands/cursor_move.rs +++ b/src/commands/cursor_move.rs @@ -1,5 +1,7 @@ +use std::path; + use crate::context::AppContext; -use crate::error::AppResult; +use crate::error::{AppError, AppErrorKind, AppResult}; use crate::ui::AppBackend; pub fn lazy_load_directory_size(context: &mut AppContext) { @@ -54,6 +56,21 @@ pub fn cursor_move(context: &mut AppContext, new_index: usize) { } } +pub fn to_path(context: &mut AppContext, path: &path::Path) -> AppResult { + // This error should never happen + let err = || AppError::new(AppErrorKind::UnknownError, String::from("Unexpected error")); + let ui_context = context.ui_context_ref().clone(); + let display_options = context.config_ref().display_options_ref().clone(); + if let Some(curr_list) = context.tab_context_mut().curr_tab_mut().curr_list_mut() { + if let path::Component::Normal(name) = path.components().next().ok_or_else(err)? { + let index = curr_list.get_index_from_name(name.to_str().ok_or_else(err)?); + curr_list.set_index(index, &ui_context, &display_options); + } + } + + Ok(()) +} + pub fn up(context: &mut AppContext, u: usize) -> AppResult { let movement = context .tab_context_ref() diff --git a/src/commands/new_directory.rs b/src/commands/new_directory.rs index ec9efd470..32b248e5c 100644 --- a/src/commands/new_directory.rs +++ b/src/commands/new_directory.rs @@ -1,5 +1,6 @@ use std::path; +use crate::commands::cursor_move; use crate::context::AppContext; use crate::error::AppResult; use crate::history::DirectoryHistory; @@ -13,5 +14,10 @@ pub fn new_directory(context: &mut AppContext, p: &path::Path) -> AppResult { tab.history_mut() .reload(&curr_path, &options, &tab_options)?; } + + if context.config_ref().focus_on_create { + cursor_move::to_path(context, p)?; + } + Ok(()) } diff --git a/src/commands/touch_file.rs b/src/commands/touch_file.rs index 27249b1c5..f36befff7 100644 --- a/src/commands/touch_file.rs +++ b/src/commands/touch_file.rs @@ -4,6 +4,7 @@ use std::time::SystemTime; use filetime::FileTime; +use crate::commands::cursor_move; use crate::context::AppContext; use crate::error::AppResult; use crate::history::create_dirlist_with_history; @@ -58,5 +59,10 @@ pub fn touch_file(context: &mut AppContext, arg: &str) -> AppResult { create_dirlist_with_history(history, path.as_path(), &options, &tab_options)?; history.insert(path, new_dirlist); } + + if context.config_ref().focus_on_create { + cursor_move::to_path(context, path::Path::new(arg))?; + } + Ok(()) } diff --git a/src/config/clean/app/config.rs b/src/config/clean/app/config.rs index 292078d5d..fb8ceda73 100644 --- a/src/config/clean/app/config.rs +++ b/src/config/clean/app/config.rs @@ -16,6 +16,7 @@ pub struct AppConfig { pub xdg_open: bool, pub xdg_open_fork: bool, pub watch_files: bool, + pub focus_on_create: bool, pub cmd_aliases: HashMap, pub _display_options: DisplayOption, pub _preview_options: PreviewOption, @@ -78,6 +79,7 @@ impl From for AppConfig { xdg_open_fork: raw.xdg_open_fork, watch_files: raw.watch_files, cmd_aliases: raw.cmd_aliases, + focus_on_create: raw.focus_on_create, _display_options: DisplayOption::from(raw.display_options), _preview_options: PreviewOption::from(raw.preview_options), _search_options: SearchOption::from(raw.search_options), diff --git a/src/config/raw/app/config.rs b/src/config/raw/app/config.rs index be358bcce..feac4f2a1 100644 --- a/src/config/raw/app/config.rs +++ b/src/config/raw/app/config.rs @@ -26,6 +26,8 @@ pub struct AppConfigRaw { pub xdg_open_fork: bool, #[serde(default = "default_true")] pub watch_files: bool, + #[serde(default = "default_true")] + pub focus_on_create: bool, #[serde(default)] pub cmd_aliases: HashMap, #[serde(default, rename = "display")] diff --git a/src/fs/dirlist.rs b/src/fs/dirlist.rs index 72b809b08..2acf7c1b8 100644 --- a/src/fs/dirlist.rs +++ b/src/fs/dirlist.rs @@ -69,6 +69,16 @@ impl JoshutoDirList { self.index } + pub fn get_index_from_name(&self, name: &str) -> Option { + for (index, entry) in self.iter().enumerate() { + if name == entry.file_name() { + return Some(index); + } + } + + None + } + pub fn get_visual_mode_anchor_index(&self) -> Option { self.visual_mode_anchor_index }