Feature to move up file hierarchy with Alt+Up

From: https://en.wikipedia.org/wiki/Table_of_keyboard_shortcuts#Browsers_/_Go_menu

Alt+Up moves up the file hierarchy until it hits root.
So, if "/home/josh" is opened, Alt+Up would move to "/home"
This commit is contained in:
Josh Megnauth 2024-02-06 22:58:29 -05:00 committed by Jeremy Soller
parent 843997a0d8
commit 2814834251
3 changed files with 40 additions and 1 deletions

View file

@ -46,6 +46,7 @@ pub enum Action {
Cut,
HistoryNext,
HistoryPrevious,
LocationUp,
MoveToTrash,
NewFile,
NewFolder,
@ -71,6 +72,7 @@ impl Action {
Action::Cut => Message::Cut(entity_opt),
Action::HistoryNext => Message::TabMessage(None, tab::Message::GoNext),
Action::HistoryPrevious => Message::TabMessage(None, tab::Message::GoPrevious),
Action::LocationUp => Message::TabMessage(None, tab::Message::LocationUp),
Action::MoveToTrash => Message::MoveToTrash(entity_opt),
Action::NewFile => Message::NewFile(entity_opt),
Action::NewFolder => Message::NewFolder(entity_opt),

View file

@ -57,6 +57,7 @@ pub fn key_binds() -> HashMap<KeyBind, Action> {
bind!([Ctrl], X, Cut);
bind!([Alt], Right, HistoryNext);
bind!([Alt], Left, HistoryPrevious);
bind!([Alt], Up, LocationUp);
bind!([Ctrl], V, Paste);
bind!([Ctrl], A, SelectAll);
bind!([Ctrl], W, TabClose);

View file

@ -23,7 +23,7 @@ use std::{
time::{Duration, Instant},
};
use crate::{fl, mime_icon::mime_icon};
use crate::{fl, home_dir, mime_icon::mime_icon};
const DOUBLE_CLICK_DURATION: Duration = Duration::from_millis(500);
//TODO: configurable
@ -384,6 +384,7 @@ pub enum Message {
GoNext,
GoPrevious,
Location(Location),
LocationUp,
RightClick(usize),
View(View),
}
@ -622,6 +623,22 @@ impl Tab {
Message::Location(location) => {
cd = Some(location);
}
Message::LocationUp => {
// Sets location to the path's parent
// Does nothing if path is root or location is Trash
if let Location::Path(ref path) = self.location {
// Canonicalize is needed because parent() can return an empty path for
// relative paths which would fail to open.
// Canonicalizing the path should do the right thing of evaluating the path
// so that the parent successfully moves up the hierarchy.
// If it fails (i.e. the path doesn't exist for some reason) then it returns
// to home.
let mut path = path.canonicalize().unwrap_or_else(|_| home_dir());
if path.pop() {
cd = Some(Location::Path(path));
}
}
}
Message::RightClick(click_i) => {
if let Some(ref mut items) = self.items_opt {
if !items.get(click_i).map_or(false, |x| x.selected) {
@ -1297,4 +1314,23 @@ mod tests {
Ok(())
}
#[test]
fn tab_locationup_moves_up_hierarchy() -> io::Result<()> {
let fs = simple_fs(0, NUM_NESTED, NUM_DIRS, 0, NAME_LEN)?;
let path = fs.path();
let mut next_dir = filter_dirs(path)?
.next()
.expect("should be at least one directory");
let mut tab = Tab::new(Location::Path(next_dir.clone()));
// This will eventually yield false once root is hit
while next_dir.pop() {
debug!("Emitting Message::LocationUp",);
tab.update(Message::LocationUp, Modifiers::empty());
assert_eq_tab_path(&tab, &next_dir);
}
Ok(())
}
}