Skip to content

Commit

Permalink
fix: don't crash if env::current_dir fails
Browse files Browse the repository at this point in the history
Rather than crashing if the current working
directory is not found, this commit ensures
helix will manage those cases nicely. Either by
relying on the absolute path of a file instead of
its relative one, displaying an appropriate
error message or using Path default value
  • Loading branch information
yo-main committed Jun 14, 2023
1 parent df09490 commit ba6ddc4
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 31 deletions.
8 changes: 3 additions & 5 deletions helix-core/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,20 +96,18 @@ pub fn get_canonicalized_path(path: &Path) -> std::io::Result<PathBuf> {
Ok(get_normalized_path(path.as_path()))
}

pub fn get_relative_path(path: &Path) -> PathBuf {
pub fn get_relative_path(path: &Path) -> std::io::Result<PathBuf> {
let path = PathBuf::from(path);
let path = if path.is_absolute() {
let cwdir = std::env::current_dir()
.map(|path| get_normalized_path(&path))
.expect("couldn't determine current directory");
let cwdir = std::env::current_dir().map(|path| get_normalized_path(&path))?;
get_normalized_path(&path)
.strip_prefix(cwdir)
.map(PathBuf::from)
.unwrap_or(path)
} else {
path
};
fold_home_dir(&path)
Ok(fold_home_dir(&path))
}

/// Returns a truncated filepath where the basepart of the path is reduced to the first
Expand Down
2 changes: 1 addition & 1 deletion helix-loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ pub fn merge_toml_values(left: toml::Value, right: toml::Value, merge_depth: usi
/// If no workspace was found returns (CWD, true).
/// Otherwise (workspace, false) is returned
pub fn find_workspace() -> (PathBuf, bool) {
let current_dir = std::env::current_dir().expect("unable to determine current directory");
let current_dir = std::env::current_dir().unwrap_or_default();
for ancestor in current_dir.ancestors() {
if ancestor.join(".git").exists() || ancestor.join(".helix").exists() {
return (ancestor.to_owned(), false);
Expand Down
4 changes: 3 additions & 1 deletion helix-term/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,9 +585,11 @@ impl Application {
}

// TODO: fix being overwritten by lsp
let path =
get_relative_path(&doc_save_event.path).unwrap_or_else(|_| doc_save_event.path.into());
self.editor.set_status(format!(
"'{}' written, {}L {}B",
get_relative_path(&doc_save_event.path).to_string_lossy(),
path.to_string_lossy(),
lines,
bytes
));
Expand Down
52 changes: 31 additions & 21 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2032,6 +2032,7 @@ fn global_search(cx: &mut Context) {

fn format(&self, current_path: &Self::Data) -> Row {
let relative_path = helix_core::path::get_relative_path(&self.path)
.unwrap_or_else(|_| self.path.to_owned())
.to_string_lossy()
.into_owned();
if current_path
Expand Down Expand Up @@ -2065,7 +2066,7 @@ fn global_search(cx: &mut Context) {
.map(|comp| (0.., std::borrow::Cow::Owned(comp.clone())))
.collect()
},
move |_editor, regex, event| {
move |editor, regex, event| {
if event != PromptEvent::Validate {
return;
}
Expand All @@ -2078,8 +2079,13 @@ fn global_search(cx: &mut Context) {
.binary_detection(BinaryDetection::quit(b'\x00'))
.build();

let search_root = std::env::current_dir()
.expect("Global search error: Failed to get current dir");
let search_root = match std::env::current_dir() {
Ok(cwd) => cwd,
Err(err) => {
editor.set_error(format!("Global search error: {err}"));
return;
}
};
let dedup_symlinks = file_picker_config.deduplicate_links;
let absolute_root = search_root
.canonicalize()
Expand Down Expand Up @@ -2151,7 +2157,9 @@ fn global_search(cx: &mut Context) {
let call: job::Callback = Callback::EditorCompositor(Box::new(
move |editor: &mut Editor, compositor: &mut Compositor| {
if all_matches.is_empty() {
editor.set_status("No matches found");
if !editor.is_err() {
editor.set_status("No matches found");
}
return;
}

Expand Down Expand Up @@ -2539,14 +2547,15 @@ fn buffer_picker(cx: &mut Context) {
type Data = ();

fn format(&self, _data: &Self::Data) -> Row {
let path = self
.path
.as_deref()
.map(helix_core::path::get_relative_path);
let path = match path.as_deref().and_then(Path::to_str) {
Some(path) => path,
None => SCRATCH_BUFFER_NAME,
};
let path = self.path.as_deref().map_or_else(
|| SCRATCH_BUFFER_NAME.to_owned(),
|path| {
helix_core::path::get_relative_path(&path)
.unwrap_or(path.into())
.to_string_lossy()
.into_owned()
},
);

let mut flags = String::new();
if self.is_modified {
Expand All @@ -2556,7 +2565,7 @@ fn buffer_picker(cx: &mut Context) {
flags.push('*');
}

Row::new([self.id.to_string(), flags, path.to_string()])
Row::new([self.id.to_string(), flags, path])
}
}

Expand Down Expand Up @@ -2610,14 +2619,15 @@ fn jumplist_picker(cx: &mut Context) {
type Data = ();

fn format(&self, _data: &Self::Data) -> Row {
let path = self
.path
.as_deref()
.map(helix_core::path::get_relative_path);
let path = match path.as_deref().and_then(Path::to_str) {
Some(path) => path,
None => SCRATCH_BUFFER_NAME,
};
let path = self.path.as_deref().map_or_else(
|| SCRATCH_BUFFER_NAME.to_owned(),
|path| {
helix_core::path::get_relative_path(&path)
.unwrap_or(path.into())
.to_string_lossy()
.into_owned()
},
);

let mut flags = Vec::new();
if self.is_current {
Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/commands/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl ui::menu::Item for SymbolInformationItem {
} else {
match self.symbol.location.uri.to_file_path() {
Ok(path) => {
let get_relative_path = path::get_relative_path(path.as_path());
let get_relative_path = path::get_relative_path(path.as_path()).unwrap_or(path);
format!(
"{} ({})",
&self.symbol.name,
Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ pub mod completers {
match path.parent() {
Some(path) if !path.as_os_str().is_empty() => path.to_path_buf(),
// Path::new("h")'s parent is Some("")...
_ => std::env::current_dir().expect("couldn't determine current directory"),
_ => std::env::current_dir().unwrap_or_default(),
}
};

Expand Down
4 changes: 3 additions & 1 deletion helix-view/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1546,10 +1546,12 @@ impl Document {
&self.selections
}

// Get the relative path of the document.
// Returns its absolute path in case the relative one could not be computed
pub fn relative_path(&self) -> Option<PathBuf> {
self.path
.as_deref()
.map(helix_core::path::get_relative_path)
.map(|path| helix_core::path::get_relative_path(path).unwrap_or_else(|_| path.into()))
}

pub fn display_name(&self) -> Cow<'static, str> {
Expand Down

0 comments on commit ba6ddc4

Please sign in to comment.