A Niri-inspired, keyboard-first terminal for macOS. Built on Ghostty with a column-and-workspace layout engine.
Infinity.mov
Build and run from source:
git clone https://github.com/yourname/giri.git
cd giri
swift run giri-terminalFor a release build:
swift build -c release
$(swift build -c release --show-bin-path)/giri-terminalOr package a local .app bundle:
./scripts/package-app.sh
open "dist/Giri Terminal.app"- Column layout — Tiles terminal panes into scrollable columns, Niri-style. Focused columns center when possible; the first column stays pinned left.
- Workspaces — Vertical workspaces for grouping columns. Switch instantly with hotkeys.
- Pane splits — Split any column into horizontal or vertical panes, each with its own terminal session.
- Ghostty runtime — Full terminal emulation via Ghostty, with GPU-accelerated rendering, ligatures, and modern escape-sequence support.
- Keyboard-first — Everything is navigable without touching the mouse.
- Session persistence — Layout state, config, and keybindings survive restarts.
- Hot-reloadable keybindings — Edit
keybindings.jsonwhile the app is running and reload from the menu. - IME support — Full composition input for multilingual text and dead keys.
| Shortcut | Action |
|---|---|
Cmd+T |
New terminal (new column) |
Cmd+W |
Close active terminal / pane |
Cmd+H / Cmd+L |
Focus pane left / right |
Cmd+K / Cmd+J |
Focus pane up / down |
Cmd+Option+H / Cmd+Option+L |
Focus pane left / right (alternative) |
Cmd+Option+K / Cmd+Option+J |
Focus pane up / down (alternative) |
Cmd+Shift+H / Cmd+Shift+L |
Move column left / right |
Cmd+Shift+J / Cmd+Shift+K |
Move column to workspace down / up |
Cmd+Ctrl+H / Cmd+Ctrl+L |
Cycle width preset backward / forward |
Cmd+Ctrl+- / Cmd+Ctrl+= |
Nudge active column width |
Cmd+1..Cmd+9 |
Focus workspace by index |
Cmd+[ / Cmd+] |
Focus first / last column |
Cmd+C / Cmd+V |
Copy / paste |
Cmd+Shift+V |
Paste as plain text |
Everything else passes through to the terminal. All shortcuts are configurable.
Giri uses a custom TerminalLayoutEngine that models:
- Workspaces — virtual rows of columns
- Columns — vertical stacks of terminal panes with adjustable width
- Panes — individual terminal surfaces inside a column, split horizontally or vertically
The engine computes geometry dynamically based on viewport size, gaps, width ratios, and focus alignment. Off-screen columns can be hidden or parked as thin edge slivers.
See docs/terminal-layout-engine.md for the full API and behavior notes.
Keybindings and layout settings are stored in:
~/Library/Application Support/GiriTerminal/
├── keybindings.json
└── session.json
Open the keybindings file from the Terminal Layout menu while running the app. Edit, save, then choose Reload Layout Keybindings to apply changes without restarting.
The default keybinding actions use canonical names from TerminalLayoutCommandNames:
column_left,column_right,column_first,column_lastworkspace_down,workspace_up,focus_workspace_1..focus_workspace_9move_column_left,move_column_right,move_column_workspace_down,move_column_workspace_upcycle_width_preset_forward,cycle_width_preset_backwardnudge_width_wider,nudge_width_narroweradd_column,remove_active_column,reset_layout
A sample keybindings.json entry:
[
{
"action": "column_left",
"key": "h",
"modifiers": ["command"]
}
]swift build # debug build
swift run layout-harness # dev harness with debug controls
swift run giri-terminal # clean terminal app
swift test # run tests
./scripts/package-app.sh # build dist/Giri Terminal.appThe repo has two executable targets:
giri-terminal— the actual terminal app, minimal UIlayout-harness— a debug harness with sliders, workspace strip, colored-block fallback, and Ghostty toggle
| Target | Purpose |
|---|---|
TerminalLayoutEngine |
Pure Swift layout core — no UI, no Ghostty dependency |
TerminalGhosttyRuntime |
Ghostty integration — surface rendering, input, clipboard |
TerminalLayoutAppSupport |
Persistence, keybindings, shared app infrastructure |
GiriTerminalApp |
SwiftUI app shell — menu commands, window scene, store |
TerminalLayoutHarness |
Debug harness — visual controls and colored-block fallback |
- Targets macOS 13+ and Swift 5.9+.
- Requires the Ghostty prebuilt framework. Run
cmux/scripts/download-prebuilt-ghosttykit.shifVendor/GhosttyKit.xcframeworkis missing. - Does not use native macOS Spaces — workspaces are handled internally by the layout engine.
- Session persistence uses
~/Library/Application Support/GiriTerminal/.
MIT