summaryrefslogtreecommitdiffstats
path: root/src/utils/process.rs
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2021-11-21 18:23:35 -0500
committerDan Davison <dandavison7@gmail.com>2021-11-22 13:18:15 -0500
commitd000e40e61871d2bf8609a0db1beb71f48228147 (patch)
tree0542ea14dcf998486e79993e7a88df6997a0207b /src/utils/process.rs
parent07892bc572a92bca8e3fec3d1b0ba717d80cc096 (diff)
Syntax-highlight `git show $revision:./path/to/file.ext` output
Diffstat (limited to 'src/utils/process.rs')
-rw-r--r--src/utils/process.rs58
1 files changed, 51 insertions, 7 deletions
diff --git a/src/utils/process.rs b/src/utils/process.rs
index 0000e9da..ee145f88 100644
--- a/src/utils/process.rs
+++ b/src/utils/process.rs
@@ -7,8 +7,9 @@ use lazy_static::lazy_static;
#[derive(Clone, Debug, PartialEq)]
pub enum CallingProcess {
- GitGrep((HashSet<String>, HashSet<String>)),
- OtherGrep, // rg, grep, ag, ack, etc
+ GitShow(String), // (extension)
+ GitGrep((HashSet<String>, HashSet<String>)), // ((long_options, short_options))
+ OtherGrep, // rg, grep, ag, ack, etc
}
pub fn calling_process() -> Option<Cow<'static, CallingProcess>> {
@@ -79,14 +80,23 @@ pub fn describe_calling_process(args: &[String]) -> ProcessArgs<CallingProcess>
match args.next() {
Some(command) => match Path::new(command).file_stem() {
Some(s) if s.to_str() == Some("git") => {
- let mut args = args.skip_while(|s| *s != "grep");
+ let mut args = args.skip_while(|s| *s != "grep" && *s != "show");
match args.next() {
- Some(_) => {
+ Some("grep") => {
ProcessArgs::Args(CallingProcess::GitGrep(parse_command_option_keys(args)))
}
- None => {
- // It's git, but not git grep. Don't look at any
- // more processes and return not-a-grep-command.
+ Some("show") => {
+ if let Some(extension) = get_git_show_file_extension(args) {
+ ProcessArgs::Args(CallingProcess::GitShow(extension.to_string()))
+ } else {
+ // It's git show, but we failed to determine the
+ // file extension. Don't look at any more processes.
+ ProcessArgs::ArgError
+ }
+ }
+ _ => {
+ // It's git, but not a subcommand that we parse. Don't
+ // look at any more processes.
ProcessArgs::ArgError
}
}
@@ -113,6 +123,18 @@ pub fn describe_calling_process(args: &[String]) -> ProcessArgs<CallingProcess>
}
}
+fn get_git_show_file_extension<'a>(args: impl Iterator<Item = &'a str>) -> Option<&'a str> {
+ if let Some(last_arg) = skip_uninteresting_args(args, "".split(' ')).last() {
+ // E.g. "HEAD~1:Makefile" or "775c3b8:./src/delta.rs"
+ match last_arg.split_once(':') {
+ Some((_, suffix)) => suffix.split('.').last(),
+ None => None,
+ }
+ } else {
+ None
+ }
+}
+
// Skip all arguments starting with '-' from `args_it`. Also skip all arguments listed in
// `skip_this_plus_parameter` plus their respective next argument.
// Keep all arguments once a '--' is encountered.
@@ -716,6 +738,28 @@ pub mod tests {
}
#[test]
+ fn test_describe_calling_process_git_show() {
+ for (command, expected_extension) in [
+ ("/usr/local/bin/git show 775c3b84:./src/hello.rs", "rs"),
+ ("/usr/local/bin/git show HEAD~1:Makefile", "Makefile"),
+ (
+ "git -c x.y=z show --abbrev-commit 775c3b84:./src/hello.bye.R",
+ "R",
+ ),
+ ] {
+ let parent = MockProcInfo::with(&[
+ (2, 100, "-shell", None),
+ (3, 100, command, Some(2)),
+ (4, 100, "delta", Some(3)),
+ ]);
+ assert_eq!(
+ calling_process_cmdline(parent, describe_calling_process),
+ Some(CallingProcess::GitShow(expected_extension.to_string())),
+ );
+ }
+ }
+
+ #[test]
fn test_process_calling_cmdline() {
// Github runs CI tests for arm under qemu where where sysinfo can not find the parent process.
if std::env::vars().any(|(key, _)| key == "CROSS_RUNNER" || key == "QEMU_LD_PREFIX") {