Skip to content
Draft
221 changes: 221 additions & 0 deletions .config/ghostty/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
# Ghostty + Neovim Keybinding Philosophy

This configuration implements a **hand-separation design** for Ghostty terminal emulator and Neovim, optimized for the ZSA Moonlander keyboard.

## Core Principles

1. **Hand Separation**: Modifier on one hand, action keys on the other
2. **Left Hand (ESDF, W, R, numbers) = NAVIGATION**
3. **Right Hand (IJKL, T) = CREATION / ADJUSTMENT**
4. **Modifier Tiers**: Different modifier combinations for Ghostty vs Neovim to prevent conflicts
5. **Preserved Sequences**:
- Terminal control: Ctrl+C (SIGINT), Ctrl+Z (SIGTSTP), Ctrl+D (EOF)
- Shell features: Ctrl+R (reverse search)
- Text editing: Ctrl+F (find), Ctrl+G (find next) - reserved for future use
6. **Non-Character Keys**:
- Navigation keys (arrows, PageUp/Down, Home/End) without modifiers are passed to applications
- Exception: Bare PageUp/PageDown are ignored to prevent escape sequence artifacts
- Use modifier combinations (Shift, Ctrl, Alt) for terminal emulator functions

## Keyboard Layout

```
ZSA Moonlander:
- Left thumb: Ctrl, Del, Space
- Right thumb: Alt, Enter, Space
- Layer 2: Alt+number → F1-F10 (blocks Alt+n for tabs)
```

## Visual Layout Guide

```
SPLIT NAVIGATION SPLIT CREATION SPLIT RESIZE
Alt + ESDF Ctrl+Shift + IJKL Ctrl + IJKL

[E] [I] [I]
[S] [F] [J] [L] [J] [L]
[D] [K] [K]

TAB NAVIGATION
Ctrl+W Previous tab
Shift+Left Previous tab
Shift+Right Next tab
Ctrl+Shift+1-9 Go to tab N
Note: Ctrl+R reserved for shell history search
```

## Ghostty Keybindings

### Split Management

| Operation | Keys | Description |
|-----------|------|-------------|
| **Navigation** | | |
| Go up | `Alt+E` | Move to split above |
| Go left | `Alt+S` | Move to split on left |
| Go down | `Alt+D` | Move to split below |
| Go right | `Alt+F` | Move to split on right |
| Previous split | `Alt+W` | Cycle to previous split |
| Next split | `Alt+R` | Cycle to next split |
| **Creation** | | |
| Create up | `Ctrl+Shift+I` | New split above |
| Create left | `Ctrl+Shift+J` | New split on left |
| Create down | `Ctrl+Shift+K` | New split below |
| Create right | `Ctrl+Shift+L` | New split on right |
| Create auto | `Ctrl+Shift+Enter` | New split (auto direction) |
| **Resize** | | |
| Resize up | `Ctrl+I` | Grow upward |
| Resize left | `Ctrl+J` | Grow leftward |
| Resize down | `Ctrl+K` | Grow downward |
| Resize right | `Ctrl+L` | Grow rightward |
| **Management** | | |
| Equalize | `Ctrl+Shift+=` | Make all splits equal |
| Zoom toggle | `Ctrl+Shift+\` | Maximize/restore split |

### Tab Management

| Operation | Keys | Description |
|-----------|------|-------------|
| Previous tab | `Ctrl+W` or `Shift+Left` | Previous tab |
| Next tab | `Shift+Right` | Next tab |
| Go to tab N | `Ctrl+Shift+1-9` | Jump to specific tab |
| New tab | `Ctrl+Shift+T` | Create new tab |
| Move tab left | `Alt+Shift+A` | Move current tab left |
| Move tab right | `Alt+Shift+G` | Move current tab right |
| Close surface | `Ctrl+Shift+W` | Close current split/tab |
| Close window | `Ctrl+Shift+Q` | Quit Ghostty |

**Note:** `Ctrl+R` is intentionally not bound to preserve shell history search (reverse-i-search).

### Other Bindings

| Category | Keys | Description |
|----------|------|-------------|
| **Clipboard** | | |
| Copy | `Ctrl+Shift+C` | Copy selection |
| Paste | `Ctrl+Shift+V` | Paste from clipboard |
| Paste selection | `Ctrl+Shift+Insert` | Paste from selection |
| **Scrolling** | | |
| Page up/down | `Shift+PageUp/PageDown` | Scroll by page |
| Line up/down | `Shift+Up/Down` | Scroll by line |
| Top/bottom | `Shift+Home/End` | Scroll to top/bottom |
| Jump prompt | `Ctrl+Shift+Up/Down` | Jump between prompts |
| **Font** | | |
| Increase | `Ctrl+=` | Larger font |
| Decrease | `Ctrl+-` | Smaller font |
| Reset | `Ctrl+0` | Reset to default |
| **Window** | | |
| New window | `Ctrl+Shift+N` | New Ghostty window |
| Fullscreen | `F11` | Toggle fullscreen |
| Quick terminal | ``Ctrl+` `` | Global quick terminal |
| **UI** | | |
| Command palette | `Ctrl+Shift+P` | Open config |
| Open config | `Ctrl+Shift+,` | Open config file |
| Tab overview | `Ctrl+Shift+A` | Toggle inspector |

