Zellij
I replaced tmux with it, mainly for its structured KDL configuration, WASM-based plugins, and the ability to save layouts to files. But the one thing that truly makes it indispensable is the seamless navigation with Neovim.
In Neovim, pressing Ctrl+h/j/k/l switches between Vim windows. When you reach the edge, pressing it again moves the focus directly to the adjacent Zellij pane, and vice versa. The entire screen is divided into a grid, so I don't need to remember "is the cursor currently in Vim or Zellij? Which keybindings should I use?"—one set of Ctrl+hjkl keys works everywhere. This is achieved by integrating the smart-splits plugin on the Neovim side with the vim-zellij-navigator plugin on the Zellij side.
For this to work smoothly, Zellij must not hijack keybindings. By default, it consumes many shortcuts that conflict with underlying programs, so I keep it in locked mode by default—intercepting almost nothing, leaving keys for Neovim and the shell. Only Ctrl+g enters its own normal mode for operations like splitting panes or opening tabs.
locked {
bind "Ctrl g" { SwitchToMode "normal"; }
}
shared_except "tmux" {
bind "Alt e" { EditScrollback; } // Dump scrollback buffer into Neovim for searching
bind "Ctrl h" { MessagePlugin ".../vim-zellij-navigator.wasm" {
name "move_focus_or_tab"; payload "left"; move_mod "ctrl"; }; }
// Similarly for j/k/l
}
I use the Alt e binding frequently: when logs scroll past, one keypress dumps the scrollback content into Neovim for searching or copying.
Once in normal mode (Ctrl+g), operations are mode-based. Zellij's design uses a primary menu plus sub-keys: p enters pane mode (then use arrow keys to open/switch panes), t for tabs, r for resizing, s for scrolling/searching, and o for sessions. Compared to tmux's "one prefix key + a bunch of letters to memorize," Zellij displays available keys in the bottom bar for each mode, requiring almost no memorization. The most common actions are opening panes, switching tabs, using w to float a pane as a temporary window, and f for fullscreen focus.
What truly adds value to a terminal multiplexer is session persistence, which deserves a separate mention:
- detach / attach:
zellij attachreconnects to the previous session. If the SSH connection drops or you accidentally close the terminal, the running processes and the entire layout remain intact. This is the practical application of my principle: "terminals are replaceable, sessions are not." - Layouts saved to files: Common workspaces (e.g., code on the left, logs on the bottom right, REPL on the top right) are written as
.kdllayout files. Runningzellij --layout devapplies the layout instantly, without manual configuration each time. Layouts can also preset the initial command and working directory for each pane. - Resurrection: After an abnormal session exit, Zellij remembers the layout. On the next launch, it can "resurrect" the session—the pane structure returns, and previously run commands can be replayed with one keypress.
The color scheme and status bar follow matugen (MaterialYou.kdl). Instead of using the default bottom bar, I replaced it with zjstatus for custom rendering: arranging mode, tabs, session name, and time in my preferred format. This allows for denser information display while maintaining a consistent color theme across the entire desktop.