7 ms·
Hacking up your own shell completion
- celeritascelery 7y agoThis is really cool! I had something similar with a bunch of pearl scripts at work. Essentially I would call perldoc on them and parse the output to get the command line options. But the fzf addition is a nice touch.
- jonfw 7y agoIt's been really cool to see tools such as tmux, FZF, or Fish make waves on our interactions with the terminal. CLI is such a mature space, tools have to be really great to gain any traction.
- lemmox 7y agoDropping a drive-by upvote for the Fish[1] reference. I started using it last year and really like it. [1] https://fishshell.com/ https://fishshell.com/
- scolby33 7y agoI use fish as my main shell. Sometimes I find its documentation a bit obtuse, but I love the sense of humor in its tag line: “a shell for the 90s.” It was first released in 2005.
- maddyboo 7y agoI've been using a zsh plugin called fzf-tab[1] for the past few weeks and it's been awesome. So many use cases: - of course, command completion - type `echo $` and press tab - fzf through all your environment variables - type `command ` and press tab - fzf through all programs available in your PATH - type `builtin ` and press tab - fzf through all of zsh's builtin functions - select multiple results at once, they'll be concatenated with spaces - pick files, with the ability to press / to select a directory and automatically restart fzf-tab inside of it 1: https://github.com/Aloxaf/fzf-tab https://github.com/Aloxaf/fzf-tab
- nhooyr 7y agoThis is included in fzf itself. See https://github.com/junegunn/fzf/wiki/Configuring-fuzzy-completion https://github.com/junegunn/fzf/wiki/Configuring-fuzzy-compl...
- TsiCClawOfLight 7y agoWhat exactly is included in fzf itself? I use fzf a lot, but I've never come across these features.
- JNRowe 7y agoThe file selection/multi picker example at least can work with the fzf package alone. There are a bunch of files in shell/ from the tarball that enable a little magic like interactive history support and the inline picker. On Debian they're also installed in /usr/share/doc/fzf/examples/ for sourcing in your .${shell}rc. No idea about out-of-the-box support for any of the other completions from maddyboo's post :/.
- akdor1154 7y agoI really want to see a cross-shell, declarative language for autocomplete definitions. Does such a thing exist?
- sullyj3 7y agohttps://www.redox-os.org/news/rsoc-ion-ux-2/ https://www.redox-os.org/news/rsoc-ion-ux-2/
- flukus 7y agoI wouldn't want to limit myself like that. The best home spun completions I've written will do things like look up values in a database, differ depending on previous arguments, parse some file, etc. These will never fit into a declarative language.
- lonelappde 7y agoYes it can. https://news.ycombinator.com/item?id=22500928 https://news.ycombinator.com/item?id=22500928
- chubot 7y agoThe "declarative" part doesn't really make sense IMO, but there are a bunch of links here about having a shell-agnostic system: https://github.com/oilshell/oil/wiki/Shell-Autocompletion https://github.com/oilshell/oil/wiki/Shell-Autocompletion https://github.com/oilshell/oil/wiki/Projects-Already-Doing-Something-Like-Shellac https://github.com/oilshell/oil/wiki/Projects-Already-Doing-... https://github.com/mbrubeck/compleat https://github.com/mbrubeck/compleat (one of the only grammar-based ones, looks nice but doesn't appear to have been used very much) There are some discussions about cross-shell autocompletion on the #shell-autocompletion channel of https://oilshell.zulipchat.com/ https://oilshell.zulipchat.com/, but it didn't go that far. The Ion work described in the sibling blog post went the furthest in terms of implementation I think, but I haven't heard anything about it in awhile.
- akdor1154 7y agoThese are awesome, thanks. By 'declarative' I mean some way of telling the shell how my bin can provide completions itself. E.g. for the AWS util, I am envisioning something like aws ec2 describe-instances --instance-id __INSTANCEID__ __INSTANCEID__: $(aws ec2 list-instances --query Instance.ID) Syntax here is not anything like a well thought out proposal, just a demonstration of what I believe to be a shell agnostic method of describing both 'where can I complete?' and 'how can I compete it?'
- pstuart 7y agoThis appears right under the CLUI post, how apropos. The CLUI stuff looks cool but I'd rather use something more unix-y than nodejs and React. Seems like ncurses with simple structured data and the right hooks could do something close to what CLUI is doing.
- mixmastamyk 7y agoPython prompt toolkit can do much of this.
- pstuart 7y agoI'm more partial to a self-contained binary type of solution -- C or Go, in this case. But that toolkit does look like a valuable source of inspiration. Thanks!
- Axsuul 7y agoFor those looking to do git command line, I find scm_breeze[0] to be indispensable 0. https://github.com/scmbreeze/scm_breeze https://github.com/scmbreeze/scm_breeze
- fuckyah 7y agoThat’s why I love fish shell! For me the best shell!
- bilekas 7y agoWell this is nice... Great way to spend my Friday!
- mic47 7y agoThis is cool, I'll definitely add this to my workflow. What I do is that I have custom bash history (with no limit on how many item there can be), that stores also an active directory, and id of the shell session. Then when I hit ctrl-R, it pipe that history into the fzf in special order: things from my current session history, then from the current directory, and then rest. This means, that if I come 2 months later to some older project and want to remember how to run tests / deploy, I just hit ctrl-r, and I find what I need.
- oarsinsync 7y agoCan you share how you do this please?
- danShumway 7y agoNot GP, and my setup is a great deal less sophisticated than GP's. However, in my `.bashrc`, I have: log_bash_persistent_history() { [[ $(history 1) =~ ^\ *[0-9]+\ +([^\ ]+\ [^\ ]+)\ +(.*)$ ]] local date_part="${BASH_REMATCH[1]}" local command_part="${BASH_REMATCH[2]}" if [ "$command_part" != "$PERSISTENT_HISTORY_LAST" ] then echo $date_part "|" "$command_part" >> ~/.persistent_history export PERSISTENT_HISTORY_LAST="$command_part" fi } # Stuff to do on PROMPT_COMMAND run_on_prompt_command() { log_bash_persistent_history } PROMPT_COMMAND="run_on_prompt_command" HISTTIMEFORMAT="%d/%m/%y %T " alias phgrep='cat ~/.persistent_history|grep --color' alias hgrep='history|grep --color' This doesn't save all of the information like the current shell, working directory, etc... but you could easily modify it to include that information. It also doesn't do all of the context-aware piping, you have to rely on grep. But just having a really good persistent history is itself insanely useful. My setup was itself stolen from someone else on HN a few years ago, and I've since forgotten their name.
- mic47 7y agoIf you want to have just persistent histry (really simple), you can use vanilla bash history something like. export HISTCONTROL=ignorespace shopt -s histappend export HISTSIZE=99999999 # Big enough number to never rotate history (or when you really don't care) export HISTFILESIZE=99999999 shopt -s checkwinsize export HISTTIMEFORMAT='%F %T '
- kfoley 7y agoHad a similar issue with an in house tool and learned that `click`, the framework we use for CLI's, has built in support for generating auto completions[0]. Could be worth it for others to check if such a feature exists for the framework they're using. [0] https://click.palletsprojects.com/en/7.x/bashcomplete/ https://click.palletsprojects.com/en/7.x/bashcomplete/