Skip to content

Conversation

@forketyfork
Copy link
Owner

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.

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.
@forketyfork forketyfork requested a review from Copilot January 19, 2026 22:36
Copy link

Copilot AI left a 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 GridLayout module for dynamic grid dimension calculation and animation management
  • Added GridResizing view mode to handle animated grid expansion/contraction
  • Removed static rows/cols configuration (now only font_scale remains 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.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a 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".

@forketyfork forketyfork requested a review from Copilot January 20, 2026 05:58
Copy link

Copilot AI left a 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) {
Copy link

Copilot AI Jan 20, 2026

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.

Suggested change
while (curr_pos <= value.len) {
while (curr_pos < value.len) {

Copilot uses AI. Check for mistakes.

/// 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);
Copy link

Copilot AI Jan 20, 2026

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.

Suggested change
var indices = try std.ArrayList(usize).initCapacity(allocator, 0);
var indices = try std.ArrayList(usize).initCapacity(allocator, countSpawnedSessions(sessions));

Copilot uses AI. Check for mistakes.
return .{
.cols = 1,
.rows = 1,
.animations = try std.ArrayList(TerminalAnimation).initCapacity(allocator, 0),
Copy link

Copilot AI Jan 20, 2026

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.

Suggested change
.animations = try std.ArrayList(TerminalAnimation).initCapacity(allocator, 0),
.animations = std.ArrayList(TerminalAnimation).init(allocator),

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants