Tmux Workflow Optimization buat Dev Sehari-hari

by Marcus Chen
Tmux Workflow Optimization buat Dev Sehari-hari

Terminal Kamu Berantakan, dan Itu Masalah Nyata

Lo lagi debug API, terus buka terminal baru buat jalanin docker compose up, terus buka lagi buat tail log, terus buka lagi buat git. Tiba-tiba ada 7 window terminal terbuka, Alt+Tab jadi mimpi buruk, dan lo nggak ingat window mana yang lagi SSH ke server production.

Itu bukan masalah konsentrasi — itu masalah tooling. Dan solusinya bukan buka lebih sedikit window; solusinya adalah tmux.

Artikel ini bukan pengenalan "apa itu tmux". Ini tentang tmux workflow optimization yang konkret: config yang gue pakai, keybinding yang mengubah cara kerja, dan beberapa script buat sesi yang reproducible. Kalau kamu udah install tmux tapi masih pakai defaults, ini yang kamu butuhkan.


Kenapa Default Config Tmux Itu Menyiksa

Prefix default tmux adalah Ctrl+b. Kedengarannya oke sampai kamu sadar jari kelingking kiri harus nahan Ctrl sambil jari telunjuk pencet b — dua tombol yang posisinya awkward banget. Setelah 50 kali sehari, pergelangan tangan mulai protes.

Selain itu:

  • Mouse support mati by default. Kamu nggak bisa scroll dengan trackpad.
  • Numbering pane mulai dari 0, tapi keyboard kamu mulai dari 1. Otak manusia bingung.
  • Copy-paste butuh ritual tersendiri yang nggak intuitif.
  • Status bar default jelek dan minim info.

Semua ini fixable dengan config yang bener.


Setup ~/.tmux.conf yang Langsung Kerja

Buat atau edit file ~/.tmux.conf. Ini base config yang gue pakai di semua mesin:

# Ganti prefix dari Ctrl+b ke Ctrl+a (lebih ergonomis)
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix

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

# Split pane dengan | dan - (lebih intuitif dari % dan ")
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
unbind '"'
unbind %

# Navigasi pane pakai Vim keys
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

# Resize pane dengan Shift+arrow
bind -n S-Left  resize-pane -L 5
bind -n S-Right resize-pane -R 5
bind -n S-Up    resize-pane -U 5
bind -n S-Down  resize-pane -D 5

# Mouse support
set -g mouse on

# Mulai numbering dari 1
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on

# History yang panjang
set -g history-limit 50000

# Kurangi escape delay (penting buat Vim/Neovim)
set -sg escape-time 0

# Status bar yang lebih informatif
set -g status-interval 5
set -g status-left-length 40
set -g status-left "#[fg=green]#S #[fg=yellow]#I:#P "
set -g status-right "#[fg=cyan]%d %b %H:%M"
set -g status-bg colour235
set -g status-fg colour136

# Aktifkan 256 color
set -g default-terminal "screen-256color"
set -ga terminal-overrides ",xterm-256color:Tc"

# Copy mode pakai Vi keys
setw -g mode-keys vi
bind -T copy-mode-vi v send -X begin-selection
bind -T copy-mode-vi y send -X copy-pipe-and-cancel "xclip -in -selection clipboard"

Setelah save, jalankan:

tmux source-file ~/.tmux.conf

Atau kalau belum ada sesi tmux aktif, buka sesi baru dan prefix r langsung reload.

Gotcha: Kalau kamu di macOS, ganti xclip dengan pbcopy:

bind -T copy-mode-vi y send -X copy-pipe-and-cancel "pbcopy"

Kalau kamu di WSL2, pakai:

bind -T copy-mode-vi y send -X copy-pipe-and-cancel "clip.exe"

Tmux Session Management yang Beneran Berguna

Satu kesalahan umum: orang pakai tmux tapi tetap buka sesi baru setiap hari, terus heran kenapa kerjaan nggak terorganisir.

Workflow yang lebih baik: satu project, satu named session.

# Buat sesi dengan nama project
tmux new-session -s myapp

# Attach ke sesi yang sudah ada
tmux attach-session -t myapp

# List semua sesi
tmux ls

# Kill sesi spesifik
tmux kill-session -t myapp

Dengan cara ini, kamu bisa detach (Ctrl+a d), laptop masuk sleep, balik lagi besoknya, attach ke sesi yang sama — semua proses masih jalan.

Script Sesi Otomatis per Project

Daripada setup layout manual setiap pagi, buat script bash yang reproducible. Ini contoh untuk project backend Node.js:

#!/usr/bin/env bash
# ~/scripts/dev-session.sh

SESSION="myapp"
PROJECT_DIR="$HOME/projects/myapp"

# Kalau sesi sudah ada, langsung attach
tmux has-session -t $SESSION 2>/dev/null
if [ $? == 0 ]; then
  tmux attach-session -t $SESSION
  exit 0
fi

# Buat sesi baru
tmux new-session -d -s $SESSION -c $PROJECT_DIR

# Window 1: Editor
tmux rename-window -t $SESSION:1 'editor'
tmux send-keys -t $SESSION:1 'nvim .' C-m

# Window 2: Server
tmux new-window -t $SESSION:2 -n 'server' -c $PROJECT_DIR
tmux send-keys -t $SESSION:2 'npm run dev' C-m

# Window 3: Database + Log
tmux new-window -t $SESSION:3 -n 'db-log' -c $PROJECT_DIR
tmux split-window -h -t $SESSION:3
tmux send-keys -t $SESSION:3.1 'docker compose up db' C-m
tmux send-keys -t $SESSION:3.2 'npm run logs' C-m

