summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Otto <th1000s@posteo.net>2022-02-25 00:31:12 +0100
committerDan Davison <dandavison7@gmail.com>2022-03-01 18:58:55 -0500
commitd2f5a9077c1d06f42425da3891fc4e5936c05a8f (patch)
treee54c9d43550a44fc56b039ce8d3c32a661aa5832
parent1403fe2b8ef26c84cd625bb6f550755f82f47576 (diff)
Also look at grandparent process when determining the caller
-rw-r--r--src/utils/process.rs61
1 files changed, 42 insertions, 19 deletions
diff --git a/src/utils/process.rs b/src/utils/process.rs
index a2984090..b810061a 100644
--- a/src/utils/process.rs
+++ b/src/utils/process.rs
@@ -298,6 +298,7 @@ impl ProcInfo {
trait ProcActions {
fn cmd(&self) -> &[String];
fn parent(&self) -> Option<DeltaPid>;
+ fn pid(&self) -> DeltaPid;
fn start_time(&self) -> u64;
}
@@ -311,6 +312,9 @@ where
fn parent(&self) -> Option<DeltaPid> {
ProcessExt::parent(self).map(|p| p.as_u32())
}
+ fn pid(&self) -> DeltaPid {
+ ProcessExt::pid(self).as_u32()
+ }
fn start_time(&self) -> u64 {
ProcessExt::start_time(self)
}
@@ -450,29 +454,41 @@ where
let my_pid = info.my_pid();
- // 1) Try the parent process. If delta is set as the pager in git, then git is the parent process.
- let parent = info.parent_process(my_pid)?;
-
- match extract_args(parent.cmd()) {
- ProcessArgs::Args(result) => return Some(result),
- ProcessArgs::ArgError => return None,
-
- // 2) The parent process was something else, this can happen if git output is piped into delta, e.g.
- // `git blame foo.txt | delta`. When the shell sets up the pipe it creates the two processes, the pids
- // are usually consecutive, so check if the process with `my_pid - 1` matches.
- ProcessArgs::OtherProcess => {
- let sibling = info.naive_sibling_process(my_pid);
- if let Some(proc) = sibling {
- if let ProcessArgs::Args(result) = extract_args(proc.cmd()) {
- return Some(result);
+ // 1) Try the parent process(es). If delta is set as the pager in git, then git is the parent process.
+ // If delta is started by a script check the parent's parent as well.
+ let mut current_pid = my_pid;
+ 'parent_iter: for depth in [1, 2, 3] {
+ let parent = match info.parent_process(current_pid) {
+ None => {
+ break 'parent_iter;
+ }
+ Some(parent) => parent,
+ };
+ let parent_pid = parent.pid();
+
+ match extract_args(parent.cmd()) {
+ ProcessArgs::Args(result) => return Some(result),
+ ProcessArgs::ArgError => return None,
+
+ // 2) The 1st parent process was something else, this can happen if git output is piped into delta, e.g.
+ // `git blame foo.txt | delta`. When the shell sets up the pipe it creates the two processes, the pids
+ // are usually consecutive, so naively check if the process with `my_pid - 1` matches.
+ ProcessArgs::OtherProcess if depth == 1 => {
+ let sibling = info.naive_sibling_process(current_pid);
+ if let Some(proc) = sibling {
+ if let ProcessArgs::Args(result) = extract_args(proc.cmd()) {
+ return Some(result);
+ }
}
}
- // else try the fallback
+ // This check is not done for the parent's parent etc.
+ ProcessArgs::OtherProcess => {}
}
+ current_pid = parent_pid;
}
/*
- 3) Neither parent nor direct sibling were a match.
+ 3) Neither parent(s) nor the direct sibling were a match.
The most likely case is that the input program of the pipe wrote all its data and exited before delta
started, so no command line can be parsed. Same if the data was piped from an input file.
@@ -498,12 +514,16 @@ where
*/
- let pid_range = my_pid.saturating_sub(10)..my_pid.saturating_add(20);
+ // Also `add` because `A_has_pid101 | delta_has_pid102`, but if A is a wrapper which then calls
+ // git (no `exec`), then the final pid of the git process might be 103 or greater.
+ let pid_range = my_pid.saturating_sub(10)..my_pid.saturating_add(10);
for p in pid_range {
// Processes which were not refreshed do not exist for sysinfo, so by selectively
// letting it know about processes the `find_sibling..` function will only
// consider these.
- info.refresh_process(p);
+ if info.process(p).is_none() {
+ info.refresh_process(p);
+ }
}
match info.find_sibling_in_refreshed_processes(my_pid, &extract_args) {
@@ -750,6 +770,9 @@ pub mod tests {
fn parent(&self) -> Option<DeltaPid> {
self.ppid
}
+ fn pid(&self) -> DeltaPid {
+ self.pid
+ }
fn start_time(&self) -> u64 {
self.start_time
}