π FZF_RG_FD_COMPLETE_GUIDE.md
π The Ultimate FZF + Ripgrep + fd Guide for Termux (2025)
The Trinity of Modern CLI Tools
Last Updated: October 2025
Optimized for: Termux on Android
π¦ Official Repositories
- fzf: https://github.com/junegunn/fzf (Fuzzy Finder)
- ripgrep (rg): https://github.com/BurntSushi/ripgrep (Fast grep alternative)
- fd: https://github.com/sharkdp/fd (Fast find alternative)
π Table of Contents
- Installation
- Why This Trinity?
- Quick Start
- FZF + FD Integration
- FZF + Ripgrep Integration
- The Complete Trinity
- Real-World Workflows
- Advanced Recipes
- Custom Functions Library
- Performance Optimization
- Termux-Specific Tips
π₯ Installation
Install All Three Tools in Termux
# Update package lists
pkg update && pkg upgrade
# Install the trinity
pkg install fzf ripgrep fd
# Optional but highly recommended companions
pkg install bat exa git
# Verify installations
fzf --version
rg --version
fd --version
π― Why This Trinity?
The Problem with Traditional Tools:
# Slow and verbose
find . -type f -name "*.js" 2>/dev/null
# Limited and outdated
grep -r "function" .
# Not interactive
locate file.txt
The Modern Solution:
| Tool | Purpose | Speed | Features |
|---|---|---|---|
| fd | Find files | π 3-10x faster than find |
Ignores .git, colors, smart case |
| rg | Search content | π 5-50x faster than grep |
Respects .gitignore, colors |
| fzf | Interactive filter | π Instant fuzzy search | Preview, multi-select, keybindings |
Combined Power:
# Find files blazingly fast + interactive selection + live preview
fd --type f | fzf --preview 'bat --color=always {}'
# Search content everywhere + interactive results + jump to line
rg --line-number . | fzf --delimiter : --preview 'bat --color=always {1} --highlight-line {2}'
β‘ Quick Start
Basic Commands
fd (Fast Find)
# Find all files
fd
# Find by name
fd config
# Find specific type
fd -e js # JavaScript files
fd -e py # Python files
fd -e md # Markdown files
# Find in specific directory
fd config /etc
# Include hidden files
fd -H
# Search in depth
fd --max-depth 3
rg (Ripgrep)
# Search in current directory
rg "pattern"
# Case-insensitive search
rg -i "pattern"
# Show line numbers
rg -n "pattern"
# Search specific file types
rg -t js "function"
rg -t py "def "
# Show context (lines before/after)
rg -C 3 "pattern"
# Search and show file names only
rg -l "pattern"
fzf (Fuzzy Finder)
# Basic fuzzy find
fzf
# With preview
fzf --preview 'cat {}'
# Multi-select
fzf -m
# Custom height
fzf --height 40%
π FZF + FD Integration
1. Basic File Finder (fd + fzf)
# Simple file search
fd --type f | fzf
# With preview
fd --type f | fzf --preview 'bat --color=always --style=numbers {}'
# Include hidden files
fd --type f --hidden | fzf --preview 'bat --color=always {}'
# Exclude patterns
fd --type f --exclude node_modules --exclude .git | fzf --preview 'bat {}'
2. Directory Navigation (fd + fzf)
# Jump to any directory
cd $(fd --type d | fzf)
# With preview of directory contents
cd $(fd --type d | fzf --preview 'ls -lah {}')
# With tree preview (if tree is installed)
cd $(fd --type d | fzf --preview 'tree -L 2 {}')
# With exa preview (modern ls)
cd $(fd --type d | fzf --preview 'exa -lah --icons {}')
3. File Type Specific Searches
# Find and edit JavaScript files
vim $(fd -e js | fzf --preview 'bat --color=always {}')
# Find Python files
fd -e py | fzf --preview 'bat -l python --color=always {}'
# Find config files
fd -e conf -e config -e yaml -e yml -e json | fzf --preview 'bat --color=always {}'
# Find images
fd -e jpg -e png -e gif | fzf --preview 'termux-open {}'
# Find markdown files
fd -e md | fzf --preview 'bat --color=always -l markdown {}'
4. Set fd as Default for fzf
Add to ~/.bashrc or ~/.zshrc:
# Use fd instead of find for fzf
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'
# For CTRL-T (file finder)
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
# For ALT-C (directory finder)
export FZF_ALT_C_COMMAND='fd --type d --hidden --follow --exclude .git'
# Better preview with bat
export FZF_CTRL_T_OPTS="
--preview 'bat --color=always --style=numbers --line-range=:500 {}'
--preview-window=right:60%:wrap
--bind='ctrl-/:toggle-preview'
--bind='ctrl-u:preview-up,ctrl-d:preview-down'
"
export FZF_ALT_C_OPTS="
--preview 'exa -lah --icons {} || ls -lah {}'
--preview-window=right:60%
"
π FZF + Ripgrep Integration
1. Content Search with Preview
# Search and preview results
rg --line-number --no-heading --color=always . | \
fzf --ansi \
--delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}' \
--preview-window 'right,60%,+{2}+3/3,~3'
# Simpler version
rg --line-number . | \
fzf --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}'
2. Interactive Ripgrep Search
# Live search - type to search, see results in real-time
rg --line-number --no-heading . 2>/dev/null | \
fzf --ansi \
--delimiter : \
--preview 'bat --style=numbers --color=always {1} --highlight-line {2}' \
--preview-window '+{2}-/2'
3. Search Specific File Types
# Search in JavaScript files
rg --type js --line-number . | \
fzf --delimiter : \
--preview 'bat --color=always -l javascript {1} --highlight-line {2}'
# Search in Python files
rg --type py --line-number . | \
fzf --delimiter : \
--preview 'bat --color=always -l python {1} --highlight-line {2}'
# Search in markdown files
rg --type md --line-number . | \
fzf --delimiter : \
--preview 'bat --color=always -l markdown {1} --highlight-line {2}'
4. Search and Open in Editor
# Open file at the exact line
vim $(rg --line-number . | \
fzf --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}' | \
cut -d: -f1-2 | tr ':' ' ' | awk '{print "+" $2 " " $1}')
# Or use this cleaner version with editor that supports +line syntax
$EDITOR $(rg --line-number . | \
fzf --delimiter : | \
awk -F: '{print "+" $2 " " $1}')
π― The Complete Trinity
1. Ultimate Search Function
This combines all three tools for the perfect search experience:
# Add to ~/.bashrc or ~/.zshrc
# Search files by name, then by content
search() {
local choice
choice=$(echo -e "π Search Files\nπ Search Content\nπ Search Directories" | fzf --height=10)
case "$choice" in
*"Search Files"*)
fd --type f --hidden --exclude .git | \
fzf --preview 'bat --color=always --style=numbers {}'
;;
*"Search Content"*)
rg --line-number --no-heading --color=always . | \
fzf --ansi --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}' \
--preview-window '+{2}+3/3'
;;
*"Search Directories"*)
fd --type d --hidden --exclude .git | \
fzf --preview 'exa -lah --icons {} || ls -lah {}'
;;
esac
}
2. Smart Search and Open
# Searches by filename OR content, then opens the file
sopen() {
local file
local line
# First, let user choose: search by name or content
local mode=$(echo -e "By Filename\nBy Content" | fzf --height=5 --prompt="Search mode: ")
if [[ "$mode" == "By Filename" ]]; then
# Search by filename with fd
file=$(fd --type f --hidden --exclude .git | \
fzf --preview 'bat --color=always --style=numbers {}')
[ -n "$file" ] && $EDITOR "$file"
else
# Search by content with rg
local result=$(rg --line-number --no-heading --color=always . | \
fzf --ansi --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}' \
--preview-window '+{2}+3/3')
[ -n "$result" ] && {
file=$(echo "$result" | cut -d: -f1)
line=$(echo "$result" | cut -d: -f2)
$EDITOR "+$line" "$file"
}
fi
}
3. Project-Wide Search
# Search across project with context
psearch() {
local query="$1"
if [ -z "$query" ]; then
echo "Usage: psearch <pattern>"
return 1
fi
rg --line-number --no-heading --color=always "$query" | \
fzf --ansi \
--delimiter : \
--preview "bat --color=always {1} --highlight-line {2} --style=numbers" \
--preview-window 'right,60%,+{2}+3/3,~3' \
--bind 'enter:execute($EDITOR +{2} {1})'
}
πΌ Real-World Workflows
Workflow 1: Code Navigation
# Find function definition
function_find() {
rg --line-number "^(function|def|class|fn|func)" | \
fzf --ansi --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2} -r {2}:' \
--preview-window '+{2}+5/3'
}
# Find TODO/FIXME comments
todo_find() {
rg --line-number "TODO|FIXME|HACK|XXX|NOTE" | \
fzf --ansi --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}'
}
# Find imports/requires
import_find() {
rg --line-number "^(import|require|from|#include)" | \
fzf --ansi --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}'
}
Workflow 2: Git Integration
# Search through git-tracked files only
git_search() {
rg --line-number . $(git rev-parse --show-toplevel) | \
fzf --ansi --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}'
}
# Find changed files
git_changed() {
git diff --name-only | \
fzf --preview 'git diff --color=always {} | bat --color=always -l diff'
}
# Search in git history
git_history_search() {
git log --oneline --color=always | \
fzf --ansi \
--preview 'git show --color=always {1}' \
--bind 'enter:execute(git show {1} | less -R)'
}
# Interactive git file browser
git_file_history() {
git ls-files | \
fzf --preview 'git log --color=always --oneline {} | head -20'
}
Workflow 3: Documentation Search
# Search markdown documentation
doc_search() {
fd -e md | \
fzf --preview 'bat --color=always -l markdown {}' \
--bind 'enter:execute($EDITOR {})'
}
# Search within markdown files
doc_content_search() {
rg --type md --line-number . | \
fzf --ansi --delimiter : \
--preview 'bat --color=always -l markdown {1} --highlight-line {2}'
}
# Search code comments
comment_search() {
rg --line-number "(//|#|\*|<!--)" | \
fzf --ansi --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}'
}
Workflow 4: Log File Analysis
# Find and view log files
log_viewer() {
fd -e log -e txt --max-depth 5 | \
fzf --preview 'tail -100 {} | bat --color=always -l log' \
--bind 'enter:execute(less {})'
}
# Search within logs
log_search() {
local pattern="$1"
rg --line-number "$pattern" $(fd -e log) | \
fzf --ansi --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2} -l log'
}
# Error log finder
error_search() {
rg --line-number -i "error|exception|fail|fatal" $(fd -e log) | \
fzf --ansi --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2} -l log --color=always'
}
Workflow 5: Configuration File Management
# Find and edit config files
config_edit() {
fd -H -e conf -e config -e cfg -e ini -e yaml -e yml -e json -e toml . ~ ~/.config /etc 2>/dev/null | \
fzf --preview 'bat --color=always {}' \
--bind 'enter:execute($EDITOR {})'
}
# Search within config files
config_search() {
local pattern="$1"
rg --line-number -g "*.{conf,config,cfg,yaml,yml,json,toml}" "$pattern" ~ ~/.config 2>/dev/null | \
fzf --ansi --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}'
}
π₯ Advanced Recipes
Recipe 1: Interactive Grep with Live Preview
# Add to ~/.bashrc or ~/.zshrc
# Live interactive search with real-time preview
rgi() {
local initial_query="$1"
rg --line-number --no-heading --color=always --smart-case "${initial_query:-.}" | \
fzf --ansi \
--disabled \
--delimiter : \
--bind "change:reload:rg --line-number --no-heading --color=always --smart-case {q} || true" \
--preview 'bat --color=always {1} --highlight-line {2} --style=numbers' \
--preview-window 'right,60%,+{2}+3/3,~3' \
--bind 'enter:execute($EDITOR +{2} {1})'
}
Recipe 2: Fuzzy File Finder with Multiple Actions
# Multi-action file finder
ff() {
local file
file=$(fd --type f --hidden --follow --exclude .git | \
fzf --preview 'bat --color=always --style=numbers {}' \
--bind 'ctrl-e:execute($EDITOR {})+abort' \
--bind 'ctrl-o:execute(xdg-open {} || termux-open {})+abort' \
--bind 'ctrl-y:execute-silent(echo {} | termux-clipboard-set || echo {} | xclip -selection clipboard)+abort' \
--bind 'ctrl-d:execute(rm -i {})+reload(fd --type f)' \
--header 'CTRL-E: Edit | CTRL-O: Open | CTRL-Y: Copy path | CTRL-D: Delete')
echo "$file"
}
Recipe 3: Smart Code Search
# Search code with file type detection
code_search() {
local pattern="$1"
local file_types="js,jsx,ts,tsx,py,go,rs,java,c,cpp,h,hpp,sh,bash,zsh"
rg --line-number --color=always --type-add "code:*.{$file_types}" -t code "$pattern" | \
fzf --ansi \
--delimiter : \
--preview 'bat --color=always {1} --highlight-line {2} --style=full' \
--preview-window 'right,60%,border-left,+{2}+3/3,~3' \
--bind 'ctrl-/:toggle-preview' \
--bind 'ctrl-e:execute($EDITOR +{2} {1})' \
--bind 'ctrl-o:execute(bat {1})' \
--header 'CTRL-E: Edit | CTRL-O: View | CTRL-/: Toggle preview'
}
Recipe 4: Recursive Directory Browser
# Browse directories recursively with instant switch
dbrowse() {
while true; do
local dir
dir=$(fd --type d --hidden --max-depth 5 --exclude .git | \
fzf --preview 'exa -lah --icons {} 2>/dev/null || ls -lah {}' \
--preview-window 'right,60%' \
--header 'Select directory (ESC to exit)' \
--bind 'ctrl-o:execute(cd {} && $SHELL)+abort')
if [ -z "$dir" ]; then
break
fi
cd "$dir" && echo "Changed to: $(pwd)"
done
}
Recipe 5: Multi-Pattern Search
# Search for multiple patterns
multi_search() {
echo "Enter search patterns (one per line, empty line to finish):"
local patterns=()
while IFS= read -r line; do
[ -z "$line" ] && break
patterns+=("$line")
done
if [ ${#patterns[@]} -eq 0 ]; then
echo "No patterns provided"
return 1
fi
# Combine patterns with OR
local combined=$(IFS='|'; echo "${patterns[*]}")
rg --line-number --color=always "$combined" | \
fzf --ansi --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}' \
--preview-window '+{2}+3/3'
}
Recipe 6: Project File Statistics
# Analyze project files
project_stats() {
echo "π Project Statistics"
echo "===================="
echo ""
echo "π File Types:"
fd --type f | sed 's/.*\.//' | sort | uniq -c | sort -rn | head -10
echo ""
echo "π Largest Files:"
fd --type f -x ls -lh {} | sort -k5 -h -r | head -10 | awk '{print $5, $9}'
echo ""
echo "π Code Statistics:"
rg --count-matches "" --type-add 'code:*.{js,py,go,rs,java}' -t code | \
awk -F: '{sum+=$2} END {print "Total Lines of Code: " sum}'
}
π Custom Functions Library
Add these to your ~/.bashrc or ~/.zshrc:
Complete Functions Collection
# ============================================
# FZF + FD + RG Functions Library
# ============================================
# --- FILE OPERATIONS ---
# Find and edit files
fe() {
local file
file=$(fd --type f --hidden --follow --exclude .git | \
fzf --preview 'bat --color=always --style=numbers {}' \
--preview-window=right:60%) && \
$EDITOR "$file"
}
# Find and edit by content
fc() {
local file line
local result=$(rg --line-number --no-heading --color=always . | \
fzf --ansi --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}' \
--preview-window '+{2}+3/3')
[ -n "$result" ] && {
file=$(echo "$result" | cut -d: -f1)
line=$(echo "$result" | cut -d: -f2)
$EDITOR "+$line" "$file"
}
}
# Find and delete files safely
frm() {
local files
files=$(fd --type f | fzf -m --preview 'bat --color=always {}')
[ -n "$files" ] && echo "$files" | xargs -I {} rm -i {}
}
# Find and copy files
fcp() {
local files dest
files=$(fd --type f | fzf -m --preview 'bat --color=always {}')
[ -n "$files" ] && {
read -p "Destination: " dest
echo "$files" | xargs -I {} cp {} "$dest"
}
}
# Find and move files
fmv() {
local files dest
files=$(fd --type f | fzf -m --preview 'bat --color=always {}')
[ -n "$files" ] && {
read -p "Destination: " dest
echo "$files" | xargs -I {} mv {} "$dest"
}
}
# --- DIRECTORY OPERATIONS ---
# Smart cd with fd and fzf
fcd() {
local dir
dir=$(fd --type d --hidden --follow --exclude .git . "${1:-.}" | \
fzf --preview 'exa -lah --icons {} 2>/dev/null || ls -lah {}' \
--preview-window=right:60%) && \
cd "$dir"
}
# cd to parent directory interactively
fup() {
local dir
dir=$(pwd | sed 's|/|\n|g' | tail -n +2 | \
fzf --preview 'ls -lah /$(echo {} | sed "s|^|$(pwd | sed "s|$PWD||; s|/|\n|g" | tail -n +2 | grep -B100 {} | tr "\n" "/" | sed "s|/$||")|/")') && \
cd "/${dir}"
}
# Create and cd into directory
fmkcd() {
local dir
read -p "Directory name: " dir
[ -n "$dir" ] && mkdir -p "$dir" && cd "$dir"
}
# --- SEARCH OPERATIONS ---
# Interactive ripgrep
frg() {
local pattern="${1:-.}"
rg --line-number --no-heading --color=always --smart-case "$pattern" | \
fzf --ansi \
--delimiter : \
--bind "change:reload:rg --line-number --no-heading --color=always --smart-case {q} || true" \
--preview 'bat --color=always {1} --highlight-line {2}' \
--preview-window '+{2}+3/3'
}
# Search and replace across files
fsr() {
local pattern replacement
read -p "Search pattern: " pattern
read -p "Replace with: " replacement
local files=$(rg -l "$pattern" | fzf -m --preview "rg --color=always '$pattern' {}")
if [ -n "$files" ]; then
echo "$files" | while read -r file; do
sed -i "s/$pattern/$replacement/g" "$file"
echo "Updated: $file"
done
fi
}
# Find duplicate files
fdup() {
fd --type f -x md5sum | \
sort | \
uniq -w32 -D | \
cut -c35- | \
fzf -m --preview 'bat --color=always {}'
}
# --- GIT OPERATIONS ---
# Git file selector
fgf() {
git ls-files | \
fzf --preview 'bat --color=always {}' \
--bind 'enter:execute($EDITOR {})'
}
# Git branch switcher with preview
fgb() {
local branch
branch=$(git branch --all | grep -v HEAD | \
sed 's/^..//' | sed 's#remotes/origin/##' | \
sort -u | \
fzf --preview 'git log --oneline --graph --date=short --color=always --pretty="format:%C(auto)%cd %h%d %s" {} | head -50') && \
git checkout "$branch"
}
# Git commit browser
fgc() {
git log --oneline --color=always | \
fzf --ansi \
--preview 'git show --color=always {1}' \
--bind 'enter:execute(git show {1} | less -R)'
}
# Git stash browser
fgs() {
git stash list | \
fzf --preview 'git stash show -p {1}' \
--bind 'enter:execute(git stash pop {1})'
}
# Interactive git add
fga() {
git status --short | \
fzf -m --preview 'git diff --color=always {2}' | \
awk '{print $2}' | \
xargs git add
}
# --- PROCESS OPERATIONS ---
# Kill process interactively
fkill() {
local pid
pid=$(ps aux | sed 1d | \
fzf -m --preview 'echo {}' --preview-window=down:3:wrap | \
awk '{print $2}')
[ -n "$pid" ] && echo "$pid" | xargs kill -${1:-9}
}
# Process tree viewer
fptree() {
ps auxf | \
fzf --preview 'echo {}' \
--preview-window=down:5:wrap \
--header 'Process Tree'
}
# --- PACKAGE OPERATIONS ---
# Search and install packages (Termux)
fpkg() {
pkg search '' | \
fzf -m --preview 'pkg show {1}' \
--bind 'enter:execute(pkg install {1})+abort'
}
# Browse installed packages
fpkgl() {
pkg list-installed | \
fzf --preview 'pkg show {}'
}
# --- UTILITY FUNCTIONS ---
# Quick note taker
fnote() {
local note_dir="$HOME/notes"
mkdir -p "$note_dir"
local choice=$(echo -e "π New Note\nπ Browse Notes\nπ Search Notes" | fzf --height=10)
case "$choice" in
*"New Note"*)
read -p "Note name: " name
$EDITOR "$note_dir/${name}.md"
;;
*"Browse Notes"*)
local note=$(fd -e md . "$note_dir" | \
fzf --preview 'bat --color=always -l markdown {}')
[ -n "$note" ] && $EDITOR "$note"
;;
*"Search Notes"*)
local result=$(rg --line-number . "$note_dir" | \
fzf --delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}')
if [ -n "$result" ]; then
local file=$(echo "$result" | cut -d: -f1)
local line=$(echo "$result" | cut -d: -f2)
$EDITOR "+$line" "$file"
fi
;;
esac
}
# History with better preview
fhist() {
eval $(history | \
fzf --tac --no-sort \
--preview 'echo {}' \
--preview-window=down:3:wrap | \
sed 's/^[ ]*[0-9]*[ ]*//')
}
# Environment variable browser
fenv() {
printenv | \
fzf --preview 'echo {}' \
--preview-window=down:3:wrap
}
# Find and open URLs
furl() {
rg -o 'https?://[^\s]+' | \
sort -u | \
fzf --preview 'echo {}' | \
xargs termux-open-url
}
# Bookmark manager
fbm() {
local bookmark_file="$HOME/.bookmarks"
touch "$bookmark_file"
local choice=$(echo -e "β Add Bookmark\nπ Open Bookmark\nποΈ Remove Bookmark" | fzf --height=10)
case "$choice" in
*"Add Bookmark"*)
read -p "URL: " url
read -p "Description: " desc
echo "$desc | $url" >> "$bookmark_file"
;;
*"Open Bookmark"*)
cat "$bookmark_file" | \
fzf | \
cut -d'|' -f2 | \
xargs termux-open-url
;;
*"Remove Bookmark"*)
local line=$(cat "$bookmark_file" | fzf)
[ -n "$line" ] && sed -i "\|$line|d" "$bookmark_file"
;;
esac
}
# Clipboard history (requires termux-clipboard-get)
fclip() {
local clip_dir="$HOME/.clipboard_history"
mkdir -p "$clip_dir"
# Save current clipboard
termux-clipboard-get > "$clip_dir/$(date +%s).txt" 2>/dev/null
# Browse history
fd . "$clip_dir" -x cat | \
fzf --preview 'echo {}' \
--bind 'enter:execute(echo {} | termux-clipboard-set)+abort'
}
# File content preview
fpreview() {
fd --type f | \
fzf --preview 'bat --color=always --style=full {}' \
--preview-window=right:70%
}
# Disk usage analyzer
fdu() {
fd --type f -x du -h {} | \
sort -h | \
fzf --preview 'bat --color=always {}' \
--bind 'enter:execute(echo {} | awk "{print \$2}" | xargs -I {} $EDITOR {})'
}
# --- COMBINED POWER FUNCTIONS ---
# Universal finder
finder() {
local choice
choice=$(echo -e "π Files\nπ Directories\nπ Content\nπ³ Git\nβοΈ Processes\nπ¦ Packages" | \
fzf --height=15 --prompt="What to find? ")
case "$choice" in
*"Files"*) fe ;;
*"Directories"*) fcd ;;
*"Content"*) fc ;;
*"Git"*) fgf ;;
*"Processes"*) fkill ;;
*"Packages"*) fpkg ;;
esac
}
# Smart open
sopen() {
local target
target=$(fd --type f --hidden | \
fzf --preview '[[ $(file --mime {}) =~ binary ]] &&
echo "Binary file" ||
bat --color=always --style=numbers {}')
if [ -n "$target" ]; then
local mime=$(file --mime-type -b "$target")
case "$mime" in
text/*) $EDITOR "$target" ;;
image/*) termux-open "$target" ;;
video/*) termux-open "$target" ;;
application/pdf) termux-open "$target" ;;
*) $EDITOR "$target" ;;
esac
fi
}
# === END OF FUNCTIONS LIBRARY ===
β‘ Performance Optimization
Speed Comparison
# Benchmark traditional vs modern tools
# Traditional (slow)
time find . -type f -name "*.js" # ~5-10 seconds
time grep -r "function" . # ~10-30 seconds
# Modern (fast)
time fd -e js # ~0.5-1 second
time rg "function" # ~0.5-2 seconds
Optimization Tips
# 1. Limit search depth
fd --max-depth 3
rg --max-depth 3
# 2. Exclude unnecessary directories
fd --exclude node_modules --exclude .git --exclude target
# 3. Use specific file types
rg --type js "pattern" # Only JavaScript
fd -e py # Only Python files
# 4. Use .gitignore
# Both fd and rg respect .gitignore by default
# 5. Disable smart case if not needed
rg --case-sensitive "Pattern"
# 6. Use fixed strings for exact matches
rg --fixed-strings "exact.string"
# 7. Limit results
fd | head -100 | fzf
rg "pattern" | head -100 | fzf
Configuration for Maximum Speed
Add to ~/.bashrc or ~/.zshrc:
# Optimized fd defaults
export FD_OPTIONS="--hidden --follow --exclude .git --exclude node_modules --max-depth 6"
# Optimized rg defaults
export RIPGREP_CONFIG_PATH="$HOME/.ripgreprc"
# Create ~/.ripgreprc
cat > ~/.ripgreprc << 'EOF'
# Exclude directories
--glob=!.git/
--glob=!node_modules/
--glob=!vendor/
--glob=!target/
--glob=!build/
--glob=!dist/
# Smart case by default
--smart-case
# Show line numbers
--line-number
# Follow symlinks
--follow
# Max columns for display
--max-columns=200
# Max depth
--max-depth=10
EOF
# Optimized fzf defaults
export FZF_DEFAULT_OPTS='
--height=40%
--layout=reverse
--info=inline
--border=rounded
--margin=1
--padding=1
--no-scrollbar
'
# Use fd for fzf
export FZF_DEFAULT_COMMAND="fd --type f --hidden --follow --exclude .git --exclude node_modules"
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_ALT_C_COMMAND="fd --type d --hidden --follow --exclude .git --exclude node_modules"
π± Termux-Specific Tips
Storage Setup
# Setup storage access first
termux-setup-storage
# Quick access to common directories
alias phone='cd ~/storage/shared && fzf | xargs termux-open'
alias pics='cd ~/storage/shared/DCIM && fd -e jpg -e png | fzf --preview "termux-open {}"'
alias downloads='cd ~/storage/downloads && fzf --preview "bat --color=always {}" | xargs termux-open'
Android Integration
# Share files from Termux
fshare() {
fd --type f | \
fzf --preview 'bat --color=always {}' | \
xargs -I {} termux-share {}
}
# Open with Android app
fopen() {
fd --type f | \
fzf --preview 'file {}' | \
xargs termux-open
}
# Send SMS with content search
fsms() {
local content=$(rg . | fzf --preview 'bat --color=always {1}')
[ -n "$content" ] && termux-sms-send -n "$1" "$content"
}
# Copy to Android clipboard
fclip() {
fd --type f | \
fzf --preview 'bat --color=always {}' | \
xargs cat | \
termux-clipboard-set
}
Quick Launch Scripts
# Create launcher script
cat > ~/launcher.sh << 'EOF'
#!/data/data/com.termux/files/usr/bin/bash
action=$(echo -e "\
π Search Files
π Browse Files
π Search Content
π Jump to Directory
π Edit Notes
π Open Bookmark
π± Phone Storage
βοΈ Edit Config
π Project Stats
π§ System Info" | fzf --height=20 --prompt="Quick Action: ")
case "$action" in
*"Search Files"*) fe ;;
*"Browse Files"*) ff ;;
*"Search Content"*) fc ;;
*"Jump to Directory"*) fcd ;;
*"Edit Notes"*) fnote ;;
*"Open Bookmark"*) fbm ;;
*"Phone Storage"*) cd ~/storage/shared && fzf | xargs termux-open ;;
*"Edit Config"*) config_edit ;;
*"Project Stats"*) project_stats ;;
*"System Info"*) termux-info ;;
esac
EOF
chmod +x ~/launcher.sh
# Add widget shortcut
mkdir -p ~/.shortcuts
ln -s ~/launcher.sh ~/.shortcuts/Launcher
Battery and Performance
# Check if running on battery
battery_check() {
local battery=$(termux-battery-status | jq -r '.percentage')
if [ "$battery" -lt 20 ]; then
echo "β οΈ Low battery ($battery%). Using fast mode."
export FD_OPTIONS="--max-depth 3"
export FZF_DEFAULT_OPTS="--height=20% --no-preview"
fi
}
# Call at shell startup
battery_check
π¨ Visual Themes
Dracula Theme
export FZF_DEFAULT_OPTS='
--color=fg:#f8f8f2,bg:#282a36,hl:#bd93f9
--color=fg+:#f8f8f2,bg+:#44475a,hl+:#bd93f9
--color=info:#ffb86c,prompt:#50fa7b,pointer:#ff79c6
--color=marker:#ff79c6,spinner:#ffb86c,header:#6272a4
--border=rounded
--preview-window=border-rounded
'
Nord Theme
export FZF_DEFAULT_OPTS='
--color=fg:#e5e9f0,bg:#3b4252,hl:#81a1c1
--color=fg+:#e5e9f0,bg+:#434c5e,hl+:#81a1c1
--color=info:#eacb8a,prompt:#bf6069,pointer:#b48dac
--color=marker:#a3be8b,spinner:#b48dac,header:#a3be8b
--border=rounded
'
Monokai Theme
export FZF_DEFAULT_OPTS='
--color=fg:#f8f8f2,bg:#272822,hl:#66d9ef
--color=fg+:#f8f8f2,bg+:#44475a,hl+:#ff79c6
--color=info:#e6db74,prompt:#a6e22e,pointer:#ae81ff
--color=marker:#a6e22e,spinner:#ae81ff,header:#75715e
--border=rounded
'
π Troubleshooting
Common Issues
1. Command not found
# Verify installations
which fd rg fzf
# Reinstall if needed
pkg install fzf ripgrep fd
2. Preview not working
# Install bat for better previews
pkg install bat
# Verify bat works
bat --version
# Test preview
echo "test" | fzf --preview 'bat --color=always {}'
3. Colors not showing
# Enable colors
export FZF_DEFAULT_OPTS='--ansi'
# For ripgrep
rg --color=always "pattern"
# For fd
fd --color=always
4. Slow performance
# Reduce search depth
fd --max-depth 3
# Exclude large directories
fd --exclude node_modules --exclude .git
# Use .gitignore
# Both fd and rg respect .gitignore by default
5. Keybindings not working
# Source key-bindings
source /data/data/com.termux/files/usr/share/fzf/key-bindings.bash
# Or for zsh
source /data/data/com.termux/files/usr/share/fzf/key-bindings.zsh
# Add to shell RC file
echo 'source /data/data/com.termux/files/usr/share/fzf/key-bindings.bash' >> ~/.bashrc
π Cheat Sheet
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FZF + RG + FD CHEAT SHEET β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β FD (FILE FINDER) β
β fd [pattern] β Find files matching pattern β
β fd -e ext β Find files with extension β
β fd -t d β Find directories only β
β fd -t f β Find files only β
β fd -H β Include hidden files β
β fd --exclude pattern β Exclude pattern β
β fd --max-depth N β Limit depth β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β RIPGREP (CONTENT SEARCH) β
β rg pattern β Search for pattern β
β rg -i pattern β Case-insensitive β
β rg -w pattern β Match whole words β
β rg -t type pattern β Search specific file type β
β rg -l pattern β Show filenames only β
β rg -n pattern β Show line numbers β
β rg -C 3 pattern β Show 3 lines context β
β rg --hidden pattern β Include hidden files β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β FZF (FUZZY FINDER) β
β fzf β Basic fuzzy find β
β fzf -m β Multi-select mode β
β fzf --preview 'cmd' β Show preview β
β fzf --height 40% β Set height β
β fzf --reverse β Reverse layout β
β fzf --ansi β Enable ANSI colors β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β COMBINATIONS β
β fd | fzf β Interactive file finder β
β rg . | fzf β Interactive content search β
β fd -t d | fzf β Interactive directory picker β
β fd | fzf --preview 'bat {}' β File finder with preview β
β rg -l pat | fzf --preview 'bat {}' β Search with preview β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β KEYBINDINGS (in fzf) β
β β/β or Ctrl-J/K β Navigate β
β TAB β Select (multi-mode) β
β Shift-TAB β Deselect β
β Enter β Confirm β
β Ctrl-C / ESC β Exit β
β Ctrl-/ β Toggle preview β
β Ctrl-U/D β Preview scroll β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β SHELL KEYBINDINGS β
β Ctrl-T β File finder β
β Ctrl-R β History search β
β Alt-C β Directory jump β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Additional Resources
Official Documentation
- fzf: https://github.com/junegunn/fzf
- ripgrep: https://github.com/BurntSushi/ripgrep
- fd: https://github.com/sharkdp/fd
Complementary Tools
- bat: https://github.com/sharkdp/bat (Better cat with syntax highlighting)
- exa: https://github.com/ogham/exa (Modern ls replacement)
- delta: https://github.com/dandavison/delta (Better git diff)
- tokei: https://github.com/XAMPPRocky/tokei (Code statistics)
Learning Resources
- fzf wiki examples: https://github.com/junegunn/fzf/wiki/examples
- ripgrep user guide: https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md
- fd user guide: https://github.com/sharkdp/fd#tutorial
π― Quick Start Guide
For Complete Beginners
Step 1: Test Each Tool
# Test fd
fd .md # Find all markdown files
# Test rg
rg "TODO" # Find all TODOs in your code
# Test fzf
echo -e "apple\nbanana\ncherry" | fzf # Try fuzzy search
Step 2: Combine Two Tools
# fd + fzf
fd -e js | fzf
# rg + fzf
rg -l "function" | fzf
Step 3: Add Preview
# Install bat first
pkg install bat
# Then try with preview
fd | fzf --preview 'bat --color=always {}'
Step 4: Use Pre-made Functions
# Copy the functions from this guide to ~/.bashrc
# Then use them:
fe # Find and edit file
fc # Find by content and edit
fcd # Jump to directory
For Intermediate Users
Focus on these high-impact functions:
fe- Daily file editingfc- Content-based file findingfcd- Quick directory navigationfrg- Interactive searchfgb- Git branch switching
For Advanced Users
Create your own combinations:
- Integrate with your existing scripts
- Create project-specific search functions
- Build automation workflows
- Customize preview commands
- Create shell widgets
This guide is current as of October 2025 and optimized for Termux.
Happy searching! π
---
# π Detailed Explanation
## How These Tools Work Together
### **The Pipeline Philosophy**
Unix/Linux tools follow a simple philosophy: do one thing well and chain tools together. Here's how our trinity embodies this:
```bash
# The Flow:
fd (finds files) β fzf (lets you choose) β bat (shows content)
# In practice:
fd --type f | fzf --preview 'bat --color=always {}'
Real Example Breakdown
Let’s break down this powerful command:
rg --line-number --color=always . | \
fzf --ansi \
--delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}' \
--preview-window '+{2}+3/3'
What’s happening:
-
rg --line-number --color=always .- Search all files in current directory
- Show line numbers
- Keep colors in output
-
fzf --ansi- Accept colored input from rg
- Make it interactive
-
--delimiter :- Split results at
:character - Results look like:
file.js:42:function hello()
- Split results at
-
--preview 'bat --color=always {1} --highlight-line {2}'- Show the file (
{1}= filename) - Highlight the line (
{2}= line number)
- Show the file (
-
--preview-window '+{2}+3/3'- Jump to the line in preview
- Show 3 lines of context
Why It’s Fast
# Traditional approach (slow):
find . -name "*.js" -exec grep -l "function" {} \;
# Problems: Spawns new process for each file, no parallelism
# Modern approach (fast):
rg -t js "function"
# Advantages: Single process, parallel search, skips binaries
Daily Workflow Examples
Morning Developer Routine
# 1. Check project status
cd ~/projects
fd --type d --max-depth 1 | fzf | xargs -I {} cd {}
# 2. See what you were working on
rg "TODO|FIXME" | fzf
# 3. Quick git status
git status
# 4. Start working
fe # Find and edit file
Code Review Workflow
# 1. Find recently changed files
git diff --name-only | fzf --preview 'git diff --color=always {}'
# 2. Search for specific patterns
rg "console.log" | fzf --preview 'bat --color=always {1} --highlight-line {2}'
# 3. Check for todos
rg "TODO" -A 2 | fzf
Debugging Workflow
# 1. Find error logs
fd -e log | fzf --preview 'tail -50 {} | bat -l log --color=always'
# 2. Search for errors
rg "error|exception" $(fd -e log) | fzf
# 3. Check stack traces
rg "at.*\.js:" | fzf --preview 'bat --color=always {1}'
Performance Tips Explained
Why These Are Fast
-
fd is faster than find because:
- Written in Rust (compiled, not interpreted)
- Parallel execution by default
- Ignores .git and respects .gitignore
- Doesn’t stat files unnecessarily
-
rg is faster than grep because:
- Uses finite automata for regex
- Memory-mapped file reading
- Parallel search across files
- Skips binary files automatically
- Respects .gitignore
-
fzf is fast because:
- Written in Go (compiled)
- Efficient fuzzy matching algorithm
- Async preview generation
- Minimal memory footprint
Optimization Strategies
# Bad: Search everything
fd | rg "pattern"
# Good: Limit scope
fd -e js -e py --max-depth 3 | rg "pattern"
# Better: Use type filters
rg -t javascript -t python "pattern"
# Best: Combine with exclusions
rg -t js "pattern" --glob "!node_modules/*" --glob "!dist/*"
Customization Philosophy
Start Simple, Add Complexity
# Level 1: Basic usage
fd | fzf
# Level 2: Add preview
fd | fzf --preview 'cat {}'
# Level 3: Better preview
fd | fzf --preview 'bat --color=always {}'
# Level 4: Full featured
fd --type f --hidden --follow --exclude .git | \
fzf --preview 'bat --color=always --style=full {}' \
--preview-window 'right:60%:border-left' \
--bind 'ctrl-/:toggle-preview'
Build Your Own Functions
Start with what you need most:
# If you edit files a lot:
fe() { vim $(fd | fzf --preview 'bat --color=always {}') }
# If you search code a lot:
fs() { rg -l "$1" | fzf --preview 'rg --color=always "$1" {}' }
# If you switch directories often:
fcd() { cd $(fd -t d | fzf --preview 'ls -lah {}') }
π― Practice Exercises
Try these to master the trinity:
Exercise 1: File Hunter
# Find all JavaScript files modified in last 7 days
fd -e js --changed-within 7d | fzf --preview 'bat {}'
Exercise 2: Code Detective
# Find all functions in your codebase
rg "^(function|def|class)" | fzf --preview 'bat --color=always {1}'
Exercise 3: Project Navigator
# Create a project switcher
cd ~/projects && cd $(fd --type d --max-depth 1 | fzf --preview 'ls -lah {}')
Exercise 4: Todo Manager
# Find and fix todos
rg "TODO" | fzf --preview 'bat --color=always {1} --highlight-line {2}' | cut -d: -f1 | xargs $EDITOR
Sources:
- fzf Official Repository: https://github.com/junegunn/fzf
- ripgrep Official Repository: https://github.com/BurntSushi/ripgrep
- fd Official Repository: https://github.com/sharkdp/fd
- fzf Wiki and Examples: https://github.com/junegunn/fzf/wiki
- ripgrep User Guide: https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md