feat: implement __rand_string generator and update jobrunner backend #98
@@ -30,6 +30,7 @@ This config layers on top of the CachyOS base Fish configuration and adds:
|
|||||||
- **Smart CLI wrappers** that prefer modern tools (`eza`, `bat`, `btop`, `dust`, `prettyping`) with graceful fallbacks
|
- **Smart CLI wrappers** that prefer modern tools (`eza`, `bat`, `btop`, `dust`, `prettyping`) with graceful fallbacks
|
||||||
- **Auto Python venv** activation on directory change (direnv-aware)
|
- **Auto Python venv** activation on directory change (direnv-aware)
|
||||||
- **Kitty terminal** deep integration for splits, tabs, and SSH
|
- **Kitty terminal** deep integration for splits, tabs, and SSH
|
||||||
|
- **Named background jobs** — `jobrunner` (short: `jr`) starts, lists, inspects, re-attaches to, and kills detached tasks via `tmux` or GNU `screen`, so long-running work survives closing the shell
|
||||||
- **Optional session logging** — terminal scrollback, multiplexer panes (tmux/zellij), and AUR-helper output can be captured to `~/.terminal_history`; **off by default**, opt in when you want it (see the caution below and [Session Logging](#session-logging))
|
- **Optional session logging** — terminal scrollback, multiplexer panes (tmux/zellij), and AUR-helper output can be captured to `~/.terminal_history`; **off by default**, opt in when you want it (see the caution below and [Session Logging](#session-logging))
|
||||||
- **AI workflow** helpers for Claude and Antigravity session management
|
- **AI workflow** helpers for Claude and Antigravity session management
|
||||||
- **WakaTime** shell activity tracking
|
- **WakaTime** shell activity tracking
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
# Copyright (C) 2026 Rootiest
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# Completions for the `jobrunner` background job manager.
|
||||||
|
# `jr` inherits these via `function jr --wraps jobrunner`.
|
||||||
|
|
||||||
|
# Offer running jobs as name<TAB>description pairs.
|
||||||
|
function __jobrunner_complete_jobs
|
||||||
|
set -l tool ""
|
||||||
|
set -l tokens (commandline -opc)
|
||||||
|
set -l idx 1
|
||||||
|
while test $idx -le (count $tokens)
|
||||||
|
switch $tokens[$idx]
|
||||||
|
case -t --tool
|
||||||
|
set idx (math $idx + 1)
|
||||||
|
if test $idx -le (count $tokens)
|
||||||
|
set tool $tokens[$idx]
|
||||||
|
end
|
||||||
|
case '--tool=*'
|
||||||
|
set tool (string replace -- "--tool=" "" $tokens[$idx])
|
||||||
|
case '-t*'
|
||||||
|
set tool (string replace -r "^-t" "" $tokens[$idx])
|
||||||
|
end
|
||||||
|
set idx (math $idx + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
for row in (__jobrunner_sessions $tool)
|
||||||
|
set -l f (string split \t -- $row)
|
||||||
|
printf '%s\t%s job (PID %s)\n' $f[1] $f[3] $f[2]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l subcmds run list attach kill logs help
|
||||||
|
set -l needs_job "__fish_seen_subcommand_from attach kill logs -a --attach -k --kill -o --output"
|
||||||
|
|
||||||
|
# No file completions; jobs are named, not paths.
|
||||||
|
complete -c jobrunner -f
|
||||||
|
|
||||||
|
# Backend tool selection flag.
|
||||||
|
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||||
|
-s t -l tool -x -a "tmux screen" -d 'Force specific backend'
|
||||||
|
|
||||||
|
# Subcommands (only as the first argument).
|
||||||
|
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||||
|
-a run -d 'Start a named job in the background'
|
||||||
|
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||||
|
-a list -d 'List all managed background jobs'
|
||||||
|
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||||
|
-a attach -d 'Re-attach interactively to a job'
|
||||||
|
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||||
|
-a kill -d 'Terminate a running background job'
|
||||||
|
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||||
|
-a logs -d "Print a job's output without attaching"
|
||||||
|
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||||
|
-a help -d 'Show usage help'
|
||||||
|
|
||||||
|
# Flag forms.
|
||||||
|
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||||
|
-s r -l run -d 'Start a named job in the background'
|
||||||
|
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||||
|
-s l -l list -d 'List all managed background jobs'
|
||||||
|
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||||
|
-s a -l attach -d 'Re-attach interactively to a job'
|
||||||
|
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||||
|
-s k -l kill -d 'Terminate a running background job'
|
||||||
|
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||||
|
-s o -l output -d "Print a job's output without attaching"
|
||||||
|
complete -c jobrunner -s h -l help -d 'Show usage help'
|
||||||
|
|
||||||
|
# Running jobs, for the subcommands that take one.
|
||||||
|
complete -c jobrunner -n "$needs_job" -a '(__jobrunner_complete_jobs)'
|
||||||
|
|
||||||
|
# A bare job name attaches to it, so offer jobs in first position too.
|
||||||
|
complete -c jobrunner -n "not __fish_seen_subcommand_from $subcmds" \
|
||||||
|
-a '(__jobrunner_complete_jobs)'
|
||||||
|
|
||||||
|
# After `run <name>`, complete the command to execute.
|
||||||
|
complete -c jobrunner -n "__fish_seen_subcommand_from run -r --run; and test (count (commandline -opc)) -ge 3" \
|
||||||
|
-a '(__fish_complete_subcommand)'
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (C) 2026 Rootiest
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
complete -c rand_string -f
|
||||||
|
|
||||||
|
complete -c rand_string -s s -l separator -x -a 'dash underscore dot none' -d 'Set separator for following words'
|
||||||
|
complete -c rand_string -s c -l case -x -a 'lower upper title' -d 'Set casing for following words'
|
||||||
|
complete -c rand_string -s h -l help -d 'Show usage help'
|
||||||
|
|
||||||
|
# List of all available lists in data/words
|
||||||
|
set -l categories
|
||||||
|
if set -q __fish_config_dir
|
||||||
|
set categories (string replace -r '\.txt$' '' (command ls $__fish_config_dir/data/words/*.txt 2>/dev/null | command xargs -n 1 basename 2>/dev/null))
|
||||||
|
end
|
||||||
|
|
||||||
|
for cat in $categories
|
||||||
|
complete -c rand_string -a "$cat" -d "Pick a random word from the $cat list"
|
||||||
|
end
|
||||||
|
|
||||||
|
complete -c rand_string -a 'digits=' -d 'Generate N random digits (e.g. digits=3)'
|
||||||
|
complete -c rand_string -a 'literal=' -d 'Insert a literal string exactly as provided'
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
admiring
|
||||||
|
adoring
|
||||||
|
affectionate
|
||||||
|
agitated
|
||||||
|
amazing
|
||||||
|
angry
|
||||||
|
awesome
|
||||||
|
beautiful
|
||||||
|
blissful
|
||||||
|
bold
|
||||||
|
boring
|
||||||
|
brave
|
||||||
|
busy
|
||||||
|
charming
|
||||||
|
clever
|
||||||
|
compassionate
|
||||||
|
competent
|
||||||
|
condescending
|
||||||
|
confident
|
||||||
|
cool
|
||||||
|
cranky
|
||||||
|
crazy
|
||||||
|
dazzling
|
||||||
|
determined
|
||||||
|
distracted
|
||||||
|
dreamy
|
||||||
|
eager
|
||||||
|
ecstatic
|
||||||
|
elastic
|
||||||
|
elated
|
||||||
|
elegant
|
||||||
|
eloquent
|
||||||
|
epic
|
||||||
|
exciting
|
||||||
|
fervent
|
||||||
|
festive
|
||||||
|
flamboyant
|
||||||
|
focused
|
||||||
|
friendly
|
||||||
|
frosty
|
||||||
|
funny
|
||||||
|
gallant
|
||||||
|
gifted
|
||||||
|
goofy
|
||||||
|
gracious
|
||||||
|
great
|
||||||
|
happy
|
||||||
|
hardcore
|
||||||
|
heuristic
|
||||||
|
hopeful
|
||||||
|
hungry
|
||||||
|
infallible
|
||||||
|
inspiring
|
||||||
|
intelligent
|
||||||
|
interesting
|
||||||
|
jolly
|
||||||
|
jovial
|
||||||
|
keen
|
||||||
|
kind
|
||||||
|
laughing
|
||||||
|
loving
|
||||||
|
lucid
|
||||||
|
magical
|
||||||
|
modest
|
||||||
|
musing
|
||||||
|
mystifying
|
||||||
|
naughty
|
||||||
|
nervous
|
||||||
|
nice
|
||||||
|
nifty
|
||||||
|
nostalgic
|
||||||
|
objective
|
||||||
|
optimistic
|
||||||
|
peaceful
|
||||||
|
pedantic
|
||||||
|
pensive
|
||||||
|
practical
|
||||||
|
priceless
|
||||||
|
quirky
|
||||||
|
quizzical
|
||||||
|
recursing
|
||||||
|
relaxed
|
||||||
|
reverent
|
||||||
|
romantic
|
||||||
|
sad
|
||||||
|
serene
|
||||||
|
sharp
|
||||||
|
silly
|
||||||
|
sleepy
|
||||||
|
stoic
|
||||||
|
strange
|
||||||
|
stupefied
|
||||||
|
suspicious
|
||||||
|
sweet
|
||||||
|
tender
|
||||||
|
thirsty
|
||||||
|
trusting
|
||||||
|
unruffled
|
||||||
|
upbeat
|
||||||
|
vibrant
|
||||||
|
vigilant
|
||||||
|
vigorous
|
||||||
|
wizardly
|
||||||
|
wonderful
|
||||||
|
xenodochial
|
||||||
|
youthful
|
||||||
|
zealous
|
||||||
|
zen
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
aardvark
|
||||||
|
albatross
|
||||||
|
alligator
|
||||||
|
alpaca
|
||||||
|
ant
|
||||||
|
anteater
|
||||||
|
antelope
|
||||||
|
ape
|
||||||
|
armadillo
|
||||||
|
baboon
|
||||||
|
badger
|
||||||
|
barracuda
|
||||||
|
bat
|
||||||
|
bear
|
||||||
|
beaver
|
||||||
|
bee
|
||||||
|
bison
|
||||||
|
boar
|
||||||
|
buffalo
|
||||||
|
butterfly
|
||||||
|
camel
|
||||||
|
capybara
|
||||||
|
caribou
|
||||||
|
cat
|
||||||
|
caterpillar
|
||||||
|
cattle
|
||||||
|
chamois
|
||||||
|
cheetah
|
||||||
|
chicken
|
||||||
|
chimpanzee
|
||||||
|
chinchilla
|
||||||
|
chough
|
||||||
|
clam
|
||||||
|
cobra
|
||||||
|
cockroach
|
||||||
|
cod
|
||||||
|
cormorant
|
||||||
|
coyote
|
||||||
|
crab
|
||||||
|
crane
|
||||||
|
crocodile
|
||||||
|
crow
|
||||||
|
curlew
|
||||||
|
deer
|
||||||
|
dinosaur
|
||||||
|
dog
|
||||||
|
dogfish
|
||||||
|
dolphin
|
||||||
|
donkey
|
||||||
|
dotterel
|
||||||
|
dove
|
||||||
|
dragonfly
|
||||||
|
duck
|
||||||
|
dugong
|
||||||
|
dunlin
|
||||||
|
eagle
|
||||||
|
echidna
|
||||||
|
eel
|
||||||
|
eland
|
||||||
|
elephant
|
||||||
|
elk
|
||||||
|
emu
|
||||||
|
falcon
|
||||||
|
ferret
|
||||||
|
finch
|
||||||
|
fish
|
||||||
|
flamingo
|
||||||
|
fly
|
||||||
|
fox
|
||||||
|
frog
|
||||||
|
gaur
|
||||||
|
gazelle
|
||||||
|
gerbil
|
||||||
|
giraffe
|
||||||
|
gnat
|
||||||
|
gnu
|
||||||
|
goat
|
||||||
|
goldfinch
|
||||||
|
goldfish
|
||||||
|
goose
|
||||||
|
gorilla
|
||||||
|
goshawk
|
||||||
|
grasshopper
|
||||||
|
grouse
|
||||||
|
guanaco
|
||||||
|
gull
|
||||||
|
hamster
|
||||||
|
hare
|
||||||
|
hawk
|
||||||
|
hedgehog
|
||||||
|
heron
|
||||||
|
herring
|
||||||
|
hippopotamus
|
||||||
|
hornet
|
||||||
|
horse
|
||||||
|
human
|
||||||
|
hummingbird
|
||||||
|
hyena
|
||||||
|
ibex
|
||||||
|
ibis
|
||||||
|
jackal
|
||||||
|
jaguar
|
||||||
|
jay
|
||||||
|
jellyfish
|
||||||
|
kangaroo
|
||||||
|
kingfisher
|
||||||
|
koala
|
||||||
|
kookabura
|
||||||
|
kouprey
|
||||||
|
kudu
|
||||||
|
lapwing
|
||||||
|
lark
|
||||||
|
lemur
|
||||||
|
leopard
|
||||||
|
lion
|
||||||
|
llama
|
||||||
|
lobster
|
||||||
|
locust
|
||||||
|
loris
|
||||||
|
louse
|
||||||
|
lyrebird
|
||||||
|
magpie
|
||||||
|
mallard
|
||||||
|
manatee
|
||||||
|
mandrill
|
||||||
|
mantis
|
||||||
|
marten
|
||||||
|
meerkat
|
||||||
|
mink
|
||||||
|
mole
|
||||||
|
mongoose
|
||||||
|
monkey
|
||||||
|
moose
|
||||||
|
mosquito
|
||||||
|
mouse
|
||||||
|
mule
|
||||||
|
narwhal
|
||||||
|
newt
|
||||||
|
nightingale
|
||||||
|
octopus
|
||||||
|
okapi
|
||||||
|
opossum
|
||||||
|
oryx
|
||||||
|
ostrich
|
||||||
|
otter
|
||||||
|
owl
|
||||||
|
oyster
|
||||||
|
panther
|
||||||
|
parrot
|
||||||
|
partridge
|
||||||
|
peafowl
|
||||||
|
pelican
|
||||||
|
penguin
|
||||||
|
pheasant
|
||||||
|
pig
|
||||||
|
pigeon
|
||||||
|
pony
|
||||||
|
porcupine
|
||||||
|
porpoise
|
||||||
|
quail
|
||||||
|
quelea
|
||||||
|
quetzal
|
||||||
|
rabbit
|
||||||
|
raccoon
|
||||||
|
rail
|
||||||
|
ram
|
||||||
|
rat
|
||||||
|
raven
|
||||||
|
red-deer
|
||||||
|
red-panda
|
||||||
|
reindeer
|
||||||
|
rhinoceros
|
||||||
|
rook
|
||||||
|
salamander
|
||||||
|
salmon
|
||||||
|
sand-dollar
|
||||||
|
sandpiper
|
||||||
|
sardine
|
||||||
|
scorpion
|
||||||
|
seahorse
|
||||||
|
seal
|
||||||
|
shark
|
||||||
|
sheep
|
||||||
|
shrew
|
||||||
|
skunk
|
||||||
|
snail
|
||||||
|
snake
|
||||||
|
sparrow
|
||||||
|
spider
|
||||||
|
spoonbill
|
||||||
|
squid
|
||||||
|
squirrel
|
||||||
|
starling
|
||||||
|
stingray
|
||||||
|
stinkbug
|
||||||
|
stork
|
||||||
|
swallow
|
||||||
|
swan
|
||||||
|
tapir
|
||||||
|
tarsier
|
||||||
|
termite
|
||||||
|
tiger
|
||||||
|
toad
|
||||||
|
trout
|
||||||
|
turkey
|
||||||
|
turtle
|
||||||
|
viper
|
||||||
|
vulture
|
||||||
|
wallaby
|
||||||
|
walrus
|
||||||
|
wasp
|
||||||
|
weasel
|
||||||
|
whale
|
||||||
|
wildcat
|
||||||
|
wolf
|
||||||
|
wolverine
|
||||||
|
wombat
|
||||||
|
woodcock
|
||||||
|
woodpecker
|
||||||
|
worm
|
||||||
|
wren
|
||||||
|
yak
|
||||||
|
zebra
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
amber
|
||||||
|
amethyst
|
||||||
|
apricot
|
||||||
|
aqua
|
||||||
|
aquamarine
|
||||||
|
auburn
|
||||||
|
azure
|
||||||
|
beige
|
||||||
|
black
|
||||||
|
blue
|
||||||
|
bronze
|
||||||
|
brown
|
||||||
|
buff
|
||||||
|
carmine
|
||||||
|
celadon
|
||||||
|
cerise
|
||||||
|
cerulean
|
||||||
|
charcoal
|
||||||
|
chartreuse
|
||||||
|
chocolate
|
||||||
|
cinnamon
|
||||||
|
copper
|
||||||
|
coral
|
||||||
|
cream
|
||||||
|
crimson
|
||||||
|
cyan
|
||||||
|
denim
|
||||||
|
emerald
|
||||||
|
fuchsia
|
||||||
|
gold
|
||||||
|
goldenrod
|
||||||
|
gray
|
||||||
|
green
|
||||||
|
grey
|
||||||
|
indigo
|
||||||
|
ivory
|
||||||
|
jade
|
||||||
|
khaki
|
||||||
|
lavender
|
||||||
|
lemon
|
||||||
|
lilac
|
||||||
|
lime
|
||||||
|
magenta
|
||||||
|
mahogany
|
||||||
|
maroon
|
||||||
|
mauve
|
||||||
|
mustard
|
||||||
|
navy
|
||||||
|
ochre
|
||||||
|
olive
|
||||||
|
orange
|
||||||
|
orchid
|
||||||
|
peach
|
||||||
|
pear
|
||||||
|
periwinkle
|
||||||
|
pink
|
||||||
|
plum
|
||||||
|
puce
|
||||||
|
purple
|
||||||
|
quartz
|
||||||
|
red
|
||||||
|
rose
|
||||||
|
ruby
|
||||||
|
rust
|
||||||
|
salmon
|
||||||
|
sapphire
|
||||||
|
scarlet
|
||||||
|
silver
|
||||||
|
slate
|
||||||
|
tan
|
||||||
|
taupe
|
||||||
|
teal
|
||||||
|
tomato
|
||||||
|
topaz
|
||||||
|
turquoise
|
||||||
|
ultramarine
|
||||||
|
umber
|
||||||
|
vanilla
|
||||||
|
violet
|
||||||
|
white
|
||||||
|
yellow
|
||||||
@@ -0,0 +1,236 @@
|
|||||||
|
agnesi
|
||||||
|
albattani
|
||||||
|
allen
|
||||||
|
almeida
|
||||||
|
antonelli
|
||||||
|
archimedes
|
||||||
|
ardinghelli
|
||||||
|
aryabhata
|
||||||
|
austin
|
||||||
|
babbage
|
||||||
|
banach
|
||||||
|
banzai
|
||||||
|
bardeen
|
||||||
|
bartik
|
||||||
|
bassi
|
||||||
|
beaver
|
||||||
|
bell
|
||||||
|
benz
|
||||||
|
bhabha
|
||||||
|
bhaskara
|
||||||
|
black
|
||||||
|
blackburn
|
||||||
|
blackwell
|
||||||
|
bohr
|
||||||
|
booth
|
||||||
|
borg
|
||||||
|
bose
|
||||||
|
bouman
|
||||||
|
boyd
|
||||||
|
brahmagupta
|
||||||
|
brattain
|
||||||
|
brown
|
||||||
|
buck
|
||||||
|
burnell
|
||||||
|
cannon
|
||||||
|
carson
|
||||||
|
cartwright
|
||||||
|
carver
|
||||||
|
cerf
|
||||||
|
chandrasekhar
|
||||||
|
chaplygin
|
||||||
|
chatelet
|
||||||
|
chatterjee
|
||||||
|
chaum
|
||||||
|
chebyshev
|
||||||
|
clarke
|
||||||
|
cohen
|
||||||
|
colden
|
||||||
|
cori
|
||||||
|
cray
|
||||||
|
curie
|
||||||
|
curran
|
||||||
|
darwin
|
||||||
|
davinci
|
||||||
|
dewdney
|
||||||
|
dhawan
|
||||||
|
diffie
|
||||||
|
dijkstra
|
||||||
|
dirac
|
||||||
|
driscoll
|
||||||
|
dubinsky
|
||||||
|
easley
|
||||||
|
edison
|
||||||
|
einstein
|
||||||
|
elbakyan
|
||||||
|
elgamal
|
||||||
|
elion
|
||||||
|
ellis
|
||||||
|
engelbart
|
||||||
|
euclid
|
||||||
|
euler
|
||||||
|
faraday
|
||||||
|
feistel
|
||||||
|
fermat
|
||||||
|
fermi
|
||||||
|
feynman
|
||||||
|
franklin
|
||||||
|
gagarin
|
||||||
|
galileo
|
||||||
|
galois
|
||||||
|
ganguly
|
||||||
|
gates
|
||||||
|
gauss
|
||||||
|
germain
|
||||||
|
goldberg
|
||||||
|
goldstine
|
||||||
|
goldwasser
|
||||||
|
golick
|
||||||
|
goodall
|
||||||
|
gould
|
||||||
|
greider
|
||||||
|
grothendieck
|
||||||
|
haibt
|
||||||
|
hamilton
|
||||||
|
haslett
|
||||||
|
hawking
|
||||||
|
heisenberg
|
||||||
|
hellman
|
||||||
|
hermann
|
||||||
|
herschel
|
||||||
|
hertz
|
||||||
|
heyrovsky
|
||||||
|
hodgkin
|
||||||
|
hofstadter
|
||||||
|
hoover
|
||||||
|
hopper
|
||||||
|
hugle
|
||||||
|
hypatia
|
||||||
|
ishizaka
|
||||||
|
jackson
|
||||||
|
jang
|
||||||
|
jemison
|
||||||
|
jennings
|
||||||
|
jepsen
|
||||||
|
johnson
|
||||||
|
joliot
|
||||||
|
jones
|
||||||
|
kalam
|
||||||
|
kapitsa
|
||||||
|
kare
|
||||||
|
keldysh
|
||||||
|
keller
|
||||||
|
kepler
|
||||||
|
khayyam
|
||||||
|
khorana
|
||||||
|
kilby
|
||||||
|
kirch
|
||||||
|
knuth
|
||||||
|
kowalevski
|
||||||
|
lalande
|
||||||
|
lamarr
|
||||||
|
lamport
|
||||||
|
leakey
|
||||||
|
leavitt
|
||||||
|
lederberg
|
||||||
|
lehmann
|
||||||
|
lewin
|
||||||
|
lichterman
|
||||||
|
liskov
|
||||||
|
lovelace
|
||||||
|
lumiere
|
||||||
|
mahavira
|
||||||
|
margulis
|
||||||
|
matsumoto
|
||||||
|
maxwell
|
||||||
|
mayer
|
||||||
|
mccarthy
|
||||||
|
mcclintock
|
||||||
|
mclaren
|
||||||
|
mclean
|
||||||
|
mcnulty
|
||||||
|
meitner
|
||||||
|
mendel
|
||||||
|
mendeleev
|
||||||
|
meninsky
|
||||||
|
merkle
|
||||||
|
mestorf
|
||||||
|
mirzakhani
|
||||||
|
montalcini
|
||||||
|
moore
|
||||||
|
morse
|
||||||
|
moser
|
||||||
|
murdock
|
||||||
|
napier
|
||||||
|
nash
|
||||||
|
neumann
|
||||||
|
newton
|
||||||
|
nightingale
|
||||||
|
nobel
|
||||||
|
noether
|
||||||
|
northcutt
|
||||||
|
noyce
|
||||||
|
panini
|
||||||
|
pare
|
||||||
|
pascal
|
||||||
|
pasteur
|
||||||
|
payne
|
||||||
|
perlman
|
||||||
|
pike
|
||||||
|
poincare
|
||||||
|
poitras
|
||||||
|
proskuriakova
|
||||||
|
ptolemy
|
||||||
|
raman
|
||||||
|
ramanujan
|
||||||
|
rhodes
|
||||||
|
ride
|
||||||
|
ritchie
|
||||||
|
robinson
|
||||||
|
roentgen
|
||||||
|
rosalind
|
||||||
|
rubin
|
||||||
|
saha
|
||||||
|
sammet
|
||||||
|
sanderson
|
||||||
|
satoshi
|
||||||
|
shamir
|
||||||
|
shannon
|
||||||
|
shaw
|
||||||
|
shirley
|
||||||
|
shockley
|
||||||
|
shtern
|
||||||
|
sinoussi
|
||||||
|
snyder
|
||||||
|
solomon
|
||||||
|
spence
|
||||||
|
stonebraker
|
||||||
|
sutherland
|
||||||
|
swanson
|
||||||
|
swartz
|
||||||
|
swirles
|
||||||
|
taussig
|
||||||
|
tesla
|
||||||
|
tharp
|
||||||
|
thompson
|
||||||
|
torvalds
|
||||||
|
tu
|
||||||
|
turing
|
||||||
|
varahamihira
|
||||||
|
vaughan
|
||||||
|
villani
|
||||||
|
visvesvaraya
|
||||||
|
volhard
|
||||||
|
wescoff
|
||||||
|
wilbur
|
||||||
|
wiles
|
||||||
|
williams
|
||||||
|
williamson
|
||||||
|
wilson
|
||||||
|
wing
|
||||||
|
wozniak
|
||||||
|
wright
|
||||||
|
wu
|
||||||
|
yalow
|
||||||
|
yonath
|
||||||
|
zhukovsky
|
||||||
+1296
File diff suppressed because it is too large
Load Diff
+1000
File diff suppressed because it is too large
Load Diff
@@ -125,6 +125,8 @@ split=### split
|
|||||||
spwin=### spwin
|
spwin=### spwin
|
||||||
detach=### detach
|
detach=### detach
|
||||||
bkg=### bkg
|
bkg=### bkg
|
||||||
|
jobrunner=### jobrunner
|
||||||
|
jr=### jr
|
||||||
ssh=### ssh
|
ssh=### ssh
|
||||||
clipboard=## 5.9 Clipboard
|
clipboard=## 5.9 Clipboard
|
||||||
copy-fn=### y
|
copy-fn=### y
|
||||||
|
|||||||
@@ -1482,6 +1482,71 @@ Add -i (interactive confirmation) to destructive commands:
|
|||||||
Example:
|
Example:
|
||||||
# Rendered automatically by fish; not called directly.
|
# Rendered automatically by fish; not called directly.
|
||||||
|
|
||||||
|
### jobrunner
|
||||||
|
|
||||||
|
Synopsis: jobrunner [<subcommand>] [<name>] [<command>...]
|
||||||
|
jr [<subcommand>] [<name>] [<command>...]
|
||||||
|
|
||||||
|
Runs, lists, inspects, re-attaches to, and terminates named background
|
||||||
|
jobs using GNU screen as the process engine. Unlike bkg and detach,
|
||||||
|
which discard output, a jobrunner job keeps a live terminal you can
|
||||||
|
return to later — it survives closing the shell, and `attach` restores
|
||||||
|
it in any subsequent session.
|
||||||
|
|
||||||
|
Every subcommand has a matching flag form, and the common cases are
|
||||||
|
inferred: no arguments lists jobs, a lone name attaches to it, and a
|
||||||
|
name followed by a command runs it.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
run, -r, --run <name> <cmd>... Start a named job in the background
|
||||||
|
list, -l, --list List all managed background jobs
|
||||||
|
attach, -a, --attach <name> Re-attach interactively to a job
|
||||||
|
kill, -k, --kill <name> Terminate a running background job
|
||||||
|
logs, -o, --output <name> Print a job's current output, no attach
|
||||||
|
help, -h, --help Show usage help
|
||||||
|
|
||||||
|
Exit Status:
|
||||||
|
0 Command succeeded, or no jobs are running
|
||||||
|
1 Invalid arguments, or the named job does not exist
|
||||||
|
127 screen is not installed
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Detach from an attached job with Ctrl-A then D; the job keeps running.
|
||||||
|
Commands are executed directly rather than through a shell, so pipes and
|
||||||
|
redirections must be wrapped explicitly, e.g.
|
||||||
|
`jobrunner run sync fish -c 'a | b'`.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
jobrunner run build make -j8
|
||||||
|
jobrunner backup rsync -a ./data remote:/backup/
|
||||||
|
jobrunner list
|
||||||
|
jobrunner logs build
|
||||||
|
jobrunner build
|
||||||
|
jobrunner kill build
|
||||||
|
|
||||||
|
**Dependencies:** `screen`, `__jobrunner_sessions`
|
||||||
|
|
||||||
|
**Used by:** `jr`
|
||||||
|
|
||||||
|
### jr
|
||||||
|
|
||||||
|
Synopsis: jr [<subcommand>] [<name>] [<command>...]
|
||||||
|
|
||||||
|
Shorthand for jobrunner. Accepts the same subcommands, flags, and
|
||||||
|
shorthands, and inherits its completions.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
See jobrunner --help for the full argument reference.
|
||||||
|
|
||||||
|
Exit Status:
|
||||||
|
Same as jobrunner.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
jr run build make -j8
|
||||||
|
jr list
|
||||||
|
|
||||||
|
**Dependencies:** `jobrunner`
|
||||||
|
|
||||||
### split
|
### split
|
||||||
|
|
||||||
Synopsis: split [-h | -v] [command...]
|
Synopsis: split [-h | -v] [command...]
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
# Copyright (C) 2026 Rootiest
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# SYNOPSIS
|
||||||
|
# __jobrunner_sessions [<tool>]
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
# Parses `tmux list-sessions` or `screen -ls` into machine-readable rows,
|
||||||
|
# one per active session: name, PID, state, and start time separated by tabs.
|
||||||
|
# Shared by jobrunner and its completions so both agree on what a session is
|
||||||
|
# named. Prints nothing when no sessions exist.
|
||||||
|
#
|
||||||
|
# EXIT STATUS
|
||||||
|
# 0 Parsed successfully (including the zero-session case)
|
||||||
|
# 1 tool (tmux or screen) is not installed
|
||||||
|
#
|
||||||
|
# RETURNS
|
||||||
|
# One line per session: <name>\t<pid>\t<state>\t<started>
|
||||||
|
#
|
||||||
|
# EXAMPLE
|
||||||
|
# __jobrunner_sessions
|
||||||
|
# __jobrunner_sessions tmux | string replace -r '\t.*$' ''
|
||||||
|
function __jobrunner_sessions --description 'List active jobrunner sessions as name/pid/state/started rows'
|
||||||
|
set -l tool $argv[1]
|
||||||
|
if test -z "$tool"
|
||||||
|
if command -q tmux
|
||||||
|
set tool tmux
|
||||||
|
else if command -q screen
|
||||||
|
set tool screen
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if test "$tool" = tmux
|
||||||
|
command -q tmux; or return 1
|
||||||
|
set -l tab (printf '\t')
|
||||||
|
for line in (command tmux list-sessions -F "#{session_name}$tab#{pid}$tab#{?session_attached,Attached,Detached}$tab#{t:session_created}" 2>/dev/null)
|
||||||
|
# tmux output is natively tab-separated.
|
||||||
|
printf '%s\n' $line
|
||||||
|
end
|
||||||
|
else if test "$tool" = screen
|
||||||
|
command -q screen; or return 1
|
||||||
|
# screen -ls exits 1 when nothing is running; the parse handles that.
|
||||||
|
for line in (command screen -ls 2>/dev/null)
|
||||||
|
# Session rows are tab-indented and start with "<pid>.<name>".
|
||||||
|
set -l m (string match -r '^\s+(\d+)\.([^\t]+)\t(.*)$' -- $line)
|
||||||
|
or continue
|
||||||
|
|
||||||
|
# Trailing fields are parenthesized: "(<date>)\t(<state>)", and some
|
||||||
|
# screen builds omit the date, so read the state off the end.
|
||||||
|
set -l fields (string split \t -- $m[4])
|
||||||
|
set -l state (string trim -c '()' -- $fields[-1])
|
||||||
|
set -l started ""
|
||||||
|
if test (count $fields) -gt 1
|
||||||
|
set started (string trim -c '()' -- $fields[1])
|
||||||
|
end
|
||||||
|
|
||||||
|
printf '%s\t%s\t%s\t%s\n' $m[3] $m[2] $state $started
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -16,27 +16,27 @@ function _fish_deps_catalog
|
|||||||
set -g _fdc_bins \
|
set -g _fdc_bins \
|
||||||
uv cargo fish starship fzf zoxide direnv paru yay \
|
uv cargo fish starship fzf zoxide direnv paru yay \
|
||||||
wakatime tailscale \
|
wakatime tailscale \
|
||||||
eza lsd bat btop dust duf prettyping ov rg lazygit lazydocker trash kitty wezterm python3 yt-dlp
|
eza lsd bat btop dust duf prettyping ov rg lazygit lazydocker trash kitty wezterm python3 yt-dlp screen
|
||||||
|
|
||||||
set -g _fdc_tiers \
|
set -g _fdc_tiers \
|
||||||
rec rec req rec req rec rec rec rec \
|
rec rec req rec req rec rec rec rec \
|
||||||
int int \
|
int int \
|
||||||
rec rec rec rec rec rec rec rec rec rec rec rec rec rec rec rec
|
rec rec rec rec rec rec rec rec rec rec rec rec rec rec rec rec rec
|
||||||
|
|
||||||
set -g _fdc_cargo \
|
set -g _fdc_cargo \
|
||||||
"" "" "" starship "" zoxide "" "" "" \
|
"" "" "" starship "" zoxide "" "" "" \
|
||||||
"" "" \
|
"" "" \
|
||||||
eza lsd bat "" du-dust "" "" ov ripgrep "" "" trashy "" "" "" ""
|
eza lsd bat "" du-dust "" "" ov ripgrep "" "" trashy "" "" "" "" ""
|
||||||
|
|
||||||
set -g _fdc_pm \
|
set -g _fdc_pm \
|
||||||
uv cargo fish starship fzf zoxide direnv "" yay \
|
uv cargo fish starship fzf zoxide direnv "" yay \
|
||||||
wakatime tailscale \
|
wakatime tailscale \
|
||||||
eza lsd bat btop dust duf prettyping ov ripgrep lazygit lazydocker trash kitty wezterm python yt-dlp
|
eza lsd bat btop dust duf prettyping ov ripgrep lazygit lazydocker trash kitty wezterm python yt-dlp screen
|
||||||
|
|
||||||
set -g _fdc_special \
|
set -g _fdc_special \
|
||||||
curl-uv rustup-installer git-cargo-fish curl-installer fzf-update "" "" paru-build yay-build \
|
curl-uv rustup-installer git-cargo-fish curl-installer fzf-update "" "" paru-build yay-build \
|
||||||
wakatime-binary "" \
|
wakatime-binary "" \
|
||||||
"" "" "" "" "" "" "" "" "" "" curl-lazydocker "" "" "" "" ""
|
"" "" "" "" "" "" "" "" "" "" curl-lazydocker "" "" "" "" "" ""
|
||||||
end
|
end
|
||||||
|
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
|
|||||||
@@ -0,0 +1,354 @@
|
|||||||
|
# Copyright (C) 2026 Rootiest
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# CATEGORY
|
||||||
|
# 08-terminal-management
|
||||||
|
#
|
||||||
|
# DEPENDENCIES
|
||||||
|
# tmux, screen, __jobrunner_sessions
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
# jobrunner [-t <tool>] [<subcommand>] [<name>] [<command>...]
|
||||||
|
# jr [-t <tool>] [<subcommand>] [<name>] [<command>...]
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
# Runs, lists, inspects, re-attaches to, and terminates named background
|
||||||
|
# jobs using tmux or GNU screen as the process engine. Unlike bkg and
|
||||||
|
# detach, which discard output, a jobrunner job keeps a live terminal you
|
||||||
|
# can return to later — it survives closing the shell, and `attach`
|
||||||
|
# restores it in any subsequent session.
|
||||||
|
# Run and manage named background jobs. Jobs are detached from the shell
|
||||||
|
# and backed by tmux (preferred) or GNU screen.
|
||||||
|
#
|
||||||
|
# If the job name is omitted when starting a new job (e.g. `jobrunner sleep 1`),
|
||||||
|
# a memorable, random name (like `sleepy-badger`) will be generated.
|
||||||
|
#
|
||||||
|
# SUBCOMMANDS
|
||||||
|
# run, -r, --run [-n <name>] <cmd> Start a new background job
|
||||||
|
# list, -l, --list List all running jobs (default if no args)
|
||||||
|
# attach, -a, --attach <name> Attach to a running job's terminal
|
||||||
|
# kill, -k, --kill <name> Terminate a running background job
|
||||||
|
# logs, -o, --output <name> Print a job's current output, no attach
|
||||||
|
# help, -h, --help Show usage help
|
||||||
|
#
|
||||||
|
# EXIT STATUS
|
||||||
|
# 0 Command succeeded, or no jobs are running
|
||||||
|
# 1 Invalid arguments, or the named job does not exist
|
||||||
|
# 127 neither tmux nor screen is installed
|
||||||
|
#
|
||||||
|
# EXAMPLE
|
||||||
|
# jobrunner run -n build make -j8
|
||||||
|
# jobrunner sleep 1000
|
||||||
|
# jobrunner -t screen run -n backup rsync -a ./data remote:/backup/
|
||||||
|
# jobrunner list
|
||||||
|
# jobrunner logs build
|
||||||
|
# jobrunner build
|
||||||
|
# jobrunner kill build
|
||||||
|
#
|
||||||
|
# NOTES
|
||||||
|
# Detach from an attached job with Ctrl-A then D; the job keeps running.
|
||||||
|
# Commands are executed directly rather than through a shell, so pipes and
|
||||||
|
# redirections must be wrapped explicitly, e.g.
|
||||||
|
# `jobrunner run sync fish -c 'a | b'`.
|
||||||
|
function jobrunner --description 'Manage detached background jobs with tmux or GNU screen'
|
||||||
|
set -l c_head (set_color --bold cyan)
|
||||||
|
set -l c_cmd (set_color --bold white)
|
||||||
|
set -l c_arg (set_color cyan)
|
||||||
|
set -l c_flag (set_color yellow)
|
||||||
|
set -l c_ok (set_color green)
|
||||||
|
set -l c_err (set_color red)
|
||||||
|
set -l c_dim (set_color brblack)
|
||||||
|
set -l c_rst (set_color normal)
|
||||||
|
|
||||||
|
set -l subcmds run list attach kill logs help \
|
||||||
|
-r --run -l --list -a --attach -k --kill -o --output -h --help
|
||||||
|
|
||||||
|
# ╭──────────────────────────────────────────────────────────╮
|
||||||
|
# │ Tool Extraction │
|
||||||
|
# ╰──────────────────────────────────────────────────────────╯
|
||||||
|
set -l tool ""
|
||||||
|
set -l global_name ""
|
||||||
|
while test (count $argv) -gt 0
|
||||||
|
switch $argv[1]
|
||||||
|
case -t
|
||||||
|
set tool $argv[2]
|
||||||
|
set -e argv[1..2]
|
||||||
|
case --tool
|
||||||
|
set tool $argv[2]
|
||||||
|
set -e argv[1..2]
|
||||||
|
case '--tool=*'
|
||||||
|
set tool (string replace -- "--tool=" "" $argv[1])
|
||||||
|
set -e argv[1]
|
||||||
|
case '-t*'
|
||||||
|
set tool (string replace -r "^-t" "" $argv[1])
|
||||||
|
set -e argv[1]
|
||||||
|
case -n
|
||||||
|
set global_name $argv[2]
|
||||||
|
set -e argv[1..2]
|
||||||
|
case --name
|
||||||
|
set global_name $argv[2]
|
||||||
|
set -e argv[1..2]
|
||||||
|
case '--name=*'
|
||||||
|
set global_name (string replace -- "--name=" "" $argv[1])
|
||||||
|
set -e argv[1]
|
||||||
|
case '-n*'
|
||||||
|
set global_name (string replace -r "^-n" "" $argv[1])
|
||||||
|
set -e argv[1]
|
||||||
|
case '*'
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# ╭──────────────────────────────────────────────────────────╮
|
||||||
|
# │ Help │
|
||||||
|
# ╰──────────────────────────────────────────────────────────╯
|
||||||
|
# Answered before the dependency check so usage is readable anywhere.
|
||||||
|
if set -q argv[1]; and contains -- $argv[1] help -h --help
|
||||||
|
echo "$c_head""Usage:$c_rst $c_cmd""jobrunner$c_rst $c_arg""[<subcommand>] [<name>] [<command>...]$c_rst"
|
||||||
|
echo
|
||||||
|
echo " Run and manage named background jobs backed by tmux or GNU screen."
|
||||||
|
echo " If $c_arg<name>$c_rst is omitted, a random memorable name is generated."
|
||||||
|
echo
|
||||||
|
echo "$c_head""Subcommands:$c_rst"
|
||||||
|
echo " $c_cmd""run$c_rst, $c_flag-r$c_rst, $c_flag--run$c_rst $c_arg""[-n <name>] <cmd>$c_rst Start a new background job"
|
||||||
|
echo " $c_cmd""list$c_rst, $c_flag-l$c_rst, $c_flag--list$c_rst List all running jobs (default)"
|
||||||
|
echo " $c_cmd""attach$c_rst, $c_flag-a$c_rst, $c_flag--attach$c_rst $c_arg""<name>$c_rst Attach to a running job's terminal"
|
||||||
|
echo " $c_cmd""kill$c_rst, $c_flag-k$c_rst, $c_flag--kill$c_rst $c_arg""<name>$c_rst Terminate a running background job"
|
||||||
|
echo " $c_cmd""logs$c_rst, $c_flag-o$c_rst, $c_flag--output$c_rst $c_arg""<name>$c_rst Print a job's current output, no attach"
|
||||||
|
echo " $c_cmd""help$c_rst, $c_flag-h$c_rst, $c_flag--help$c_rst Show usage help"
|
||||||
|
echo
|
||||||
|
echo "$c_head""Options:$c_rst"
|
||||||
|
echo " $c_flag-t$c_rst, $c_flag--tool$c_rst $c_arg""<tool>$c_rst Force backend tool ('tmux' or 'screen')"
|
||||||
|
echo " $c_flag-n$c_rst, $c_flag--name$c_rst $c_arg""<name>$c_rst Set explicit name for a new job"
|
||||||
|
echo
|
||||||
|
echo "$c_head""Shortcuts:$c_rst"
|
||||||
|
echo " $c_cmd""jobrunner$c_rst $c_arg""<name>$c_rst $c_dim""attach <name>$c_rst"
|
||||||
|
echo " $c_cmd""jobrunner$c_rst $c_arg""[-n <name>] <cmd>...$c_rst$c_dim""run [-n <name>] <cmd>...$c_rst"
|
||||||
|
echo
|
||||||
|
echo "$c_head""Examples:$c_rst"
|
||||||
|
echo " $c_cmd""jobrunner$c_rst $c_arg""run -n build$c_rst""$c_dim"" make -j8$c_rst"
|
||||||
|
echo " $c_cmd""jobrunner$c_rst $c_arg""sleep 1000$c_rst"
|
||||||
|
echo " $c_cmd""jobrunner$c_rst $c_arg""logs build$c_rst"
|
||||||
|
echo " $c_cmd""jobrunner$c_rst $c_arg""kill build$c_rst"
|
||||||
|
echo
|
||||||
|
echo "$c_dim""Detach from an attached job with Ctrl-A then D.$c_rst"
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
# ╭──────────────────────────────────────────────────────────╮
|
||||||
|
# │ Dependency check │
|
||||||
|
# ╰──────────────────────────────────────────────────────────╯
|
||||||
|
if test -n "$tool"
|
||||||
|
if not contains -- $tool tmux screen
|
||||||
|
echo "$c_err""jobrunner:$c_rst invalid tool '$c_arg$tool$c_rst', must be 'tmux' or 'screen'." >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
if not command -q $tool
|
||||||
|
echo "$c_err""jobrunner:$c_rst '$tool' is required but was not found in PATH." >&2
|
||||||
|
return 127
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if command -q tmux
|
||||||
|
set tool tmux
|
||||||
|
else if command -q screen
|
||||||
|
set tool screen
|
||||||
|
else
|
||||||
|
echo "$c_err""jobrunner:$c_rst neither 'tmux' nor 'screen' was found in PATH." >&2
|
||||||
|
return 127
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# ╭──────────────────────────────────────────────────────────╮
|
||||||
|
# │ Argument pre-processing │
|
||||||
|
# ╰──────────────────────────────────────────────────────────╯
|
||||||
|
set -q argv[1]; or set argv list
|
||||||
|
set -l cmd $argv[1]
|
||||||
|
|
||||||
|
if not contains -- $cmd $subcmds
|
||||||
|
if test (count $argv) -eq 1
|
||||||
|
# A lone name attaches, but only if that job actually exists.
|
||||||
|
if contains -- $cmd (__jobrunner_sessions $tool | string replace -r '\t.*$' '')
|
||||||
|
set argv attach $argv
|
||||||
|
set cmd attach
|
||||||
|
else
|
||||||
|
echo "$c_err""jobrunner:$c_rst unknown subcommand or job '$c_arg$cmd$c_rst'." >&2
|
||||||
|
echo "Run $c_cmd""jobrunner --help$c_rst for usage." >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
# A name plus a command line is an implicit run.
|
||||||
|
set argv run $argv
|
||||||
|
set cmd run
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# ╭──────────────────────────────────────────────────────────╮
|
||||||
|
# │ Dispatch │
|
||||||
|
# ╰──────────────────────────────────────────────────────────╯
|
||||||
|
switch $cmd
|
||||||
|
case run -r --run
|
||||||
|
set -l name "$global_name"
|
||||||
|
set -l task
|
||||||
|
|
||||||
|
while test (count $argv) -gt 1
|
||||||
|
switch $argv[2]
|
||||||
|
case -n --name
|
||||||
|
set name $argv[3]
|
||||||
|
set -e argv[2..3]
|
||||||
|
case '--name=*'
|
||||||
|
set name (string replace -- "--name=" "" $argv[2])
|
||||||
|
set -e argv[2]
|
||||||
|
case '-n*'
|
||||||
|
set name (string replace -r "^-n" "" $argv[2])
|
||||||
|
set -e argv[2]
|
||||||
|
case '*'
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if test (count $argv) -lt 2
|
||||||
|
echo "$c_head""Usage:$c_rst $c_cmd""jobrunner run$c_rst $c_arg""[-n <name>] <command>...$c_rst" >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -z "$name"
|
||||||
|
set name (rand_string adjective animal)
|
||||||
|
end
|
||||||
|
set task $argv[2..-1]
|
||||||
|
|
||||||
|
# screen stores each session as a socket file named after it.
|
||||||
|
if string match -q '*/*' -- $name
|
||||||
|
echo "$c_err""jobrunner:$c_rst job name may not contain '/'." >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
if contains -- $name (__jobrunner_sessions $tool | string replace -r '\t.*$' '')
|
||||||
|
echo "$c_err""jobrunner:$c_rst job '$c_arg$name$c_rst' is already running." >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if test "$tool" = tmux
|
||||||
|
command tmux new-session -d -s $name $task
|
||||||
|
else
|
||||||
|
command screen -d -m -S $name $task
|
||||||
|
end
|
||||||
|
or begin
|
||||||
|
echo "$c_err""jobrunner:$c_rst failed to start job '$c_arg$name$c_rst'." >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l pid
|
||||||
|
for row in (__jobrunner_sessions $tool)
|
||||||
|
set -l f (string split \t -- $row)
|
||||||
|
test "$f[1]" = "$name"; and set pid $f[2]; and break
|
||||||
|
end
|
||||||
|
|
||||||
|
if set -q pid[1]
|
||||||
|
echo "$c_ok""✔$c_rst Started job $c_arg$name$c_rst $c_dim(PID $pid)$c_rst"
|
||||||
|
else
|
||||||
|
# The job may have finished (or failed) before we looked.
|
||||||
|
echo "$c_ok""✔$c_rst Started job $c_arg$name$c_rst $c_dim(already exited)$c_rst"
|
||||||
|
end
|
||||||
|
|
||||||
|
case list -l --list
|
||||||
|
set -l rows (__jobrunner_sessions $tool)
|
||||||
|
if test (count $rows) -eq 0
|
||||||
|
echo "No background jobs running."
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
printf '%s%-20s %-8s %-10s %s%s\n' "$c_head" JOB PID STATE STARTED "$c_rst"
|
||||||
|
for row in $rows
|
||||||
|
set -l f (string split \t -- $row)
|
||||||
|
printf '%s%-20s%s %-8s %-10s %s%s%s\n' \
|
||||||
|
"$c_arg" $f[1] "$c_rst" $f[2] $f[3] "$c_dim" $f[4] "$c_rst"
|
||||||
|
end
|
||||||
|
|
||||||
|
case attach -a --attach
|
||||||
|
if test (count $argv) -ne 2
|
||||||
|
echo "$c_head""Usage:$c_rst $c_cmd""jobrunner attach$c_rst $c_arg""<name>$c_rst" >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
set -l name $argv[2]
|
||||||
|
if not contains -- $name (__jobrunner_sessions $tool | string replace -r '\t.*$' '')
|
||||||
|
echo "$c_err""jobrunner:$c_rst no such job '$c_arg$name$c_rst'." >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
if test "$tool" = tmux
|
||||||
|
command tmux attach-session -t $name
|
||||||
|
else
|
||||||
|
# -x attaches to an already-attached session instead of failing.
|
||||||
|
command screen -x $name
|
||||||
|
end
|
||||||
|
|
||||||
|
case kill -k --kill
|
||||||
|
if test (count $argv) -ne 2
|
||||||
|
echo "$c_head""Usage:$c_rst $c_cmd""jobrunner kill$c_rst $c_arg""<name>$c_rst" >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
set -l name $argv[2]
|
||||||
|
if not contains -- $name (__jobrunner_sessions $tool | string replace -r '\t.*$' '')
|
||||||
|
echo "$c_err""jobrunner:$c_rst no such job '$c_arg$name$c_rst'." >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
if test "$tool" = tmux
|
||||||
|
command tmux kill-session -t $name
|
||||||
|
else
|
||||||
|
command screen -X -S $name quit
|
||||||
|
end
|
||||||
|
or begin
|
||||||
|
echo "$c_err""jobrunner:$c_rst failed to terminate job '$c_arg$name$c_rst'." >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
echo "$c_ok""✔$c_rst Terminated job $c_arg$name$c_rst"
|
||||||
|
|
||||||
|
case logs -o --output
|
||||||
|
if test (count $argv) -ne 2
|
||||||
|
echo "$c_head""Usage:$c_rst $c_cmd""jobrunner logs$c_rst $c_arg""<name>$c_rst" >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
set -l name $argv[2]
|
||||||
|
if not contains -- $name (__jobrunner_sessions $tool | string replace -r '\t.*$' '')
|
||||||
|
echo "$c_err""jobrunner:$c_rst no such job '$c_arg$name$c_rst'." >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l out
|
||||||
|
if test "$tool" = tmux
|
||||||
|
# capture-pane -S - -p outputs the scrollback and current pane directly to stdout.
|
||||||
|
set out (command tmux capture-pane -t $name -S - -p)
|
||||||
|
or begin
|
||||||
|
echo "$c_err""jobrunner:$c_rst could not read output of '$c_arg$name$c_rst'." >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
# hardcopy -h dumps scrollback plus the visible screen to a file.
|
||||||
|
# ponytail: snapshot only; add `screen -L` logging if full
|
||||||
|
# since-start history is ever needed.
|
||||||
|
set -l dump (command mktemp)
|
||||||
|
command screen -X -S $name hardcopy -h $dump
|
||||||
|
or begin
|
||||||
|
command rm -f $dump
|
||||||
|
echo "$c_err""jobrunner:$c_rst could not read output of '$c_arg$name$c_rst'." >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
set out (command cat $dump)
|
||||||
|
command rm -f $dump
|
||||||
|
end
|
||||||
|
|
||||||
|
# hardcopy (and sometimes tmux) pad the dump with empty lines.
|
||||||
|
while set -q out[1]; and test -z "$out[-1]"
|
||||||
|
set -e out[-1]
|
||||||
|
end
|
||||||
|
if set -q out[1]
|
||||||
|
printf '%s\n' $out
|
||||||
|
else
|
||||||
|
echo "$c_dim(no output yet)$c_rst"
|
||||||
|
end
|
||||||
|
|
||||||
|
case '*'
|
||||||
|
echo "$c_err""jobrunner:$c_rst invalid subcommand '$c_arg$cmd$c_rst'." >&2
|
||||||
|
echo "Run $c_cmd""jobrunner --help$c_rst for usage." >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Copyright (C) 2026 Rootiest
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# CATEGORY
|
||||||
|
# 08-terminal-management
|
||||||
|
#
|
||||||
|
# DEPENDENCIES
|
||||||
|
# jobrunner
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
# jr [<subcommand>] [<name>] [<command>...]
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
# Shorthand for jobrunner. Accepts the same subcommands, flags, and
|
||||||
|
# shorthands, and inherits its completions.
|
||||||
|
#
|
||||||
|
# ARGUMENTS
|
||||||
|
# See jobrunner --help for the full argument reference.
|
||||||
|
#
|
||||||
|
# EXIT STATUS
|
||||||
|
# Same as jobrunner.
|
||||||
|
#
|
||||||
|
# EXAMPLE
|
||||||
|
# jr run build make -j8
|
||||||
|
# jr list
|
||||||
|
function jr --wraps jobrunner --description 'Shorthand for jobrunner'
|
||||||
|
jobrunner $argv
|
||||||
|
end
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
# lstree ~/projects/myapp
|
# lstree ~/projects/myapp
|
||||||
function lstree --description 'Full recursive tree listing'
|
function lstree --description 'Full recursive tree listing'
|
||||||
if which eza >/dev/null 2>&1
|
if which eza >/dev/null 2>&1
|
||||||
eza --tree --icons --color=auto --hyperlink $argv
|
eza --tree --icons --color=auto --hyperlink=auto $argv
|
||||||
else if which lsd >/dev/null 2>&1
|
else if which lsd >/dev/null 2>&1
|
||||||
lsd --tree --hyperlink=auto $argv
|
lsd --tree --hyperlink=auto $argv
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -0,0 +1,185 @@
|
|||||||
|
# Copyright (C) 2026 Rootiest
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
# CATEGORY
|
||||||
|
# 14-miscellaneous
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
# rand_string [COMPONENTS/MODIFIERS]...
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
# Generates a random, memorable string using a sequence of specified word
|
||||||
|
# categories and formatting modifiers. Words are pulled from curated
|
||||||
|
# plain-text databases bundled in `data/words/`.
|
||||||
|
#
|
||||||
|
# Modifiers like `--separator` and `--case` are evaluated sequentially and
|
||||||
|
# apply only to the components that follow them.
|
||||||
|
#
|
||||||
|
# Supported Components:
|
||||||
|
# <category> A bundled word list (e.g. adjective, animal, color, name, noun, verb)
|
||||||
|
# digits=<N> N random digits (e.g. digits=3 -> 842)
|
||||||
|
# literal=<text> A static string component (e.g. literal=TEST)
|
||||||
|
#
|
||||||
|
# ARGUMENTS
|
||||||
|
# -s, --separator=<sep> Delimiter for subsequent words (dash, underscore, dot, none, or literal chars)
|
||||||
|
# -c, --case=<casing> Casing for subsequent words (lower, upper, title)
|
||||||
|
# -h, --help Show usage help
|
||||||
|
#
|
||||||
|
# EXIT STATUS
|
||||||
|
# 0 String generated successfully
|
||||||
|
# 1 Unknown category or missing word list file
|
||||||
|
#
|
||||||
|
# EXAMPLE
|
||||||
|
# rand_string adjective animal
|
||||||
|
# rand_string --case=title color animal --separator=dot digits=4
|
||||||
|
# rand_string literal=TEST --separator=underscore verb noun
|
||||||
|
#
|
||||||
|
# NOTES
|
||||||
|
# Falls back to `random choice` if GNU `shuf` is missing, but `shuf` is
|
||||||
|
# much faster for files with >1000 lines.
|
||||||
|
function rand_string --description 'Generate random, memorable strings from curated word databases'
|
||||||
|
set -l c_head (set_color --bold cyan)
|
||||||
|
set -l c_cmd (set_color --bold white)
|
||||||
|
set -l c_arg (set_color cyan)
|
||||||
|
set -l c_flag (set_color yellow)
|
||||||
|
set -l c_rst (set_color normal)
|
||||||
|
|
||||||
|
if set -q argv[1]; and contains -- $argv[1] -h --help
|
||||||
|
echo "$c_head""Usage:$c_rst $c_cmd""rand_string$c_rst $c_arg""[COMPONENTS/MODIFIERS]...$c_rst"
|
||||||
|
echo
|
||||||
|
echo " Generate random, memorable strings from curated word databases."
|
||||||
|
echo
|
||||||
|
echo "$c_head""Components:$c_rst"
|
||||||
|
echo " $c_arg<category>$c_rst A bundled word list (e.g. adjective, animal, color, name, noun, verb)"
|
||||||
|
echo " $c_arg""digits=<N>$c_rst N random digits (e.g. digits=3 -> 842)"
|
||||||
|
echo " $c_arg""literal=<text>$c_rst A static string component for prefixes/suffixes (e.g. literal=TEST)"
|
||||||
|
echo
|
||||||
|
echo "$c_head""Modifiers:$c_rst"
|
||||||
|
echo " $c_flag-s$c_rst, $c_flag--separator=<sep>$c_rst Delimiter for subsequent words (dash, underscore, dot, none)"
|
||||||
|
echo " $c_flag-c$c_rst, $c_flag--case=<casing>$c_rst Casing for subsequent words (lower, upper, title)"
|
||||||
|
echo " $c_flag-h$c_rst, $c_flag--help$c_rst Show usage help"
|
||||||
|
echo
|
||||||
|
echo "$c_head""Examples:$c_rst"
|
||||||
|
echo " $c_cmd""rand_string$c_rst adjective animal"
|
||||||
|
echo " $c_cmd""rand_string$c_rst --case=title color animal --separator=dot digits=4"
|
||||||
|
echo " $c_cmd""rand_string$c_rst literal=TEST --separator=underscore verb noun"
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l sep "dash"
|
||||||
|
set -l casing "lower"
|
||||||
|
|
||||||
|
# Locate the words directory relative to this function
|
||||||
|
set -l words_dir ""
|
||||||
|
if set -q __fish_config_dir
|
||||||
|
set words_dir "$__fish_config_dir/data/words"
|
||||||
|
else
|
||||||
|
# Fallback if __fish_config_dir isn't available
|
||||||
|
set words_dir "$HOME/.config/fish/data/words"
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l result ""
|
||||||
|
set -l i 1
|
||||||
|
|
||||||
|
while test $i -le (count $argv)
|
||||||
|
set -l arg $argv[$i]
|
||||||
|
set -l handled 0
|
||||||
|
|
||||||
|
# 1. Parse inline modifiers
|
||||||
|
switch $arg
|
||||||
|
case -s --separator
|
||||||
|
set i (math $i + 1)
|
||||||
|
set sep $argv[$i]
|
||||||
|
set handled 1
|
||||||
|
case '--separator=*'
|
||||||
|
set sep (string replace -- "--separator=" "" $arg)
|
||||||
|
set handled 1
|
||||||
|
case '-s*'
|
||||||
|
set sep (string replace -r "^-s" "" $arg)
|
||||||
|
set handled 1
|
||||||
|
case -c --case
|
||||||
|
set i (math $i + 1)
|
||||||
|
set casing $argv[$i]
|
||||||
|
set handled 1
|
||||||
|
case '--case=*'
|
||||||
|
set casing (string replace -- "--case=" "" $arg)
|
||||||
|
set handled 1
|
||||||
|
case '-c*'
|
||||||
|
set casing (string replace -r "^-c" "" $arg)
|
||||||
|
set handled 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if test $handled -eq 1
|
||||||
|
set i (math $i + 1)
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
# 2. Resolve separator alias
|
||||||
|
set -l actual_sep $sep
|
||||||
|
switch $sep
|
||||||
|
case dash
|
||||||
|
set actual_sep "-"
|
||||||
|
case underscore
|
||||||
|
set actual_sep "_"
|
||||||
|
case dot
|
||||||
|
set actual_sep "."
|
||||||
|
case none empty
|
||||||
|
set actual_sep ""
|
||||||
|
end
|
||||||
|
|
||||||
|
# 3. Generate the component part
|
||||||
|
set -l part ""
|
||||||
|
switch $arg
|
||||||
|
case 'digits=*'
|
||||||
|
set -l n (string replace -- "digits=" "" $arg)
|
||||||
|
if not string match -qr '^\d+$' -- $n
|
||||||
|
set n 1
|
||||||
|
end
|
||||||
|
for idx in (seq $n)
|
||||||
|
set part "$part"(random 0 9)
|
||||||
|
end
|
||||||
|
case 'literal=*'
|
||||||
|
set part (string replace -- "literal=" "" $arg)
|
||||||
|
case 'string=*'
|
||||||
|
set part (string replace -- "string=" "" $arg)
|
||||||
|
case '*'
|
||||||
|
set -l db "$words_dir/$arg.txt"
|
||||||
|
if not test -f "$db"
|
||||||
|
echo "rand_string: unknown category or file missing for '$arg'" >&2
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
# Fetch random line (shuf is fastest, random choice is portable fallback)
|
||||||
|
if command -q shuf
|
||||||
|
set part (command shuf -n 1 "$db")
|
||||||
|
else
|
||||||
|
set part (random choice (command cat "$db"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# 4. Apply casing (skip for literal text)
|
||||||
|
if not string match -q 'literal=*' -- $arg; and not string match -q 'string=*' -- $arg
|
||||||
|
switch $casing
|
||||||
|
case upper
|
||||||
|
set part (string upper $part)
|
||||||
|
case lower
|
||||||
|
set part (string lower $part)
|
||||||
|
case title
|
||||||
|
set part (string replace -r '^(.)' '\U$1' (string lower $part))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# 5. Append to result
|
||||||
|
if test -n "$result"
|
||||||
|
set result "$result$actual_sep$part"
|
||||||
|
else
|
||||||
|
set result "$part"
|
||||||
|
end
|
||||||
|
|
||||||
|
set i (math $i + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -n "$result"
|
||||||
|
echo $result
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user