Skip to content
Open
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
29 changes: 25 additions & 4 deletions src/commands/cd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,40 @@

use std::{env, path::Path};

fn get_home() -> Option<std::path::PathBuf> {
env::var("HOME").ok().map(std::path::PathBuf::from)
}

pub fn command(args: &[&str]) -> Result<(), String> {
if args.len() != 1 {
return Err("Usage: cd <directory>".to_string());
}
let target = args[0];
let target_path = match target {
"." => env::current_dir().map_err(|e| format!("Unable to get current directory: {}", e))?,
"~" => {
// Single ~ means home directory.
get_home().ok_or_else(|| "Unable to determine home directory".to_string())?
}
path if path.starts_with("~/") => {
let home =
get_home().ok_or_else(|| "Unable to determine home directory".to_string())?;
let rest = &path[2..];
home.join(rest)
}
path => {
let current_dir = env::current_dir()
.map_err(|e| format!("Unable to get current directory: {}", e))?;
let mut path_buf = current_dir;
for component in Path::new(path).components() {
let path_obj = Path::new(path);
let mut path_buf = if path_obj.is_absolute() {
std::path::PathBuf::new()
} else {
env::current_dir().map_err(|e| format!("Unable to get current directory: {}", e))?
};

for component in path_obj.components() {
match component {
std::path::Component::RootDir => {
path_buf.push("/");
}
std::path::Component::ParentDir => {
if !path_buf.pop() {
return Err("Already at root directory".to_string());
Expand Down