diff --git a/src/app.rs b/src/app.rs index 59109c8..1e49d85 100644 --- a/src/app.rs +++ b/src/app.rs @@ -252,7 +252,7 @@ pub enum Message { TabConfig(TabConfig), TabMessage(Option, tab::Message), TabNew, - TabRescan(Entity, Location, Vec), + TabRescan(Entity, Location, Vec, Option), ToggleContextPage(ContextPage), Undo(usize), UndoTrash(usize, Arc<[PathBuf]>), @@ -393,7 +393,7 @@ impl App { Command::batch([ self.update_title(), self.update_watcher(), - self.rescan_tab(entity, location), + self.rescan_tab(entity, location, None), ]) } @@ -403,13 +403,20 @@ impl App { self.pending_operations.insert(id, (operation, 0.0)); } - fn rescan_tab(&mut self, entity: Entity, location: Location) -> Command { + fn rescan_tab( + &mut self, + entity: Entity, + location: Location, + selection_path: Option, + ) -> Command { let icon_sizes = self.config.tab.icon_sizes; Command::perform( async move { let location2 = location.clone(); match tokio::task::spawn_blocking(move || location2.scan(icon_sizes)).await { - Ok(items) => message::app(Message::TabRescan(entity, location, items)), + Ok(items) => { + message::app(Message::TabRescan(entity, location, items, selection_path)) + } Err(err) => { log::warn!("failed to rescan: {}", err); message::none() @@ -432,7 +439,7 @@ impl App { let mut commands = Vec::with_capacity(needs_reload.len()); for (entity, location) in needs_reload { - commands.push(self.rescan_tab(entity, location)); + commands.push(self.rescan_tab(entity, location, None)); } Command::batch(commands) } @@ -443,16 +450,12 @@ impl App { if let Some(tab) = self.tab_model.data_mut::(entity) { match &tab.location { Location::Path(path) | Location::Search(path, ..) => { - let location = if !self.search_input.is_empty() { - Location::Search(path.clone(), self.search_input.clone()) - } - else { + let location = if !self.search_input.is_empty() { + Location::Search(path.clone(), self.search_input.clone()) + } else { Location::Path(path.clone()) }; - tab.change_location( - &location, - None, - ); + tab.change_location(&location, None); title_location_opt = Some((tab.title(), tab.location.clone())); } _ => {} @@ -463,7 +466,7 @@ impl App { return Command::batch([ self.update_title(), self.update_watcher(), - self.rescan_tab(entity, location), + self.rescan_tab(entity, location, None), ]); } Command::none() @@ -1394,7 +1397,7 @@ impl Application for App { }; if let Some(title) = title_opt { self.tab_model.text_set(entity, title); - commands.push(self.rescan_tab(entity, home_location.clone())); + commands.push(self.rescan_tab(entity, home_location.clone(), None)); } } if !commands.is_empty() { @@ -1492,7 +1495,7 @@ impl Application for App { let mut commands = Vec::with_capacity(needs_reload.len()); for (entity, location) in needs_reload { - commands.push(self.rescan_tab(entity, location)); + commands.push(self.rescan_tab(entity, location, None)); } return Command::batch(commands); } @@ -1899,14 +1902,14 @@ impl Application for App { tab::Command::Action(action) => { commands.push(self.update(action.message(Some(entity)))); } - tab::Command::ChangeLocation(tab_title, tab_path) => { + tab::Command::ChangeLocation(tab_title, tab_path, selection_path) => { self.activate_nav_model_location(&tab_path); self.tab_model.text_set(entity, tab_title); commands.push(Command::batch([ self.update_title(), self.update_watcher(), - self.rescan_tab(entity, tab_path), + self.rescan_tab(entity, tab_path, selection_path), ])); } tab::Command::EmptyTrash => { @@ -1981,11 +1984,14 @@ impl Application for App { }; return self.open_tab(location); } - Message::TabRescan(entity, location, items) => { + Message::TabRescan(entity, location, items, selection_path) => { match self.tab_model.data_mut::(entity) { Some(tab) => { if location == tab.location { tab.set_items(items); + if let Some(selection_path) = selection_path { + tab.select_path(selection_path); + } } } _ => (), @@ -2115,7 +2121,7 @@ impl Application for App { return Command::batch([ self.update_title(), self.update_watcher(), - self.rescan_tab(entity, location), + self.rescan_tab(entity, location, None), ]); } } diff --git a/src/dialog.rs b/src/dialog.rs index b111632..c713ac9 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -754,7 +754,7 @@ impl Application for App { tab::Command::Action(action) => { log::warn!("Action {:?} not supported in dialog", action); } - tab::Command::ChangeLocation(_tab_title, _tab_path) => { + tab::Command::ChangeLocation(_tab_title, _tab_path, _selection_path) => { commands .push(Command::batch([self.update_watcher(), self.rescan_tab()])); } diff --git a/src/tab.rs b/src/tab.rs index 9ac25e4..e35528f 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -573,7 +573,7 @@ impl Location { #[derive(Clone, Debug)] pub enum Command { Action(Action), - ChangeLocation(String, Location), + ChangeLocation(String, Location, Option), EmptyTrash, FocusButton(widget::Id), FocusTextInput(widget::Id), @@ -1022,11 +1022,16 @@ impl Tab { *self.cached_selected.borrow_mut() = None; if let Some(ref mut items) = self.items_opt { for item in items.iter_mut() { - if item.name == name { - item.selected = true; - } else { - item.selected = false; - } + item.selected = item.name == name; + } + } + } + + pub fn select_path(&mut self, path: PathBuf) { + *self.cached_selected.borrow_mut() = None; + if let Some(ref mut items) = self.items_opt { + for item in items.iter_mut() { + item.selected = item.path_opt.as_ref() == Some(&path); } } } @@ -1862,8 +1867,13 @@ impl Tab { Location::Search(path, _term) => path.is_dir(), Location::Trash => true, } { + let prev_path = if let Location::Path(path) = &self.location { + Some(path.clone()) + } else { + None + }; self.change_location(&location, history_i_opt); - commands.push(Command::ChangeLocation(self.title(), location)); + commands.push(Command::ChangeLocation(self.title(), location, prev_path)); } else { log::warn!("tried to cd to {:?} which is not a directory", location); }