Files

57 lines
2.1 KiB
TOML
Raw Permalink Normal View History

2026-10-14 13:32:59 -04:00
[metadata]
name = "jobs"
description = """
The current fish shell's background jobs (stopped or running). tv runs in a
child process and cannot see the shell's job table, so the ctrl-z binding
(_jobs_bind) writes it to the file named by $TV_JOBS; enter prints the job id
and the binding runs `fg %<id>`; ctrl-d kills the job. Opened any other way,
the list is empty.
"""
requirements = ["ps"]
# Record: "%<id> <state> <command>", job id, process group (tab separated).
# Newest job first, the order fish's `jobs` prints.
[source]
command = '[ -n "$TV_JOBS" ] && [ -r "$TV_JOBS" ] && cat "$TV_JOBS"'
shell = "bash"
display = "{split:\\t:0}"
output = "{split:\\t:1}"
[preview]
command = '''
pg='{split:\t:2}'
# No other braces in this script: tv would read them as templates. procps
# `ps -g` matches sessions, not process groups, so filter on pgid by hand.
pids=$(ps -e -o pgid=,pid= --sort=start_time | while read -r g p; do [ "$g" = "$pg" ] && echo "$p"; done)
if [ -z "$pids" ]; then
echo "process group $pg is gone"
exit 0
fi
first=$(echo "$pids" | head -n1)
printf '\033[1mcwd\033[0m %s\n' "$(readlink "/proc/$first/cwd" 2>/dev/null || echo '?')"
printf '\033[1mstarted\033[0m %s\n\n' "$(ps -o lstart= -p "$first" | sed 's/^ *//')"
# STAT T = stopped (ctrl-z), S/R = running in the background.
ps -o pid,stat,etime,pcpu,rss,args --forest -p "$(echo $pids | tr ' ' ,)"
'''
shell = "bash"
[keybindings]
ctrl-d = ["actions:kill", "reload_source"]
# SIGTERM to the whole process group, then SIGCONT: a stopped job holds TERM
# until it runs again. The row leaves $TV_JOBS only once the group is gone
# (up to 1 s), so reload_source keeps a job that ignored TERM. No braces: tv
# would read them as templates.
[actions.kill]
description = "Kill the job (SIGTERM to its process group)"
command = '''
pg='{split:\t:2}'
kill -TERM -- "-$pg" 2>/dev/null
kill -CONT -- "-$pg" 2>/dev/null
for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 -- "-$pg" 2>/dev/null || break; sleep 0.1; done
if ! kill -0 -- "-$pg" 2>/dev/null && [ -w "$TV_JOBS" ]; then
awk -F '\t' -v g="$pg" '$3 != g' "$TV_JOBS" >"$TV_JOBS.new" && mv "$TV_JOBS.new" "$TV_JOBS"
fi
'''
shell = "bash"
mode = "fork"