diff --git a/CHANGELOG.md b/CHANGELOG.md index e9816f97..50e5a8b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - removed unmaintained dependency `spin` ([#172](https://github.com/extrawurst/gitui/issues/172)) +- fix opening relative paths in external editor ([#184](https://github.com/extrawurst/gitui/issues/184)) ## [0.8.1] - 2020-07-07 diff --git a/asyncgit/src/sync/utils.rs b/asyncgit/src/sync/utils.rs index 6292a2a8..0b847a65 100644 --- a/asyncgit/src/sync/utils.rs +++ b/asyncgit/src/sync/utils.rs @@ -28,7 +28,7 @@ pub fn is_bare_repo(repo_path: &str) -> Result { } /// -pub fn repo(repo_path: &str) -> Result { +pub(crate) fn repo(repo_path: &str) -> Result { let repo = Repository::open_ext( repo_path, RepositoryOpenFlags::empty(), @@ -43,10 +43,20 @@ pub fn repo(repo_path: &str) -> Result { } /// -pub fn work_dir(repo: &Repository) -> &Path { +pub(crate) fn work_dir(repo: &Repository) -> &Path { repo.workdir().expect("unable to query workdir") } +/// +pub fn repo_work_dir(repo_path: &str) -> Result { + let repo = repo(repo_path)?; + if let Some(workdir) = work_dir(&repo).to_str() { + Ok(workdir.to_string()) + } else { + Err(Error::Generic("invalid workdir".to_string())) + } +} + /// pub fn get_head(repo_path: &str) -> Result { let repo = repo(repo_path)?; diff --git a/src/components/externaleditor.rs b/src/components/externaleditor.rs index f580acd4..f0027035 100644 --- a/src/components/externaleditor.rs +++ b/src/components/externaleditor.rs @@ -7,6 +7,7 @@ use crate::{ ui::{self, style::SharedTheme}, }; use anyhow::{anyhow, Result}; +use asyncgit::{sync::utils::repo_work_dir, CWD}; use crossterm::{ event::Event, terminal::{EnterAlternateScreen, LeaveAlternateScreen}, @@ -38,6 +39,14 @@ impl ExternalEditorComponent { /// opens file at given `path` in an available editor pub fn open_file_in_editor(path: &Path) -> Result<()> { + let work_dir = repo_work_dir(CWD)?; + + let path = if path.is_relative() { + Path::new(&work_dir).join(path) + } else { + path.into() + }; + if !path.exists() { return Err(anyhow!("file not found: {:?}", path)); } @@ -52,6 +61,11 @@ impl ExternalEditorComponent { .or_else(|| env::var("VISUAL").ok()) .or_else(|| env::var("EDITOR").ok()) .unwrap_or_else(|| String::from("vi")); + + //TODO: check the path.to_str result and return err on None because + //otherwise this will pretty likely fail in the command stage otherwise + //and https://github.com/extrawurst/gitui/issues/184 showed how weird + //'vi' handles opening not existing files editor.push_str(&format!(" {}", path.to_string_lossy())); let mut editor = editor.split_whitespace(); @@ -61,6 +75,7 @@ impl ExternalEditorComponent { })?; Command::new(command) + .current_dir(work_dir) .args(editor) .status() .map_err(|e| anyhow!("\"{}\": {}", command, e))?;