Skip to content
Terminal Productivity — tmux, Zsh Plugins, fzf, ripgrep & More

Terminal Productivity — tmux, Zsh Plugins, fzf, ripgrep & More

DodaTech Updated Jun 20, 2026 10 min read

The terminal is the most powerful tool in a developer’s arsenal. Mastering it saves hundreds of hours per year — whether you use Bash, Zsh, or Vim.

What You’ll Learn

In this tutorial, you’ll learn how to supercharge your terminal workflow: tmux for session management, Zsh plugins for autosuggestions and syntax highlighting, fzf for fuzzy searching everything, ripgrep (rg) for lightning-fast code search, fd as a modern find, bat as a better cat, lazygit for visual git, jq for JSON processing, httpie for API testing, and the Starship prompt.

Why It Matters

Every keystroke you save adds up. A developer makes thousands of terminal commands per day. Mastering these tools reduces friction, keeps you in flow state, and makes complex tasks feel effortless.

Real-World Use

When debugging a production issue, you tmux into the server, rg through logs for the error pattern, pipe relevant JSON lines through jq, edit with lazygit to commit the fix, and use httpie to verify the endpoint works. Durga Antivirus Pro’s engineering team uses these tools daily for log analysis and system debugging.

    flowchart LR
  A[Terminal Startup] --> B[Zsh + Starship]
  B --> C[Session Management]
  C --> D[tmux]
  D --> E{Task}
  E --> F[Search Code]
  E --> G[Find Files]
  E --> H[View Logs]
  E --> I[Git Operations]
  E --> J[API Testing]
  F --> K[rg + fzf]
  G --> L[fd + fzf]
  H --> M[bat + rg]
  I --> N[lazygit]
  J --> O[httpie + jq]
  

tmux — Terminal Multiplexer

tmux lets you manage multiple terminal sessions, windows, and panes from a single terminal window.

Sessions, Windows, Panes

# Session management
tmux new -s project      # Create new session named "project"
tmux detach              # Detach (Ctrl+b d)
tmux attach -t project   # Reattach to session
tmux ls                  # List sessions
tmux kill-session -t old # Kill session

# Window management (inside tmux)
# Ctrl+b c  — New window
# Ctrl+b ,  — Rename window
# Ctrl+b n/p — Next/previous window
# Ctrl+b w  — List windows
# Ctrl+b &  — Close window

# Pane management
# Ctrl+b %  — Split vertically
# Ctrl+b "  — Split horizontally
# Ctrl+b arrow — Navigate panes
# Ctrl+b z  — Zoom pane fullscreen
# Ctrl+b x  — Close pane

.tmux.conf

# ~/.tmux.conf
# Use Ctrl+a instead of Ctrl+b (easier on standard keyboards)
set -g prefix C-a
unbind C-b
bind C-a send-prefix

# Increase scrollback
set -g history-limit 50000

# Mouse support
set -g mouse on

# Better colours
set -g default-terminal "tmux-256color"

# Vim-style navigation in copy mode
setw -g mode-keys vi

# Reload config
bind r source-file ~/.tmux.conf \; display "Config reloaded!"

# Split panes with | and -
bind | split-window -h
bind - split-window -v

Zsh Plugins

Install via a framework like Oh My Zsh or zinit.

zsh-autosuggestions

Suggests commands as you type based on history.

# After typing, press → to accept suggestion
$ git co<→>
# Suggests: git commit -m "fix: resolve timeout issue"

zsh-syntax-highlighting

Highlights commands as you type — green for valid, red for invalid.

# Valid command → green
$ git status

# Invalid/file → red
$ gti stats

.zshrc additions

# ~/.zshrc

# Plugins (Oh My Zsh)
plugins=(
  git
  docker
  docker-compose
  kubectl
  npm
  node
  zsh-autosuggestions
  zsh-syntax-highlighting
)

# History settings
HISTSIZE=100000
SAVEHIST=100000
setopt SHARE_HISTORY
setopt HIST_IGNORE_DUPS
setopt HIST_IGNORE_SPACE

fzf — Fuzzy Finder

fzf lets you fuzzy-search anything — files, commands, processes, git branches, and more.

# Interactive file search (fuzzy find)
vim **<Tab>          # Interactively search and select files to open
cd **<Tab>           # Fuzzy search directories
kill -9 **<Tab>      # Fuzzy search processes to kill
ssh **<Tab>          # Fuzzy search SSH hosts from ~/.ssh/config

# Pipe anything to fzf
cat huge_log.txt | fzf   # Search interactively through large files
ps aux | fzf             # Fuzzy find a process

# Preview window
fzf --preview 'bat --style=numbers --color=always {}'

fzf with fd

# Search files recursively with preview
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_CTRL_T_OPTS='--preview "bat --style=numbers --color=always {}"'

ripgrep (rg)

