-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix expansion of ~
#284
Fix expansion of ~
#284
Changes from all commits
271bb19
0087e96
7353ade
1fcfa88
a45027a
d8b97ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,6 +102,36 @@ where | |
} | ||
} | ||
|
||
/// Expands tilde `~` into users home directory if avilable, otherwise returns the path | ||
/// unchanged. The tilde will only be expanded when present as the first component of the path | ||
/// and only slash follows it. | ||
pub fn expand_tilde(path: &Path) -> PathBuf { | ||
let mut components = path.components().peekable(); | ||
if let Some(Component::Normal(c)) = components.peek() { | ||
if c == &"~" { | ||
if let Ok(home) = helix_core::home_dir() { | ||
// it's ok to unwrap, the path starts with `~` | ||
return home.join(path.strip_prefix("~").unwrap()); | ||
} | ||
} | ||
} | ||
|
||
path.to_path_buf() | ||
} | ||
|
||
/// Replaces users home directory from `path` with tilde `~` if the directory | ||
/// is available, otherwise returns the path unchanged. | ||
pub fn fold_home_dir(path: &Path) -> PathBuf { | ||
if let Ok(home) = helix_core::home_dir() { | ||
if path.starts_with(&home) { | ||
// it's ok to unwrap, the path starts with home dir | ||
return PathBuf::from("~").join(path.strip_prefix(&home).unwrap()); | ||
} | ||
} | ||
|
||
path.to_path_buf() | ||
} | ||
|
||
/// Normalize a path, removing things like `.` and `..`. | ||
/// | ||
/// CAUTION: This does not resolve symlinks (unlike | ||
|
@@ -112,6 +142,7 @@ where | |
/// needs to improve on. | ||
/// Copied from cargo: https://github.com/rust-lang/cargo/blob/070e459c2d8b79c5b2ac5218064e7603329c92ae/crates/cargo-util/src/paths.rs#L81 | ||
pub fn normalize_path(path: &Path) -> PathBuf { | ||
let path = expand_tilde(path); | ||
let mut components = path.components().peekable(); | ||
let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() { | ||
components.next(); | ||
|
@@ -138,12 +169,17 @@ pub fn normalize_path(path: &Path) -> PathBuf { | |
ret | ||
} | ||
|
||
// Returns the canonical, absolute form of a path with all intermediate components normalized. | ||
// | ||
// This function is used instead of `std::fs::canonicalize` because we don't want to verify | ||
// here if the path exists, just normalize it's components. | ||
/// Returns the canonical, absolute form of a path with all intermediate components normalized. | ||
/// | ||
/// This function is used instead of `std::fs::canonicalize` because we don't want to verify | ||
/// here if the path exists, just normalize it's components. | ||
pub fn canonicalize_path(path: &Path) -> std::io::Result<PathBuf> { | ||
std::env::current_dir().map(|current_dir| normalize_path(¤t_dir.join(path))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You still want this because paths need to be converted to absolute. Not taking There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tilde expansion should be a step before normalization: https://github.com/netvl/shellexpand/blob/e707d07a0a2638df7ab26b152f814e80ce3b3992/src/lib.rs#L665-L690 |
||
let normalized = normalize_path(path); | ||
if normalized.is_absolute() { | ||
Ok(normalized) | ||
} else { | ||
std::env::current_dir().map(|current_dir| current_dir.join(normalized)) | ||
} | ||
} | ||
|
||
use helix_lsp::lsp; | ||
|
@@ -684,12 +720,19 @@ impl Document { | |
&self.selections[&view_id] | ||
} | ||
|
||
pub fn relative_path(&self) -> Option<&Path> { | ||
pub fn relative_path(&self) -> Option<PathBuf> { | ||
let cwdir = std::env::current_dir().expect("couldn't determine current directory"); | ||
|
||
self.path | ||
.as_ref() | ||
.map(|path| path.strip_prefix(cwdir).unwrap_or(path)) | ||
self.path.as_ref().map(|path| { | ||
let path = fold_home_dir(path); | ||
if path.is_relative() { | ||
path | ||
} else { | ||
path.strip_prefix(cwdir) | ||
.map(|p| p.to_path_buf()) | ||
.unwrap_or(path) | ||
} | ||
}) | ||
} | ||
|
||
// pub fn slice<R>(&self, range: R) -> RopeSlice where R: RangeBounds { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for
to_string()
here, it's already aCow
I think.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunatelly:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a consequence of changing the return type of
relative_path
to be ownedPathBuf
not&Path
but I'm not sure I can return a&Path
while still folding home directory into tilde.