Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/configuration/keymap.toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ All methods (except `reverse`) support the `--reverse` flag:
- `cd ~`: go to home directory
- `cd -`: go to previous directory in history (If it exists)

### `history_next`: go to next dir in navigation history

### `history_prev`: go to previous dir in navigation history

### `open`: open file or directory

- if joshuto does not know how to open the file format (via extension currently),
Expand Down
28 changes: 11 additions & 17 deletions src/commands/change_directory.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::path;
use std::path::Path;

use crate::commands::{reload, zoxide};
use crate::error::AppResult;
Expand All @@ -7,17 +7,21 @@ use crate::types::state::AppState;
use crate::utils::cwd;

// ChangeDirectory command
pub fn cd(path: &path::Path, app_state: &mut AppState) -> std::io::Result<()> {
pub fn cd(path: &Path, app_state: &mut AppState, history_update: bool) -> std::io::Result<()> {
cwd::set_current_dir(path)?;
app_state.state.tab_state_mut().curr_tab_mut().set_cwd(path);
app_state
.state
.tab_state_mut()
.curr_tab_mut()
.set_cwd(path, history_update);
if app_state.config.zoxide_update {
debug_assert!(path.is_absolute());
zoxide::zoxide_add(path.to_str().expect("cannot convert path to string"))?;
}
Ok(())
}

pub fn change_directory(app_state: &mut AppState, mut path: &path::Path) -> AppResult {
pub fn change_directory(app_state: &mut AppState, mut path: &Path) -> AppResult {
let new_cwd = if path.is_absolute() {
path.to_path_buf()
} else {
Expand All @@ -31,7 +35,7 @@ pub fn change_directory(app_state: &mut AppState, mut path: &path::Path) -> AppR
new_cwd
};

cd(new_cwd.as_path(), app_state)?;
cd(new_cwd.as_path(), app_state, true)?;
let dirlists = generate_entries_to_root(
new_cwd.as_path(),
app_state.state.tab_state_ref().curr_tab_ref().history_ref(),
Expand All @@ -58,12 +62,7 @@ pub fn parent_directory(app_state: &mut AppState) -> AppResult {
.parent()
.map(|p| p.to_path_buf())
{
cwd::set_current_dir(&parent)?;
app_state
.state
.tab_state_mut()
.curr_tab_mut()
.set_cwd(parent.as_path());
cd(&parent, app_state, true)?;
reload::soft_reload_curr_tab(app_state)?;
}
Ok(())
Expand All @@ -78,12 +77,7 @@ pub fn previous_directory(app_state: &mut AppState) -> AppResult {
.previous_dir()
{
let path = path.to_path_buf();
cwd::set_current_dir(&path)?;
app_state
.state
.tab_state_mut()
.curr_tab_mut()
.set_cwd(path.as_path());
cd(&path, app_state, true)?;
reload::soft_reload_curr_tab(app_state)?;
}
Ok(())
Expand Down
46 changes: 46 additions & 0 deletions src/commands/history.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use std::path::PathBuf;

use crate::error::AppResult;
use crate::types::state::AppState;

use super::change_directory;

fn next_or_prev(app_state: &mut AppState, path_opt: Option<PathBuf>) -> AppResult {
if let Some(path) = path_opt {
if !matches!(path.try_exists(), Ok(true)) {
app_state
.state
.tab_state_mut()
.curr_tab_mut()
.navigation_history_mut()
.remove_current();
return next(app_state);
}

change_directory::cd(&path, app_state, false)?;
}

Ok(())
}

pub fn next(app_state: &mut AppState) -> AppResult {
let next = app_state
.state
.tab_state_mut()
.curr_tab_mut()
.navigation_history_mut()
.next()
.cloned();
next_or_prev(app_state, next)
}

pub fn prev(app_state: &mut AppState) -> AppResult {
let prev = app_state
.state
.tab_state_mut()
.curr_tab_mut()
.navigation_history_mut()
.prev()
.cloned();
next_or_prev(app_state, prev)
}
1 change: 1 addition & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub mod filter_regex;
pub mod filter_string;
pub mod flat;
pub mod fzf;
pub mod history;
pub mod line_nums;
pub mod linemode;
pub mod new_directory;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/open_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ pub fn open(app_state: &mut AppState, backend: &mut AppBackend) -> AppResult {
None => (),
Some(entry) if entry.file_path().is_dir() => {
let path = entry.file_path().to_path_buf();
change_directory::cd(path.as_path(), app_state)?;
change_directory::cd(path.as_path(), app_state, true)?;
reload::soft_reload_curr_tab(app_state)?;
}
Some(entry) => {
Expand Down
2 changes: 1 addition & 1 deletion src/commands/parent_cursor_move.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn parent_cursor_move(app_state: &mut AppState, new_index: usize) -> AppResu
}
if let Some(path) = path.as_ref() {
cwd::set_current_dir(path)?;
curr_tab.set_cwd(path);
curr_tab.set_cwd(path, true);
}
}
Ok(())
Expand Down
2 changes: 2 additions & 0 deletions src/constants/command_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ cmd_constants![
(CMD_CHANGE_DIRECTORY, "cd"),
(CMD_PARENT_DIRECTORY, "cd .."),
(CMD_PREVIOUS_DIRECTORY, "cd -"),
(CMD_HISTORY_NEXT, "history_next"),
(CMD_HISTORY_PREV, "history_prev"),
(CMD_NEW_TAB, "new_tab"),
(CMD_CLOSE_TAB, "close_tab"),
(CMD_CUT_FILES, "cut_files"),
Expand Down
20 changes: 19 additions & 1 deletion src/tab/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
mod homepage;
mod nav_history;
mod new_tab_mode;
mod options;

pub use homepage::*;
pub use new_tab_mode::*;
pub use options::*;

use nav_history::NavigationHistory;

use std::collections::HashMap;
use std::path;

Expand All @@ -22,6 +25,7 @@ pub struct JoshutoTab {
pub history: JoshutoHistory,
pub history_metadata: HistoryMetadata,
pub options: TabDisplayOption,
pub navigation_history: NavigationHistory,
}

impl JoshutoTab {
Expand All @@ -30,11 +34,13 @@ impl JoshutoTab {
history: JoshutoHistory,
tab_options: TabDisplayOption,
) -> std::io::Result<Self> {
let navigation_history = NavigationHistory::from(&cwd);
let new_tab = Self {
cwd,
previous_dir: None,
history,
history_metadata: HashMap::new(),
navigation_history,
options: tab_options,
};

Expand All @@ -52,10 +58,14 @@ impl JoshutoTab {
pub fn get_cwd(&self) -> &path::Path {
self.cwd.as_path()
}
pub fn set_cwd(&mut self, cwd: &path::Path) {
pub fn set_cwd(&mut self, cwd: &path::Path, history_update: bool) {
self.previous_dir = Some(self.cwd.to_path_buf());
self.cwd = cwd.to_path_buf();

if history_update {
self.navigation_history.push(cwd);
}

// OSC 7: Escape sequence to set the working directory
// print!("\x1b]7;file://{}{}\x1b\\", HOSTNAME.as_str(), cwd.display());
}
Expand All @@ -78,6 +88,14 @@ impl JoshutoTab {
&mut self.history_metadata
}

#[allow(dead_code)]
pub fn navigation_history_ref(&self) -> &NavigationHistory {
&self.navigation_history
}
pub fn navigation_history_mut(&mut self) -> &mut NavigationHistory {
&mut self.navigation_history
}

pub fn curr_list_ref(&self) -> Option<&JoshutoDirList> {
self.history.get(self.get_cwd())
}
Expand Down
51 changes: 51 additions & 0 deletions src/tab/nav_history.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use std::path::{Path, PathBuf};

#[derive(Default)]
pub struct NavigationHistory {
items: Vec<PathBuf>,
index: usize,
}

impl From<&PathBuf> for NavigationHistory {
fn from(value: &PathBuf) -> Self {
Self {
items: vec![value.to_path_buf()],
index: 0,
}
}
}

impl NavigationHistory {
pub fn prev(&mut self) -> Option<&PathBuf> {
if self.index == 0 {
return None;
}

self.index -= 1;
self.items.get(self.index)
}

pub fn next(&mut self) -> Option<&PathBuf> {
if self.index == self.items.len() - 1 {
return None;
}

self.index += 1;
self.items.get(self.index)
}

pub fn push(&mut self, path: &Path) {
self.index += 1;

if self.index < self.items.len() {
self.items.truncate(self.index);
}

self.items.push(path.to_path_buf());
}

pub fn remove_current(&mut self) {
self.items.remove(self.index);
self.items.dedup();
}
}
3 changes: 3 additions & 0 deletions src/types/command/impl_appcommand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ impl AppCommand for Command {
Self::ParentDirectory => CMD_PARENT_DIRECTORY,
Self::PreviousDirectory => CMD_PREVIOUS_DIRECTORY,

Self::HistoryNext => CMD_HISTORY_NEXT,
Self::HistoryPrev => CMD_HISTORY_PREV,

Self::NewTab { .. } => CMD_NEW_TAB,
Self::CloseTab => CMD_CLOSE_TAB,
Self::CommandLine { .. } => CMD_COMMAND_LINE,
Expand Down
3 changes: 3 additions & 0 deletions src/types/command/impl_appexecute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ impl AppExecute for Command {
Self::ParentDirectory => change_directory::parent_directory(app_state),
Self::PreviousDirectory => change_directory::previous_directory(app_state),

Self::HistoryNext => history::next(app_state),
Self::HistoryPrev => history::prev(app_state),

Self::NewTab { mode, last } => tab_ops::new_tab(app_state, mode, *last),
Self::CloseTab => tab_ops::close_tab(app_state),
Self::CommandLine { prefix, suffix } => command_line::read_and_execute(
Expand Down
3 changes: 3 additions & 0 deletions src/types/command/impl_comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ impl CommandComment for Command {
Self::ParentDirectory => "CD to parent directory",
Self::PreviousDirectory => "CD to the last dir in history",

Self::HistoryNext => "Go forward in navigation history",
Self::HistoryPrev => "Go back in navigation history",

Self::NewTab { .. } => "Open a new tab",
Self::CloseTab => "Close current tab",
Self::CommandLine { prefix, .. } => match prefix.trim() {
Expand Down
3 changes: 3 additions & 0 deletions src/types/command/impl_from_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ impl std::str::FromStr for Command {

simple_command_conversion_case!(command, CMD_HELP, Self::Help);

simple_command_conversion_case!(command, CMD_HISTORY_NEXT, Self::HistoryNext);
simple_command_conversion_case!(command, CMD_HISTORY_PREV, Self::HistoryPrev);

simple_command_conversion_case!(command, CMD_BOOKMARK_ADD, Self::BookmarkAdd);
simple_command_conversion_case!(
command,
Expand Down
3 changes: 3 additions & 0 deletions src/types/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ pub enum Command {
ParentDirectory,
PreviousDirectory,

HistoryNext,
HistoryPrev,

CommandLine {
prefix: String,
suffix: String,
Expand Down
Loading