-
Notifications
You must be signed in to change notification settings - Fork 0
feat: implement dynamic grid layout #148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
The grid now starts with a single terminal and expands/contracts automatically as terminals are added or removed: - Cmd+N adds a new terminal and expands the grid if needed - Cmd+W closes a terminal and shrinks the grid if possible - Grid maintains cols >= rows (e.g., 1x1 → 2x1 → 2x2 → 3x2 → 3x3) - Terminals are defragmented when the grid shrinks - All grid transitions are smoothly animated Implementation: - Add GridLayout module for dynamic grid dimension management - Add GridResizing view mode for animated grid transitions - Remove static rows/cols from config (only font_scale remains) - Allocate MAX_TERMINALS (144) session slots upfront - Update renderer to handle GridResizing animation mode - Update all grid-dependent calculations to use dynamic dimensions The grid can hold up to 12x12 = 144 terminals maximum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements a dynamic grid layout system that automatically expands and contracts based on the number of active terminals. The grid now starts with a single terminal and grows/shrinks as terminals are added or removed, maintaining a columns >= rows constraint throughout. All grid transitions are smoothly animated.
Changes:
- Introduced
GridLayoutmodule for dynamic grid dimension calculation and animation management - Added
GridResizingview mode to handle animated grid expansion/contraction - Removed static
rows/colsconfiguration (now onlyfont_scaleremains in grid config) - Pre-allocated 144 session slots (12×12 maximum) to avoid runtime reallocation
- Updated all grid-dependent calculations to use dynamic dimensions from
GridLayout
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/app/grid_layout.zig | New module implementing dynamic grid dimension calculation, animation state management, and grid position utilities |
| src/app/app_state.zig | Added GridResizing view mode enum variant |
| src/app/runtime.zig | Integrated GridLayout, implemented terminal spawning/despawning with grid expansion/contraction logic, pre-allocated MAX_TERMINALS sessions |
| src/render/renderer.zig | Added rendering support for GridResizing mode with animated terminal positions |
| src/input/mapper.zig | Updated escape key handling to exclude GridResizing mode |
| src/app/layout.zig | Extended mode checks to include GridResizing in grid-related calculations |
| src/config.zig | Removed static rows/cols fields and validation from GridConfig |
| docs/configuration.md | Updated documentation to reflect dynamic grid sizing behavior |
| docs/architecture.md | Added GridResizing to view mode documentation |
| README.md | Updated feature descriptions to highlight dynamic grid capabilities |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 388adc58c0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| fn writeTomlString(writer: *std.Io.Writer, value: []const u8) !void { | ||
| _ = try writer.writeByte('"'); | ||
| var curr_pos: usize = 0; | ||
| while (curr_pos <= value.len) { |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loop condition should be curr_pos < value.len instead of curr_pos <= value.len. The current condition causes the loop to iterate one extra time when curr_pos == value.len, which will cause indexOfAnyPos to search starting from an invalid position and the condition if (next_pos != value.len) at line 408 will always be false on the final iteration, making the last check unnecessary.
| while (curr_pos <= value.len) { | |
| while (curr_pos < value.len) { |
|
|
||
| /// Collect indices of all spawned sessions in order. | ||
| fn collectActiveSessionIndices(sessions: []const SessionState, allocator: std.mem.Allocator) !std.ArrayList(usize) { | ||
| var indices = try std.ArrayList(usize).initCapacity(allocator, 0); |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initializing with capacity 0 defeats the purpose of using initCapacity. Consider estimating the expected number of active sessions or use init() instead. A reasonable estimate would be the number of spawned sessions to avoid reallocation.
| var indices = try std.ArrayList(usize).initCapacity(allocator, 0); | |
| var indices = try std.ArrayList(usize).initCapacity(allocator, countSpawnedSessions(sessions)); |
| return .{ | ||
| .cols = 1, | ||
| .rows = 1, | ||
| .animations = try std.ArrayList(TerminalAnimation).initCapacity(allocator, 0), |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initializing with capacity 0 defeats the purpose of using initCapacity. Consider using a reasonable initial capacity (e.g., 8 or 16 terminals) or use init() instead to avoid the overhead of capacity allocation when the list starts empty.
| .animations = try std.ArrayList(TerminalAnimation).initCapacity(allocator, 0), | |
| .animations = std.ArrayList(TerminalAnimation).init(allocator), |
The grid now starts with a single terminal and expands/contracts
automatically as terminals are added or removed:
Implementation:
The grid can hold up to 12x12 = 144 terminals maximum.