From d1eea4f26ae601f176e52e9015e126325b2e9f13 Mon Sep 17 00:00:00 2001 From: Mortdecai Date: Thu, 26 Mar 2026 19:18:56 -0400 Subject: [PATCH] feat: kitty-compatible keybindings via tmux extended-keys (CSI u) All Ctrl+Shift shortcuts mapped to match kitty defaults: - Ctrl+Shift+T/W/Left/Right for tab management - Ctrl+Shift+Enter for splits, ]/[ for pane cycling - Ctrl+Shift+C/V for copy/paste, H for scrollback pager - Ctrl+Shift+1-9 for goto tab, F11 for fullscreen - Dvorak extras and Alt shortcuts preserved alongside --- README.md | 136 +++++++++++++++++++++++++---------------------- config/tmux.conf | 109 ++++++++++++++++++++++++++++++------- 2 files changed, 163 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index b6a2358..2c43910 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,84 @@ # sethmux -Mobile-first web terminal powered by [ttyd](https://github.com/tsl0922/ttyd) + [tmux](https://github.com/tmux/tmux). One persistent session, multiple tabs, accessible from any browser. +Mobile-first web terminal powered by [ttyd](https://github.com/tsl0922/ttyd) + [tmux](https://github.com/tmux/tmux). One persistent session, multiple tabs, accessible from any browser. Kitty-compatible keybindings. ## Features -- **Single persistent tmux session** — shared across all connected clients -- **Mobile touch toolbar** — on-screen buttons for tabs, signals, navigation, splits, and text selection -- **Text selection mode** — tap `Sel` to select and copy text on touch devices +- **Single persistent tmux session** — shared across all connected clients, live-synced across devices +- **Kitty keybindings** — `Ctrl+Shift+T/W/Left/Right` etc. via tmux extended-keys (CSI u) +- **Mobile touch toolbar** — two-row on-screen buttons for all common actions +- **AI CLI optimized** — 200K scrollback, pane capture/logging, pre-built session layout - **Push notifications** — `sethmux-notify "Build done!"` sends browser notifications - **PWA installable** — add to home screen for app-like experience - **Dark theme** — Sethian dark + orange (#D35400) accent +## Keybindings + +### Kitty-compatible (Ctrl+Shift+key) + +| Key | Action | +|-----|--------| +| `Ctrl+Shift+T` | New tab | +| `Ctrl+Shift+W` | Close tab | +| `Ctrl+Shift+Right/Left` | Next / previous tab | +| `Ctrl+Shift+1-9` | Go to tab N | +| `Ctrl+Shift+. / ,` | Move tab forward / backward | +| `Ctrl+Shift+Enter` | New split (horizontal) | +| `Ctrl+Shift+] / [` | Next / previous pane | +| `Ctrl+Shift+L` | Cycle layouts | +| `Ctrl+Shift+Up/Down` | Scroll up / down | +| `Ctrl+Shift+PageUp/PageDown` | Scroll page | +| `Ctrl+Shift+Home/End` | Scroll to top / bottom | +| `Ctrl+Shift+H` | Show scrollback in pager | +| `Ctrl+Shift+C` | Enter copy mode (vi-style) | +| `Ctrl+Shift+V` | Paste | +| `Ctrl+Shift+Delete` | Clear terminal + scrollback | +| `F11` | Toggle fullscreen (zoom pane) | + +### Dvorak extras (prefix Ctrl-A) + +| Key | Action | +|-----|--------| +| `Ctrl-A v / s` | Split vertical / horizontal | +| `Ctrl-A S` | Capture pane to `~/logs/` | +| `Ctrl-A L` | Toggle live logging to `~/logs/` | +| `Ctrl-A z` | Zoom pane | + +### Alt shortcuts (no prefix) + +| Key | Action | +|-----|--------| +| `Alt-T` | New tab | +| `Alt-W` | Close tab | +| `Alt-1` to `Alt-5` | Go to tab N | +| `Alt-Left/Right` | Previous / next tab | + +## Mobile Toolbar + +Two rows, appears on screens < 900px: + +**Row 1:** `+Tab` `Next` `Prev` | `^C` `^D` `Clr` | `Esc` `Tab` `▲` `▼` +**Row 2:** `Sel` `Paste` `Zoom` `Save` | `V.Spl` `H.Spl` `Pane` `Kill` + +## Session Layout + +On startup, four named windows are created: + +| Window | Purpose | +|--------|---------| +| **code** | Main working terminal | +| **git** | Git operations | +| **run** | Running services / builds | +| **logs** | Tailing logs, monitoring | + +## Push Notifications + +```bash +sethmux-notify "Deploy complete!" +echo "done" | sethmux-notify +make build && sethmux-notify "OK" || sethmux-notify "FAIL" +``` + ## Architecture ``` @@ -29,6 +97,7 @@ chmod +x /usr/local/bin/ttyd # Deploy sudo mkdir -p /opt/sethmux sudo cp static/* /opt/sethmux/ +sudo cp sethmux-start.sh /opt/sethmux/ sudo cp notify-server.py /opt/sethmux/ sudo cp sethmux-notify /usr/local/bin/ sudo cp config/tmux.conf ~/.tmux.conf @@ -37,46 +106,6 @@ sudo systemctl daemon-reload sudo systemctl enable --now sethmux sethmux-notify ``` -Open `http://YOUR_IP:7683` in a browser. - -## Mobile Toolbar - -Appears on screens < 900px. Buttons: - -| Button | Action | tmux Key | -|--------|--------|----------| -| **+Tab** | New tab | `Ctrl-A c` | -| **Next/Prev** | Switch tabs | `Ctrl-A n/p` | -| **^C / ^D / Clr** | Interrupt / EOF / Clear | | -| **Esc / Tab / Up / Down** | Navigation | | -| **Sel** | Text selection mode | | -| **V.Spl** | Split vertical | `Ctrl-A v` | -| **H.Spl** | Split horizontal | `Ctrl-A s` | -| **Pane** | Cycle panes | `Ctrl-A o` | -| **Kill** | Kill pane/tab | `Ctrl-A x` | - -## Push Notifications - -```bash -sethmux-notify "Deploy complete!" -echo "done" | sethmux-notify -make build && sethmux-notify "OK" || sethmux-notify "FAIL" -``` - -## tmux Keybindings - -Prefix: `Ctrl-A` (not the default Ctrl-B — easier on mobile). - -| Key | Action | -|-----|--------| -| `Ctrl-A c` | New window | -| `Ctrl-A n / p` | Next / previous | -| `Ctrl-A v / s` | Split vertical / horizontal (Dvorak home row) | -| `Ctrl-A o` | Cycle panes | -| `Ctrl-A x` | Kill pane | -| `Alt-1` to `Alt-5` | Jump to window | -| Mouse scroll | History | - ## Reverse Proxy (Caddy) ``` @@ -90,25 +119,6 @@ mux.example.com { } ``` -## Files - -``` -sethmux/ - static/ - index.html # Custom ttyd page with toolbar injection - toolbar.js # Mobile touch toolbar - manifest.json # PWA manifest - icon-192.png # PWA icon - icon-512.png # PWA icon - config/ - tmux.conf # Sethian-themed tmux config - systemd/ - sethmux.service # ttyd + tmux systemd unit - sethmux-notify.service # Notification API unit - notify-server.py # Push notification HTTP API - sethmux-notify # CLI notification command -``` - ## License MIT diff --git a/config/tmux.conf b/config/tmux.conf index a15debc..cec7258 100644 --- a/config/tmux.conf +++ b/config/tmux.conf @@ -1,12 +1,91 @@ -# sethmux — Sethian tmux config for AI CLI workflows -# Dvorak-optimized, mobile-friendly, built for long-running AI sessions +# sethmux — kitty-compatible keybindings for tmux +# Mirrors kitty's Ctrl+Shift+key shortcuts via extended-keys (CSI u) +# Dvorak-optimized, mobile-friendly, built for AI CLI workflows -# --- Prefix --- +# --- Extended keys (required for Ctrl+Shift detection) --- +set -g extended-keys on +set -g extended-keys-format csi-u + +# --- No prefix for kitty-style bindings --- +# Kitty uses Ctrl+Shift+key directly, no prefix needed. +# We keep Ctrl-A as prefix for tmux-native stuff (capture, logging, etc.) unbind C-b set -g prefix C-a bind C-a send-prefix -# --- Tab/Window management --- +# ============================================================ +# Kitty-compatible keybindings (Ctrl+Shift+key) +# ============================================================ + +# --- Tab management --- +bind -n C-S-t new-window -c "#{pane_current_path}" +bind -n C-S-w kill-window +bind -n C-S-Right next-window +bind -n C-S-Left previous-window + +# Ctrl+Shift+1-9 = goto tab (tmux base-index 1) +bind -n C-S-1 select-window -t 1 +bind -n C-S-2 select-window -t 2 +bind -n C-S-3 select-window -t 3 +bind -n C-S-4 select-window -t 4 +bind -n C-S-5 select-window -t 5 +bind -n C-S-6 select-window -t 6 +bind -n C-S-7 select-window -t 7 +bind -n C-S-8 select-window -t 8 +bind -n C-S-9 select-window -t 9 + +# Ctrl+Shift+. / , = move tab forward/backward +bind -n C-S-. swap-window -t +1 \; next-window +bind -n C-S-, swap-window -t -1 \; previous-window + +# --- Window/split management --- +# Ctrl+Shift+Enter = new split (kitty calls these "windows") +bind -n C-S-Enter split-window -v -c "#{pane_current_path}" + +# Ctrl+Shift+] / [ = next/previous pane +bind -n C-S-] select-pane -t :.+ +bind -n C-S-[ select-pane -t :.- + +# Ctrl+Shift+l = next layout (cycle through layouts) +bind -n C-S-l next-layout + +# --- Scrolling --- +bind -n C-S-Up copy-mode \; send -X scroll-up +bind -n C-S-Down copy-mode \; send -X scroll-down +bind -n C-S-PageUp copy-mode \; send -X page-up +bind -n C-S-PageDown copy-mode \; send -X page-down +bind -n C-S-Home copy-mode \; send -X history-top +bind -n C-S-End copy-mode \; send -X history-bottom + +# Ctrl+Shift+h = show scrollback in pager (like kitty's show_scrollback) +bind -n C-S-h capture-pane -pS - \; save-buffer /tmp/sethmux-scrollback.txt \; new-window "less +G /tmp/sethmux-scrollback.txt" + +# --- Clipboard --- +# Ctrl+Shift+c = copy (enter copy mode, or copy selection if in copy mode) +bind -n C-S-c copy-mode +bind -T copy-mode-vi C-S-c send -X copy-selection-and-cancel + +# Ctrl+Shift+v = paste from tmux buffer +bind -n C-S-v paste-buffer + +# --- Clear terminal --- +# Ctrl+Shift+Delete = clear terminal + scrollback +bind -n C-S-DC send-keys C-l \; clear-history + +# --- Fullscreen --- +# F11 = toggle pane zoom (closest to kitty's fullscreen) +bind -n F11 resize-pane -Z + +# ============================================================ +# Dvorak-friendly extras (prefix Ctrl-A) +# ============================================================ +bind s split-window -v -c "#{pane_current_path}" +bind v split-window -h -c "#{pane_current_path}" +bind z resize-pane -Z +bind c new-window -c "#{pane_current_path}" +bind o select-pane -t :.+ + +# --- Alt shortcuts (no prefix, kept for mobile/quick access) --- bind -n M-t new-window -c "#{pane_current_path}" bind -n M-w kill-window bind -n M-1 select-window -t 1 @@ -16,15 +95,10 @@ bind -n M-4 select-window -t 4 bind -n M-5 select-window -t 5 bind -n M-Left previous-window bind -n M-Right next-window -bind c new-window -c "#{pane_current_path}" -# --- Dvorak-friendly splits --- -bind s split-window -v -c "#{pane_current_path}" -bind v split-window -h -c "#{pane_current_path}" - -# --- Pane navigation --- -bind o select-pane -t :.+ -bind z resize-pane -Z +# ============================================================ +# AI CLI workflow features +# ============================================================ # --- Mouse --- set -g mouse on @@ -39,16 +113,15 @@ bind -T copy-mode-vi y send -X copy-selection-and-cancel bind -T copy-mode-vi MouseDragEnd1Pane send -X copy-selection-and-cancel # --- Capture & logging --- -# Ctrl-A S = save entire scrollback to file bind S capture-pane -pS - \; save-buffer ~/logs/capture-#{session_name}-#{window_index}-#{pane_index}-#(date +%s).txt \; display "Pane captured to ~/logs/" - -# Ctrl-A L = toggle pipe-pane logging bind L pipe-pane -o "cat >> ~/logs/live-#{session_name}-#{window_index}-#(date +%s).log" \; display "Logging toggled" # --- Clipboard --- set -g set-clipboard on -# Copy on select (mouse) -bind -T copy-mode-vi MouseDragEnd1Pane send -X copy-pipe-and-cancel "cat" + +# ============================================================ +# Appearance +# ============================================================ # --- Numbering --- set -g base-index 1 @@ -75,8 +148,6 @@ setw -g window-status-separator "" # --- Pane borders --- set -g pane-border-style "fg=#333333" set -g pane-active-border-style "fg=#D35400" -set -g pane-border-format " #{pane_current_command} " -set -g pane-border-status off # --- Terminal --- set -g default-terminal "tmux-256color"