Bash + fzf - V2.0: One Hop Function to Rule Them All

codeniocodenio
3 min read

Building on the Foundation: Project Switching Gets Even Better

A few months ago, I shared a Bash function for faster project switching using fzf. It was simple, effective, and saved me countless keystrokes daily. But as I kept using it, I noticed some limitations and opportunities for improvement.

Today, I'm sharing version 2.0โ€”a more flexible, powerful approach that handles multiple project directories and gives you more control over what happens after you select a project.

The Evolution : From projects() ๐Ÿš€ hop()

Here's the new and improved function:

hop() { 
    base_dir="$1"

    # List directory contents
    if [[ $2 == *-l* || $2 == *--list* ]]; then
        ll $base_dir

    # Navigate to selected project
    elif [[ $2 == *-c* || $2 == *--cd* ]]; then
        repo=`command ls $base_dir | fzf --height=50% --layout=reverse`
        if [[ "$repo" != "" ]]; then
            cd $base_dir/$repo
        fi

    # Open project in editor
    elif [[ $2 == *-o* ||  $2 == *--open* ]]; then
        valid_options="code cursor" 
        option=`echo "code\ncursor" | fzf --height=50% --layout=reverse`
        if [[ "${valid_options}" =~ "${option}" ]]; then
            repo=`command ls $base_dir | fzf --height=50% --layout=reverse` 
            if [[ "$repo" != "" ]]; then
                $option $base_dir/$repo
            fi
        fi

    # Default: change to base directory
    else
        cd $base_dir
    fi
}

Using hop

The function works with both direct calls and convenient aliases:

# Direct calls to any directory with flag
hop ~/workspace/projects -o
hop /Volumes/ExternalDrive/client-work -l

# Create convenient aliases for different project directories
# Each alias calls hop() with a specific directory path
alias projects='hop ~/workspace/projects' # Work projects
alias github='hop ~/workspace/github'     # GitHub repositories

When you call hop with a path or run any alias (say projects), here's what happens:

  1. Choose your action: Use flags to specify what you want to do

    • No flags โ†’ Change to the directory

    • -l โ†’ List the contents of the directory

    • -c โ†’ Browse projects with fzf, then navigate there

    • -o โ†’ Choose editor (VS Code/Cursor), then open the selected project

      • code โ†’ Browse the directories, then open in VS Code

      • cursor โ†’ Browse the directories, then open in Cursor

Extending the Function

Want to add support for your favorite editor? Just modify the valid_options and add it to the echo statement:

valid_options="code cursor vim subl"
option=`echo "code\ncursor\nvim\nsubl" | fzf --height=50% --layout=reverse`

Need a new hopping directory? Add an alias:

alias gohub='hop ~/go/src/github.com'

Key Improvements

Small improvements matter. This version builds on the original by providing a more flexible flag-based approach that works with any directory. Sometimes the best upgrades are the ones that eliminate friction you didn't notice before.

  • Simpler Interface: Use flags (-l, -c, -o) to control behavior, or no flags to simply navigate

  • Generic Directories Support: One function handles hopping to any directory through direct calls or aliases

  • Extensible Design: Easy to add new editors or project directories without modifying the core function

Get Started

Add the function and aliases to your .bashrc or .zshrc, adjust the paths to match your setup, and reload your shell.

If you're already using the previous version, this is a drop-in replacement that will feel immediately familiar but more powerful.

Try it out and let me know what you think. Better yet, tell me how you've customized it for your workflow.

Happy hopping! ๐Ÿฆ˜

0
Subscribe to my newsletter

Read articles from codenio directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

codenio
codenio