I have a little helper command in ~/.zshrc
called stfu
.
stfu() {
if [ -z "$1" ]; then
echo "Usage: stfu <program> [arguments...]"
return 1
fi
nohup "$@" &>/dev/null &
disown
}
complete -W "$(ls /usr/bin)" stfu
stfu
will run some other command but also detach it from the terminal and make any output shut up. I use it for things such as starting a browser from the terminal without worrying about CTRL+Z
, bg
, and disown
.
$ stfu firefox -safe-mode
# Will not output stuff to the terminal, and
# I can close the terminal too.
Here’s my issue:
On the second argument and above, when I hit tab, how do I let autocomplete suggest me the arguments and command line switches for the command I’m passing in?
e.g. stfu ls -<tab>
should show me whatever ls’s completion function is, rather than listing every /usr/bin
command again.
# Intended completion
$ stfu cat -<TAB>
-e -- equivalent to -vE
--help -- display help and exit
--number -n -- number all output lines
--number-nonblank -b -- number nonempty output lines, overrides -n
--show-all -A -- equivalent to -vET
--show-ends -E -- display $ at end of each line
--show-nonprinting -v -- use ^ and M- notation, except for LFD and TAB
--show-tabs -T -- display TAB characters as ^I
--squeeze-blank -s -- suppress repeated empty output lines
-t -- equivalent to -vT
-u -- ignored
# Actual completion
$ stfu cat <tab>
...a list of all /usr/bin commands
$ stfu cat -<tab>
...nothing, since no /usr/bin commands start with -
(repost, prev was removed)
EDIT: Solved.
I needed to set the curcontext
to the second word. Below is my (iffily annotated) zsh implementation, enjoy >:)
stfu() {
if [ -z "$1" ]; then
echo "Usage: stfu <program> [arguments...]"
return 1
fi
nohup "$@" &>/dev/null &
disown
}
#complete -W "$(ls /usr/bin)" stfu
_stfu() {
# Curcontext looks like this:
# $ stfu <tab>
# :complete:stfu:
local curcontext="$curcontext"
#typeset -A opt_args # idk what this does, i removed it
_arguments \
'1: :_command_names -e' \
'*::args:->args'
case $state in
args)
# idk where CURRENT came from
if (( CURRENT > 1 )); then
# $words is magic that splits up the "words" in a shell command.
# 1. stfu
# 2. yourSubCommand
# 3. argument 1 to that subcommand
local cmd=${words[2]}
# We update the autocompletion curcontext to
# pay attention to your subcommand instead
curcontext="$cmd"
# Call completion function
_normal
fi
;;
esac
}
compdef _stfu stfu
Deduced via docs (look for The Dispatcher), this dude's docs, stackoverflow and overreliance on ChatGPT.
EDIT: Best solution (Andy)
stfu() {
if [ -z "$1" ]; then
echo "Usage: stfu <program> [arguments...]"
return 1
fi
nohup "$@" &>/dev/null &
disown
}
_stfu () {
# shift autocomplete to right
shift words
(( CURRENT-=1 ))
_normal
}
compdef _stfu stfu
Sometimes friends, in their curiosity, come up to me and ask me, Jordan Belfort-style, "Sell me ~~this pen~~ Linux." Why do I like it so much, they wonder?
And I always tell them:
"Linux is like... the vegan OS. (bear with me) Mac and Windows people don't really care about OSes. People who switch to Linux either find they couldn't be assed to deal with it, or they love it, and those who love it love it. Then they always tell people lol.
A good thing though: because everyone's such an opinionated nerd, the lateral set of problems you run into won't be 'solved' by random Microsoft Forums
/sfc scannow
s or arcane regedits, but by a nut who debugged the entire thing 30 minutes after the bug came to exist to find a workaround. True story.Buuuut Linux is more of a lateral movement in terms of problems, it's just a tool after all. You solve Microsoft Recall and start menu ads but run into new but tiny annoyances. I find Linux problems easier to fix than Windows ones because of the nerd army thing but if your Windows setup works for you, it works and that's really all that's important. If you do start Linuxing though you'll learn a lot just by osmosis."
And they usually laugh and decide to keep their routines in place. Don't hate me vegans.