diff options
Diffstat (limited to 'src/handlers')
-rw-r--r-- | src/handlers/diff_header.rs | 105 | ||||
-rw-r--r-- | src/handlers/hunk_header.rs | 24 |
2 files changed, 61 insertions, 68 deletions
diff --git a/src/handlers/diff_header.rs b/src/handlers/diff_header.rs index e3b29a34..4b82bec4 100644 --- a/src/handlers/diff_header.rs +++ b/src/handlers/diff_header.rs @@ -6,8 +6,8 @@ use unicode_segmentation::UnicodeSegmentation; use super::draw; use crate::config::Config; use crate::delta::{DiffType, Source, State, StateMachine}; -use crate::features; use crate::paint::Painter; +use crate::{features, utils}; // https://git-scm.com/docs/git-config#Documentation/git-config.txt-diffmnemonicPrefix const DIFF_PREFIXES: [&str; 6] = ["a/", "b/", "c/", "i/", "o/", "w/"]; @@ -64,16 +64,12 @@ impl<'a> StateMachine<'a> { } let mut handled_line = false; - let (path_or_mode, file_event) = parse_diff_header_line( - &self.line, - self.source == Source::GitDiff, - if self.config.relative_paths { - self.config.cwd_relative_to_repo_root.as_deref() - } else { - None - }, - ); - self.minus_file = path_or_mode; + let (path_or_mode, file_event) = + parse_diff_header_line(&self.line, self.source == Source::GitDiff); + + self.minus_file = utils::path::relativize_path_maybe(&path_or_mode, self.config) + .map(|p| p.to_string_lossy().to_owned().to_string()) + .unwrap_or(path_or_mode); self.minus_file_event = file_event; if self.source == Source::DiffUnified { @@ -118,16 +114,12 @@ impl<'a> StateMachine<'a> { return Ok(false); } let mut handled_line = false; - let (path_or_mode, file_event) = parse_diff_header_line( - &self.line, - self.source == Source::GitDiff, - if self.config.relative_paths { - self.config.cwd_relative_to_repo_root.as_deref() - } else { - None - }, - ); - self.plus_file = path_or_mode; + let (path_or_mode, file_event) = + parse_diff_header_line(&self.line, self.source == Source::GitDiff); + + self.plus_file = utils::path::relativize_path_maybe(&path_or_mode, self.config) + .map(|p| p.to_string_lossy().to_owned().to_string()) + .unwrap_or(path_or_mode); self.plus_file_event = file_event; self.painter .set_syntax(get_file_extension_from_diff_header_line_file_path( @@ -187,12 +179,17 @@ impl<'a> StateMachine<'a> { "".to_string() } }; - let format_file = |file| { - if self.config.hyperlinks { - features::hyperlinks::format_osc8_file_hyperlink(file, None, file, self.config) - } else { - Cow::from(file) - } + let format_file = |file| match ( + self.config.hyperlinks, + utils::path::absolute_path(file, self.config), + ) { + (true, Some(absolute_path)) => features::hyperlinks::format_osc8_file_hyperlink( + absolute_path, + None, + file, + self.config, + ), + _ => Cow::from(file), }; let label = format_label(&self.config.file_modified_label); let name = get_repeated_file_path_from_diff_line(&self.diff_line) @@ -274,12 +271,8 @@ pub fn get_extension(s: &str) -> Option<&str> { .or_else(|| path.file_name().and_then(|s| s.to_str())) } -fn parse_diff_header_line( - line: &str, - git_diff_name: bool, - relative_path_base: Option<&str>, -) -> (String, FileEvent) { - let (mut path_or_mode, file_event) = match line { +fn parse_diff_header_line(line: &str, git_diff_name: bool) -> (String, FileEvent) { + match line { line if line.starts_with("--- ") || line.starts_with("+++ ") => { let offset = 4; let file = _parse_file_path(&line[offset..], git_diff_name); @@ -298,17 +291,7 @@ fn parse_diff_header_line( (line[8..].to_string(), FileEvent::Copy) // "copy to ".len() } _ => ("".to_string(), FileEvent::NoEvent), - }; - - if let Some(base) = relative_path_base { - if let Some(relative_path) = pathdiff::diff_paths(&path_or_mode, base) { - if let Some(relative_path) = relative_path.to_str() { - path_or_mode = relative_path.to_owned(); - } - } } - - (path_or_mode, file_event) } /// Given input like "diff --git a/src/my file.rs b/src/my file.rs" @@ -369,12 +352,12 @@ pub fn get_file_change_description_from_file_paths( plus_file ) } else { - let format_file = |file| { - if config.hyperlinks { - features::hyperlinks::format_osc8_file_hyperlink(file, None, file, config) - } else { - Cow::from(file) + let format_file = |file| match (config.hyperlinks, utils::path::absolute_path(file, config)) + { + (true, Some(absolute_path)) => { + features::hyperlinks::format_osc8_file_hyperlink(absolute_path, None, file, config) } + _ => Cow::from(file), }; match (minus_file, plus_file, minus_file_event, plus_file_event) { (minus_file, plus_file, _, _) if minus_file == plus_file => format!( @@ -479,21 +462,21 @@ mod tests { #[test] fn test_get_file_path_from_git_diff_header_line() { assert_eq!( - parse_diff_header_line("--- /dev/null", true, None), + parse_diff_header_line("--- /dev/null", true), ("/dev/null".to_string(), FileEvent::Change) ); for prefix in &DIFF_PREFIXES { assert_eq!( - parse_diff_header_line(&format!("--- {}src/delta.rs", prefix), true, None), + parse_diff_header_line(&format!("--- {}src/delta.rs", prefix), true), ("src/delta.rs".to_string(), FileEvent::Change) ); } assert_eq!( - parse_diff_header_line("--- src/delta.rs", true, None), + parse_diff_header_line("--- src/delta.rs", true), ("src/delta.rs".to_string(), FileEvent::Change) ); assert_eq!( - parse_diff_header_line("+++ src/delta.rs", true, None), + parse_diff_header_line("+++ src/delta.rs", true), ("src/delta.rs".to_string(), FileEvent::Change) ); } @@ -501,23 +484,23 @@ mod tests { #[test] fn test_get_file_path_from_git_diff_header_line_containing_spaces() { assert_eq!( - parse_diff_header_line("+++ a/my src/delta.rs", true, None), + parse_diff_header_line("+++ a/my src/delta.rs", true), ("my src/delta.rs".to_string(), FileEvent::Change) ); assert_eq!( - parse_diff_header_line("+++ my src/delta.rs", true, None), + parse_diff_header_line("+++ my src/delta.rs", true), ("my src/delta.rs".to_string(), FileEvent::Change) ); assert_eq!( - parse_diff_header_line("+++ a/src/my delta.rs", true, None), + parse_diff_header_line("+++ a/src/my delta.rs", true), ("src/my delta.rs".to_string(), FileEvent::Change) ); assert_eq!( - parse_diff_header_line("+++ a/my src/my delta.rs", true, None), + parse_diff_header_line("+++ a/my src/my delta.rs", true), ("my src/my delta.rs".to_string(), FileEvent::Change) ); assert_eq!( - parse_diff_header_line("+++ b/my src/my enough/my delta.rs", true, None), + parse_diff_header_line("+++ b/my src/my enough/my delta.rs", true), ( "my src/my enough/my delta.rs".to_string(), FileEvent::Change @@ -528,7 +511,7 @@ mod tests { #[test] fn test_get_file_path_from_git_diff_header_line_rename() { assert_eq!( - parse_diff_header_line("rename from nospace/file2.el", true, None), + parse_diff_header_line("rename from nospace/file2.el", true), ("nospace/file2.el".to_string(), FileEvent::Rename) ); } @@ -536,7 +519,7 @@ mod tests { #[test] fn test_get_file_path_from_git_diff_header_line_rename_containing_spaces() { assert_eq!( - parse_diff_header_line("rename from with space/file1.el", true, None), + parse_diff_header_line("rename from with space/file1.el", true), ("with space/file1.el".to_string(), FileEvent::Rename) ); } @@ -544,11 +527,11 @@ mod tests { #[test] fn test_parse_diff_header_line() { assert_eq!( - parse_diff_header_line("--- src/delta.rs", false, None), + parse_diff_header_line("--- src/delta.rs", false), ("src/delta.rs".to_string(), FileEvent::Change) ); assert_eq!( - parse_diff_header_line("+++ src/delta.rs", false, None), + parse_diff_header_line("+++ src/delta.rs", false), ("src/delta.rs".to_string(), FileEvent::Change) ); } diff --git a/src/handlers/hunk_header.rs b/src/handlers/hunk_header.rs index b52ba5b4..7a9e2a1c 100644 --- a/src/handlers/hunk_header.rs +++ b/src/handlers/hunk_header.rs @@ -399,8 +399,11 @@ pub mod tests { } #[test] - #[cfg(not(target_os = "windows"))] fn test_paint_file_path_with_line_number_hyperlinks() { + use std::{iter::FromIterator, path::PathBuf}; + + use crate::utils; + // hunk-header-style (by default) includes 'line-number' but not 'file'. // Normally, `paint_file_path_with_line_number` would return a painted line number. // But in this test hyperlinks are activated, and the test ensures that delta.__workdir__ is @@ -408,14 +411,21 @@ pub mod tests { // This test confirms that, under those circumstances, `paint_file_path_with_line_number` // returns a hyperlinked file path with line number. - let mut config = - integration_test_utils::make_config_from_args(&["--features", "hyperlinks"]); - config.cwd_of_user_shell_process = - Some(std::path::PathBuf::from("/some/current/directory")); + let config = integration_test_utils::make_config_from_args(&["--features", "hyperlinks"]); + let relative_path = PathBuf::from_iter(["some-dir", "some-file"]); - let result = paint_file_path_with_line_number(Some(3), "some-file", &config); + let result = + paint_file_path_with_line_number(Some(3), &relative_path.to_string_lossy(), &config); - 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}\\"); + assert_eq!( + result, + format!( + "\u{1b}]8;;file://{}\u{1b}\\\u{1b}[34m3\u{1b}[0m\u{1b}]8;;\u{1b}\\", + utils::path::fake_delta_cwd_for_tests() + .join(relative_path) + .to_string_lossy() + ) + ); } #[test] |