# Window 4: Git / terminal bebas
tmux new-window -t $SESSION:4 -n 'git' -c $PROJECT_DIR

# Fokus ke window pertama
tmux select-window -t $SESSION:1

# Attach
tmux attach-session -t $SESSION

Kasih execute permission dan jalankan:

chmod +x ~/scripts/dev-session.sh
./scripts/dev-session.sh

Gotcha yang gue kena: tmux send-keys kadang ngirim command sebelum shell siap, terutama kalau ada .nvmrc atau conda activate yang lambat. Fix-nya tambah sleep 0.5 sebelum send-keys di window yang butuh init:

tmux new-window -t $SESSION:2 -n 'server' -c $PROJECT_DIR
sleep 0.5
tmux send-keys -t $SESSION:2 'npm run dev' C-m

Keybinding Tambahan yang Gue Pakai Tiap Hari

Beberapa binding yang nggak ada di config default tapi drastis mengubah kecepatan kerja:

# Sync input ke semua pane (berguna buat deploy ke banyak server sekaligus)
bind e setw synchronize-panes on
bind E setw synchronize-panes off

# Pindah ke window terakhir yang dipakai (toggle)
bind C-a last-window

# Buka window baru di direktori yang sama
bind c new-window -c "#{pane_current_path}"

# Zoom pane (toggle fullscreen pane)
bind z resize-pane -Z

# Cepat rename window
bind n command-prompt -I "#W" "rename-window '%%'"

# Kill pane tanpa konfirmasi
bind x kill-pane

Tambahkan ke ~/.tmux.conf dan reload.


Integrasi dengan Neovim / Vim

Kalau kamu pakai Neovim, ada friction yang sering muncul: navigasi antara tmux pane dan Vim split terasa beda. Plugin vim-tmux-navigator solve ini.

Install di Neovim (pakai lazy.nvim):

-- ~/.config/nvim/lua/plugins/tmux.lua
return {
  "christoomey/vim-tmux-navigator",
  cmd = {
    "TmuxNavigateLeft",
    "TmuxNavigateDown",
    "TmuxNavigateUp",
    "TmuxNavigateRight",
  },
  keys = {
    { "<c-h>", "<cmd>TmuxNavigateLeft<cr>" },
    { "<c-j>", "<cmd>TmuxNavigateDown<cr>" },
    { "<c-k>", "<cmd>TmuxNavigateUp<cr>" },
    { "<c-l>", "<cmd>TmuxNavigateRight<cr>" },
  },
}

Dan tambahkan ini ke ~/.tmux.conf:

# vim-tmux-navigator
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?|fzf)(diff)?$'"
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' 'select-pane -L'
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j' 'select-pane -D'
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k' 'select-pane -U'
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' 'select-pane -R'

Sekarang Ctrl+h/j/k/l kerja seamless antara Vim split dan tmux pane — nggak perlu mikir lagi lagi pakai Ctrl+a dulu atau nggak.


Tmux Plugin Manager (TPM) dan Plugin yang Worth It

Kalau mau extend lebih jauh, install TPM dulu:

git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm

Tambahkan ke bagian bawah ~/.tmux.conf:

# Plugin list
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'

# tmux-resurrect: restore sesi setelah reboot
set -g @resurrect-capture-pane-contents 'on'

# tmux-continuum: auto-save setiap 15 menit
set -g @continuum-restore 'on'
set -g @continuum-save-interval '15'

# Inisialisasi TPM (harus di baris paling akhir)
run '~/.tmux/plugins/tpm/tpm'

Install plugin dengan Ctrl+a I (huruf I kapital) di dalam sesi tmux.

Plugin yang paling worth it:

  • tmux-resurrect: save dan restore semua sesi, window, pane — bahkan setelah reboot. Ini yang paling gue andalkan.
  • tmux-continuum: auto-save berkala supaya resurrect selalu punya snapshot terbaru.

Gotcha: tmux-continuum dengan @continuum-restore 'on' kadang restore sesi lama yang nggak kamu mau waktu pertama buka tmux. Kalau ini ganggu, set ke off dan restore manual dengan Ctrl+a Ctrl+r.


Yang Gue Lakuin Sekarang

Setelah pakai config ini beberapa bulan, workflow gue sekarang:

  1. Pagi buka terminal, jalankan ~/scripts/dev-session.sh — semua window langsung siap.
  2. Kalau harus switch project, Ctrl+a $ rename sesi, atau buat sesi baru dengan script yang berbeda.
  3. Sore, detach saja (Ctrl+a d). Besok attach lagi, semua masih ada.
  4. Kalau laptop restart, tmux-resurrect restore semuanya dalam 2 detik.

Hal kecil yang bikin beda: karena prefix gue sekarang Ctrl+a dan navigasi pakai Vim keys, context switch antara editor dan terminal hampir nol friction. Otak nggak harus ganti mode.

Kalau kamu mau mulai dari yang paling impactful: ganti prefix ke Ctrl+a, aktifkan mouse, dan buat satu script sesi untuk project utama kamu. Tiga hal itu aja udah mengubah cara kerja sehari-hari. Untuk setup yang lebih mendalam tentang optimasi sistem, kamu bisa juga melihat linux kernel sysctl hardening parameters yang bisa meningkatkan performa server kamu secara keseluruhan.

Config lengkap ada di gist yang bisa kamu fork dan sesuaikan — struktur direktori dan nama project tinggal diganti sesuai setup kamu sendiri.