Commit 1e9e0d1fb3ad

Vincent Demeester <vincent@sbr.pm>
2025-12-23 15:32:50
feat(terminal): Add bépo-optimized tmux/Kitty integration with Emacs support
- Enable ergonomic CTSR navigation on bépo home row across tmux and Kitty - Prevent Emacs conflicts by using Ctrl-B prefix and Emacs copy mode - Provide Alt-based one-key shortcuts for efficient tmux control in Kitty - Support seamless workflow with Niri WM via conflict-free keybindings Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 3e70681
Changed files (2)
home
common
desktop
shell
home/common/desktop/kitty.nix
@@ -28,6 +28,55 @@
       "shift+up" = "neighboring_window up";
       "shift+down" = "neighboring_window down";
     };
+
+    # Bépo-optimized tmux conditional bindings (Alt-based, context-aware)
+    # These only activate when tmux is running (title contains "tmux")
+    # Using Alt key to avoid conflicts with Niri window manager
+    # Compatible with Emacs workflow (using Ctrl-B prefix instead of Ctrl-Space)
+    extraConfig = ''
+      # ============================================================================
+      # BÉPO-OPTIMIZED KITTY TMUX BINDINGS (Alt-based, Emacs-compatible)
+      # ============================================================================
+      # Escape sequence: \x02 = Ctrl-B (default tmux prefix, Emacs-friendly)
+
+      # Pane navigation - Alt+CTSR (bépo home row)
+      map --when-focus-on title:tmux alt+c send_text all \x02c
+      map --when-focus-on title:tmux alt+t send_text all \x02t
+      map --when-focus-on title:tmux alt+s send_text all \x02s
+      map --when-focus-on title:tmux alt+r send_text all \x02r
+
+      # Pane resizing - Alt+Shift+CTSR
+      map --when-focus-on title:tmux alt+shift+c send_text all \x02C
+      map --when-focus-on title:tmux alt+shift+t send_text all \x02T
+      map --when-focus-on title:tmux alt+shift+s send_text all \x02S
+      map --when-focus-on title:tmux alt+shift+r send_text all \x02R
+
+      # Window navigation - Alt+N/P (next/prev)
+      map --when-focus-on title:tmux alt+n send_text all \x02p
+      map --when-focus-on title:tmux alt+p send_text all \x02é
+
+      # Move windows - Alt+Shift+N/P
+      map --when-focus-on title:tmux alt+shift+n send_text all \x02P
+      map --when-focus-on title:tmux alt+shift+p send_text all \x02É
+
+      # Window/Pane creation & management
+      map --when-focus-on title:tmux alt+enter send_text all \x02b
+      map --when-focus-on title:tmux alt+w send_text all \x02w
+      map --when-focus-on title:tmux alt+x send_text all \x02x
+
+      # Splits
+      map --when-focus-on title:tmux alt+minus send_text all \x02-
+      map --when-focus-on title:tmux alt+backslash send_text all \x02|
+
+      # Other actions
+      map --when-focus-on title:tmux alt+z send_text all \x02z
+      map --when-focus-on title:tmux alt+[ send_text all \x02[
+      map --when-focus-on title:tmux alt+] send_text all \x02]
+      map --when-focus-on title:tmux alt+a send_text all \x02a
+      map --when-focus-on title:tmux alt+d send_text all \x02d
+      map --when-focus-on title:tmux alt+shift+r send_text all \x02R
+    '';
+
     # Automatic theme switching enabled via xdg.configFile below
     # Removed hardcoded themeFile to allow dark/light auto-switching
     # action_alias mkh kitten hints --alphabet asdfghjklqwertyuiopzxcvbnmASDFGHJKLQWERTYUIOPZXCVBNM
home/common/shell/tmux/tmux.conf
@@ -1,97 +1,216 @@
-# Tmux configuration file
+# ============================================================================
+# BÉPO-OPTIMIZED TMUX CONFIGURATION
+# ============================================================================
 # Documented by Vincent Demeester.
-# Note that I am using bepo keyboard (that why key binding might be a
-# little weird for you).
-# First thing first, quickly reload $HOME/.tmux.conf
-#bind o source-file ~/.tmux.conf; display "tmux configuration reloaded."
+# Note: Using bépo keyboard layout with CTSR navigation (home row ergonomics)
+
+# ============================================================================
+# PREFIX KEY
+# ============================================================================
+# Using default Ctrl-B prefix (compatible with Emacs workflow)
+# Note: Ctrl-Space conflicts with Emacs set-mark-command
+
+# Set window title to enable Kitty detection
+set-option -g set-titles on
+set-option -g set-titles-string "tmux: #S"
+
+# ============================================================================
+# GENERAL SETTINGS
+# ============================================================================
 set -g history-limit 500000
-# Be sure to deactive the mode
-# set -g mode-mouse off
+
 # By default tmux adds a small delay when sending commands.
 # Reducing this delay by setting escape-time.
