Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .trinity/seals/t27os_T27osEditors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"built_by": "t27c-bootstrap@0.5.2+339a2d31b",
"closure": [
{
"spec": "specs/t27os/session_store.t27",
"spec_hash": "sha256:7d05d7dda14587458a77291c3d587e3f08516d8e678f0a4bd06dcaab7f6d1f2f"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:c884fccdcb816ab5c48fd289bd04515452873c300889d29149cd7481abcf8939",
"gen_hash_rust": "sha256:cac70330d6d304ab3800f870ca5114f10bb2f5d1e029c4de28d2f7232f5a92ca",
"gen_hash_verilog": "sha256:82a39ca4aa16b7d3c37d5fa37f7ac3aeecfde29d0d31030fa23726ef1235eacd",
"gen_hash_zig": "sha256:4dd5942ad00da4c9bc011cb373421e8da83eb6cb98a8ff1bdb1caafb5e98fe78",
"module": "T27osEditors",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-20T07:42:07Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:fc3608c5131f7fae21d6084102a019fc0425117ecf7544ec1eebfa8155d74f72",
"spec_path": "specs/t27os/editors.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 30,
"total": 30,
"vacuous": 0
},
"toolchain": {
"test_runner": "sha256:8512b80da533b79289110fca4a65f3336abd7a059ca4b72ea595d5e33ff8ad10",
"zig": "0.16.0"
}
}
37 changes: 37 additions & 0 deletions .trinity/seals/t27os_T27osTermPane.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"built_by": "t27c-bootstrap@0.5.2+339a2d31b",
"closure": [
{
"spec": "specs/t27os/pty_proto.t27",
"spec_hash": "sha256:fe9dee96f99eccaa6273124bb9022a66ca916bc9a0f6c3f415c2f4b6ab964ab1"
},
{
"spec": "specs/t27os/windows.t27",
"spec_hash": "sha256:eddbb0bab395f5d23c89d2e43ee081a2e0c0281ff112151aa61c7fab0ee875af"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:97ceec65b02689bcecdc7a3c8e9cdd359f34d6d8cd073c7d846ea7134205b604",
"gen_hash_rust": "sha256:30d38401423690741c966e8f2067738639bc403e5d32df756d4a0fe16e35ce24",
"gen_hash_verilog": "sha256:a53251a619ef71e8be2dd0de46530dcabd56f70af9701b8c3a81649725a66a10",
"gen_hash_zig": "sha256:0edf236094c91e001fc45a83c938e113451211b31853e0c1d366134693ad4116",
"module": "T27osTermPane",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-20T07:42:12Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:50a9ff94e1c09c8e4d3ac9e2199c871ee00d821cd3e5d9c5b12fc5b994f5ba4e",
"spec_path": "specs/t27os/term_pane.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 10,
"total": 10,
"vacuous": 0
},
"toolchain": {
"test_runner": "sha256:8512b80da533b79289110fca4a65f3336abd7a059ca4b72ea595d5e33ff8ad10",
"zig": "0.16.0"
}
}
142 changes: 140 additions & 2 deletions specs/t27os/editors.t27
Original file line number Diff line number Diff line change
Expand Up @@ -426,10 +426,11 @@ test only_an_absolute_clean_directory_is_handed_over {
// ---- the OPEN IN strip at the foot of the KEYS panel: the installed editors as a grid of text chips ----

/// Three chips of 88 pt fill the 268 pt of the Queen/KEYS panel (QP_W 300 less two QP_PAD): "Antigravity IDE"
/// and "VS Code Insiders" fit one chip at 9 pt, where four 66 pt chips overlapped.
/// and "VS Code Insiders" fit one chip at 9 pt, where four 66 pt chips overlapped. A chip row is 14 pt (it was
/// 16): two rows, the status row and the OPEN IN row then fit under the nine provider rows of a 540 pt window.
pub const ED_COLS : u32 = 3;
pub const ED_SLOT_W : f64 = 88.0;
pub const ED_SLOT_H : f64 = 16.0;
pub const ED_SLOT_H : f64 = 14.0;
pub const ED_NONE : u32 = 255;

/// The editor (index into the table) that is the k-th installed one in `mask`; ED_NONE when there are fewer.
Expand Down Expand Up @@ -486,6 +487,143 @@ pub fn ed_hit(x: f64, y: f64, l: f64, pad: f64, top: f64, count: u32) -> u32 {
return ED_NONE;
}

// ---- the foot of the KEYS panel: the status row, the OPEN IN row, then the chips, one band each ----
// Owner, 2026-10-20: the claude status line was drawn on top of the second row of chips. The foot starts at
// `top`, the bottom edge of the last provider row, and stacks rows that never share a y band:
// the status row FT_LINE_H tall, its baseline FT_BASE below the band's top;
// the OPEN IN row FT_LINE_H tall, same baseline;
// the chips ED_COLS to a row, ED_SLOT_H tall, baseline ED_BASE below the slot's top.
// How many chip rows there are comes from the chip count. A row that does not fit above the bottom edge `sh`
// is not drawn, and its chips cannot be clicked (foot_chips): at 960 x 540 six chips are two rows.

pub const FT_LINE_H : f64 = 12.0;
pub const FT_BASE : f64 = 9.0;
pub const ED_BASE : f64 = 10.0;
/// The ink of a 9 to 9.5 pt line reaches at most FT_ASC above its baseline and FT_DESC below it.
pub const FT_ASC : f64 = 7.0;
pub const FT_DESC : f64 = 2.5;

/// Chip rows that `count` chips make, ED_COLS to a row.
pub fn strip_rows(count: u32) -> u32 {
return (count + ED_COLS - 1) / ED_COLS;
}

pub fn foot_status_top(top: f64) -> f64 {
return top;
}

pub fn foot_head_top(top: f64) -> f64 {
return top + FT_LINE_H;
}

/// The strip's top edge: the first chip slot (ed_slot_y, ed_hit take this as `top`).
pub fn foot_chips_top(top: f64) -> f64 {
return top + 2.0 * FT_LINE_H;
}

/// The status row's band lies inside the panel.
pub fn foot_status_fits(top: f64, sh: f64) -> bool {
return top + FT_LINE_H <= sh;
}

/// Whole chip rows between the strip's top edge and the bottom edge `sh`.
pub fn foot_rows_fit(top: f64, sh: f64) -> u32 {
const room : f64 = sh - foot_chips_top(top);
if (room < ED_SLOT_H) { return 0; }
return @as(u32, @intFromFloat(room / ED_SLOT_H));
}

/// Chip rows drawn: all of them when they fit, else as many as fit.
pub fn foot_rows(top: f64, sh: f64, count: u32) -> u32 {
const want : u32 = strip_rows(count);
const fit : u32 = foot_rows_fit(top, sh);
if (want < fit) { return want; }
return fit;
}

/// Chips drawn, and the only ones a click can land on.
pub fn foot_chips(top: f64, sh: f64, count: u32) -> u32 {
const shown : u32 = foot_rows(top, sh, count) * ED_COLS;
if (count < shown) { return count; }
return shown;
}

/// The bottom edge of the last chip row drawn (the strip's top when there is none).
pub fn foot_bottom(top: f64, sh: f64, count: u32) -> f64 {
return foot_chips_top(top) + @as(f64, @floatFromInt(foot_rows(top, sh, count))) * ED_SLOT_H;
}

test the_foot_rows_come_from_the_chip_count {
assert strip_rows(0) == 0;
assert strip_rows(1) == 1;
assert strip_rows(ED_COLS) == 1;
assert strip_rows(ED_COLS + 1) == 2;
assert strip_rows(6) == 2;
assert strip_rows(EDITOR_COUNT) == 9;
// with room, every chip is drawn: the rows are the count over ED_COLS, rounded up
assert foot_rows(487.0, 1440.0, 6) == 2;
assert foot_rows(487.0, 1440.0, 7) == 3;
assert foot_chips(487.0, 1440.0, 7) == 7;
assert foot_chips(487.0, 1440.0, EDITOR_COUNT) == EDITOR_COUNT;
assert foot_rows(487.0, 1440.0, 0) == 0;
}

test no_two_text_rows_of_the_foot_share_a_y_band {
const top : f64 = 487.0;
// a line's ink band is [baseline - FT_ASC, baseline + FT_DESC]; each band ends before the next begins
assert foot_status_top(top) + FT_BASE - FT_ASC >= top;
assert foot_status_top(top) + FT_BASE + FT_DESC <= foot_head_top(top) + FT_BASE - FT_ASC;
assert foot_head_top(top) + FT_BASE + FT_DESC <= foot_chips_top(top) + ED_BASE - FT_ASC;
// and two chip rows in a row: the next slot's ink starts after this one's ends
assert ED_BASE + FT_DESC <= ED_SLOT_H + ED_BASE - FT_ASC;
assert ED_SLOT_H >= FT_ASC + FT_DESC;
// a chip's baseline is inside its slot, and the slots do not overlap
assert ED_BASE + FT_DESC <= ED_SLOT_H;
assert ed_slot_y(foot_chips_top(top), ED_COLS) == ed_slot_y(foot_chips_top(top), 0) + ED_SLOT_H;
// the foot's three kinds of row are in the order status, OPEN IN, chips
assert foot_status_top(top) < foot_head_top(top);
assert foot_head_top(top) < foot_chips_top(top);
}

test the_foot_never_draws_below_the_panel_and_hides_whole_rows_only {
const top : f64 = 487.0;
var n : u32 = 0;
while (n <= EDITOR_COUNT) {
// 540 is the window's own height, 720 a taller window, 1440 a full screen
const h0 : f64 = 540.0;
const h1 : f64 = 720.0;
const h2 : f64 = 1440.0;
assert foot_bottom(top, h0, n) <= h0;
assert foot_bottom(top, h1, n) <= h1;
assert foot_bottom(top, h2, n) <= h2;
// a chip that is drawn belongs to a whole row, and a row that is hidden hides all its chips
assert foot_chips(top, h0, n) <= n;
assert foot_chips(top, h0, n) <= foot_rows(top, h0, n) * ED_COLS;
// more room never shows fewer chips
assert foot_chips(top, h1, n) >= foot_chips(top, h0, n);
assert foot_chips(top, h2, n) >= foot_chips(top, h1, n);
// in full screen every one of the 27 editors fits
assert foot_chips(top, h2, n) == n;
n = n + 1;
}
}

test a_chip_in_a_row_that_is_not_drawn_cannot_be_clicked {
const top : f64 = 487.0;
const l : f64 = 660.0;
const ct : f64 = foot_chips_top(top);
// 540 high: nine chips would be three rows, two fit, so six are drawn and clickable
assert foot_chips(top, 540.0, 9) == 6;
assert ed_hit(l + 16.0 + 3.0, ct + 3.0, l, 16.0, ct, foot_chips(top, 540.0, 9)) == 0;
assert ed_hit(l + 16.0 + 3.0, ct + ED_SLOT_H + 3.0, l, 16.0, ct, foot_chips(top, 540.0, 9)) == ED_COLS;
assert ed_hit(l + 16.0 + 3.0, ct + 2.0 * ED_SLOT_H + 3.0, l, 16.0, ct, foot_chips(top, 540.0, 9)) == ED_NONE;
// in full screen the same click is the seventh chip
assert ed_hit(l + 16.0 + 3.0, ct + 2.0 * ED_SLOT_H + 3.0, l, 16.0, ct, foot_chips(top, 1440.0, 9)) == 2 * ED_COLS;
// a click on the status row or on the OPEN IN row is on no chip
assert ed_hit(l + 16.0 + 3.0, foot_status_top(top) + 3.0, l, 16.0, ct, 6) == ED_NONE;
assert ed_hit(l + 16.0 + 3.0, foot_head_top(top) + 3.0, l, 16.0, ct, 6) == ED_NONE;
}

test the_kth_installed_editor_skips_the_missing_ones {
assert nth_installed(0, 0) == ED_NONE;
assert nth_installed(1 + 4 + 16, 0) == 0;
Expand Down
Loading
Loading