[Jodavaho.io] — Josh Vander Hook

Using FZF and bash to quickly move about

Warp, zsh, etc etc. You don’t need those for normal everyday things, since Bash is Turing Complete(tm) view full post

Oh look

… another advanced cli utility that is a rewrite + a tiny bit of functionality. And bonus, it’s in Rust!

https://news.ycombinator.com/item?id=45342943

This particular utility, z was also posted last year. It’s part of the “Warp” shell, and one could be forgiven for feeling like a dusty left-behind with all these fancy shell features. Thing is, bash is turing complete. You can do all this with a tiny bit of learning about how to use the shell you have, vs learning an entirely new shell. Plus, you’ll never be lost when you find yourself on another machine that isn’t hyper-customized with your brittle setup!

Basic example

Let’s say you have fzf installed. If you don’t, you’ll probably want it for many reasons. If you refuse, then see below, but this does make things much easier. Try this: cd $(find . -type d | fzf). That will change to a directory using fzf, and honestly it’s quite functional as is. You could make a bash function from that and use it.

Try it with preview! cd $(find . type d | fzf --preview="ls {} -l").

Scale up

Slightly more advanced would be tab-complete for a z-like cd command.

It would work like this:

  1. Make an alias fcd
  2. Make a tab complete that does that for the command fcd

This is kind of 101 bash - just DIY.

Here’s mine:

(2) is the hardest part - just write something that works with complete and fzf. Nowadays this is childs play for any AI to just spit out.

fz_comp()
{
  COMPREPLY=()
  local cur="${COMP_WORDS[COMP_CWORD]}"
  local prev="${COMP_WORDS[COMP_CWORD-1]}"
  local opts="none"
  if [ -z "$cur" ];then
    COMPREPLY=($(find $1 -type d | fzf --preview="ls {} -l"))
    return
  fi
  COMPREPLY=($(find $1 -type d | grep $cur | fzf --preview="ls {} -l"))
}

(1) is just a) set the new command b) make the completion call c) map that call to completion.

alias fcd=cd
_fcd(){ fz_comp $(pwd) }
complete -F _fcd fcd

there you go. Now you can fcd <tab> to get fuzzy search on directories to change to.

Extending

Note this: fz_comp $(pwd)… This sets the current directory ($(pwd)) to be the root of the search. You can pick any directory. I have several aliases like fcd to change to my work root workspace, or my journal, or anywhere else.

Just add many commands like this:

# Change to a subfolder of .logs
alias lcd=cd
_lcd(){ fz_comp ~/.logs }
complete -F _lcd lcd

# Change to a subfolder of .journal
alias jcd=cd
_jcd(){ fz_comp ~/.journal }
complete -F _jcd jcd

etc…

No fzf for idealogical reasons?

OK, so you want to fight about fzf? That’s fine, try it this way (github.com/jodavaho/smartcd) which is pure bash and easily installed. Of course, I wrote it by hand long ago when I was too dumb to use fzf, and it’s in serious need of cleanup, but there you go.

Comments

I have not configured comments for this site yet as there doesn't seem to be any good, free solutions. Please feel free to email, or reach out on social media if you have any thoughts or questions. I'd love to hear from you!