
Hacking up your own shell completion - feltarock
https://feltrac.co/environment/2020/01/18/build-your-own-shell-completion.html
======
maddyboo
I'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
This is included in fzf itself. See
[https://github.com/junegunn/fzf/wiki/Configuring-fuzzy-
compl...](https://github.com/junegunn/fzf/wiki/Configuring-fuzzy-completion)

~~~
TsiCClawOfLight
What exactly is included in fzf itself? I use fzf a lot, but I've never come
across these features.

~~~
JNRowe
The 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 :/.

------
mic47
This 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
Can you share how you do this please?

~~~
danShumway
Not 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
If 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 '

------
jonfw
It'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
Dropping 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
I 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.

------
Axsuul
For 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)

~~~
StavrosK
No love for fish? Aw.

~~~
ghthor
I'd love to add support for fish, but I have a hard enough time maintaining
the zsh support.

------
pstuart
This 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
Python prompt toolkit can do much of this.

~~~
pstuart
I'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!

------
kfoley
Had 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/)

------
celeritascelery
This 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.

------
akdor1154
I really want to see a cross-shell, declarative language for autocomplete
definitions. Does such a thing exist?

~~~
dim-an
On my Christmas holidays I built a little tool that does similar things.

Features I wanted to include originally were

    
    
       1 shell completion autogeneration from `--help` texts;
       2 support bash/zsh/fish;
       3 support toml-like description of command arguments.
    

At the moment I have a tool that generates completions from `--help` messages
and supports bash/zsh. I use it daily and it makes me little bit happier.

[1] [https://github.com/dim-an/cod](https://github.com/dim-an/cod)

~~~
StavrosK
It's called "cod" and doesn't support fish? :(

~~~
dim-an
Why would I need a fish if I already have cod? ;)

Actually when I started this project I used fish as my main shell on laptop
and first versions of cod did support fish, but then I decided to focus
bash/zsh as they look more popular.

I still want to add fish support when I have some time though. It doesn't look
complicated.

------
bilekas
Well this is nice... Great way to spend my Friday!