**Reserved Keys (Not Bound):**
- `Ctrl+R` - Reserved for shell history search (reverse-i-search)
- `Ctrl+F`, `Ctrl+Shift+F` - Reserved for "find" functionality (when implemented)
- `Ctrl+G`, `Ctrl+Shift+G` - Reserved for "find next/previous" functionality (when implemented)

**Ignored Keys (Explicitly Bound to Prevent Escape Sequences):**
- `PageUp`, `PageDown` - Ignored to prevent generating tilde (~) characters
- These keys without modifiers were causing escape sequences to be passed to the terminal
- Applications like vim, less, and man pages can still handle these keys directly
- Use `Shift+PageUp`/`Shift+PageDown` for Ghostty scrollback instead

## Neovim Keybindings (within Ghostty)

Neovim uses **one tier higher modifiers** than Ghostty to prevent conflicts:

### Window Management

| Operation | Keys | Description |
|-----------|------|-------------|
| **Navigation** | | |
| Go up | `Alt+Shift+E` | Move to window above |
| Go left | `Alt+Shift+S` | Move to window on left |
| Go down | `Alt+Shift+D` | Move to window below |
| Go right | `Alt+Shift+F` | Move to window on right |
| Previous window | `Alt+Shift+W` | Cycle to previous window |
| Next window | `Alt+Shift+R` | Cycle to next window |
| **Creation** | | |
| Split up | `Ctrl+W, I` | Split horizontally (above) |
| Split left | `Ctrl+W, J` | Split vertically (left) |
| Split down | `Ctrl+W, K` | Split horizontally (below) |
| Split right | `Ctrl+W, L` | Split vertically (right) |
| **Resize** | | |
| Grow height | `Alt+Shift+I` | Increase window height |
| Shrink width | `Alt+Shift+J` | Decrease window width |
| Shrink height | `Alt+Shift+K` | Decrease window height |
| Grow width | `Alt+Shift+L` | Increase window width |
| **Move/Swap** | | |
| Move to top | `Ctrl+Alt+Shift+E` | Move window to top |
| Move to left | `Ctrl+Alt+Shift+S` | Move window to left |
| Move to bottom | `Ctrl+Alt+Shift+D` | Move window to bottom |
| Move to right | `Ctrl+Alt+Shift+F` | Move window to right |
| **Management** | | |
| Equalize | `Ctrl+W, =` | Equalize window sizes |
| Zoom | `Ctrl+W, z` | Zoom window (new tab) |
| Rotate down | `Ctrl+W, r` | Rotate windows down/right |
| Rotate up | `Ctrl+W, R` | Rotate windows up/left |

## Design Rationale

### Why ESDF for Navigation?

- **Home row positioning**: Keeps fingers on home row
- **Better hand separation**: Clear left-hand navigation zone
- **More accessible modifiers**: Alt on right thumb + ESDF on left hand

### Why IJKL for Creation/Resize?

- **Mirrors ESDF layout**: Same spatial relationship (up/left/down/right)
- **Right hand only**: Complements left-hand navigation
- **Natural for adjustments**: Right hand for "building" and "tweaking"

### Why Different Modifier Tiers?

