Something went wrong. Try again.
My version of https://github.com/vercel-labs/fx
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160const std = @import("std");const editor_state = @import("editor_state.zig");const registered_entities = @import("registered_entities.zig");
const Decision = union(enum) { reset, move: struct { raw_offset: usize, preferred_column: usize, },};
fn decideTarget( input: []const u8, entities: *const registered_entities.State, target_raw_offset: ?usize, preferred_column: usize,) Decision { const raw_offset = target_raw_offset orelse return .reset; if (entities.entityContaining(input, raw_offset) != null) return .reset; return .{ .move = .{ .raw_offset = raw_offset, .preferred_column = preferred_column, } };}
/// Owns the sticky display-column intent for composer vertical navigation./// Terminal layout adapters provide target offsets and measured columns.pub const State = struct { preferred_column: ?usize = null,
pub fn reset(self: *State) void { self.* = .{}; }
pub fn preferredColumn(self: State) ?usize { return self.preferred_column; }
pub fn applyTarget( self: *State, edit: *editor_state.State, entities: *const registered_entities.State, target_raw_offset: ?usize, preferred_column: usize, ) bool { return self.applyTargetWithSelection( edit, entities, target_raw_offset, preferred_column, false, ); }
pub fn applyTargetWithSelection( self: *State, edit: *editor_state.State, entities: *const registered_entities.State, target_raw_offset: ?usize, preferred_column: usize, extend_selection: bool, ) bool { switch (decideTarget( edit.input.items, entities, target_raw_offset, preferred_column, )) { .reset => { self.reset(); return false; }, .move => |target| { _ = edit.moveCursorTo(target.raw_offset, extend_selection); self.preferred_column = target.preferred_column; return true; }, } }};
test "vertical navigation applies a legal target and clears selection" { const alloc = std.testing.allocator; var edit: editor_state.State = .{}; defer edit.deinit(alloc); try edit.setText(alloc, "abcdef"); _ = edit.beginSelection(1); _ = edit.extendSelection(4);
var entities: registered_entities.State = .{}; defer entities.deinit(alloc); var state: State = .{};
try std.testing.expect(state.applyTarget(&edit, &entities, 5, 3)); try std.testing.expectEqual(@as(usize, 5), edit.cursor); try std.testing.expect(edit.selectionRange() == null); try std.testing.expectEqual(@as(?usize, 3), state.preferredColumn());}
test "vertical navigation reset decisions preserve the editor" { const alloc = std.testing.allocator; var edit: editor_state.State = .{}; defer edit.deinit(alloc); try edit.setText(alloc, "abcdef"); _ = edit.beginSelection(1); _ = edit.extendSelection(4);
var entities: registered_entities.State = .{}; defer entities.deinit(alloc); var state: State = .{ .preferred_column = 4 };
try std.testing.expect(!state.applyTarget(&edit, &entities, null, 0)); try std.testing.expectEqual(@as(usize, 4), edit.cursor); try std.testing.expectEqual( editor_state.SelectionRange{ .start = 1, .end = 4 }, edit.selectionRange().?, ); try std.testing.expectEqual(@as(?usize, null), state.preferredColumn());}
test "vertical navigation rejects targets inside registered entities" { const alloc = std.testing.allocator; var edit: editor_state.State = .{}; defer edit.deinit(alloc); try edit.setText(alloc, "[Image #1]"); _ = edit.setCursor(0);
var entities: registered_entities.State = .{}; defer entities.deinit(alloc); try entities.image_tokens.append(alloc, .{ .id = 1, .span = .{ .raw_start = 0, .raw_end = edit.input.items.len }, }); var state: State = .{ .preferred_column = 2 };
try std.testing.expect(!state.applyTarget(&edit, &entities, 3, 3)); try std.testing.expectEqual(@as(usize, 0), edit.cursor); try std.testing.expectEqual(@as(?usize, null), state.preferredColumn());}
test "vertical navigation extends from the original cursor when requested" { const alloc = std.testing.allocator; var edit: editor_state.State = .{}; defer edit.deinit(alloc); try edit.setText(alloc, "abcdef"); _ = edit.setCursor(2);
var entities: registered_entities.State = .{}; defer entities.deinit(alloc); var state: State = .{};
try std.testing.expect(state.applyTargetWithSelection(&edit, &entities, 5, 3, true)); try std.testing.expectEqual( editor_state.SelectionRange{ .start = 2, .end = 5 }, edit.selectionRange().?, ); try std.testing.expectEqual(@as(?usize, 3), state.preferredColumn());}