← Back to list

Emacs keybindings everywhere: making tmux speak `C-x`

I spend most of my day inside Emacs. Then I drop into tmux to juggle a few shells, and my hands betray me — they fire `C-x` muscle memory…

Max Holovanov · 2026-05-22 07:03 · 53 claps · 5.1 min read
#tmux #emacs #terminal #productivity #programming
Open on Medium ↗
Wiki topics: GEN · Genomics & Sequencing 💻 · Programming ⏱️ · Productivity

Emacs keybindings everywhere: making tmux speak C-x

Dvorak in mind

Dvorak in mind

I spend most of my day inside Emacs. Then I drop into tmux to juggle a few shells, and my hands betray me — they fire C-x muscle memory into a world that expects C-b. Nothing happens. Or worse, something happens. Every context switch costs a tiny stutter, and those stutters add up.

So I stopped switching contexts. I made tmux speak Emacs.

This isn’t about theming, or making tmux look like Emacs. It’s about one keymap, one set of verbs, living in one brain. Here’s the whole approach.

Why C-x

tmux’s default prefix is C-b. The old-timer move is C-a, inherited from GNU Screen. For an Emacs user, both are landmines:

  • C-b is backward-char
  • C-a is move-beginning-of-line

Both are keys I press hundreds of times an hour. Rebinding tmux onto either one doesn’t remove the collision — it just relocates it into tmux.

C-x is different. In Emacs, C-x already means “this is the start of a command.” It is a prefix in the truest sense. Reusing it for tmux isn’t a collision — it’s the same mental gesture pointed at a different surface. My hand already knows C-x means “I’m about to do something structural.tmux just becomes one more thing C-x can address.

The four lines that set it up:

set -g prefix C-x
bind C-x send-prefix
set -g mode-keys emacs
set -g status-keys emacs

Two of these deserve a note.

bind C-x send-prefix is your escape hatch. Since C-x is now tmux’s prefix, the shell underneath never sees it — unless you press it twice. C-x C-x sends a literal C-x through to whatever is running. You’ll want this the first time a program inside tmux needs a real C-x.

set -g mode-keys emacs makes tmux’s copy mode use Emacs motion and editing keys instead of vi’s. This is the line that makes the copy-mode section below actually work.

Windows are buffers

The first mental mapping: a tmux window is like an Emacs buffer. A named thing you cycle through.

bind C-f next-window
bind C-b previous-window
bind Tab last-window

C-x C-f and C-x C-b step forward and back through windows. They aren’t lifted from any specific Emacs command — they’re chosen because f and b are alreadyforward” and “back” in my fingers (forward-char, backward-char). The letters carry the direction.

C-x Tab jumps to the last window — the tmux equivalent of bouncing between your two most recent buffers.

Panes are windows — the Emacs kind

This is the mapping that sells the whole idea. Emacs “windows” — the split-the-frame kind — map almost perfectly onto tmux panes, and Emacs already has a beautiful, decades-old keymap for them:

bind 2 split-window -v -c "#{pane_current_path}"
bind 3 split-window -h -c "#{pane_current_path}"
bind 0 kill-pane
bind 1 kill-pane -a
bind o display-panes

If you use Emacs, you already know these:

  • **C-x 2** — split below
  • **C-x 3** — split right
  • **C-x 0** — kill this pane
  • **C-x 1** — kill the other panes (“delete other windows”)
  • **C-x o** — other pane

I didn’t have to learn a single one. I already had them. The **-c “*#{pane_current_path}*”** is a small bonus tmux gives you that Emacs doesn’t need: new panes open in the same directory as the one you split from.

Pane navigation reuses Emacs cursor motion:

bind f select-pane -R
bind b select-pane -L
bind n select-pane -D
bind p select-pane -U

**f** / **b** / **n** / **p** — forward, back, next, previous. The same four letters that move point in Emacs now move focus between panes. **C-x n** moves down because **C-n** is **next-line**. Nothing to memorize; the knowledge transferred for free.

