diff --git a/local/recipes/tui/tlc/source/src/filemanager/panel.rs b/local/recipes/tui/tlc/source/src/filemanager/panel.rs index 96902a6327..f321063c40 100644 --- a/local/recipes/tui/tlc/source/src/filemanager/panel.rs +++ b/local/recipes/tui/tlc/source/src/filemanager/panel.rs @@ -694,14 +694,23 @@ impl Panel { Ok(p) } - /// Set the panel's path to `p` and re-read the directory. - /// Used by Find/Tree/Hotlist dialogs to navigate the active - /// panel to a chosen location. + /// Set the panel's path to `p` and re-read the directory. Used + /// by Find/Tree/Hotlist dialogs to navigate the active panel to + /// a chosen location. Relative paths are resolved against the + /// current working directory before navigation. pub fn set_path(&mut self, p: &Path) -> Result<()> { - if p == self.path { + let resolved = if p.is_relative() { + match std::env::current_dir() { + Ok(cwd) => cwd.join(p), + Err(_) => p.to_path_buf(), + } + } else { + p.to_path_buf() + }; + if resolved == self.path { return Ok(()); } - self.read_directory(p) + self.read_directory(&resolved) } /// Re-read the current directory. @@ -1103,6 +1112,23 @@ mod tests { let _ = fs::remove_dir_all(&dir); } + #[test] + fn set_path_resolves_relative_against_cwd() { + let dir = std::env::temp_dir().join("tlc-panel-relative-test"); + let sub = dir.join("sub"); + let _ = fs::create_dir_all(&sub); + fs::write(sub.join("x.txt"), b"x").unwrap(); + let mut p = Panel::new(&dir, &empty_cfg()).unwrap(); + // Simulate cwd = dir by chdir; restore on drop. + let prev_cwd = std::env::current_dir().unwrap(); + std::env::set_current_dir(&dir).unwrap(); + let relative = std::path::PathBuf::from("sub"); + p.set_path(&relative).unwrap(); + assert_eq!(p.path(), sub.canonicalize().unwrap_or(sub)); + std::env::set_current_dir(&prev_cwd).unwrap(); + let _ = fs::remove_dir_all(&dir); + } + #[test] fn cursor_movement() { let dir = std::env::temp_dir().join("tlc-panel-cursor-test");