summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2022-01-06 18:33:36 -0500
committerDan Davison <dandavison7@gmail.com>2022-01-17 18:30:32 -0500
commite9e9fb7c6975ae9f0a04cf4f14fec4a38c281af1 (patch)
tree71d2dff2ce102caac56c91dc1311b73241b9b11a
parentfb38eddd9a8b6faa079ff8bdac2affc3b7c3f2b3 (diff)
Construct hyperlink file path relative to cwd
Fixes #890
-rw-r--r--src/config.rs2
-rw-r--r--src/features/hyperlinks.rs6
-rw-r--r--src/git_config/git_config_entry.rs2
-rw-r--r--src/handlers/hunk_header.rs8
-rw-r--r--src/options/set.rs9
-rw-r--r--src/utils/cwd.rs25
-rw-r--r--src/utils/mod.rs1
7 files changed, 33 insertions, 20 deletions
diff --git a/src/config.rs b/src/config.rs
index 75bc7488..72fd4710 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -70,6 +70,7 @@ pub struct Config {
pub color_only: bool,
pub commit_regex: Regex,
pub commit_style: Style,
+ pub cwd: Option<PathBuf>,
pub cwd_relative_to_repo_root: Option<String>,
pub decorations_width: cli::Width,
pub default_language: Option<String>,
@@ -254,6 +255,7 @@ impl From<cli::Opt> for Config {
commit_style: styles["commit-style"],
color_only: opt.color_only,
commit_regex,
+ cwd: std::env::current_dir().ok(),
cwd_relative_to_repo_root: std::env::var("GIT_PREFIX").ok(),
decorations_width: opt.computed.decorations_width,
default_language: opt.default_language,
diff --git a/src/features/hyperlinks.rs b/src/features/hyperlinks.rs
index ef85211e..4a2fb8fc 100644
--- a/src/features/hyperlinks.rs
+++ b/src/features/hyperlinks.rs
@@ -7,6 +7,7 @@ use regex::{Captures, Regex};
use crate::config::Config;
use crate::features::OptionValueFunction;
use crate::git_config::{GitConfig, GitConfigEntry, GitRemoteRepo};
+use crate::utils::cwd::cwd_of_user_shell_process;
pub fn make_feature() -> Vec<(String, OptionValueFunction)> {
builtin_feature!([
@@ -60,9 +61,8 @@ pub fn format_osc8_file_hyperlink<'a>(
text: &str,
config: &Config,
) -> Cow<'a, str> {
- if let Some(GitConfigEntry::Path(workdir)) = config.git_config_entries.get("delta.__workdir__")
- {
- let absolute_path = workdir.join(relative_path);
+ if let Some(cwd) = cwd_of_user_shell_process(config) {
+ let absolute_path = cwd.join(relative_path);
let mut url = config
.hyperlinks_file_link_format
.replace("{path}", &absolute_path.to_string_lossy());
diff --git a/src/git_config/git_config_entry.rs b/src/git_config/git_config_entry.rs
index 81787181..2f026cf2 100644
--- a/src/git_config/git_config_entry.rs
+++ b/src/git_config/git_config_entry.rs
@@ -1,4 +1,3 @@
-use std::path::PathBuf;
use std::result::Result;
use std::str::FromStr;
@@ -11,7 +10,6 @@ use crate::errors::*;
pub enum GitConfigEntry {
Style(String),
GitRemote(GitRemoteRepo),
- Path(PathBuf),
}
#[derive(Clone, Debug, PartialEq)]
diff --git a/src/handlers/hunk_header.rs b/src/handlers/hunk_header.rs
index f1d90900..32d0bea5 100644
--- a/src/handlers/hunk_header.rs
+++ b/src/handlers/hunk_header.rs
@@ -316,7 +316,6 @@ fn write_to_output_buffer(
pub mod tests {
use super::*;
use crate::ansi::strip_ansi_codes;
- use crate::git_config::GitConfigEntry;
use crate::tests::integration_test_utils;
#[test]
@@ -410,14 +409,11 @@ pub mod tests {
// returns a hyperlinked file path with line number.
let mut cfg = integration_test_utils::make_config_from_args(&["--features", "hyperlinks"]);
- cfg.git_config_entries.insert(
- "delta.__workdir__".to_string(),
- GitConfigEntry::Path("/some/workdir".into()),
- );
+ cfg.cwd = Some("/some/current/directory".into());
let result = paint_file_path_with_line_number(Some(3), "some-file", &cfg);
- assert_eq!(result, "\u{1b}]8;;file:///some/workdir/some-file\u{1b}\\\u{1b}[34m3\u{1b}[0m\u{1b}]8;;\u{1b}\\");
+ assert_eq!(result, "\u{1b}]8;;file:///some/current/directory/some-file\u{1b}\\\u{1b}[34m3\u{1b}[0m\u{1b}]8;;\u{1b}\\");
}
#[test]
diff --git a/src/options/set.rs b/src/options/set.rs
index e82b9f39..f4806c1b 100644
--- a/src/options/set.rs
+++ b/src/options/set.rs
@@ -668,15 +668,6 @@ fn set_git_config_entries(opt: &mut cli::Opt, git_config: &mut GitConfig) {
.insert(key.to_string(), GitConfigEntry::Style(style_string));
}
}
-
- if let Some(repo) = &git_config.repo {
- if let Some(workdir) = repo.workdir() {
- opt.git_config_entries.insert(
- "delta.__workdir__".to_string(),
- GitConfigEntry::Path(workdir.to_path_buf()),
- );
- }
- }
}
#[cfg(test)]
diff --git a/src/utils/cwd.rs b/src/utils/cwd.rs
new file mode 100644
index 00000000..951c2ead
--- /dev/null
+++ b/src/utils/cwd.rs
@@ -0,0 +1,25 @@
+use std::path::PathBuf;
+
+use crate::config::Config;
+
+/// Return current working directory of the user's shell process. I.e. the directory in which they
+/// are in when delta exits. This is the directory relative to which the file paths in delta output
+/// are constructed if they are using either (a) delta's relative-paths option or (b) git's
+/// --relative flag.
+pub fn cwd_of_user_shell_process(config: &Config) -> Option<PathBuf> {
+ match (&config.cwd, &config.cwd_relative_to_repo_root) {
+ (Some(cwd), None) => {
+ // We are not a child process of git
+ Some(PathBuf::from(cwd))
+ }
+ (Some(repo_root), Some(cwd_relative_to_repo_root)) => {
+ // We are a child process of git; git spawned us from repo_root and preserved the user's
+ // original cwd in the GIT_PREFIX env var (available as config.cwd_relative_to_repo_root)
+ Some(PathBuf::from(repo_root).join(cwd_relative_to_repo_root))
+ }
+ (None, _) => {
+ // Unexpected
+ None
+ }
+ }
+}
diff --git a/src/utils/mod.rs b/src/utils/mod.rs
index 46ea9906..63089531 100644
--- a/src/utils/mod.rs
+++ b/src/utils/mod.rs
@@ -1,5 +1,6 @@
#[cfg(not(tarpaulin_include))]
pub mod bat;
+pub mod cwd;
pub mod process;
pub mod regex_replacement;
pub mod syntect;