-set -sg escape-time 1
-bind v paste-buffer
-# Vim-behavior for moving between panes
+set -sg escape-time 0
+
+# Enable mouse support
+set -g mouse on
+
+# Start windows and panes at 1, not 0
+set -g base-index 1
+setw -g pane-base-index 1
+
+# Renumber windows when one is closed
+set -g renumber-windows on
+
+# Enable 24-bit color
+set -g default-terminal "tmux-256color"
+set -ga terminal-overrides ",*256col*:Tc"
+
+# ============================================================================
+# BÉPO NAVIGATION - CTSR (matches vim-bepo)
+# ============================================================================
+
+# Pane navigation: C(left) T(down) S(up) R(right)
 bind c select-pane -L
 bind t select-pane -D
 bind s select-pane -U
 bind r select-pane -R
-# Re-binding new-window and kill-pane to something more bepo-ish
-bind x new-window
-unbind c
-bind y kill-pane
-# Re-binding list-of-session
+
+# Pane resizing: Shift+CTSR
+bind C resize-pane -L 5
+bind T resize-pane -D 5
+bind S resize-pane -U 5
+bind R resize-pane -R 5
+
+# ============================================================================
+# WINDOW MANAGEMENT
+# ============================================================================
+
+# Window navigation: É(prev) P(next) - home row accessible
+bind é previous-window
+bind p next-window
+
+# Move windows: Shift+É/P
+bind É swap-window -t -1\; select-window -t -1
+bind P swap-window -t +1\; select-window -t +1
+
+# Create new window: B (prominent on bépo top-left)
+bind b new-window -c "#{pane_current_path}"
+
+# Close window: W
+bind w confirm-before -p "kill-window #W? (y/n)" kill-window
+
+# ============================================================================
+# SPLITS - Using bépo-accessible symbols
+# ============================================================================
+
+# Vertical split: - (minus, accessible on bépo)
+bind - split-window -v -c "#{pane_current_path}"
+
+# Horizontal split: | (pipe, Shift+- on bépo)
+bind | split-window -h -c "#{pane_current_path}"
+
+# Alternative: = for vertical (no shift needed)
+bind = split-window -v -c "#{pane_current_path}"
+
+# Keep default splits with current path
+bind '"' split-window -v -c '#{pane_current_path}'
+bind '%' split-window -h -c '#{pane_current_path}'
+
+# ============================================================================
+# OTHER BINDINGS
+# ============================================================================
+
+# Zoom pane: Z
+bind z resize-pane -Z
+
+# Copy mode: Escape or [
+bind Escape copy-mode
+bind [ copy-mode
+
+# Paste: ] or v (keep old binding)
+bind ] paste-buffer
+bind v paste-buffer
+
+# Reload config: <prefix> + R (Shift+r)
+bind R source-file ~/.config/tmux/tmux.conf \; display "✓ Config reloaded!"
+
+# Detach: D
+bind d detach-client
+
+# Choose session: A (left home row)
+bind a choose-session
+
+# Kill pane: X
+bind x confirm-before -p "kill-pane #P? (y/n)" kill-pane
+
+# Legacy bindings (keep for compatibility)
 bind u list-sessions
-# Vim-behavior for moving between windows
-bind -r C-t select-window -t :-
-bind -r C-s select-window -t :+
-# Vim-behavior for resizing panes
-bind -r C resize-pane -L 5
-bind -r T resize-pane -D 5
-bind -r S resize-pane -U 5
-bind -r R resize-pane -R 5
-# vi-mode for copy.
-set -g mode-key vi
-# `PREFIX`-`ESCAPE` for going into copy mode
-bind-key ESCAPE copy-mode
-bind-key b copy-mode
-# Rebinding some vi-copy keys in a more bepoish fashion.
-#bind-key -Tvi-copy 'v' begin-selection
-#bind-key -Tvi-copy 'y' copy-selection
-#bind-key -Tvi-copy 'C' top-line
-#bind-key -Tvi-copy 'T' scroll-down
-#bind-key -Tvi-copy 'S' scroll-up
-#bind-key -Tvi-copy 'R' bottom-line
-#bind-key -Tvi-copy 'c' cursor-left
-#bind-key -Tvi-copy 't' cursor-down
-#bind-key -Tvi-copy 's' cursor-up
-#bind-key -Tvi-copy 'r' cursor-right
-# Telling childs that this is a 256 terminal multiplexer
-set -g default-terminal "screen-256color"
-# Maximizing/Restoring panes (useful for *a lot* of workflows)
+bind y kill-pane
+bind C-a last-window
+bind C-r command-prompt 'rename-window %%'
+bind m switch-client -l
+bind M command-prompt -p 'switch session:' "run \"tm.sh '%%'\""
+
+# ============================================================================
+# COPY MODE (Emacs-style with bépo)
+# ============================================================================
+
+setw -g mode-keys emacs
+
+# Bépo navigation in copy mode (Emacs bindings)
+# Note: Emacs mode uses M-c, M-t, M-s, M-r for navigation
+bind -T copy-mode M-c send-keys -X cursor-left
+bind -T copy-mode M-t send-keys -X cursor-down
+bind -T copy-mode M-s send-keys -X cursor-up
+bind -T copy-mode M-r send-keys -X cursor-right
+
+# Word movement with bépo (M-é for forward, M-É for backward)
+bind -T copy-mode M-é send-keys -X next-word
+bind -T copy-mode M-É send-keys -X previous-word
+
+# Copy to clipboard (using wl-copy for Wayland)
+# In emacs mode, M-w is the standard copy binding
+bind -T copy-mode M-w send-keys -X copy-pipe-and-cancel "wl-copy"
+
+# Alternative: Keep standard Emacs bindings available too
+# C-Space to set mark (begin selection) - already works in emacs mode
+# M-w to copy - configured above
+# ============================================================================
+# ADVANCED FEATURES
+# ============================================================================
+
+# Maximizing/Restoring panes (useful for many workflows)
 unbind Up
 bind Up new-window -d -n tmp \; swap-pane -s tmp \; select-window -t tmp
 unbind Down
 bind Down last-window \; swap-pane -s tmp \; kill-window -t tmp