| Level | Ghostty | Neovim | Purpose |
|-------|---------|--------|---------|
| Base | `Alt+ESDF` | - | Ghostty split navigation |
| +Shift | - | `Alt+Shift+ESDF` | Neovim window navigation |
| Ctrl | `Ctrl+IJKL` | - | Ghostty split resize |
| Ctrl+Shift | `Ctrl+Shift+IJKL` | - | Ghostty split creation |
| Alt+Shift | - | `Alt+Shift+IJKL` | Neovim window resize |
| Triple | `Ctrl+Alt+ESDF` (reserved) | `Ctrl+Alt+Shift+ESDF` | Future/window move |

This tiered approach allows both tools to coexist without conflicts while maintaining consistent mental models.

## ZSA Moonlander Integration

The configuration assumes:
- **Left thumb cluster**: Ctrl (primary), Del, Space
- **Right thumb cluster**: Alt (primary), Enter, Space
- **Layer 2**: Alt+number keys produce F1-F10

This layout optimizes for:
1. **Comfort**: Most common operations use single-hand combos
2. **Speed**: Thumb modifiers + finger keys = fast navigation
3. **Learning**: Consistent patterns across both tools
4. **Ergonomics**: Minimal hand movement and stretching

## Tips

1. **Start with basics**: Learn Ghostty split navigation (`Alt+ESDF`) first
2. **Build muscle memory**: Practice tab switching (`Ctrl+W`/`Ctrl+R`)
3. **Layer up**: Add Neovim navigation once Ghostty feels natural
4. **Use visual cues**: Remember the ASCII art above for spatial layouts
5. **Customize as needed**: These are starting points, adjust to your workflow

## Files

- **Ghostty config**: `~/.config/ghostty/config`
- **Neovim config**: `~/.config/nvim/lua/config/ghostty-compat.lua`
- **Neovim init**: `~/.config/nvim/init.lua` (loads ghostty-compat)

## Future Enhancements

- **Ghostty split moving**: When supported, use `Ctrl+Alt+ESDF`
- **Additional workspaces**: Consider Alt+Shift+W/R for workspace switching
- **Context-aware bindings**: Different bindings for different terminal modes
148 changes: 147 additions & 1 deletion .config/ghostty/config
Original file line number Diff line number Diff line change
@@ -1,7 +1,153 @@
# ============================================================================
# SHELL CONFIGURATION
# ============================================================================
command = zsh
macos-option-as-alt = true

# ============================================================================
# FONT CONFIGURATION
# ============================================================================
font-family = FiraMono Nerd Font
font-size = 16.0

# ============================================================================
# THEME CONFIGURATION
# ============================================================================
theme = tinted-theming

# ============================================================================
# WINDOW CONFIGURATION
# ============================================================================
window-show-tab-bar = always

# ============================================================================
# GTK-SPECIFIC CONFIGURATION
# ============================================================================
gtk-tabs-location = bottom

# ============================================================================
# MACOS-SPECIFIC CONFIGURATION
# ============================================================================
macos-option-as-alt = true
macos-titlebar-style = tabs

# ============================================================================
# KEYBINDINGS - Hand Separation Design Philosophy
# ============================================================================
# Left hand (ESDF, W, R, numbers) = NAVIGATION
# Right hand (IJKL, T) = CREATION / ADJUSTMENT
# Modifiers: Alt/Alt+Shift (right thumb) + left hand for navigation
# Ctrl/Ctrl+Shift (left thumb) + right hand for creation/adjustment
# ============================================================================

# Split Navigation - Alt + ESDF (left hand navigation)
keybind = alt+e=goto_split:top
keybind = alt+s=goto_split:left
keybind = alt+d=goto_split:bottom
keybind = alt+f=goto_split:right

# Split Navigation - Previous/Next
keybind = alt+w=goto_split:previous
keybind = alt+r=goto_split:next

# Split Creation - Ctrl+Shift + IJKL (right hand creation)
keybind = ctrl+shift+i=new_split:up
keybind = ctrl+shift+j=new_split:left
keybind = ctrl+shift+k=new_split:down
keybind = ctrl+shift+l=new_split:right

# Split Creation - Auto direction
keybind = ctrl+shift+enter=new_split:auto