rg is grep on steroids — recursively searches file contents with blazing speed. It respects .gitignore, ignores binary files, and uses parallelism.

# Basic search
rg "pattern"                  # Search recursively in current dir
rg "TODO|FIXME" src/          # Search for multiple patterns
rg -i "error"                 # Case-insensitive search
rg -w "class"                 # Whole word match
rg -l "import"                # Only list matching filenames
rg -c "function"              # Count matches per file

# Context
rg -C 3 "panic"               # 3 lines of context before and after
rg -A 5 "error"               # 5 lines after
rg -B 2 "warning"             # 2 lines before

# File type filters
rg -t ts "interface"          # Only TypeScript files
rg -t py "def "               # Only Python files
rg -g "*.test.ts" "describe"  # Glob pattern

# Advanced
rg --json "error" | jq '.data.path.text'  # JSON output piped to jq
rg --no-heading -n "class"    # No filename heading, show line numbers

Why rg is faster than grep: it uses SIMD instructions for byte-level search, respects .gitignore out of the box, and is parallelised across CPU cores.

fd — Find Alternative

fd is a faster, simpler find with sensible defaults.

fd "pattern"                  # Find files/dirs matching pattern
fd -e py                      # Find all Python files
fd -e js -e ts                # Find JS and TS files
fd -t d "src"                 # Find directories named "src"
fd -t f -x wc -l              # Execute wc -l on each matching file
fd --hidden ".gitignore"      # Search hidden files too (respects .gitignore by default)

bat — Cat with Wings

bat is cat with syntax highlighting, line numbers, and git integration.

bat file.py                   # Display with syntax highlighting
bat --show-all file.conf      # Show invisible characters
bat -A file.log               # Show non-printable chars
bat --theme=Dracula file.rs   # Use a specific theme
bat file.json                 # JSON files get automatic formatting

Environment setup

# Use bat as pager for man
export MANPAGER="sh -c 'col -bx | bat -l man -p'"

# Preview bat output in fzf
export FZF_DEFAULT_OPTS='--preview "bat --style=numbers --color=always {}"'

lazygit — Git in the Terminal

lazygit provides a terminal UI for git with keyboard shortcuts for common operations.

# Install
# macOS: brew install lazygit
# Linux: sudo apt install lazygit  # or download from releases

# Usage (run inside a git repo)
lazygit

Key shortcuts:

  • 1 — Status panel
  • 2 — Files panel (stage/unstage with space)
  • 3 — Branch panel
  • 4 — Commit log
  • space — Stage/unstage file
  • c — Commit
  • p — Push
  • P — Pull
  • d — Diff (with arrow keys to navigate)

jq — JSON Processor

jq is like sed for JSON — it slices, filters, maps, and transforms JSON data.

# Basic
echo '{"name": "Alice", "age": 30}' | jq '.name'
# → "Alice"

# Array access
echo '[{"id": 1}, {"id": 2}]' | jq '.[0].id'
# → 1

# Pretty print
curl -s https://api.github.com/repos/jqlang/jq | jq '.'

# Select fields
curl -s https://api.github.com/repos/jqlang/jq | jq '{name, description, stars: .stargazers_count}'

# Filtering
echo '[{"name":"Alice","age":30},{"name":"Bob","age":25}]' | \
  jq '.[] | select(.age > 25) | .name'
# → "Alice"

# Transform
echo '{"users": [{"name": "Alice"}, {"name": "Bob"}]}' | \
  jq '.users | map(.name)'
# → ["Alice","Bob"]

httpie — Modern HTTP Client

httpie is curl for humans — colourful, intuitive, with JSON support built in.

# GET with headers
http httpbin.org/get

# POST with JSON body
http POST httpbin.org/post name=John email=john@example.com

# Custom headers
http httpbin.org/get Authorization:"Bearer your-token"

# File upload
http -f POST httpbin.org/post file@./photo.jpg

# Download binary
http --download https://example.com/file.zip

# Follow redirects
http --follow http://httpbin.org/redirect/3

# Verbose output (show request and response)
http -v httpbin.org/get

Starship Prompt

Starship is a fast, customisable prompt for any shell. It shows git branch, runtime versions, command duration, and more.

# ~/.config/starship.toml
format = """
[╭─](bold blue)($username)(@)$directory$git_branch$git_status\
$fill$all\
[ ](bold blue)\
[╰─](bold blue)$character"""

[nodejs]
symbol = "⬡ "
style = "bold green"

[rust]
symbol = "🦀 "
style = "bold red"

[python]
symbol = "🐍 "
style = "bold yellow"

[git_branch]
symbol = " "
style = "bold purple"

[cmd_duration]
show_milliseconds = true
min_time = 500
style = "yellow"

Essential Aliases

# ~/.zsh_aliases

# Navigation
alias ..="cd .."
alias ...="cd ../.."
alias ~="cd ~"

