mirror of
https://github.com/prdlk/dotfiles.git
synced 2026-11-02 19:32:43 +00:00
feat(cable): add jobs.toml for managing shell background jobs
This commit is contained in:
1 parent
ab0aa2a548
commit
c62668af30
1 file changed
+57
@@ -0,0 +1,57 @@
|
||||
[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"
|
||||
Reference in new issue
Block a user