b9d5ee79130172aaeff05b2b49ba6507573957f6

Author
Marc Cornellà <marc.cornella@live.com>
Committer
GitHub <noreply@github.com>
Date

Message

lib: automatic title: replace fg with description from jobs (#7982)

* Automatic title: Replace fg with description from jobs

* Avoid error messages when there is no job

* Use $jobstates and $jobtexts to look for jobs

`jobs %string` doesn't work correctly when run inside `$()`. `$jobstates` and
`$jobtexts` is available in the current shell process, so even though we need
to replicate a bit more logic, every type of `fg` invocation works correctly.

* lib: clean up termsupport.zsh

Co-authored-by: Marc Cornellà <marc.cornella@live.com>

Diff

 1diff --git a/lib/termsupport.zsh b/lib/termsupport.zsh
 2index 19fd57b9de5167e1348c91c55a5ecc8094c0e65b..654927a1ce1d4bafa745a86e360dc753ba6df3ea 100644
 3--- a/lib/termsupport.zsh
 4+++ b/lib/termsupport.zsh
 5@@ -32,10 +32,10 @@ function title {
 6         # Try to use terminfo to set the title
 7         # If the feature is available set title
 8         if [[ -n "$terminfo[fsl]" ]] && [[ -n "$terminfo[tsl]" ]]; then
 9-	  echoti tsl
10-	  print -Pn "$1"
11-	  echoti fsl
12-	fi
13+          echoti tsl
14+          print -Pn "$1"
15+          echoti fsl
16+        fi
17       fi
18       ;;
19   esac
20@@ -50,22 +50,52 @@ fi
21 
22 # Runs before showing the prompt
23 function omz_termsupport_precmd {
24-  emulate -L zsh
25-
26-  if [[ "$DISABLE_AUTO_TITLE" == true ]]; then
27-    return
28-  fi
29-
30+  [[ "$DISABLE_AUTO_TITLE" == true ]] && return
31   title $ZSH_THEME_TERM_TAB_TITLE_IDLE $ZSH_THEME_TERM_TITLE_IDLE
32 }
33 
34 # Runs before executing the command
35 function omz_termsupport_preexec {
36+  [[ "$DISABLE_AUTO_TITLE" == true ]] && return
37+
38   emulate -L zsh
39   setopt extended_glob
40 
41-  if [[ "$DISABLE_AUTO_TITLE" == true ]]; then
42-    return
43+  # split command into array of arguments
44+  local -a cmdargs
45+  cmdargs=("${(z)2}")
46+  # if running fg, extract the command from the job description
47+  if [[ "${cmdargs[1]}" = fg ]]; then
48+    # get the job id from the first argument passed to the fg command
49+    local job_id jobspec="${cmdargs[2]#%}"
50+    # logic based on jobs arguments:
51+    # http://zsh.sourceforge.net/Doc/Release/Jobs-_0026-Signals.html#Jobs
52+    # https://www.zsh.org/mla/users/2007/msg00704.html
53+    case "$jobspec" in
54+      <->) # %number argument:
55+        # use the same <number> passed as an argument
56+        job_id=${jobspec} ;;
57+      ""|%|+) # empty, %% or %+ argument:
58+        # use the current job, which appears with a + in $jobstates:
59+        # suspended:+:5071=suspended (tty output)
60+        job_id=${(k)jobstates[(r)*:+:*]} ;;
61+      -) # %- argument:
62+        # use the previous job, which appears with a - in $jobstates:
63+        # suspended:-:6493=suspended (signal)
64+        job_id=${(k)jobstates[(r)*:-:*]} ;;
65+      [?]*) # %?string argument:
66+        # use $jobtexts to match for a job whose command *contains* <string>
67+        job_id=${(k)jobtexts[(r)*${(Q)jobspec}*]} ;;
68+      *) # %string argument:
69+        # use $jobtexts to match for a job whose command *starts with* <string>
70+        job_id=${(k)jobtexts[(r)${(Q)jobspec}*]} ;;
71+    esac
72+
73+    # override preexec function arguments with job command
74+    if [[ -n "${jobtexts[$job_id]}" ]]; then
75+      1="${jobtexts[$job_id]}"
76+      2="${jobtexts[$job_id]}"
77+    fi
78   fi
79 
80   # cmd name only, or if this is sudo or ssh, the next cmd