# List
alias ls="eza --icons"                               # Better ls
alias ll="eza --icons -la"                            # Long listing
alias lt="eza --icons --tree --level=2"               # Tree view
alias la="ls -a"

# Git
alias gs="git status"
alias ga="git add"
alias gc="git commit"
alias gp="git push"
alias gco="git checkout"
alias gb="git branch"
alias gl="git log --oneline --graph --decorate"

# Search
alias grep="rg"
alias find="fd"
alias cat="bat"

# Networking
alias myip="curl -s https://api.ipify.org && echo"
alias localip="ipconfig getifaddr en0"

# Docker
alias dps="docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'"
alias dlog="docker logs -f"
alias dstopall="docker stop $(docker ps -q)"

# Misc
alias ,,="lazygit"
alias ports="lsof -i -P -n | grep LISTEN"
alias path='echo -e "${PATH//:/\\n}"'

Common Mistakes

1. Installing everything without understanding

Don’t blindly install all tools. Start with fzf and rg — they have the highest ROI. Add more as you identify specific pain points.

2. Not learning tmux keybindings

tmux is useless if you don’t learn the keybindings. Focus on: create/kill windows/panes, navigate, detach/attach, scrollback mode.

3. Using default grep instead of rg

Once you try rg --json piped to jq, you won’t go back. But many developers don’t know about these tools at all.

4. Over-customising the prompt

A slow prompt adds latency to every command. Starship is fast, but git status in huge repos can be slow. Use Starship’s scan_for_worktrees = false in large monorepos.

5. Not persisting tmux sessions

After a reboot, your tmux sessions are gone. Use a tool like tmux-resurrect or tmuxinator to save/restore sessions automatically.

6. Ignoring fd’s smart case

fd defaults to smart-case: case-sensitive if the pattern includes uppercase, case-insensitive otherwise. This catches people used to find -name.

Practice Questions

  1. What’s the difference between a tmux session, window, and pane? Session = collection of windows (like a project). Window = workspace within a session. Pane = split within a window.

  2. Why is ripgrep faster than grep? rg uses SIMD instructions, respects .gitignore, ignores binary files, and searches in parallel across CPU cores.

  3. What does fzf’s preview window show? A preview of the selected item’s content — file contents, process info, git diff, etc., using tools like bat for syntax highlighting.

  4. How does jq select elements from a JSON array? Use .array[index] for a specific index, .[] to iterate, and select(.field == value) to filter.

  5. What advantage does httpie have over curl for daily use? httpie has sensible defaults, coloured JSON output, automatic JSON formatting for POST bodies, and cleaner syntax.

Challenge

Create a shell script that:

  1. Opens or creates a tmux session with 3 windows: code, server, shell
  2. In the “server” window, runs the dev server
  3. In the “code” window, opens Neovim
  4. Uses fzf to select which project to work on

Real-World Task

Use rg --json together with jq to analyse a large codebase. Find all functions with more than 50 lines, all TODO comments by author, and all deprecated API calls. Visualise the results.

FAQ

Should I use tmux or just multiple terminal tabs?
tmux sessions persist across disconnections (SSH), support split panes, and let you share sessions. For local development, terminal tabs work fine. For remote servers, tmux is essential.
What’s the best Zsh plugin manager?
Oh My Zsh is easiest for beginners. zinit and antigen are faster. Starship doesn’t need a plugin manager at all.
Is bat better than cat?
bat is cat with syntax highlighting, git integration, and line numbers. For scripts and piping, use cat (bat adds ANSI codes). Set bat --plain for pipe-friendly output.
How do I remember all these shortcuts?
You don’t need to. Learn 3-5 shortcuts for each tool, use them until they’re muscle memory, then learn more. The cheat sheets in this tutorial cover the essentials.
What about Alacritty, Kitty, or WezTerm?
These are GPU-accelerated terminal emulators. They’re faster than the default terminal on macOS/Linux. Alacritty is minimal; Kitty has more features; WezTerm is Lua-configurable and cross-platform.

Mini Project: Terminal Workflow Setup Script

Create a bash script that:

  1. Installs all tools: tmux, fzf, rg, fd, bat, lazygit, jq, httpie, starship
  2. Configures ~/.tmux.conf, ~/.zshrc, ~/.config/starship.toml
  3. Sets up essential aliases
  4. Installs Oh My Zsh with zsh-autosuggestions and zsh-syntax-highlighting

Security angle: Terminal logging (script, asciinema) captures commands for audit trails. On production servers, limit which tools are available and log all shell activity for incident response.

What’s Next

Before moving on, you should understand:

  • tmux session/window/pane management
  • How to use fzf for interactive searching
  • ripgrep vs grep and when to use each
  • jq for JSON processing from the terminal
  • Essential aliases and their tool equivalents

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro