Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
6 changes: 3 additions & 3 deletions .github/workflows/build-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
jobs:
build:
name: Core - Build and Test
runs-on: ubuntu-latest
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -21,7 +21,7 @@ jobs:
- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.14.1
version: 0.15.2

- name: Install dependencies
run: bun install
Expand All @@ -34,4 +34,4 @@ jobs:
- name: Run tests
run: |
cd packages/core
bun run test
bun run test:js
7 changes: 5 additions & 2 deletions .github/workflows/build-native.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ on:
default: false

env:
ZIG_VERSION: 0.14.1
ZIG_VERSION: 0.15.2

jobs:
build-native:
Expand All @@ -39,7 +39,10 @@ jobs:
run: bun install

- name: Build packages (cross-compile for all platforms)
run: bun run build
run: |
cd packages/core
bun run build:native --all
bun run build:lib

- name: Verify build outputs
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build-react.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
jobs:
build:
name: React - Build and Test
runs-on: ubuntu-latest
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -21,7 +21,7 @@ jobs:
- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.14.1
version: 0.15.2

- name: Install dependencies
run: bun install
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build-solid.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
jobs:
build:
name: Solid - Build and Test
runs-on: ubuntu-latest
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -21,7 +21,7 @@ jobs:
- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.14.1
version: 0.15.2

- name: Install dependencies
run: bun install
Expand Down
2 changes: 1 addition & 1 deletion .zig-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.14.1
0.15.2
34 changes: 15 additions & 19 deletions packages/core/scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const args = process.argv.slice(2)
const buildLib = args.find((arg) => arg === "--lib")
const buildNative = args.find((arg) => arg === "--native")
const isDev = args.includes("--dev")
const buildAll = args.includes("--all") // Build for all platforms (requires macOS or cross-compilation setup)

const variants: Variant[] = [
{ platform: "darwin", arch: "x64" },
Expand Down Expand Up @@ -78,16 +79,17 @@ if (missingRequired.length > 0) {
}

if (buildNative) {
console.log(`Building native ${isDev ? "dev" : "prod"} binaries...`)
console.log(`Building native ${isDev ? "dev" : "prod"} binaries${buildAll ? " for all platforms" : ""}...`)

const zigBuild: SpawnSyncReturns<Buffer> = spawnSync(
"zig",
["build", `-Doptimize=${isDev ? "Debug" : "ReleaseFast"}`],
{
cwd: join(rootDir, "src", "zig"),
stdio: "inherit",
},
)
const zigArgs = ["build", `-Doptimize=${isDev ? "Debug" : "ReleaseFast"}`]
if (buildAll) {
zigArgs.push("-Dall")
}

const zigBuild: SpawnSyncReturns<Buffer> = spawnSync("zig", zigArgs, {
cwd: join(rootDir, "src", "zig"),
stdio: "inherit",
})

if (zigBuild.error) {
console.error("Error: Zig is not installed or not in PATH")
Expand Down Expand Up @@ -124,16 +126,10 @@ if (buildNative) {
}

if (copiedFiles === 0) {
console.error(`Error: No dynamic libraries found for ${platform}-${arch} in ${libDir}`)
console.error(`Expected to find files like: libopentui.so, libopentui.dylib, opentui.dll`)
console.error(`Found files in ${libDir}:`)
if (existsSync(libDir)) {
const files = spawnSync("ls", ["-la", libDir], { stdio: "pipe" })
if (files.stdout) console.error(files.stdout.toString())
} else {
console.error("Directory does not exist")
}
process.exit(1)
// Skip platforms that weren't built (e.g., macOS when cross-compiling from Linux)
console.log(`Skipping ${platform}-${arch}: no libraries found (cross-compilation may not be supported)`)
rmSync(nativeDir, { recursive: true, force: true })
continue
}

const indexTsContent = `const module = await import("./${libraryFileName}", { with: { type: "file" } })
Expand Down
17 changes: 10 additions & 7 deletions packages/core/src/zig/ansi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ pub const ANSI = struct {

// Direct writing to any writer - the most efficient option
pub fn moveToOutput(writer: anytype, x: u32, y: u32) AnsiError!void {
std.fmt.format(writer, "\x1b[{d};{d}H", .{ y, x }) catch return AnsiError.WriteFailed;
writer.print("\x1b[{d};{d}H", .{ y, x }) catch return AnsiError.WriteFailed;
}

pub fn fgColorOutput(writer: anytype, r: u8, g: u8, b: u8) AnsiError!void {
std.fmt.format(writer, "\x1b[38;2;{d};{d};{d}m", .{ r, g, b }) catch return AnsiError.WriteFailed;
writer.print("\x1b[38;2;{d};{d};{d}m", .{ r, g, b }) catch return AnsiError.WriteFailed;
}

pub fn bgColorOutput(writer: anytype, r: u8, g: u8, b: u8) AnsiError!void {
std.fmt.format(writer, "\x1b[48;2;{d};{d};{d}m", .{ r, g, b }) catch return AnsiError.WriteFailed;
writer.print("\x1b[48;2;{d};{d};{d}m", .{ r, g, b }) catch return AnsiError.WriteFailed;
}

// Text attribute constants
Expand All @@ -51,11 +51,11 @@ pub const ANSI = struct {
pub const cursorUnderlineBlink = "\x1b[3 q";

pub fn cursorColorOutputWriter(writer: anytype, r: u8, g: u8, b: u8) AnsiError!void {
std.fmt.format(writer, "\x1b]12;#{x:0>2}{x:0>2}{x:0>2}\x07", .{ r, g, b }) catch return AnsiError.WriteFailed;
writer.print("\x1b]12;#{x:0>2}{x:0>2}{x:0>2}\x07", .{ r, g, b }) catch return AnsiError.WriteFailed;
}

pub fn explicitWidthOutput(writer: anytype, width: u32, text: []const u8) AnsiError!void {
std.fmt.format(writer, "\x1b]66;w={d};{s}\x1b\\", .{ width, text }) catch return AnsiError.WriteFailed;
writer.print("\x1b]66;w={d};{s}\x1b\\", .{ width, text }) catch return AnsiError.WriteFailed;
}

pub const resetCursorColor = "\x1b]112\x07";
Expand Down Expand Up @@ -131,12 +131,15 @@ pub const ANSI = struct {
pub const setTerminalTitle = "\x1b]0;{s}\x07";

pub fn setTerminalTitleOutput(writer: anytype, title: []const u8) AnsiError!void {
std.fmt.format(writer, setTerminalTitle, .{title}) catch return AnsiError.WriteFailed;
writer.print(setTerminalTitle, .{title}) catch return AnsiError.WriteFailed;
}

pub fn makeRoomForRendererOutput(writer: anytype, height: u32) AnsiError!void {
if (height > 1) {
writer.writeByteNTimes('\n', height - 1) catch return AnsiError.WriteFailed;
var i: u32 = 0;
while (i < height - 1) : (i += 1) {
writer.writeByte('\n') catch return AnsiError.WriteFailed;
}
}
}
};
Expand Down
26 changes: 13 additions & 13 deletions packages/core/src/zig/buffer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ pub const OptimizedBuffer = struct {
grapheme_tracker: gp.GraphemeTracker,
width_method: utf8.WidthMethod,
id: []const u8,
scissor_stack: std.ArrayList(ClipRect),
opacity_stack: std.ArrayList(f32),
scissor_stack: std.ArrayListUnmanaged(ClipRect),
opacity_stack: std.ArrayListUnmanaged(f32),

const InitOptions = struct {
respectAlpha: bool = false,
Expand All @@ -159,11 +159,11 @@ pub const OptimizedBuffer = struct {
const owned_id = allocator.dupe(u8, options.id) catch return BufferError.OutOfMemory;
errdefer allocator.free(owned_id);

var scissor_stack = std.ArrayList(ClipRect).init(allocator);
errdefer scissor_stack.deinit();
var scissor_stack: std.ArrayListUnmanaged(ClipRect) = .{};
errdefer scissor_stack.deinit(allocator);

var opacity_stack = std.ArrayList(f32).init(allocator);
errdefer opacity_stack.deinit();
var opacity_stack: std.ArrayListUnmanaged(f32) = .{};
errdefer opacity_stack.deinit(allocator);

self.* = .{
.buffer = .{
Expand Down Expand Up @@ -209,8 +209,8 @@ pub const OptimizedBuffer = struct {
}

pub fn deinit(self: *OptimizedBuffer) void {
self.opacity_stack.deinit();
self.scissor_stack.deinit();
self.opacity_stack.deinit(self.allocator);
self.scissor_stack.deinit(self.allocator);
self.grapheme_tracker.deinit();
self.allocator.free(self.buffer.char);
self.allocator.free(self.buffer.fg);
Expand Down Expand Up @@ -292,7 +292,7 @@ pub const OptimizedBuffer = struct {
}
}

try self.scissor_stack.append(rect);
try self.scissor_stack.append(self.allocator, rect);
}

pub fn popScissorRect(self: *OptimizedBuffer) void {
Expand All @@ -315,7 +315,7 @@ pub const OptimizedBuffer = struct {
pub fn pushOpacity(self: *OptimizedBuffer, opacity: f32) !void {
const current = self.getCurrentOpacity();
const effective = current * std.math.clamp(opacity, 0.0, 1.0);
try self.opacity_stack.append(effective);
try self.opacity_stack.append(self.allocator, effective);
}

/// Pop an opacity value from the stack
Expand Down Expand Up @@ -750,11 +750,11 @@ pub const OptimizedBuffer = struct {

const is_ascii_only = utf8.isAsciiOnly(text);

var grapheme_list = std.ArrayList(utf8.GraphemeInfo).init(self.allocator);
defer grapheme_list.deinit();
var grapheme_list: std.ArrayListUnmanaged(utf8.GraphemeInfo) = .{};
defer grapheme_list.deinit(self.allocator);

const tab_width: u8 = 2;
try utf8.findGraphemeInfo(text, tab_width, is_ascii_only, self.width_method, &grapheme_list);
try utf8.findGraphemeInfo(text, tab_width, is_ascii_only, self.width_method, self.allocator, &grapheme_list);
const specials = grapheme_list.items;

var advance_cells: u32 = 0;
Expand Down
Loading
Loading