Kamu grep -R sebuah codebase dan nunggu. Hasilnya 400 baris yang kamu scroll lewat. Kamu cat sebuah config file dan dapat tembok teks polos. Kamu pencet Ctrl-R dan muter-muter history shell berharap command yang kamu butuh ada di sepuluh entri terakhir. Itu pengalaman terminal default, dan semuanya sebenernya opsional.
Tiga tools ngegantiin workflow itu: ripgrep buat nyari, fzf buat milih, bat buat baca. Semua yang ada di artikel ini udah dites di Ubuntu 24.04 dan dicek silang ke dokumentasi resmi tiap project. Install, command yang penting, dan gotcha yang diwarnain README tapi jarang dibahas tutorial lain.
Prerequisites
- Linux, macOS, atau WSL (Windows juga bisa, lewat winget atau scoop)
- Shell yang beneran kamu pake, idealnya bash atau zsh
- Project dengan file lebih dari segenggam, karena di situ tools ini kerasa manfaatnya
Bagian 1: ripgrep, pencarian yang hormat sama project kamu
ripgrep (rg) adalah tool pencarian rekursif yang ditulis pake Rust. Yang bikin beda dari grep -R adalah default-nya: dia skip file hidden, skip file binary, dan abaikan apa pun yang dikecualikan .gitignore kamu (di dalam git repo), .ignore, atau .rgignore. Kamu nyari kodenya, bukan artifact build-nya.
Install
# Debian/Ubuntu
sudo apt-get install ripgrep
# macOS
brew install ripgrep
# Windows
winget install BurntSushi.ripgrep.MSVC
Command yang penting
rg "TODO" -n # nomor baris
rg "def " -l # cuma nama file
rg "return" -c # jumlah match per file
rg -tpy "def " # cuma file Python
rg -Tjs "TODO" # kecualikan JavaScript
rg "handle" -A 3 -B 1 # baris konteks
rg -w "add" # whole word aja
rg --smart-case "todo" # case-sensitive kalau kamu ngetik huruf kapital
rg -P "(?<=def )\w+" # PCRE2: look-around, backreference
Semua command di atas beneran dijalanin di project percobaan. Filter tipe file layak dipelajari sendiri: -tpy itu kependekan dari --type py, dan rg --type-list nampilin semua tipe yang dikenal tool ini.
Secara default rg nggak nyari file hidden, dan -uuu mematikan semua filter otomatis. Flag itu dipakai buat nyari di dalam node_modules atau .git kalau emang terpaksa, yang hampir nggak pernah.
Kenapa cepet
Dari README project-nya, nyari [A-Z]+_SUSPEND di source tree Linux kernel (Intel i9-12900K): ripgrep 0.082 detik, The Silver Searcher 0.443 detik, ack 2.935 detik. Kecepatannya datang dari regex engine Rust dengan SIMD dan optimasi literal, memory-mapped file buat file tunggal, dan directory walker paralel. Bukan sulap, ini pilihan engineering, dan benchmark-nya publik.
Pakai rg daripada grep kecuali kamu butuh portabilitas POSIX di mesin yang nggak kamu pegang. grep ada di mana-mana. rg enggak.
Bagian 2: fzf, fuzzy finder buat semua hal
fzf baca list dari stdin, filter selagi kamu ngetik, dan print pilihan kamu ke stdout. Deskripsi itu ngeremehin dia. fzf adalah bagian yang ngubah milih file, nyari history, bahkan live grep, jadi UI interaktif.
Install dan shell integration
# Debian/Ubuntu (19.10+)
sudo apt install fzf
# macOS
brew install fzf
Install binary aja nggak cukup. Key binding-nya langkah terpisah. Buat bash, tambahin baris ini ke .bashrc:
eval "$(fzf --bash)"
Buat zsh: source <(fzf --zsh). Terus buka shell baru.
Tiga key binding utama
Ctrl-T: tempel path file atau direktori ke command line kamuCtrl-R: fuzzy search history shell, gantiin scroll history manualAlt-C: cd ke subdirektori
Ctrl-R doang udah worth install. Kamu ngetik sebagian command yang kamu inget, fuzzy match ngerjain sisanya.
Sintaks pencarian
fzf cocokin secara fuzzy secara default: sbtrkt cocok dengan item apa pun yang mengandung huruf-huruf itu berurutan. Sintaks extended nanganin sisanya:
^music: diawali music.mp3$: diakhiri .mp3!fire: nggak mengandung fire'wild: exact match, tanpa fuzzinggo$ | rb$ | py$: operator OR
Udah dites: printf 'core.go\ncore.rb\ncore.py\nother.txt\n' | fzf --filter="^core go$ | rb$ | py$" ngembaliin tiga file core.
Preview dengan bat
Preview window yang bikin fzf kerasa kayak tool beneran, bukan mainan:
fzf --preview 'bat --color=always {}' --preview-window '~3'
Buat file gede, batasi yang dimuat bat: --line-range=:500.
Live grep dengan fzf dan rg
README fzf punya resep yang ngubah fzf jadi launcher rg interaktif. Tiap keystroke ngerestart pencarian, dan Enter buka match-nya di vim di baris yang tepat:
: | rg_prefix='rg --column --line-number --no-heading --color=always --smart-case' \
fzf --bind 'start:reload:$rg_prefix ""' \
--bind 'change:reload:$rg_prefix {q} || true' \
--bind 'enter:become(vim {1} +{2})' \
--ansi --disabled \
--height=50% --layout=reverse
--disabled ngasih tahu fzf buat nggak filter list-nya sendiri; rg yang filter. {q} itu query sekarang, {1} dan {2} kolom pertama dan kedua dari baris yang cocok, yaitu file dan nomor baris.
Bagian 3: bat, cat yang punya mata
bat adalah clone cat dengan syntax highlighting dan integrasi git. Dia highlight file source, nampilin gutter berisi nomor baris dan penanda modifikasi git, dan otomatis page output yang kepanjangan.
Install (dan gotcha batcat)
sudo apt install bat
Di Debian dan sebagian rilis Ubuntu, binary-nya keinstall sebagai batcat, karena nama bat bentrok sama package lain. Saya ngalamin ini di Ubuntu 24.04, padahal README-nya nyebut ini cuma ngaruh ke rilis lawas. Kalau bat --version bilang command not found, jalanin batcat --version dan beresin sekali:
mkdir -p ~/.local/bin
ln -s /usr/bin/batcat ~/.local/bin/bat
Di macOS: brew install bat, tanpa drama.
Pemakaian sehari-hari
bat -n src/app.py # nomor baris
bat -A /etc/hosts # tampilkan karakter non-printable
echo '{"a": 1}' | bat -l json # bahasa eksplisit dari stdin
bat --paging=never # kelakuannya kayak cat kalau perlu
bat auto-detect syntax dari ekstensi file, dan dari shebang pas baca stdin. Kalau output di-pipe ke command lain, dia balik ke perilaku cat polos, jadi script yang pake cat tetap jalan kalau kamu alias:
alias cat='bat --paging=never'
Integrasi git
bat --diff nge-highlight baris relatif ke git index. README-nya ngebungkus itu jadi fungsi yang nge-diff semua file berubah sekaligus:
batdiff() {
git diff --name-only --relative --diff-filter=d -z | xargs -0 bat --diff
}
Output git show juga tetep ke-highlight: git show HEAD~1:src/app.py | bat -l py.
bat sebagai pager
Pakai bat buat nampilin man page:
export MANPAGER="bat -plman"
man 2 select
Trik yang sama buat output --help. README bat nyaranin helper yang ngewarnain teks help command apa pun:
alias bathelp='bat --plain --language=help'
help() {
"$@" --help 2>&1 | bathelp
}
Terus help git commit kebaca kayak dokumentasi, bukan tembok teks.
Kapan pakai vs alternatif
- rg vs grep: grep pilihan yang tepat kalau kamu butuh tool yang ada di semua mesin Unix, termasuk yang bukan kamu yang ngurus. rg pilihan yang tepat di semua kondisi lain.
- bat vs cat: cat tetap standar buat scripting, karena output-nya harus polos. bat buat mata kamu.
- bat vs delta: delta khusus buat git diff dan lebih bagus di situ. bat nutupin baca file, man page, help text, dan diff dengan satu binary.
- fzf vs history biasa: kalau workflow kamu cuma lima command, Ctrl-R standar udah cukup. fzf menang kalau list-nya kepanjangan sampe scroll nggak mempan.
Langkah berikutnya
- Taruh alias dan baris eval fzf di dotfiles, terus commit.
- Coba
fzf --bind 'enter:become(vim {})'biar milih langsung buka file. - Baca fzf ADVANCED.md buat pola reload dan workflow multi-select.
- Tambah fd (
sudo apt install fd-find) dan arahinFZF_DEFAULT_COMMANDke dia buat list file yang lebih cepet. - Cek bat-extras (batgrep, batdiff, batman) setelah tiga tool inti ini kerasa biasa.