A terminal app that grows — GPU-accelerated terminal emulator written in Rust for macOS.
- Modular: Each module has a single responsibility. You don't need to know the VT parser to fix clipboard copy.
- Testable: Pure functions and state machines are verified with unit tests; module interactions with integration tests.
- Evolvable: Reversible structure makes it safe to change, grow, and evolve.
- GPU Rendering — wgpu-based 2-pass rendering (background + glyphs)
- Korean Support — IME input with preedit overlay, wide character handling, D2Coding font
- Tabs — Cmd+T/W to open/close, Cmd+1-9 to switch, Cmd+Shift+[/] to cycle, click tab bar, new tabs inherit working directory
- VT Parsing — SGR attributes (bold, dim, italic, underline, strikethrough, inverse), 256/RGB color, cursor movement, screen clearing
- TUI App Support — Alternate screen, scroll regions, mouse tracking (SGR), bracketed paste, synchronized output, cursor visibility (DECTCEM)
- Scrollback — 10,000 line history, Cmd+PageUp/PageDown, draggable auto-hiding scrollbar
- Copy Mode — Vim-style copy mode (Cmd+Shift+C) with hjkl navigation
- Mouse Selection & Clipboard — Drag selection with wide character awareness, Cmd+C/V, Cmd+A to copy input line
- URL Highlight — Cmd+hover to underline and detect URLs
- Pomodoro Timer — 25min work / 3min break cycle with input blocking
- Response Timer — Per-tab command response time measurement
- Font Zoom — Cmd+=/- to adjust size (8pt–72pt)
- Box Drawing — Light, heavy, double, and rounded corner characters with geometric rendering
- Keyboard — xterm-style encoding, Shift/Ctrl/Alt modifier combinations, kitty keyboard protocol
| Shortcut | Action |
|---|---|
| Cmd+N | New window |
| Cmd+T | New tab |
| Cmd+W | Close tab |
| Cmd+1–9 | Switch to tab by number |
| Cmd+Shift+[ / ] | Previous / next tab |
| Cmd+C | Copy |
| Cmd+V | Paste |
| Cmd+A | Copy input line to clipboard |
| Cmd+= / Cmd+- | Zoom in / out |
| Cmd+PageUp/Down | Scroll one page |
| Cmd+Home / End | Scroll to top / bottom |
| Cmd+Click | Open URL under cursor |
` or Cmd+Shift+C |
Enter / exit copy mode |
| Key | Action |
|---|---|
| j / k | Move 1 line down / up |
| h / l | Move 10 lines up / down |
| v | Toggle visual mode (multi-line selection) |
| Cmd+C | Copy selection and exit copy mode |
- Claude Code cursor position fix — Fixed cursor position issues when running Claude Code
- Composing language enter — Pressing Enter during IME composition (e.g. Korean) now commits the character and sends Enter simultaneously
Key Input → Input Encoding → PTY
↓
VT Parser
↓
Grid
↓
Render Commands
↓
GPU Rendering → Screen
Data types shared by all modules (Cell, Color, KeyEvent, etc.). A common language so modules can talk to each other.
Translates keystrokes into bytes the shell understands.
Ctrl+C → \x03 · Arrow Up → \x1b[A
PTY (Pseudo-Terminal) is a pipe between our app and the shell. Fools the shell into thinking it's connected to a real terminal.
\x03 → shell → \x1b[31mHello
Parses the raw bytes from the shell into structured commands.
\x1b[31mHi → [SetColor(Red), Print('H'), Print('i')]
A 2D grid of cells, like a spreadsheet. Stores each character with its position and style. Also keeps scrollback history.
[SetColor(Red), Print('H')] → grid[row=0][col=0] = 'H' (red)
Reads the grid and produces a draw list. Adds cursor, selection highlight, and IME overlay on top.
grid[0][0]='H'(red) → DrawCell { row:0, col:0, char:'H', fg:#FF0000, bg:#000000 }
Takes the draw list and paints pixels on screen using the GPU. Each character becomes a bitmap composited onto the window.
DrawCell { char:'H', fg:#FF0000 } → pixels on screen
Creates the window, receives mouse/keyboard events from the OS, and handles IME (Korean input).
The conductor. Connects all modules: keystrokes come in, shell output comes back, the grid updates, the screen redraws.
cargo build --release
cargo run -p growterm-app./install.shBuilds the release binary and installs growTerm.app to /Applications.
cargo test594+ tests (unit + integration).
- Rust (stable)
- macOS (wgpu Metal backend)