summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Otto <th1000s@posteo.net>2024-05-04 15:44:39 +0200
committerGitHub <noreply@github.com>2024-05-04 09:44:39 -0400
commit3b953daac79e050ffd72c41d208e81e853f9206c (patch)
tree5b5ed17e2db079033fcfbb9ede42767c47a5ebc1
parent3c6c50e4f5a515f17240a8205e2e6941809dcdff (diff)
Repair --default-language, and highlight using full filename (#1549)
* Fix clippy warnings * Repair --default-language, and highlight using full filename Fixed that the "txt" fallback was used instead of --default-language And when looking for syntax highlighting, keep the filename around as long as possible. Using simple custom logic (filename > 4) a Makefile can be highlighted with make syntax, but a 'cc' or 'ini' file does not get treated like a *.cc or *.ini file. Currently the underlying highlighting lib syntect and the sublime syntax definitions can not make this distinction (<http://www.sublimetext.com/docs/syntax.html>).
-rw-r--r--src/cli.rs8
-rw-r--r--src/config.rs5
-rw-r--r--src/handlers/blame.rs10
-rw-r--r--src/handlers/diff_header.rs73
-rw-r--r--src/handlers/git_show_file.rs4
-rw-r--r--src/handlers/grep.rs8
-rw-r--r--src/options/get.rs2
-rw-r--r--src/options/set.rs2
-rw-r--r--src/paint.rs49
-rw-r--r--src/subcommands/show_colors.rs2
-rw-r--r--src/tests/ansi_test_utils.rs12
-rw-r--r--src/tests/test_example_diffs.rs58
-rw-r--r--src/utils/process.rs141
-rw-r--r--src/wrapping.rs2
14 files changed, 208 insertions, 168 deletions
diff --git a/src/cli.rs b/src/cli.rs
index 4cddd6fb..723ea42c 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -287,12 +287,12 @@ pub struct Opt {
/// For more control, see the style options and --syntax-theme.
pub dark: bool,
- #[arg(long = "default-language", value_name = "LANG")]
+ #[arg(long = "default-language", value_name = "LANG", default_value = "txt")]
/// Default language used for syntax highlighting.
///
- /// Used when the language cannot be inferred from a filename. It will typically make sense to
- /// set this in per-repository git config (.git/config)
- pub default_language: Option<String>,
+ /// Used as a fallback when the language cannot be inferred from a filename. It will
+ /// typically make sense to set this in the per-repository config file '.git/config'.
+ pub default_language: String,
/// Detect whether or not the terminal is dark or light by querying for its colors.
///
diff --git a/src/config.rs b/src/config.rs
index 7d3d442d..76789289 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -31,6 +31,9 @@ use crate::wrapping::WrapConfig;
pub const INLINE_SYMBOL_WIDTH_1: usize = 1;
+// Used if an invalid default-language was specified.
+pub const SYNTAX_FALLBACK_LANG: &str = "txt";
+
#[cfg_attr(test, derive(Clone))]
pub struct Config {
pub available_terminal_width: usize,
@@ -49,7 +52,7 @@ pub struct Config {
pub cwd_of_user_shell_process: Option<PathBuf>,
pub cwd_relative_to_repo_root: Option<String>,
pub decorations_width: cli::Width,
- pub default_language: Option<String>,
+ pub default_language: String,
pub diff_stat_align_width: usize,
pub error_exit_code: i32,
pub file_added_label: String,
diff --git a/src/handlers/blame.rs b/src/handlers/blame.rs
index e8c2e435..fc3d6d1c 100644
--- a/src/handlers/blame.rs
+++ b/src/handlers/blame.rs
@@ -77,13 +77,9 @@ impl<'a> StateMachine<'a> {
// Emit syntax-highlighted code
if matches!(self.state, State::Unknown) {
- if let Some(lang) = utils::process::git_blame_filename_extension()
- .as_ref()
- .or(self.config.default_language.as_ref())
- {
- self.painter.set_syntax(Some(lang));
- self.painter.set_highlighter();
- }
+ self.painter
+ .set_syntax(utils::process::git_blame_filename().as_deref());
+ self.painter.set_highlighter();
}
self.state = State::Blame(key);
self.painter.syntax_highlight_and_paint_line(
diff --git a/src/handlers/diff_header.rs b/src/handlers/diff_header.rs
index 3c71a61a..11b8b8e1 100644
--- a/src/handlers/diff_header.rs
+++ b/src/handlers/diff_header.rs
@@ -95,10 +95,10 @@ impl<'a> StateMachine<'a> {
if self.source == Source::DiffUnified {
self.state = State::DiffHeader(DiffType::Unified);
self.painter
- .set_syntax(get_file_extension_from_marker_line(&self.line));
+ .set_syntax(get_filename_from_marker_line(&self.line));
} else {
self.painter
- .set_syntax(get_file_extension_from_diff_header_line_file_path(
+ .set_syntax(get_filename_from_diff_header_line_file_path(
&self.minus_file,
));
}
@@ -129,7 +129,7 @@ impl<'a> StateMachine<'a> {
.unwrap_or(path_or_mode);
self.plus_file_event = file_event;
self.painter
- .set_syntax(get_file_extension_from_diff_header_line_file_path(
+ .set_syntax(get_filename_from_diff_header_line_file_path(
&self.plus_file,
));
self.current_file_pair = Some((self.minus_file.clone(), self.plus_file.clone()));
@@ -300,30 +300,23 @@ pub fn write_generic_diff_header_header_line(
#[allow(clippy::tabs_in_doc_comments)]
/// Given input like
-/// "--- one.rs 2019-11-20 06:16:08.000000000 +0100"
-/// Return "rs"
-fn get_file_extension_from_marker_line(line: &str) -> Option<&str> {
+/// "--- a/zero/one.rs 2019-11-20 06:16:08.000000000 +0100"
+/// Return "one.rs"
+fn get_filename_from_marker_line(line: &str) -> Option<&str> {
line.split('\t')
.next()
.and_then(|column| column.split(' ').nth(1))
- .and_then(|file| file.split('.').last())
+ .and_then(get_filename_from_diff_header_line_file_path)
}
-fn get_file_extension_from_diff_header_line_file_path(path: &str) -> Option<&str> {
- if path.is_empty() || path == "/dev/null" {
- None
- } else {
- get_extension(path).map(|ex| ex.trim())
- }
-}
-
-/// Attempt to parse input as a file path and return extension as a &str.
-pub fn get_extension(s: &str) -> Option<&str> {
- let path = Path::new(s);
- path.extension()
- .and_then(|e| e.to_str())
- // E.g. 'Makefile' is the file name and also the extension
- .or_else(|| path.file_name().and_then(|s| s.to_str()))
+fn get_filename_from_diff_header_line_file_path(path: &str) -> Option<&str> {
+ Path::new(path).file_name().and_then(|filename| {
+ if path != "/dev/null" {
+ filename.to_str()
+ } else {
+ None
+ }
+ })
}
fn parse_diff_header_line(line: &str, git_diff_name: bool) -> (String, FileEvent) {
@@ -477,51 +470,49 @@ mod tests {
use super::*;
#[test]
- fn test_get_file_extension_from_marker_line() {
+ fn test_get_filename_from_marker_line() {
assert_eq!(
- get_file_extension_from_marker_line(
- "--- src/one.rs 2019-11-20 06:47:56.000000000 +0100"
- ),
- Some("rs")
+ get_filename_from_marker_line("--- src/one.rs 2019-11-20 06:47:56.000000000 +0100"),
+ Some("one.rs")
);
}
#[test]
- fn test_get_file_extension_from_diff_header_line() {
+ fn test_get_filename_from_diff_header_line() {
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("a/src/parse.rs"),
- Some("rs")
+ get_filename_from_diff_header_line_file_path("a/src/parse.rs"),
+ Some("parse.rs")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("b/src/pa rse.rs"),
- Some("rs")
+ get_filename_from_diff_header_line_file_path("b/src/pa rse.rs"),
+ Some("pa rse.rs")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("src/pa rse.rs"),
- Some("rs")
+ get_filename_from_diff_header_line_file_path("src/pa rse.rs"),
+ Some("pa rse.rs")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("wat hello.rs"),
- Some("rs")
+ get_filename_from_diff_header_line_file_path("wat hello.rs"),
+ Some("wat hello.rs")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("/dev/null"),
+ get_filename_from_diff_header_line_file_path("/dev/null"),
None
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("Dockerfile"),
+ get_filename_from_diff_header_line_file_path("Dockerfile"),
Some("Dockerfile")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("Makefile"),
+ get_filename_from_diff_header_line_file_path("Makefile"),
Some("Makefile")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("a/src/Makefile"),
+ get_filename_from_diff_header_line_file_path("a/src/Makefile"),
Some("Makefile")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("src/Makefile"),
+ get_filename_from_diff_header_line_file_path("src/Makefile"),
Some("Makefile")
);
}
diff --git a/src/handlers/git_show_file.rs b/src/handlers/git_show_file.rs
index a9e1358e..ff670eb9 100644
--- a/src/handlers/git_show_file.rs
+++ b/src/handlers/git_show_file.rs
@@ -9,11 +9,11 @@ impl<'a> StateMachine<'a> {
self.painter.emit()?;
let mut handled_line = false;
if matches!(self.state, State::Unknown) {
- if let process::CallingProcess::GitShow(_, Some(extension)) =
+ if let process::CallingProcess::GitShow(_, Some(filename)) =
&*process::calling_process()
{
self.state = State::GitShowFile;
- self.painter.set_syntax(Some(extension));
+ self.painter.set_syntax(Some(filename));
} else {
return Ok(handled_line);
}
diff --git a/src/handlers/grep.rs b/src/handlers/grep.rs
index b7f2dc53..63cc1a3e 100644
--- a/src/handlers/grep.rs
+++ b/src/handlers/grep.rs
@@ -132,12 +132,8 @@ impl<'a> StateMachine<'a> {
self.painter.set_highlighter()
}
if new_path {
- if let Some(lang) = handlers::diff_header::get_extension(&grep_line.path)
- .or(self.config.default_language.as_deref())
- {
- self.painter.set_syntax(Some(lang));
- self.painter.set_highlighter();
- }
+ self.painter.set_syntax(Some(grep_line.path.as_ref()));
+ self.painter.set_highlighter();
}
match &self.state {
State::Grep(GrepType::Ripgrep, _, _, _) => {
diff --git a/src/options/get.rs b/src/options/get.rs
index fcea8c5a..40f3d581 100644
--- a/src/options/get.rs
+++ b/src/options/get.rs
@@ -38,7 +38,7 @@ where
T::get_option_value(option_name, builtin_features, opt, git_config)
}
-static GIT_CONFIG_THEME_REGEX: &str = r#"^delta\.(.+)\.(light|dark)$"#;
+static GIT_CONFIG_THEME_REGEX: &str = r"^delta\.(.+)\.(light|dark)$";
pub fn get_themes(git_config: Option<git_config::GitConfig>) -> Vec<String> {
let mut themes: Vec<String> = Vec::new();
diff --git a/src/options/set.rs b/src/options/set.rs
index cfb42987..5c8e1b43 100644
--- a/src/options/set.rs
+++ b/src/options/set.rs
@@ -735,7 +735,7 @@ pub mod tests {
assert_eq!(opt.commit_decoration_style, "black black");
assert_eq!(opt.commit_style, "black black");
assert!(!opt.dark);
- assert_eq!(opt.default_language, Some("rs".to_owned()));
+ assert_eq!(opt.default_language, "rs".to_owned());
// TODO: should set_options not be called on any feature flags?
// assert_eq!(opt.diff_highlight, true);
// assert_eq!(opt.diff_so_fancy, true);
diff --git a/src/paint.rs b/src/paint.rs
index ee2fefec..4b487ea3 100644
--- a/src/paint.rs
+++ b/src/paint.rs
@@ -70,9 +70,7 @@ pub enum StyleSectionSpecifier<'l> {
impl<'p> Painter<'p> {
pub fn new(writer: &'p mut dyn Write, config: &'p config::Config) -> Self {
- let default_syntax =
- Self::get_syntax(&config.syntax_set, None, config.default_language.as_deref());
-
+ let default_syntax = Self::get_syntax(&config.syntax_set, None, &config.default_language);
let panel_width_fix = ansifill::UseFullPanelWidth::new(config);
let line_numbers_data = if config.line_numbers {
@@ -104,27 +102,50 @@ impl<'p> Painter<'p> {
}
}
- pub fn set_syntax(&mut self, extension: Option<&str>) {
+ pub fn set_syntax(&mut self, filename: Option<&str>) {
self.syntax = Painter::get_syntax(
&self.config.syntax_set,
- extension,
- self.config.default_language.as_deref(),
+ filename,
+ &self.config.default_language,
);
}
fn get_syntax<'a>(
syntax_set: &'a SyntaxSet,
- extension: Option<&str>,
- fallback_extension: Option<&str>,
+ filename: Option<&str>,
+ fallback: &str,
) -> &'a SyntaxReference {
- for extension in [extension, fallback_extension].iter().flatten() {
- if let Some(syntax) = syntax_set.find_syntax_by_extension(extension) {
- return syntax;
+ if let Some(filename) = filename {
+ let path = std::path::Path::new(filename);
+ let file_name = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
+ let extension = path.extension().and_then(|x| x.to_str()).unwrap_or("");
+
+ // Like syntect's `find_syntax_for_file`, without inspecting the file content, plus:
+ // If the file has NO extension then look up the whole filename as a
+ // syntax definition (if it is longer than 4 bytes).
+ // This means file formats like Makefile/Dockerfile/Rakefile etc. will get highlighted,
+ // but 1-4 short filenames will not -- even if they, as a whole, match an extension:
+ // 'rs' will not get highlighted, while 'x.rs' will.
+ if !extension.is_empty() || file_name.len() > 4 {
+ if let Some(syntax) = syntax_set
+ .find_syntax_by_extension(file_name)
+ .or_else(|| syntax_set.find_syntax_by_extension(extension))
+ {
+ return syntax;
+ }
}
}
- syntax_set
- .find_syntax_by_extension("txt")
- .unwrap_or_else(|| delta_unreachable("Failed to find any language syntax definitions."))
+
+ // Nothing found, try the user provided fallback, or the internal fallback.
+ if let Some(syntax) = syntax_set.find_syntax_for_file(fallback).unwrap_or(None) {
+ syntax
+ } else {
+ syntax_set
+ .find_syntax_by_extension(config::SYNTAX_FALLBACK_LANG)
+ .unwrap_or_else(|| {
+ delta_unreachable("Failed to find any language syntax definitions.")
+ })
+ }
}
pub fn set_highlighter(&mut self) {
diff --git a/src/subcommands/show_colors.rs b/src/subcommands/show_colors.rs
index 8ad9fc35..2898dd97 100644
--- a/src/subcommands/show_colors.rs
+++ b/src/subcommands/show_colors.rs
@@ -28,7 +28,7 @@ pub fn show_colors() -> std::io::Result<()> {
let writer = output_type.handle().unwrap();
let mut painter = paint::Painter::new(writer, &config);
- painter.set_syntax(Some("ts"));
+ painter.set_syntax(Some("a.ts"));
painter.set_highlighter();
let title_style = ansi_term::Style::new().bold();
diff --git a/src/tests/ansi_test_utils.rs b/src/tests/ansi_test_utils.rs
index 5e60223b..8ccd1296 100644
--- a/src/tests/ansi_test_utils.rs
+++ b/src/tests/ansi_test_utils.rs
@@ -122,15 +122,19 @@ pub mod ansi_test_utils {
line_number: usize,
substring_begin: usize,
expected_substring: &str,
- language_extension: &str,
+ filename_for_highlighting: &str,
state: State,
config: &Config,
) {
+ assert!(
+ filename_for_highlighting.contains("."),
+ "expecting filename, not just a file extension"
+ );
let line = output.lines().nth(line_number).unwrap();
let substring_end = substring_begin + expected_substring.len();
let substring = &ansi::strip_ansi_codes(line)[substring_begin..substring_end];
assert_eq!(substring, expected_substring);
- let painted_substring = paint_line(substring, language_extension, state, config);
+ let painted_substring = paint_line(substring, filename_for_highlighting, state, config);
// remove trailing newline appended by paint::paint_lines.
assert!(line.contains(painted_substring.trim_end()));
}
@@ -163,7 +167,7 @@ pub mod ansi_test_utils {
pub fn paint_line(
line: &str,
- language_extension: &str,
+ filename_for_highlighting: &str,
state: State,
config: &Config,
) -> String {
@@ -174,7 +178,7 @@ pub mod ansi_test_utils {
is_syntax_highlighted: true,
..Style::new()
};
- painter.set_syntax(Some(language_extension));
+ painter.set_syntax(Some(filename_for_highlighting));
painter.set_highlighter();
let lines = vec![(line.to_string(), state)];
let syntax_style_sections = paint::get_syntax_style_sections_for_lines(
diff --git a/src/tests/test_example_diffs.rs b/src/tests/test_example_diffs.rs
index 104807a7..c686924f 100644
--- a/src/tests/test_example_diffs.rs
+++ b/src/tests/test_example_diffs.rs
@@ -111,7 +111,7 @@ mod tests {
12,
1,
" rsync -avu --delete $src/ $dst",
- "bash",
+ "abc.bash",
State::HunkZero(DiffType::Unified, None),
&config,
);
@@ -126,18 +126,50 @@ mod tests {
"bash",
]);
let output = integration_test_utils::run_delta(MODIFIED_BASH_AND_CSHARP_FILES, &config);
+ eprintln!("{}", &output);
ansi_test_utils::assert_line_has_syntax_highlighted_substring(
&output,
19,
1,
" static void Main(string[] args)",
- "cs",
+ "abc.cs",
State::HunkZero(DiffType::Unified, None),
&config,
);
}
#[test]
+ fn test_full_filename_used_to_detect_language() {
+ let config = integration_test_utils::make_config_from_args(&[
+ "--color-only",
+ "--default-language",
+ "txt",
+ ]);
+ let output = integration_test_utils::run_delta(MODIFIED_DOCKER_AND_RS_FILES, &config);
+ let ansi = ansi::explain_ansi(&output, false);
+
+ // Ensure presence and absence of highlighting. Do not use `assert_line_has_syntax_highlighted_substring`
+ // because it uses the same code path as the one to be tested here.
+ let expected = r"(normal)diff --git a/Dockerfile b/Dockerfile
+index 0123456..1234567 100644
+--- a/Dockerfile
++++ b/Dockerfile
+@@ -0,0 +2 @@
+(normal 22)+(203)FROM(231) foo(normal)
+(normal 22)+(203)COPY(231) bar baz(normal)
+diff --git a/rs b/rs
+index 0123456..1234567 100644
+--- a/rs
++++ b/rs
+@@ -0,0 +2 @@
+(normal 22)+(231)fn foobar() -> i8 {(normal)
+(normal 22)+(231) 8(normal)
+(normal 22)+(231)}(normal)
+";
+ assert_eq!(expected, ansi);
+ }
+
+ #[test]
fn test_diff_unified_two_files() {
let config =
integration_test_utils::make_config_from_args(&["--file-modified-label", "comparing:"]);
@@ -1461,7 +1493,7 @@ src/align.rs:71: impl<'a> Alignment<'a> { │
11,
4,
"impl<'a> Alignment<'a> { ",
- "rs",
+ "a.rs",
State::HunkHeader(
DiffType::Unified,
ParsedHunkHeader::default(),
@@ -1797,7 +1829,7 @@ src/align.rs:71: impl<'a> Alignment<'a> { │
12,
1,
" for (i, x_i) in self.x.iter().enumerate() {",
- "rs",
+ "align.rs",
State::HunkZero(DiffType::Unified, None),
&config,
);
@@ -2167,6 +2199,24 @@ index 2e73468..8d8b89d 100644
}
";
+ const MODIFIED_DOCKER_AND_RS_FILES: &str = "\
+diff --git a/Dockerfile b/Dockerfile
+index 0123456..1234567 100644
+--- a/Dockerfile
++++ b/Dockerfile
+@@ -0,0 +2 @@
++FROM foo
++COPY bar baz
+diff --git a/rs b/rs
+index 0123456..1234567 100644
+--- a/rs
++++ b/rs
+@@ -0,0 +2 @@
++fn foobar() -> i8 {
++ 8
++}
+";
+
const RENAMED_FILE_INPUT: &str = "\
commit 1281650789680f1009dfff2497d5ccfbe7b96526
Author: Dan Davison <dandavison7@gmail.com>
diff --git a/src/utils/process.rs b/src/utils/process.rs
index 1876d679..ab7a7e48 100644
--- a/src/utils/process.rs
+++ b/src/utils/process.rs
@@ -10,7 +10,7 @@ pub type DeltaPid = u32;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum CallingProcess {
GitDiff(CommandLine),
- GitShow(CommandLine, Option<String>), // element 2 is file extension
+ GitShow(CommandLine, Option<String>), // element 2 is filename
GitLog(CommandLine),
GitReflog(CommandLine),
GitGrep(CommandLine),
@@ -110,11 +110,11 @@ pub enum ProcessArgs<T> {
OtherProcess,
}
-pub fn git_blame_filename_extension() -> Option<String> {
- calling_process_cmdline(ProcInfo::new(), guess_git_blame_filename_extension)
+pub fn git_blame_filename() -> Option<String> {
+ calling_process_cmdline(ProcInfo::new(), guess_git_blame_filename)
}
-pub fn guess_git_blame_filename_extension(args: &[String]) -> ProcessArgs<String> {
+pub fn guess_git_blame_filename(args: &[String]) -> ProcessArgs<String> {
let all_args = args.iter().map(|s| s.as_str());
// See git(1) and git-blame(1). Some arguments separate their parameter with space or '=', e.g.
@@ -126,10 +126,15 @@ pub fn guess_git_blame_filename_extension(args: &[String]) -> ProcessArgs<String
skip_uninteresting_args(all_args, git_blame_options_with_parameter.split(' '));
match selected_args.as_slice() {
- [git, "blame", .., last_arg] if is_git_binary(git) => match last_arg.split('.').last() {
- Some(arg) => ProcessArgs::Args(arg.to_string()),
- None => ProcessArgs::ArgError,
- },
+ [git, "blame", .., last_arg] if is_git_binary(git) => {
+ match Path::new(last_arg)
+ .file_name()
+ .map(|filename| filename.to_string_lossy().to_string())
+ {
+ Some(filename) => ProcessArgs::Args(filename),
+ None => ProcessArgs::ArgError,
+ }
+ }
[git, "blame"] if is_git_binary(git) => ProcessArgs::ArgError,
_ => ProcessArgs::OtherProcess,
}
@@ -158,17 +163,17 @@ pub fn describe_calling_process(args: &[String]) -> ProcessArgs<CallingProcess>
}
Some("show") => {
let command_line = parse_command_line(args);
- let extension = if let Some(last_arg) = &command_line.last_arg {
+ let filename = if let Some(last_arg) = &command_line.last_arg {
match last_arg.split_once(':') {
- Some((_, suffix)) => {
- suffix.split('.').last().map(|s| s.to_string())
- }
+ Some((_, filename)) => Path::new(filename)
+ .file_name()
+ .map(|f| f.to_string_lossy().to_string()),
None => None,
}
} else {
None
};
- ProcessArgs::Args(CallingProcess::GitShow(command_line, extension))
+ ProcessArgs::Args(CallingProcess::GitShow(command_line, filename))
}
Some("log") => {
ProcessArgs::Args(CallingProcess::GitLog(parse_command_line(args)))
@@ -682,17 +687,14 @@ pub mod tests {
}
#[test]
- fn test_guess_git_blame_filename_extension() {
+ fn test_guess_git_blame_filename() {
use ProcessArgs::Args;
fn make_string_vec(args: &[&str]) -> Vec<String> {
args.iter().map(|&x| x.to_owned()).collect::<Vec<String>>()
}
let args = make_string_vec(&["git", "blame", "hello", "world.txt"]);
- assert_eq!(
- guess_git_blame_filename_extension(&args),
- Args("txt".into())
- );
+ assert_eq!(guess_git_blame_filename(&args), Args("world.txt".into()));
let args = make_string_vec(&[
"git",
@@ -704,46 +706,31 @@ pub mod tests {
"--date",
"now",
]);
- assert_eq!(
- guess_git_blame_filename_extension(&args),
- Args("txt".into())
- );
+ assert_eq!(guess_git_blame_filename(&args), Args("hello.txt".into()));
let args = make_string_vec(&["git", "blame", "-s", "-f", "--", "hello.txt"]);
- assert_eq!(
- guess_git_blame_filename_extension(&args),
- Args("txt".into())
- );
+ assert_eq!(guess_git_blame_filename(&args), Args("hello.txt".into()));
let args = make_string_vec(&["git", "blame", "--", "--not.an.argument"]);
assert_eq!(
- guess_git_blame_filename_extension(&args),
- Args("argument".into())
+ guess_git_blame_filename(&args),
+ Args("--not.an.argument".into())
);
let args = make_string_vec(&["foo", "bar", "-a", "--123", "not.git"]);
- assert_eq!(
- guess_git_blame_filename_extension(&args),
- ProcessArgs::OtherProcess
- );
+ assert_eq!(guess_git_blame_filename(&args), ProcessArgs::OtherProcess);
let args = make_string_vec(&["git", "blame", "--help.txt"]);
- assert_eq!(
- guess_git_blame_filename_extension(&args),
- ProcessArgs::ArgError
- );
+ assert_eq!(guess_git_blame_filename(&args), ProcessArgs::ArgError);
let args = make_string_vec(&["git", "-c", "a=b", "blame", "main.rs"]);
- assert_eq!(guess_git_blame_filename_extension(&args), Args("rs".into()));
+ assert_eq!(guess_git_blame_filename(&args), Args("main.rs".into()));
let args = make_string_vec(&["git", "blame", "README"]);
- assert_eq!(
- guess_git_blame_filename_extension(&args),
- Args("README".into())
- );
+ assert_eq!(guess_git_blame_filename(&args), Args("README".into()));
let args = make_string_vec(&["git", "blame", ""]);
- assert_eq!(guess_git_blame_filename_extension(&args), Args("".into()));
+ assert_eq!(guess_git_blame_filename(&args), ProcessArgs::ArgError);
}
#[derive(Debug, Default)]
@@ -830,27 +817,22 @@ pub mod tests {
{
let _args = FakeParentArgs::once("git blame hello");
assert_eq!(
- calling_process_cmdline(ProcInfo::new(), guess_git_blame_filename_extension),
+ calling_process_cmdline(ProcInfo::new(), guess_git_blame_filename),
Some("hello".into())
);
}
{
let _args = FakeParentArgs::once("git blame world.txt");
assert_eq!(
- calling_process_cmdline(ProcInfo::new(), guess_git_blame_filename_extension),
- Some("txt".into())
+ calling_process_cmdline(ProcInfo::new(), guess_git_blame_filename),
+ Some("world.txt".into())
);
}
{
let _args = FakeParentArgs::for_scope("git blame hello world.txt");
assert_eq!(
- calling_process_cmdline(ProcInfo::new(), guess_git_blame_filename_extension),
- Some("txt".into())
- );
-
- assert_eq!(
- calling_process_cmdline(ProcInfo::new(), guess_git_blame_filename_extension),
- Some("txt".into())
+ calling_pr