-# Recording pane content to a file. (This is crasy !)
-bind P pipe-pane -o "cat >>~/#W.log" \; display "Toggled logging to ~/#W.log"
 
-# titles
-# set -g show -g says
-set -g set-titles on
-set -g set-titles-string "tmux - #S:#I.#P (#W)"
-# Set window notifications
-setw -g monitor-activity on
-set -g visual-activity on
+# Recording pane content to a file
+bind-key F1 pipe-pane -o "cat >>~/#W.log" \; display "Toggled logging to ~/#W.log"
+
 # Rather than constraining window size to the maximum size of any client
 # connected to the *session*, constrain window size to the maximum size of any
 # client connected to *that window*. Much more reasonable.
 setw -g aggressive-resize on
-# binding
-bind-key C-a last-window
-bind-key C-r command-prompt 'rename-window %%'
-bind-key '"' split-window -v -c '#{pane_current_path}'
-bind-key '%' split-window -h -c '#{pane_current_path}'
 
-# Custom status line
-set-option -g status-left '-- #[fg=colour253]#S - '
-set-window-option -g window-status-format '#[fg=colour244]#I/#[fg=colour253] #W '
-set-window-option -g window-status-current-format '#[fg=colour244]#I/#[fg=colour253,bg=colour238] #W '
-set-option -g status-right '#[fg=colour250] %Y-%m-%d #[fg=colour254]%H.%M'
-set-option -g status-bg colour234
-set-option -g status-fg colour007
-set-option -g status-position top
+# ============================================================================
+# APPEARANCE AND STATUS BAR
+# ============================================================================
 
-# Custom split colours
-set -g pane-active-border-style bg=colour234,fg=colour234
-set -g pane-border-style bg=colour234,fg=colour234
+# Status bar at top
+set -g status-position top
+set -g status-style bg=default,fg=white
 
-# loud or quiet?
-set-option -g visual-activity off
-set-option -g visual-bell on
-set-option -g visual-silence off
-set-window-option -g monitor-activity on
-set-option -g bell-action none
+# Status left: session name
+set-option -g status-left '#[fg=blue,bold]#{session_name} '
 
-bind m switch-client -l
-bind M command-prompt -p 'switch session:' "run \"tm.sh '%%'\""
\ No newline at end of file
+# Window status format
+set-window-option -g window-status-format ' #I:#W '
+set-window-option -g window-status-current-format ' #I:#W '
+set-window-option -g window-status-current-style fg=green,bold
+
+# Status right: date and time
+set-option -g status-right '#[fg=yellow]%Y-%m-%d %H:%M '
+
+# Pane borders
+set -g pane-border-style fg=brightblack
+set -g pane-active-border-style fg=blue
+
+# ============================================================================
+# NOTIFICATIONS AND MONITORING
+# ============================================================================
+
+# Set window notifications
+setw -g monitor-activity on
+set -g visual-activity off
+set -g visual-bell on
+set -g visual-silence off
+set -g bell-action none
+
+# ============================================================================
+# VIM INTEGRATION (Optional - disabled for Emacs users)
+# ============================================================================
+# Note: The vim-tmux-navigator integration is commented out because it
+# intercepts Ctrl-C/T/S/R globally, which breaks:
+# - Ctrl-C: Terminal interrupt signal (SIGINT)
+# - Ctrl-S/R: Terminal flow control and Emacs bindings
+#
+# Uncomment if you're a Vim user and want seamless vim/tmux navigation:
+#
+# is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
+# bind -n C-c if-shell "$is_vim" 'send-keys C-c' 'select-pane -L'
+# bind -n C-t if-shell "$is_vim" 'send-keys C-t' 'select-pane -D'
+# bind -n C-s if-shell "$is_vim" 'send-keys C-s' 'select-pane -U'
+# bind -n C-r if-shell "$is_vim" 'send-keys C-r' 'select-pane -R'
\ No newline at end of file