# Split Resize - Ctrl + IJKL (right hand adjustment)
keybind = ctrl+i=resize_split:up,10
keybind = ctrl+j=resize_split:left,10
keybind = ctrl+k=resize_split:down,10
keybind = ctrl+l=resize_split:right,10

# Split Management
keybind = ctrl+shift+equal=equalize_splits
keybind = ctrl+shift+backslash=toggle_split_zoom

# Split Move/Swap (reserved for future Ghostty feature)
# keybind = ctrl+alt+e=move_split:top
# keybind = ctrl+alt+s=move_split:left
# keybind = ctrl+alt+d=move_split:bottom
# keybind = ctrl+alt+f=move_split:right

# Tab Navigation - Ctrl + W (left hand navigation)
# Note: Ctrl+R is reserved for shell history search (reverse-i-search)
keybind = ctrl+w=previous_tab
# keybind = ctrl+r=next_tab # DISABLED: Conflicts with shell reverse search

# Tab Navigation - Shift + Arrow keys (standard terminal emulator pattern)
keybind = shift+arrow_left=previous_tab
keybind = shift+arrow_right=next_tab

# Tab Direct Access - Ctrl+Shift + 1-9
keybind = ctrl+shift+1=goto_tab:1
keybind = ctrl+shift+2=goto_tab:2
keybind = ctrl+shift+3=goto_tab:3
keybind = ctrl+shift+4=goto_tab:4
keybind = ctrl+shift+5=goto_tab:5
keybind = ctrl+shift+6=goto_tab:6
keybind = ctrl+shift+7=goto_tab:7
keybind = ctrl+shift+8=goto_tab:8
keybind = ctrl+shift+9=goto_tab:9

# Tab Management
keybind = ctrl+shift+t=new_tab
keybind = alt+shift+a=move_tab:-1
keybind = alt+shift+g=move_tab:1
keybind = ctrl+shift+w=close_surface
keybind = ctrl+shift+q=quit

# Copy/Paste
keybind = ctrl+shift+c=copy_to_clipboard
keybind = ctrl+shift+v=paste_from_clipboard
keybind = ctrl+shift+insert=paste_from_selection

# Search
# Note: Ctrl+F and Ctrl+Shift+F are reserved for "find" functionality
# Ghostty doesn't currently support scrollback search
# keybind = ctrl+shift+f=toggle_quick_terminal # DISABLED: Conflicts with find convention

# Scrolling
keybind = shift+page_up=scroll_page_up
keybind = shift+page_down=scroll_page_down
keybind = shift+up=scroll_page_lines:-1
keybind = shift+down=scroll_page_lines:1
keybind = shift+home=scroll_to_top
keybind = shift+end=scroll_to_bottom

# Ignore bare PageUp/PageDown to prevent escape sequences
# Note: These keys without modifiers were generating tilde (~) characters
# because their escape sequences were being passed through to the terminal.
# Applications like vim/less that need these keys will handle them directly.
# Use Shift+PageUp/PageDown for scrollback in Ghostty.
keybind = page_up=ignore
keybind = page_down=ignore

# Prompt Jumping
keybind = ctrl+shift+up=jump_to_prompt:-1
keybind = ctrl+shift+down=jump_to_prompt:1

# Font Size
keybind = ctrl+equal=increase_font_size:1
keybind = ctrl+minus=decrease_font_size:1
keybind = ctrl+0=reset_font_size

# Window Management
keybind = ctrl+shift+n=new_window
keybind = f11=toggle_fullscreen

# Quick Terminal (global)
keybind = ctrl+backquote=toggle_quick_terminal

# UI Actions
keybind = ctrl+shift+p=open_config
keybind = ctrl+shift+comma=open_config
keybind = ctrl+shift+a=inspector:toggle

# Reverse Search
# Note: Ctrl+R is now free for shell history search (no Ghostty binding needed)
# Note: Ctrl+G and Ctrl+Shift+G are reserved for find next/previous (not bound)
3 changes: 3 additions & 0 deletions .config/nvim/init.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
require("config.lazy")

-- Load Ghostty-compatible keybindings
require("config.ghostty-compat")

-- Set Bash as the shell, pulled from the top of PATH
vim.o.shell = vim.fn.exepath("bash")

Expand Down
Loading