Resizing piggybacks on the same letters, shifted:

bind -r P resize-pane -U 2
bind -r N resize-pane -D 2
bind -r B resize-pane -L 2
bind -r F resize-pane -R 2

The **-r** flag makes them repeatable — press **C-x** once, then tap **F F F** to keep growing a pane.

Copy mode that feels like Emacs

**set -g mode-keys emacs** did most of the work; these bindings finish it:

bind [ copy-mode
bind-key -T copy-mode M-w send-keys -X copy-selection-and-cancel
bind-key -T copy-mode C-w send-keys -X copy-selection-and-cancel
bind-key -T copy-mode C-g send-keys -X cancel
bind-key -T copy-mode C-s send-keys -X search-forward
bind-key -T copy-mode C-r send-keys -X search-backward

**C-x [** enters copy mode. From there it’s pure Emacs: **C-Space** to set the mark, **M-w** to copy, **C-g** to bail, **C-s** / **C-r** to search forward and back. Scrolling a terminal’s scrollback now uses the exact reflexes I use to scroll a buffer.

Sessions: the part with no Emacs analogy

tmux sessions don’t map cleanly onto anything in Emacs — there’s no real equivalent of “a whole separate workspace of buffers.” So instead of forcing an analogy, I designed for raw speed:

bind    C-l switch-client -l
bind    s   choose-tree -Zs
bind -n M-s switch-client -l
bind -n M-t display-popup -E -w 60% -h 50% \
  "tmux list-sessions | cut -d: -f1 | fzf --reverse | xargs -r tmux switch-client -t" 

**C-x C-l** toggles to the last session. **M-s** does the same with no prefix at all — one chord, instant. And **M-t** pops up an fzf picker right in the terminal: fuzzy-search every session, hit Enter, you’re there.

The **-n** flag means “no prefix” — these fire on the bare **M-** chord. Sessions are the thing I switch most, so they get the cheapest keys.

The honest tradeoffs

No config is free. Three things I gave up:

Window-number jumps. Default tmux lets **prefix 0–9** jump straight to a window. I spent **0** and **1** on kill-pane to match **C-x 0** / **C-x 1**. I jump windows with **C-f** / **C-b** instead — and I rarely have ten windows anyway. But know the cost before you copy this.

C-x is a two-key chord. **C-b** is one keypress; **C-x** is a held modifier plus a key. Marginally more work per command. This config only pays off if you’re already an Emacs person — the win is reusing existing muscle memory, not the chord itself.

send-prefix friction. Anything inside tmux that wants a literal **C-x** needs **C-x C-x**. In practice this almost never comes up, but it’s a real edge.

One thing that helped: I type on a Kinesis Advantage in Dvorak. Modifier-heavy chords like **C-x** are genuinely comfortable there in a way they aren’t on a staggered QWERTY board. On a standard keyboard, weigh the comfort cost a little higher.

The payoff

The point was never to make tmux clever. It was to delete a category of friction: the half-second where my brain notices it’s “in tmux now” and reaches for a different keymap. That half-second is gone. **C-x** means the same thing whether I’m splitting an Emacs frame or a tmux pane, and my hands stopped caring which one they’re talking to.

The full config lives in my dotfiles:[ https://github.com/maxclax/dotfiles ](https://maxclax.com/go/dotfiles-medium/) Steal what’s useful.


메타데이터
post_id
b28d18974dff
slug
emacs-keybindings-everywhere-making-tmux-speak-c-x-b28d18974dff
url
https://medium.com/@maxclax/emacs-keybindings-everywhere-making-tmux-speak-c-x-b28d18974dff
canonical_url
https://medium.com/@maxclax/emacs-keybindings-everywhere-making-tmux-speak-c-x-b28d18974dff
author_url
https://medium.com/@maxclax
status
ok
fetched_at
2026-06-15 20:49:13