Adding ~user tilde recognition in file paths (#5251)

* Added search terms to math commands

* Attempts to add ~user.

From: // Extend this to work with "~user" style of home paths

* Clippy recommendation

* clippy suggestions, again.

* fixing non-compilation on windows and macos

* fmt apparently does not like my imports

* even more clippy issues.

* less expect(), single conversion, match. Should work for MacOS too.

* Attempted to add functionality for windows: all it does is take the home path of current user, and replace the username.

* silly mistake in Windows version of user_home_dir()

* Update tilde.rs

* user_home_dir now returns a path instead of a string - should be smoother with no conversions to string

* clippy warnings

* clippy warnings 2

* Changed user_home_dir to return PathBuf now.

* Changed user_home_dir to return PathBuf now.

* forgot to fmt

* fixed windows build errors from modifying pathbuf but not returning it

* fixed windows clippy errors from returning () instead of pathbuf

* forgot to fmt

* borrowed path did not live long enough.

* previously, path.push did not work because rest_of_path started with "/" - it was not relative. Removing the / makes it a relative path again.

* Issue fixed.

* Update tilde.rs

* fmt.

* There is now a zero chance of panic. All expect()s have been removed.
This commit is contained in:
merelymyself
2022-04-25 06:12:57 +08:00
committed by GitHub
parent 9771270b38
commit b38f90d4c7
3 changed files with 154 additions and 1 deletions

View File

@ -9,3 +9,6 @@ version = "0.61.1"
[dependencies]
dirs-next = "2.0.0"
dunce = "1.0.1"
[target.'cfg(target_os = "linux")'.dependencies]
pwd = "1.3.1"

View File

@ -1,10 +1,17 @@
#[cfg(target_os = "linux")]
use pwd::Passwd;
use std::path::{Path, PathBuf};
fn expand_tilde_with_home(path: impl AsRef<Path>, home: Option<PathBuf>) -> PathBuf {
let path = path.as_ref();
if !path.starts_with("~") {
return path.into();
let string = path.to_string_lossy();
let mut path_as_string = string.as_ref().chars();
return match path_as_string.next() {
Some('~') => expand_tilde_with_another_user_home(path),
_ => path.into(),
};
}
match home {
@ -31,6 +38,104 @@ fn expand_tilde_with_home(path: impl AsRef<Path>, home: Option<PathBuf>) -> Path
}
}
#[cfg(target_os = "linux")]
fn user_home_dir(username: &str) -> PathBuf {
let passwd = Passwd::from_name(username);
match &passwd.ok() {
Some(Some(dir)) => PathBuf::from(&dir.dir),
_ => {
let mut file = String::from("/home/");
file.push_str(username);
PathBuf::from(file)
}
}
// PathBuf::from(concat!("/home/", username)),
// Returns home dir of user.
}
#[cfg(target_os = "macos")]
fn user_home_dir(username: &str) -> PathBuf {
match dirs_next::home_dir() {
None => {
let mut expected_path = String::from("/Users/");
expected_path.push_str(username);
let path = Path::new(&expected_path);
let mut home = PathBuf::new();
home.push(path);
home
}
Some(user) => {
let mut expected_path = user;
expected_path.pop();
expected_path.push(Path::new(username));
if expected_path.is_dir() {
expected_path
} else {
let mut expected_path_as_string = String::from("/Users/");
expected_path_as_string.push_str(username);
let path = Path::new(&expected_path_as_string);
let mut home = PathBuf::new();
home.push(path);
home
}
}
}
}
#[cfg(target_os = "windows")]
fn user_home_dir(username: &str) -> PathBuf {
match dirs_next::home_dir() {
None => {
let mut expected_path = String::from("C:\\Users\\");
expected_path.push_str(username);
let path = Path::new(&expected_path);
let mut home = PathBuf::new();
home.push(path);
home
}
Some(user) => {
let mut expected_path = user;
expected_path.pop();
expected_path.push(Path::new(username));
if expected_path.is_dir() {
expected_path
} else {
let mut expected_path_as_string = String::from("C:\\Users\\");
expected_path_as_string.push_str(username);
let path = Path::new(&expected_path_as_string);
let mut home = PathBuf::new();
home.push(path);
home
}
}
}
}
fn expand_tilde_with_another_user_home(path: &Path) -> PathBuf {
return match path.to_str() {
Some(file_path) => {
let mut file = file_path.to_string();
match file_path.chars().position(|c| c == '/' || c == '\\') {
None => {
file.remove(0);
user_home_dir(&file)
}
Some(i) => {
let (pre_name, rest_of_path) = file.split_at(i);
let mut name = pre_name.to_string();
let mut rest_path = rest_of_path.to_string();
rest_path.remove(0);
name.remove(0);
let mut path = user_home_dir(&name);
path.push(Path::new(&rest_path));
path
}
}
}
None => path.to_path_buf(),
};
}
/// Expand tilde ("~") into a home directory if it is the first path component
pub fn expand_tilde(path: impl AsRef<Path>) -> PathBuf {
// TODO: Extend this to work with "~user" style of home paths