Ideally this could all be part of a library such as argparse for typical cases, right?
A similar thing in Bash is `complete -F _longopt YourCmd`, but these will not work with "multi-commands" that have "sub-commands" as the article of this thread covers. Truth is, as non-standard as GNU long opts already are, how subcommands work is even more non-standard (are there even global options? Or between each subcommand? Is it how Python does it? Or Go? Or some one specific library or ..?)
[^1]: https://no-color.org/
ripgrep exposes its (bespoke) shell completion and man page generation through a --generate option: rg --generate=man, rg --generate=complete-bash, etcetera. In xh (clap-based) we provide the same but AFAIK we're the only one to copy that interface.
Symfony (for PHP) provides some kind of runtime completion generation but I don't know the details.
https://pkgstats.archlinux.de/compare/packages#packages=bash...
OTOH, it's only 4-7% on Debian (also opt-in):
If you don’t like the Verb-Noun nonsense I’d encourage you to look at the default aliases as they make everything a lot less verbose. For example Where-Object is just “where” or getchild-item is default aliased to ls and gci.
Id encourage you to look at NuShell as well since it is mostly the same philosophy as PowerShell.
And `rc` under plan9/9front did a Unix shell better than the classic Unix itself.
It parses all man pages on your system and generates completion files for you. By default, they go into ~/.cache/fish/generated_completions/*
If the man page was written poorly/is missing, you can always write your own completion (and hopefully send it upstream). fish uses such a simple format that I don't think there's any need for tutorials save the official doc:
https://fishshell.com/docs/current/completions.html
For example, here's an excerpt from curl
complete --command curl --short-option 'L' --long-option 'location' --description 'Follow redirects'
complete --command curl --short-option 'O' --long-option 'remote-name' --description 'Write output to file named as remote file'
Still in an early stage, but it should work.
thanks a lot
Say you have a widget that has 3 commands: list, start and stop.
With one of those completion files widget stop <tab> will show you a tab-able list of widgets which are running.
https://github.com/fish-shell/fish-shell/discussions/11670#d...
> I'm not sure that subsequence matching ever produces results that people expect (I feel like we've discussed this before but haven't had time to go digging)
No solution, but the discussion seems positive, from a maintainer too.
> We don't really do config flags like this, as a philosophical point.
> I would be against accepting such a PR. I do not believe this should be changed.
I understand that they want to keep the list of configs short and manageable, but it means that's not a tool for me. I'm all for good, opinionated defaults but I want to be able to make some changes if I want to.
They apparently reconsidered and implemented the change since migrating fish to rust though.
(Well that and all my machines come from the same NixOS configs.)
I have personally embraced the insanity but let’s not kid ourselves about nixos basically just being three bashes in a trench coat.
Basically https://xkcd.com/224/ , but s/lisp/nix/ s/perl/bash/
Some year something better will show up from someone with more taste (and I know I am not alone in having thoughts on what it would look like), but for now the yak has already been shaven. At least the builds are sandboxed.
As an example of diversity estimation that you can try at home, a couple of times I have run every single command in my command search PATH with --help </dev/null >/tmp/help.$c 2>&1 . Caution - be careful if you do this! Have backups/checksums of everything important and run as an unprivileged user. I always have to kill off several processes that just hang doing something or otherwise manually intervene. Anyway, this alone suggests data collection of help text is not a trivial problem.
Beyond data collection, many commands did not/do not use CLI toolkits at all. Their commands may have even less regular syntax. Freeform help makes it harder to produce a regular help syntax to convert into the interpreter needed by a completion system. That said, as elsethread commented for some toolkits the Zsh _gnu_generic works great! It essentially IS the "automagic" system you might want, just for a highly restricted circumstance.
Any CLI toolkit itself does have the data, by necessity. So, if the CLI framework supports the 2 or 3 common shells there is no need for a translator exactly. You just need a code generator. There is a stab at an auto-generation framework from said data for the Nim CLI toolkit, cligen, over at:
https://github.com/c-blake/cligen/blob/master/util/complgen....
but it only works for Zsh right now. Anyway, I don't think perfect should be the enemy of the good or anything like that, but you seemed to ask an earnest "why" question and these are some of the complexities.
As for the 30..60 commands, I use the following "tricks"
1) my ctrl-p is mapped in a way that it searches the prefix into history. (On phone right now)
2) long history which syncs with other machines in a machine-name-suffixed file via syncthing
3) justfile which are really a game changer. I used bare j to tell me what commands are available (as opposed to running the first command) and I basically know everything I can and do do in that folder
4)
See: https://pixi.carapace.sh/ or https://github.com/withfig/autocomplete
It's still a hard problem as lots of tools format --help differently. One of the things I'm jealous in Poweshell is their standardized completions
Sometimes I’m close to disabling/uninstalling all completion scripts out of irritation as decades of muscle memory are frustrated by this behavior.
It’s like that bad/annoying UX with text fields where the UI is constantly fighting against you in order prevent you from producing “illegal” intermediate input - e.g. let me paste the clipboard here goddammit - I know what I’m doing - I’ll correct it.
Unbelievably frustrating.
It should at least print a message like "file foo.exe exists but it isn't executable".
It's not a fix but it'll save a little time sometimes.
TLDR: M-/ (Alt /) will do file auto-completions regardless of the commands auto-comoletion. It is a different method, but maybe could help.
There are a collection of other non-context aware completion functions that are bound by default too, useful for example when you when you wish to complete hostnames in a for-loop.
zle has what is largely a significant superset of this, the documentation is spread about between the zshzle and zshcomp* manpages.
#compdef set-java-home
local -a versions=(~/apps/java/*(:t))
_describe 'version' versions
So basically almost a one-liner (but couldn't do it really one-liner, unfortunately).That being said, csh advocates definitely influenced everything in the Bourne/POSIX family.
Custom completions may be configured by creating an array named ‘complete_command’, optionally suffixed with an argument number to complete only for a single argument. So defining an array named ‘complete_kill’ provides possible completions for any argument to the kill(1) command, but ‘complete_kill_1’ only completes the first argument. For example, the following command makes ksh offer a selection of signal names for the first argument to kill(1):
set -A complete_kill_1 -- -9 -HUP -INFO -KILL -TERM
Or is this ksh93 syntax that oksh back ported?
David Korn thanked the pdksh authors and maintainers for making it available in the years when true ksh was closed (ksh88) or open but licensed with awkward terms (ksh93 for several years).
David Korn interview (I asked one of the questions):
https://m.slashdot.org/story/16351
"First of all pdksh is a ksh88 clone; and I might add a better clone than the MKS Korn Shell...
"I don't know the pdksh development team but I would like to thank them for the service they have done in making a version of ksh available while ksh was proprietary. I have noticed remarkable improvements in pdksh in its ability to mimic ksh88 functionality. I don't know what plans the pdksh development team has now that ksh93 is available in open source form, but I certainly would help them try to maintain compatibility if they do continue pdksh distribution. Otherwise, I would hope that they would pick up the ksh93 source and help support and enhance it."
Unfortunately my work doesn't allow me to share code, but essentially I remapped ssh to a bash script that maintains an environment variable containing the args (you must do this because each <tab> press is an independent invocation of the script. Then you run into persistence problems, so I added a call to compute elapsed seconds so that it flushes the state variable after a 10s timeout).
The bash script then forwards the args to a python script that reads a JSON file and figures out which params (such as 'co' or 'qa') map to which hostnames. It also matches against partial hostnames, so when you see this after tab
qa-server-co1 qa-server-co2 pr-server-co3
you only need to add '3' to the list of args to narrow it down to 1 match, then hit <enter> to ssh to that host.
I'm still on the fence if replacing the argparse blocks in my fish scripts is worth the hassle, but against things like old school optparse, it's far better
lihaoyi•15h ago
oezi•15h ago
tetha•14h ago
But at work, I've been slowly adding auto completion to our ansible wrapper scripts, like explanations which playbooks to use when, smart `-l` completion based off a possibly selected playbook (so, if the playbook is postgres.yml, it doesn't suggest mariadb groups), tag autocompletion (with a few, admittedly, hardcoded explanations how these tags should be used) and such.
It's somewhat of a friday-afternoon struggle project, but it's making the big ansible project pretty approachable to use.
imcritic•12h ago
bbkane•11h ago
Instead of sourcing the zsh completion script on every startup, you can install it into somewhere on $fpath and zsh will "compile" and cache the completions. This can really speed up shell startup time, but of course is harder to set up. Users have to understand $fpath to put the completions there.
I distribute my CLIs via Homebrew which can install completions automatically.