@ -127,6 +127,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 `..`.
/// Normalize a path, removing things like `.` and `..`.
///
///
/// CAUTION: This does not resolve symlinks (unlike
/// CAUTION: This does not resolve symlinks (unlike
@ -137,6 +167,7 @@ where
/// needs to improve on.
/// needs to improve on.
/// Copied from cargo: https://github.com/rust-lang/cargo/blob/070e459c2d8b79c5b2ac5218064e7603329c92ae/crates/cargo-util/src/paths.rs#L81
/// 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 {
pub fn normalize_path ( path : & Path ) -> PathBuf {
let path = expand_tilde ( path ) ;
let mut components = path . components ( ) . peekable ( ) ;
let mut components = path . components ( ) . peekable ( ) ;
let mut ret = if let Some ( c @ Component ::Prefix ( .. ) ) = components . peek ( ) . cloned ( ) {
let mut ret = if let Some ( c @ Component ::Prefix ( .. ) ) = components . peek ( ) . cloned ( ) {
components . next ( ) ;
components . next ( ) ;
@ -163,12 +194,17 @@ pub fn normalize_path(path: &Path) -> PathBuf {
ret
ret
}
}
// Returns the canonical, absolute form of a path with all intermediate components normalized.
/ // 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
/ // 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.
/ // here if the path exists, just normalize it's components.
pub fn canonicalize_path ( path : & Path ) -> std ::io ::Result < PathBuf > {
pub fn canonicalize_path ( path : & Path ) -> std ::io ::Result < PathBuf > {
std ::env ::current_dir ( ) . map ( | current_dir | normalize_path ( & current_dir . join ( path ) ) )
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 ;
use helix_lsp ::lsp ;
@ -709,12 +745,19 @@ impl Document {
& self . selections [ & view_id ]
& self . selections [ & view_id ]
}
}
pub fn relative_path ( & self ) -> Option < & Path > {
pub fn relative_path ( & self ) -> Option < Path Buf > {
let cwdir = std ::env ::current_dir ( ) . expect ( "couldn't determine current directory" ) ;
let cwdir = std ::env ::current_dir ( ) . expect ( "couldn't determine current directory" ) ;
self . path
self . path . as_ref ( ) . map ( | path | {
. as_ref ( )
let path = fold_home_dir ( path ) ;
. map ( | path | path . strip_prefix ( cwdir ) . unwrap_or ( 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 {
// pub fn slice<R>(&self, range: R) -> RopeSlice where R: RangeBounds {