mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-02 07:58:37 +00:00
Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
21c21730c7 | ||
![]() |
29e14aafb8 | ||
![]() |
4a0573b789 | ||
![]() |
b21b9b2dcf |
@@ -4,7 +4,7 @@ const builtin = @import("builtin");
|
|||||||
const buildpkg = @import("src/build/main.zig");
|
const buildpkg = @import("src/build/main.zig");
|
||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
buildpkg.requireZig("0.14.0");
|
buildpkg.requireZig("0.15.1");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(b: *std.Build) !void {
|
pub fn build(b: *std.Build) !void {
|
||||||
@@ -249,8 +249,6 @@ pub fn build(b: *std.Build) !void {
|
|||||||
{
|
{
|
||||||
const mod_vt_test = b.addTest(.{
|
const mod_vt_test = b.addTest(.{
|
||||||
.root_module = mod.vt,
|
.root_module = mod.vt,
|
||||||
.target = config.target,
|
|
||||||
.optimize = config.optimize,
|
|
||||||
.filters = test_filters,
|
.filters = test_filters,
|
||||||
});
|
});
|
||||||
const mod_vt_test_run = b.addRunArtifact(mod_vt_test);
|
const mod_vt_test_run = b.addRunArtifact(mod_vt_test);
|
||||||
@@ -258,8 +256,6 @@ pub fn build(b: *std.Build) !void {
|
|||||||
|
|
||||||
const mod_vt_c_test = b.addTest(.{
|
const mod_vt_c_test = b.addTest(.{
|
||||||
.root_module = mod.vt_c,
|
.root_module = mod.vt_c,
|
||||||
.target = config.target,
|
|
||||||
.optimize = config.optimize,
|
|
||||||
.filters = test_filters,
|
.filters = test_filters,
|
||||||
});
|
});
|
||||||
const mod_vt_c_test_run = b.addRunArtifact(mod_vt_c_test);
|
const mod_vt_c_test_run = b.addRunArtifact(mod_vt_c_test);
|
||||||
|
@@ -9,48 +9,49 @@
|
|||||||
|
|
||||||
.libxev = .{
|
.libxev = .{
|
||||||
// mitchellh/libxev
|
// mitchellh/libxev
|
||||||
.url = "https://github.com/mitchellh/libxev/archive/7f803181b158a10fec8619f793e3b4df515566cb.tar.gz",
|
.url = "https://github.com/mitchellh/libxev/archive/34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz",
|
||||||
.hash = "libxev-0.0.0-86vtc2UaEwDfiTKX3iBI-s_hdzfzWQUarT3MUrmUQl-Q",
|
.hash = "libxev-0.0.0-86vtc4IcEwCqEYxEYoN_3KXmc6A9VLcm22aVImfvecYs",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.vaxis = .{
|
.vaxis = .{
|
||||||
// rockorager/libvaxis
|
// rockorager/libvaxis
|
||||||
.url = "git+https://github.com/rockorager/libvaxis#1f41c121e8fc153d9ce8c6eb64b2bbab68ad7d23",
|
.url = "https://github.com/rockorager/libvaxis/archive/6eb16bb4190dc074dafaf4f0ce7dadd50e81192a.tar.gz",
|
||||||
.hash = "vaxis-0.1.0-BWNV_FUICQAFZnTCL11TUvnUr1Y0_ZdqtXHhd51d76Rn",
|
.hash = "vaxis-0.5.1-BWNV_BMgCQDXdZzABeY4F_xwgE7nHFtYEP07KgEwJWo8",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.z2d = .{
|
.z2d = .{
|
||||||
// vancluever/z2d
|
// vancluever/z2d
|
||||||
.url = "https://github.com/vancluever/z2d/archive/refs/tags/v0.8.1.tar.gz",
|
.url = "https://github.com/vancluever/z2d/archive/a1237f6881d99b75abd8a20a934e62e34b44a005.tar.gz",
|
||||||
.hash = "z2d-0.8.1-j5P_Hq8vDwB8ZaDA54-SzESDLF2zznG_zvTHiQNJImZP",
|
.hash = "z2d-0.8.2-pre-j5P_HlVRFgCsBTQ3EgUoKbYHx5JMnyH1mHsOSPiafnef",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.zig_objc = .{
|
.zig_objc = .{
|
||||||
// mitchellh/zig-objc
|
// mitchellh/zig-objc
|
||||||
.url = "https://github.com/mitchellh/zig-objc/archive/c9e917a4e15a983b672ca779c7985d738a2d517c.tar.gz",
|
.url = "https://github.com/mitchellh/zig-objc/archive/f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz",
|
||||||
.hash = "zig_objc-0.0.0-Ir_SpwsPAQBJgi9YRm2ubJMfdoysSq5gKpsIj3izQ8Zk",
|
.hash = "zig_objc-0.0.0-Ir_Sp5gTAQCvxxR7oVIrPXxXwsfKgVP7_wqoOQrZjFeK",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.zig_js = .{
|
.zig_js = .{
|
||||||
// mitchellh/zig-js
|
// mitchellh/zig-js
|
||||||
.url = "https://deps.files.ghostty.org/zig_js-12205a66d423259567764fa0fc60c82be35365c21aeb76c5a7dc99698401f4f6fefc.tar.gz",
|
.url = "https://github.com/mitchellh/zig-js/archive/04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz",
|
||||||
.hash = "N-V-__8AAB9YCQBaZtQjJZVndk-g_GDIK-NTZcIa63bFp9yZ",
|
.hash = "zig_js-0.0.0-rjCAV-6GAADxFug7rDmPH-uM_XcnJ5NmuAMJCAscMjhi",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.uucode = .{
|
.uucode = .{
|
||||||
.url = "https://github.com/jacobsandlund/uucode/archive/190706c6b56f0842d29778007f74f7d3d1335fc5.tar.gz",
|
// TODO: currently the use-llvm branch because its broken on self-hosted
|
||||||
.hash = "uucode-0.1.0-ZZjBPpAFQABNCvd9cVPBg4I7233Ays-NWfWphPNqGbyE",
|
.url = "https://github.com/jacobsandlund/uucode/archive/f81f8ef8518b8ec5a7fca30ec5fdbc76cc6197df.tar.gz",
|
||||||
|
.hash = "uucode-0.1.0-ZZjBPjQHQADuCy1VMWftjrMl3iWqgMpUugWVQJG6_7xT",
|
||||||
},
|
},
|
||||||
.zig_wayland = .{
|
.zig_wayland = .{
|
||||||
// codeberg ifreund/zig-wayland
|
// codeberg ifreund/zig-wayland
|
||||||
.url = "https://codeberg.org/ifreund/zig-wayland/archive/f3c5d503e540ada8cbcb056420de240af0c094f7.tar.gz",
|
.url = "https://codeberg.org/ifreund/zig-wayland/archive/1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz",
|
||||||
.hash = "wayland-0.4.0-dev-lQa1kjfIAQCmhhQu3xF0KH-94-TzeMXOqfnP0-Dg6Wyy",
|
.hash = "wayland-0.5.0-dev-lQa1khrMAQDJDwYFKpdH3HizherB7sHo5dKMECfvxQHe",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.zf = .{
|
.zf = .{
|
||||||
// natecraddock/zf
|
// natecraddock/zf
|
||||||
.url = "https://github.com/natecraddock/zf/archive/7aacbe6d155d64d15937ca95ca6c014905eb531f.tar.gz",
|
.url = "https://github.com/jcollie/zf/archive/52ad2e5528ab754f77437edf08a07b5ec843661c.tar.gz",
|
||||||
.hash = "zf-0.10.3-OIRy8aiIAACLrBllz0zjxaH0aOe5oNm3KtEMyCntST-9",
|
.hash = "zf-0.10.3-OIRy8QGJAACJcu3tCGtfbJnnd3Y4QL7OW_X8PJ8u_ASR",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.gobject = .{
|
.gobject = .{
|
||||||
|
6
flake.lock
generated
6
flake.lock
generated
@@ -97,11 +97,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1748261582,
|
"lastModified": 1759192380,
|
||||||
"narHash": "sha256-3i0IL3s18hdDlbsf0/E+5kyPRkZwGPbSFngq5eToiAA=",
|
"narHash": "sha256-0BWJgt4OSzxCESij5oo8WLWrPZ+1qLp8KUQe32QeV4Q=",
|
||||||
"owner": "mitchellh",
|
"owner": "mitchellh",
|
||||||
"repo": "zig-overlay",
|
"repo": "zig-overlay",
|
||||||
"rev": "aafb1b093fb838f7a02613b719e85ec912914221",
|
"rev": "0bcd1401ed43d10f10cbded49624206553e92f57",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@@ -47,7 +47,7 @@
|
|||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
in {
|
in {
|
||||||
devShell.${system} = pkgs.callPackage ./nix/devShell.nix {
|
devShell.${system} = pkgs.callPackage ./nix/devShell.nix {
|
||||||
zig = zig.packages.${system}."0.14.1";
|
zig = zig.packages.${system}."0.15.1";
|
||||||
wraptest = pkgs.callPackage ./nix/wraptest.nix {};
|
wraptest = pkgs.callPackage ./nix/wraptest.nix {};
|
||||||
zon2nix = zon2nix;
|
zon2nix = zon2nix;
|
||||||
};
|
};
|
||||||
|
@@ -46,19 +46,19 @@ pub fn addPaths(
|
|||||||
// find the SDK path.
|
// find the SDK path.
|
||||||
const libc = try std.zig.LibCInstallation.findNative(.{
|
const libc = try std.zig.LibCInstallation.findNative(.{
|
||||||
.allocator = b.allocator,
|
.allocator = b.allocator,
|
||||||
.target = step.rootModuleTarget(),
|
.target = &step.rootModuleTarget(),
|
||||||
.verbose = false,
|
.verbose = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Render the file compatible with the `--libc` Zig flag.
|
// Render the file compatible with the `--libc` Zig flag.
|
||||||
var list: std.ArrayList(u8) = .init(b.allocator);
|
var stream: std.io.Writer.Allocating = .init(b.allocator);
|
||||||
defer list.deinit();
|
defer stream.deinit();
|
||||||
try libc.render(list.writer());
|
try libc.render(&stream.writer);
|
||||||
|
|
||||||
// Create a temporary file to store the libc path because
|
// Create a temporary file to store the libc path because
|
||||||
// `--libc` expects a file path.
|
// `--libc` expects a file path.
|
||||||
const wf = b.addWriteFiles();
|
const wf = b.addWriteFiles();
|
||||||
const path = wf.add("libc.txt", list.items);
|
const path = wf.add("libc.txt", stream.written());
|
||||||
|
|
||||||
// Determine our framework path. Zig has a bug where it doesn't
|
// Determine our framework path. Zig has a bug where it doesn't
|
||||||
// parse this from the libc txt file for `-framework` flags:
|
// parse this from the libc txt file for `-framework` flags:
|
||||||
|
@@ -19,9 +19,8 @@ pub fn build(b: *std.Build) !void {
|
|||||||
try apple_sdk.addPaths(b, lib);
|
try apple_sdk.addPaths(b, lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{});
|
|
||||||
|
|
||||||
if (b.lazyDependency("breakpad", .{})) |upstream| {
|
if (b.lazyDependency("breakpad", .{})) |upstream| {
|
||||||
lib.addIncludePath(upstream.path("src"));
|
lib.addIncludePath(upstream.path("src"));
|
||||||
|
@@ -55,19 +55,19 @@ pub fn build(b: *std.Build) !void {
|
|||||||
if (imgui_) |imgui| lib.addIncludePath(imgui.path(""));
|
if (imgui_) |imgui| lib.addIncludePath(imgui.path(""));
|
||||||
module.addIncludePath(b.path("vendor"));
|
module.addIncludePath(b.path("vendor"));
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DCIMGUI_FREETYPE=1",
|
"-DCIMGUI_FREETYPE=1",
|
||||||
"-DIMGUI_USE_WCHAR32=1",
|
"-DIMGUI_USE_WCHAR32=1",
|
||||||
"-DIMGUI_DISABLE_OBSOLETE_FUNCTIONS=1",
|
"-DIMGUI_DISABLE_OBSOLETE_FUNCTIONS=1",
|
||||||
});
|
});
|
||||||
if (target.result.os.tag == .windows) {
|
if (target.result.os.tag == .windows) {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DIMGUI_IMPL_API=extern\t\"C\"\t__declspec(dllexport)",
|
"-DIMGUI_IMPL_API=extern\t\"C\"\t__declspec(dllexport)",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DIMGUI_IMPL_API=extern\t\"C\"",
|
"-DIMGUI_IMPL_API=extern\t\"C\"",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -82,9 +82,9 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
|||||||
lib.addIncludePath(b.path("override/include"));
|
lib.addIncludePath(b.path("override/include"));
|
||||||
module.addIncludePath(b.path("override/include"));
|
module.addIncludePath(b.path("override/include"));
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DHAVE_DIRENT_H",
|
"-DHAVE_DIRENT_H",
|
||||||
"-DHAVE_FCNTL_H",
|
"-DHAVE_FCNTL_H",
|
||||||
"-DHAVE_STDLIB_H",
|
"-DHAVE_STDLIB_H",
|
||||||
@@ -129,12 +129,12 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
|||||||
});
|
});
|
||||||
|
|
||||||
switch (target.result.ptrBitWidth()) {
|
switch (target.result.ptrBitWidth()) {
|
||||||
32 => try flags.appendSlice(&.{
|
32 => try flags.appendSlice(b.allocator, &.{
|
||||||
"-DSIZEOF_VOID_P=4",
|
"-DSIZEOF_VOID_P=4",
|
||||||
"-DALIGNOF_VOID_P=4",
|
"-DALIGNOF_VOID_P=4",
|
||||||
}),
|
}),
|
||||||
|
|
||||||
64 => try flags.appendSlice(&.{
|
64 => try flags.appendSlice(b.allocator, &.{
|
||||||
"-DSIZEOF_VOID_P=8",
|
"-DSIZEOF_VOID_P=8",
|
||||||
"-DALIGNOF_VOID_P=8",
|
"-DALIGNOF_VOID_P=8",
|
||||||
}),
|
}),
|
||||||
@@ -142,14 +142,14 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
|||||||
else => @panic("unsupported arch"),
|
else => @panic("unsupported arch"),
|
||||||
}
|
}
|
||||||
if (target.result.os.tag == .windows) {
|
if (target.result.os.tag == .windows) {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DFC_CACHEDIR=\"LOCAL_APPDATA_FONTCONFIG_CACHE\"",
|
"-DFC_CACHEDIR=\"LOCAL_APPDATA_FONTCONFIG_CACHE\"",
|
||||||
"-DFC_TEMPLATEDIR=\"c:/share/fontconfig/conf.avail\"",
|
"-DFC_TEMPLATEDIR=\"c:/share/fontconfig/conf.avail\"",
|
||||||
"-DCONFIGDIR=\"c:/etc/fonts/conf.d\"",
|
"-DCONFIGDIR=\"c:/etc/fonts/conf.d\"",
|
||||||
"-DFC_DEFAULT_FONTS=\"\\t<dir>WINDOWSFONTDIR</dir>\\n\\t<dir>WINDOWSUSERFONTDIR</dir>\\n\"",
|
"-DFC_DEFAULT_FONTS=\"\\t<dir>WINDOWSFONTDIR</dir>\\n\\t<dir>WINDOWSUSERFONTDIR</dir>\\n\"",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DHAVE_FSTATFS",
|
"-DHAVE_FSTATFS",
|
||||||
"-DHAVE_FSTATVFS",
|
"-DHAVE_FSTATVFS",
|
||||||
"-DHAVE_GETOPT",
|
"-DHAVE_GETOPT",
|
||||||
@@ -173,13 +173,13 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (target.result.os.tag == .freebsd) {
|
if (target.result.os.tag == .freebsd) {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DFC_TEMPLATEDIR=\"/usr/local/etc/fonts/conf.avail\"",
|
"-DFC_TEMPLATEDIR=\"/usr/local/etc/fonts/conf.avail\"",
|
||||||
"-DFONTCONFIG_PATH=\"/usr/local/etc/fonts\"",
|
"-DFONTCONFIG_PATH=\"/usr/local/etc/fonts\"",
|
||||||
"-DCONFIGDIR=\"/usr/local/etc/fonts/conf.d\"",
|
"-DCONFIGDIR=\"/usr/local/etc/fonts/conf.d\"",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DFC_TEMPLATEDIR=\"/usr/share/fontconfig/conf.avail\"",
|
"-DFC_TEMPLATEDIR=\"/usr/share/fontconfig/conf.avail\"",
|
||||||
"-DFONTCONFIG_PATH=\"/etc/fonts\"",
|
"-DFONTCONFIG_PATH=\"/etc/fonts\"",
|
||||||
"-DCONFIGDIR=\"/usr/local/fontconfig/conf.d\"",
|
"-DCONFIGDIR=\"/usr/local/fontconfig/conf.d\"",
|
||||||
@@ -187,7 +187,7 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (target.result.os.tag == .linux) {
|
if (target.result.os.tag == .linux) {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DHAVE_SYS_STATFS_H",
|
"-DHAVE_SYS_STATFS_H",
|
||||||
"-DHAVE_SYS_VFS_H",
|
"-DHAVE_SYS_VFS_H",
|
||||||
});
|
});
|
||||||
@@ -214,14 +214,14 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
|||||||
// Libxml2
|
// Libxml2
|
||||||
_ = b.systemIntegrationOption("libxml2", .{}); // So it shows up in help
|
_ = b.systemIntegrationOption("libxml2", .{}); // So it shows up in help
|
||||||
if (libxml2_enabled) {
|
if (libxml2_enabled) {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DENABLE_LIBXML2",
|
"-DENABLE_LIBXML2",
|
||||||
"-DLIBXML_STATIC",
|
"-DLIBXML_STATIC",
|
||||||
"-DLIBXML_PUSH_ENABLED",
|
"-DLIBXML_PUSH_ENABLED",
|
||||||
});
|
});
|
||||||
if (target.result.os.tag == .windows) {
|
if (target.result.os.tag == .windows) {
|
||||||
// NOTE: this should be defined on all targets
|
// NOTE: this should be defined on all targets
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-Werror=implicit-function-declaration",
|
"-Werror=implicit-function-declaration",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -77,9 +77,9 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
|||||||
try apple_sdk.addPaths(b, lib);
|
try apple_sdk.addPaths(b, lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DFT2_BUILD_LIBRARY",
|
"-DFT2_BUILD_LIBRARY",
|
||||||
|
|
||||||
"-DFT_CONFIG_OPTION_SYSTEM_ZLIB=1",
|
"-DFT_CONFIG_OPTION_SYSTEM_ZLIB=1",
|
||||||
@@ -103,7 +103,7 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
|||||||
// Libpng
|
// Libpng
|
||||||
_ = b.systemIntegrationOption("libpng", .{}); // So it shows up in help
|
_ = b.systemIntegrationOption("libpng", .{}); // So it shows up in help
|
||||||
if (libpng_enabled) {
|
if (libpng_enabled) {
|
||||||
try flags.append("-DFT_CONFIG_OPTION_USE_PNG=1");
|
try flags.append(b.allocator, "-DFT_CONFIG_OPTION_USE_PNG=1");
|
||||||
|
|
||||||
if (b.systemIntegrationOption("libpng", .{})) {
|
if (b.systemIntegrationOption("libpng", .{})) {
|
||||||
lib.linkSystemLibrary2("libpng", dynamic_link_opts);
|
lib.linkSystemLibrary2("libpng", dynamic_link_opts);
|
||||||
|
@@ -193,8 +193,8 @@ pub const Face = struct {
|
|||||||
) void {
|
) void {
|
||||||
c.FT_Set_Transform(
|
c.FT_Set_Transform(
|
||||||
self.handle,
|
self.handle,
|
||||||
@constCast(@ptrCast(matrix)),
|
@ptrCast(@constCast(matrix)),
|
||||||
@constCast(@ptrCast(delta)),
|
@ptrCast(@constCast(delta)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -59,9 +59,9 @@ fn buildGlslang(
|
|||||||
try apple_sdk.addPaths(b, lib);
|
try apple_sdk.addPaths(b, lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-fno-sanitize=undefined",
|
"-fno-sanitize=undefined",
|
||||||
"-fno-sanitize-trap=undefined",
|
"-fno-sanitize-trap=undefined",
|
||||||
});
|
});
|
||||||
|
@@ -36,10 +36,13 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
|||||||
const optimize = options.optimize;
|
const optimize = options.optimize;
|
||||||
|
|
||||||
// Shared library
|
// Shared library
|
||||||
const lib = b.addSharedLibrary(.{
|
const lib = b.addLibrary(.{
|
||||||
.name = "gtk4-layer-shell",
|
.name = "gtk4-layer-shell",
|
||||||
|
.linkage = .dynamic,
|
||||||
|
.root_module = b.createModule(.{
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
b.installArtifact(lib);
|
b.installArtifact(lib);
|
||||||
|
|
||||||
|
@@ -111,13 +111,13 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
|||||||
|
|
||||||
const dynamic_link_opts = options.dynamic_link_opts;
|
const dynamic_link_opts = options.dynamic_link_opts;
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DHAVE_STDBOOL_H",
|
"-DHAVE_STDBOOL_H",
|
||||||
});
|
});
|
||||||
if (target.result.os.tag != .windows) {
|
if (target.result.os.tag != .windows) {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DHAVE_UNISTD_H",
|
"-DHAVE_UNISTD_H",
|
||||||
"-DHAVE_SYS_MMAN_H",
|
"-DHAVE_SYS_MMAN_H",
|
||||||
"-DHAVE_PTHREAD=1",
|
"-DHAVE_PTHREAD=1",
|
||||||
@@ -127,7 +127,7 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
|||||||
// Freetype
|
// Freetype
|
||||||
_ = b.systemIntegrationOption("freetype", .{}); // So it shows up in help
|
_ = b.systemIntegrationOption("freetype", .{}); // So it shows up in help
|
||||||
if (freetype_enabled) {
|
if (freetype_enabled) {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DHAVE_FREETYPE=1",
|
"-DHAVE_FREETYPE=1",
|
||||||
|
|
||||||
// Let's just assume a new freetype
|
// Let's just assume a new freetype
|
||||||
@@ -153,7 +153,7 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (coretext_enabled) {
|
if (coretext_enabled) {
|
||||||
try flags.appendSlice(&.{"-DHAVE_CORETEXT=1"});
|
try flags.appendSlice(b.allocator, &.{"-DHAVE_CORETEXT=1"});
|
||||||
lib.linkFramework("CoreText");
|
lib.linkFramework("CoreText");
|
||||||
module.linkFramework("CoreText", .{});
|
module.linkFramework("CoreText", .{});
|
||||||
}
|
}
|
||||||
|
@@ -31,9 +31,9 @@ pub fn build(b: *std.Build) !void {
|
|||||||
try apple_sdk.addPaths(b, lib);
|
try apple_sdk.addPaths(b, lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
// Avoid changing binaries based on the current time and date.
|
// Avoid changing binaries based on the current time and date.
|
||||||
"-Wno-builtin-macro-redefined",
|
"-Wno-builtin-macro-redefined",
|
||||||
"-D__DATE__=\"redacted\"",
|
"-D__DATE__=\"redacted\"",
|
||||||
@@ -69,7 +69,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
"-fno-vectorize",
|
"-fno-vectorize",
|
||||||
});
|
});
|
||||||
if (target.result.os.tag != .windows) {
|
if (target.result.os.tag != .windows) {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-fmath-errno",
|
"-fmath-errno",
|
||||||
"-fno-exceptions",
|
"-fno-exceptions",
|
||||||
});
|
});
|
||||||
|
@@ -22,9 +22,9 @@ pub fn build(b: *std.Build) !void {
|
|||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DHAVE_CONFIG_H",
|
"-DHAVE_CONFIG_H",
|
||||||
"-DLOCALEDIR=\"\"",
|
"-DLOCALEDIR=\"\"",
|
||||||
});
|
});
|
||||||
|
@@ -46,9 +46,9 @@ pub fn build(b: *std.Build) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (b.lazyDependency("libpng", .{})) |upstream| {
|
if (b.lazyDependency("libpng", .{})) |upstream| {
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DPNG_ARM_NEON_OPT=0",
|
"-DPNG_ARM_NEON_OPT=0",
|
||||||
"-DPNG_POWERPC_VSX_OPT=0",
|
"-DPNG_POWERPC_VSX_OPT=0",
|
||||||
"-DPNG_INTEL_SSE_OPT=0",
|
"-DPNG_INTEL_SSE_OPT=0",
|
||||||
|
@@ -25,9 +25,9 @@ pub fn build(b: *std.Build) !void {
|
|||||||
lib.addIncludePath(b.path("override/config/posix"));
|
lib.addIncludePath(b.path("override/config/posix"));
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
// Version info, hardcoded
|
// Version info, hardcoded
|
||||||
comptime "-DLIBXML_VERSION=" ++ Version.number(),
|
comptime "-DLIBXML_VERSION=" ++ Version.number(),
|
||||||
comptime "-DLIBXML_VERSION_STRING=" ++ Version.string(),
|
comptime "-DLIBXML_VERSION_STRING=" ++ Version.string(),
|
||||||
@@ -46,7 +46,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
"-DWITHOUT_TRIO=1",
|
"-DWITHOUT_TRIO=1",
|
||||||
});
|
});
|
||||||
if (target.result.os.tag != .windows) {
|
if (target.result.os.tag != .windows) {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DHAVE_ARPA_INET_H=1",
|
"-DHAVE_ARPA_INET_H=1",
|
||||||
"-DHAVE_ARPA_NAMESER_H=1",
|
"-DHAVE_ARPA_NAMESER_H=1",
|
||||||
"-DHAVE_DL_H=1",
|
"-DHAVE_DL_H=1",
|
||||||
@@ -74,25 +74,25 @@ pub fn build(b: *std.Build) !void {
|
|||||||
var nameBuf: [32]u8 = undefined;
|
var nameBuf: [32]u8 = undefined;
|
||||||
const name = std.ascii.upperString(&nameBuf, field.name);
|
const name = std.ascii.upperString(&nameBuf, field.name);
|
||||||
const define = try std.fmt.allocPrint(b.allocator, "-DLIBXML_{s}_ENABLED=1", .{name});
|
const define = try std.fmt.allocPrint(b.allocator, "-DLIBXML_{s}_ENABLED=1", .{name});
|
||||||
try flags.append(define);
|
try flags.append(b.allocator, define);
|
||||||
|
|
||||||
if (std.mem.eql(u8, field.name, "history")) {
|
if (std.mem.eql(u8, field.name, "history")) {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DHAVE_LIBHISTORY=1",
|
"-DHAVE_LIBHISTORY=1",
|
||||||
"-DHAVE_LIBREADLINE=1",
|
"-DHAVE_LIBREADLINE=1",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (std.mem.eql(u8, field.name, "mem_debug")) {
|
if (std.mem.eql(u8, field.name, "mem_debug")) {
|
||||||
try flags.append("-DDEBUG_MEMORY_LOCATION=1");
|
try flags.append(b.allocator, "-DDEBUG_MEMORY_LOCATION=1");
|
||||||
}
|
}
|
||||||
if (std.mem.eql(u8, field.name, "regexp")) {
|
if (std.mem.eql(u8, field.name, "regexp")) {
|
||||||
try flags.append("-DLIBXML_UNICODE_ENABLED=1");
|
try flags.append(b.allocator, "-DLIBXML_UNICODE_ENABLED=1");
|
||||||
}
|
}
|
||||||
if (std.mem.eql(u8, field.name, "run_debug")) {
|
if (std.mem.eql(u8, field.name, "run_debug")) {
|
||||||
try flags.append("-DLIBXML_DEBUG_RUNTIME=1");
|
try flags.append(b.allocator, "-DLIBXML_DEBUG_RUNTIME=1");
|
||||||
}
|
}
|
||||||
if (std.mem.eql(u8, field.name, "thread")) {
|
if (std.mem.eql(u8, field.name, "thread")) {
|
||||||
try flags.append("-DHAVE_LIBPTHREAD=1");
|
try flags.append(b.allocator, "-DHAVE_LIBPTHREAD=1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -68,7 +68,7 @@ pub const MutableArray = opaque {
|
|||||||
comptime Elem: type,
|
comptime Elem: type,
|
||||||
value: *const Elem,
|
value: *const Elem,
|
||||||
) void {
|
) void {
|
||||||
CFArrayAppendValue(self, @constCast(@ptrCast(value)));
|
CFArrayAppendValue(self, @ptrCast(@constCast(value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn removeValue(self: *MutableArray, idx: usize) void {
|
pub fn removeValue(self: *MutableArray, idx: usize) void {
|
||||||
|
@@ -10,7 +10,7 @@ pub const AttributedString = opaque {
|
|||||||
str: *foundation.String,
|
str: *foundation.String,
|
||||||
attributes: *foundation.Dictionary,
|
attributes: *foundation.Dictionary,
|
||||||
) Allocator.Error!*AttributedString {
|
) Allocator.Error!*AttributedString {
|
||||||
return @constCast(@ptrCast(c.CFAttributedStringCreate(
|
return @ptrCast(@constCast(c.CFAttributedStringCreate(
|
||||||
null,
|
null,
|
||||||
@ptrCast(str),
|
@ptrCast(str),
|
||||||
@ptrCast(attributes),
|
@ptrCast(attributes),
|
||||||
|
@@ -17,8 +17,8 @@ pub const Dictionary = opaque {
|
|||||||
|
|
||||||
return @as(?*Dictionary, @ptrFromInt(@intFromPtr(c.CFDictionaryCreate(
|
return @as(?*Dictionary, @ptrFromInt(@intFromPtr(c.CFDictionaryCreate(
|
||||||
null,
|
null,
|
||||||
@constCast(@ptrCast(if (keys) |slice| slice.ptr else null)),
|
@ptrCast(@constCast(if (keys) |slice| slice.ptr else null)),
|
||||||
@constCast(@ptrCast(if (values) |slice| slice.ptr else null)),
|
@ptrCast(@constCast(if (values) |slice| slice.ptr else null)),
|
||||||
@intCast(if (keys) |slice| slice.len else 0),
|
@intCast(if (keys) |slice| slice.len else 0),
|
||||||
&c.kCFTypeDictionaryKeyCallBacks,
|
&c.kCFTypeDictionaryKeyCallBacks,
|
||||||
&c.kCFTypeDictionaryValueCallBacks,
|
&c.kCFTypeDictionaryValueCallBacks,
|
||||||
|
@@ -68,7 +68,7 @@ pub const Font = opaque {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn copyTable(self: *Font, tag: FontTableTag) ?*foundation.Data {
|
pub fn copyTable(self: *Font, tag: FontTableTag) ?*foundation.Data {
|
||||||
return @constCast(@ptrCast(c.CTFontCopyTable(
|
return @ptrCast(@constCast(c.CTFontCopyTable(
|
||||||
@ptrCast(self),
|
@ptrCast(self),
|
||||||
@intFromEnum(tag),
|
@intFromEnum(tag),
|
||||||
c.kCTFontTableOptionNoOptions,
|
c.kCTFontTableOptionNoOptions,
|
||||||
@@ -90,7 +90,7 @@ pub const Font = opaque {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn createPathForGlyph(self: *Font, glyph: graphics.Glyph) ?*graphics.Path {
|
pub fn createPathForGlyph(self: *Font, glyph: graphics.Glyph) ?*graphics.Path {
|
||||||
return @constCast(@ptrCast(c.CTFontCreatePathForGlyph(
|
return @ptrCast(@constCast(c.CTFontCreatePathForGlyph(
|
||||||
@ptrCast(self),
|
@ptrCast(self),
|
||||||
glyph,
|
glyph,
|
||||||
null,
|
null,
|
||||||
|
@@ -51,7 +51,7 @@ pub const Line = opaque {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getGlyphRuns(self: *Line) *foundation.Array {
|
pub fn getGlyphRuns(self: *Line) *foundation.Array {
|
||||||
return @constCast(@ptrCast(c.CTLineGetGlyphRuns(@ptrCast(self))));
|
return @ptrCast(@constCast(c.CTLineGetGlyphRuns(@ptrCast(self))));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -74,7 +74,7 @@ pub const DisplayLink = opaque {
|
|||||||
|
|
||||||
callbackFn(
|
callbackFn(
|
||||||
displayLink,
|
displayLink,
|
||||||
@alignCast(@ptrCast(inner_userinfo)),
|
@ptrCast(@alignCast(inner_userinfo)),
|
||||||
);
|
);
|
||||||
return c.kCVReturnSuccess;
|
return c.kCVReturnSuccess;
|
||||||
}
|
}
|
||||||
|
@@ -100,9 +100,8 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
|||||||
.SIZEOF_VOIDP = t.ptrBitWidth() / t.cTypeBitSize(.char),
|
.SIZEOF_VOIDP = t.ptrBitWidth() / t.cTypeBitSize(.char),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{});
|
|
||||||
lib.addCSourceFiles(.{
|
lib.addCSourceFiles(.{
|
||||||
.root = upstream.path(""),
|
.root = upstream.path(""),
|
||||||
.flags = flags.items,
|
.flags = flags.items,
|
||||||
|
@@ -6,7 +6,7 @@ const errors = @import("errors.zig");
|
|||||||
/// the encodings that the program will use.
|
/// the encodings that the program will use.
|
||||||
pub fn init(encs: []const *Encoding) !void {
|
pub fn init(encs: []const *Encoding) !void {
|
||||||
_ = try errors.convertError(c.onig_initialize(
|
_ = try errors.convertError(c.onig_initialize(
|
||||||
@constCast(@ptrCast(@alignCast(encs.ptr))),
|
@ptrCast(@alignCast(@constCast(encs.ptr))),
|
||||||
@intCast(encs.len),
|
@intCast(encs.len),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@@ -26,22 +26,21 @@ pub fn build(b: *std.Build) !void {
|
|||||||
try apple_sdk.addPaths(b, lib);
|
try apple_sdk.addPaths(b, lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{});
|
|
||||||
if (target.result.os.tag == .windows) {
|
if (target.result.os.tag == .windows) {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DSENTRY_WITH_UNWINDER_DBGHELP",
|
"-DSENTRY_WITH_UNWINDER_DBGHELP",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DSENTRY_WITH_UNWINDER_LIBBACKTRACE",
|
"-DSENTRY_WITH_UNWINDER_LIBBACKTRACE",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
switch (backend) {
|
switch (backend) {
|
||||||
.crashpad => try flags.append("-DSENTRY_BACKEND_CRASHPAD"),
|
.crashpad => try flags.append(b.allocator, "-DSENTRY_BACKEND_CRASHPAD"),
|
||||||
.breakpad => try flags.append("-DSENTRY_BACKEND_BREAKPAD"),
|
.breakpad => try flags.append(b.allocator, "-DSENTRY_BACKEND_BREAKPAD"),
|
||||||
.inproc => try flags.append("-DSENTRY_BACKEND_INPROC"),
|
.inproc => try flags.append(b.allocator, "-DSENTRY_BACKEND_INPROC"),
|
||||||
.none => {},
|
.none => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,11 +20,11 @@ pub fn build(b: *std.Build) !void {
|
|||||||
try apple_sdk.addPaths(b, lib);
|
try apple_sdk.addPaths(b, lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
// Zig 0.13 bug: https://github.com/ziglang/zig/issues/20414
|
// Zig 0.13 bug: https://github.com/ziglang/zig/issues/20414
|
||||||
// (See root Ghostty build.zig on why we do this)
|
// (See root Ghostty build.zig on why we do this)
|
||||||
try flags.appendSlice(&.{"-DSIMDUTF_IMPLEMENTATION_ICELAKE=0"});
|
try flags.appendSlice(b.allocator, &.{"-DSIMDUTF_IMPLEMENTATION_ICELAKE=0"});
|
||||||
|
|
||||||
lib.addCSourceFiles(.{
|
lib.addCSourceFiles(.{
|
||||||
.flags = flags.items,
|
.flags = flags.items,
|
||||||
|
@@ -64,9 +64,9 @@ fn buildSpirvCross(
|
|||||||
try apple_sdk.addPaths(b, lib);
|
try apple_sdk.addPaths(b, lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DSPIRV_CROSS_C_API_GLSL=1",
|
"-DSPIRV_CROSS_C_API_GLSL=1",
|
||||||
"-DSPIRV_CROSS_C_API_MSL=1",
|
"-DSPIRV_CROSS_C_API_MSL=1",
|
||||||
|
|
||||||
|
@@ -19,9 +19,8 @@ pub fn build(b: *std.Build) !void {
|
|||||||
try apple_sdk.addPaths(b, lib);
|
try apple_sdk.addPaths(b, lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{});
|
|
||||||
|
|
||||||
lib.addCSourceFiles(.{
|
lib.addCSourceFiles(.{
|
||||||
.flags = flags.items,
|
.flags = flags.items,
|
||||||
|
@@ -17,11 +17,11 @@ pub fn build(b: *std.Build) !void {
|
|||||||
});
|
});
|
||||||
unit_tests.linkLibC();
|
unit_tests.linkLibC();
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.append("-DWUFFS_IMPLEMENTATION");
|
try flags.append(b.allocator, "-DWUFFS_IMPLEMENTATION");
|
||||||
inline for (@import("src/c.zig").defines) |key| {
|
inline for (@import("src/c.zig").defines) |key| {
|
||||||
try flags.append("-D" ++ key);
|
try flags.append(b.allocator, "-D" ++ key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b.lazyDependency("wuffs", .{})) |wuffs_dep| {
|
if (b.lazyDependency("wuffs", .{})) |wuffs_dep| {
|
||||||
|
@@ -31,7 +31,7 @@ pub fn decode(alloc: Allocator, data: []const u8) Error!ImageData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var source_buffer: c.wuffs_base__io_buffer = .{
|
var source_buffer: c.wuffs_base__io_buffer = .{
|
||||||
.data = .{ .ptr = @constCast(@ptrCast(data.ptr)), .len = data.len },
|
.data = .{ .ptr = @ptrCast(@constCast(data.ptr)), .len = data.len },
|
||||||
.meta = .{
|
.meta = .{
|
||||||
.wi = data.len,
|
.wi = data.len,
|
||||||
.ri = 0,
|
.ri = 0,
|
||||||
|
@@ -31,7 +31,7 @@ pub fn decode(alloc: Allocator, data: []const u8) Error!ImageData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var source_buffer: c.wuffs_base__io_buffer = .{
|
var source_buffer: c.wuffs_base__io_buffer = .{
|
||||||
.data = .{ .ptr = @constCast(@ptrCast(data.ptr)), .len = data.len },
|
.data = .{ .ptr = @ptrCast(@constCast(data.ptr)), .len = data.len },
|
||||||
.meta = .{
|
.meta = .{
|
||||||
.wi = data.len,
|
.wi = data.len,
|
||||||
.ri = 0,
|
.ri = 0,
|
||||||
|
@@ -26,9 +26,9 @@ pub fn build(b: *std.Build) !void {
|
|||||||
.{ .include_extensions = &.{".h"} },
|
.{ .include_extensions = &.{".h"} },
|
||||||
);
|
);
|
||||||
|
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags: std.ArrayList([]const u8) = .empty;
|
||||||
defer flags.deinit();
|
defer flags.deinit(b.allocator);
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(b.allocator, &.{
|
||||||
"-DHAVE_SYS_TYPES_H",
|
"-DHAVE_SYS_TYPES_H",
|
||||||
"-DHAVE_STDINT_H",
|
"-DHAVE_STDINT_H",
|
||||||
"-DHAVE_STDDEF_H",
|
"-DHAVE_STDDEF_H",
|
||||||
|
@@ -282,7 +282,7 @@ pub fn Common(
|
|||||||
fn setter(self: *Self, value: ?[:0]const u8) void {
|
fn setter(self: *Self, value: ?[:0]const u8) void {
|
||||||
const priv = private(self);
|
const priv = private(self);
|
||||||
if (@field(priv, name)) |v| {
|
if (@field(priv, name)) |v| {
|
||||||
glib.free(@constCast(@ptrCast(v)));
|
glib.free(@ptrCast(@constCast(v)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't need to copy this because it was already
|
// We don't need to copy this because it was already
|
||||||
|
@@ -172,7 +172,7 @@ pub const ResizeOverlay = extern struct {
|
|||||||
/// overlay if it is currently hidden; you must call schedule.
|
/// overlay if it is currently hidden; you must call schedule.
|
||||||
pub fn setLabel(self: *Self, label: ?[:0]const u8) void {
|
pub fn setLabel(self: *Self, label: ?[:0]const u8) void {
|
||||||
const priv = self.private();
|
const priv = self.private();
|
||||||
if (priv.label_text) |v| glib.free(@constCast(@ptrCast(v)));
|
if (priv.label_text) |v| glib.free(@ptrCast(@constCast(v)));
|
||||||
priv.label_text = null;
|
priv.label_text = null;
|
||||||
if (label) |v| priv.label_text = glib.ext.dupeZ(u8, v);
|
if (label) |v| priv.label_text = glib.ext.dupeZ(u8, v);
|
||||||
self.as(gobject.Object).notifyByPspec(properties.label.impl.param_spec);
|
self.as(gobject.Object).notifyByPspec(properties.label.impl.param_spec);
|
||||||
@@ -285,7 +285,7 @@ pub const ResizeOverlay = extern struct {
|
|||||||
fn finalize(self: *Self) callconv(.c) void {
|
fn finalize(self: *Self) callconv(.c) void {
|
||||||
const priv = self.private();
|
const priv = self.private();
|
||||||
if (priv.label_text) |v| {
|
if (priv.label_text) |v| {
|
||||||
glib.free(@constCast(@ptrCast(v)));
|
glib.free(@ptrCast(@constCast(v)));
|
||||||
priv.label_text = null;
|
priv.label_text = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1526,7 +1526,7 @@ pub const Surface = extern struct {
|
|||||||
priv.core_surface = null;
|
priv.core_surface = null;
|
||||||
}
|
}
|
||||||
if (priv.mouse_hover_url) |v| {
|
if (priv.mouse_hover_url) |v| {
|
||||||
glib.free(@constCast(@ptrCast(v)));
|
glib.free(@ptrCast(@constCast(v)));
|
||||||
priv.mouse_hover_url = null;
|
priv.mouse_hover_url = null;
|
||||||
}
|
}
|
||||||
if (priv.default_size) |v| {
|
if (priv.default_size) |v| {
|
||||||
@@ -1542,15 +1542,15 @@ pub const Surface = extern struct {
|
|||||||
priv.min_size = null;
|
priv.min_size = null;
|
||||||
}
|
}
|
||||||
if (priv.pwd) |v| {
|
if (priv.pwd) |v| {
|
||||||
glib.free(@constCast(@ptrCast(v)));
|
glib.free(@ptrCast(@constCast(v)));
|
||||||
priv.pwd = null;
|
priv.pwd = null;
|
||||||
}
|
}
|
||||||
if (priv.title) |v| {
|
if (priv.title) |v| {
|
||||||
glib.free(@constCast(@ptrCast(v)));
|
glib.free(@ptrCast(@constCast(v)));
|
||||||
priv.title = null;
|
priv.title = null;
|
||||||
}
|
}
|
||||||
if (priv.title_override) |v| {
|
if (priv.title_override) |v| {
|
||||||
glib.free(@constCast(@ptrCast(v)));
|
glib.free(@ptrCast(@constCast(v)));
|
||||||
priv.title_override = null;
|
priv.title_override = null;
|
||||||
}
|
}
|
||||||
self.clearCgroup();
|
self.clearCgroup();
|
||||||
@@ -1574,7 +1574,7 @@ pub const Surface = extern struct {
|
|||||||
/// title. For manually set titles see `setTitleOverride`.
|
/// title. For manually set titles see `setTitleOverride`.
|
||||||
pub fn setTitle(self: *Self, title: ?[:0]const u8) void {
|
pub fn setTitle(self: *Self, title: ?[:0]const u8) void {
|
||||||
const priv = self.private();
|
const priv = self.private();
|
||||||
if (priv.title) |v| glib.free(@constCast(@ptrCast(v)));
|
if (priv.title) |v| glib.free(@ptrCast(@constCast(v)));
|
||||||
priv.title = null;
|
priv.title = null;
|
||||||
if (title) |v| priv.title = glib.ext.dupeZ(u8, v);
|
if (title) |v| priv.title = glib.ext.dupeZ(u8, v);
|
||||||
self.as(gobject.Object).notifyByPspec(properties.title.impl.param_spec);
|
self.as(gobject.Object).notifyByPspec(properties.title.impl.param_spec);
|
||||||
@@ -1584,7 +1584,7 @@ pub const Surface = extern struct {
|
|||||||
/// unless this is unset (null).
|
/// unless this is unset (null).
|
||||||
pub fn setTitleOverride(self: *Self, title: ?[:0]const u8) void {
|
pub fn setTitleOverride(self: *Self, title: ?[:0]const u8) void {
|
||||||
const priv = self.private();
|
const priv = self.private();
|
||||||
if (priv.title_override) |v| glib.free(@constCast(@ptrCast(v)));
|
if (priv.title_override) |v| glib.free(@ptrCast(@constCast(v)));
|
||||||
priv.title_override = null;
|
priv.title_override = null;
|
||||||
if (title) |v| priv.title_override = glib.ext.dupeZ(u8, v);
|
if (title) |v| priv.title_override = glib.ext.dupeZ(u8, v);
|
||||||
self.as(gobject.Object).notifyByPspec(properties.@"title-override".impl.param_spec);
|
self.as(gobject.Object).notifyByPspec(properties.@"title-override".impl.param_spec);
|
||||||
@@ -1598,7 +1598,7 @@ pub const Surface = extern struct {
|
|||||||
/// Set the pwd for this surface, copies the value.
|
/// Set the pwd for this surface, copies the value.
|
||||||
pub fn setPwd(self: *Self, pwd: ?[:0]const u8) void {
|
pub fn setPwd(self: *Self, pwd: ?[:0]const u8) void {
|
||||||
const priv = self.private();
|
const priv = self.private();
|
||||||
if (priv.pwd) |v| glib.free(@constCast(@ptrCast(v)));
|
if (priv.pwd) |v| glib.free(@ptrCast(@constCast(v)));
|
||||||
priv.pwd = null;
|
priv.pwd = null;
|
||||||
if (pwd) |v| priv.pwd = glib.ext.dupeZ(u8, v);
|
if (pwd) |v| priv.pwd = glib.ext.dupeZ(u8, v);
|
||||||
self.as(gobject.Object).notifyByPspec(properties.pwd.impl.param_spec);
|
self.as(gobject.Object).notifyByPspec(properties.pwd.impl.param_spec);
|
||||||
@@ -1683,7 +1683,7 @@ pub const Surface = extern struct {
|
|||||||
|
|
||||||
pub fn setMouseHoverUrl(self: *Self, url: ?[:0]const u8) void {
|
pub fn setMouseHoverUrl(self: *Self, url: ?[:0]const u8) void {
|
||||||
const priv = self.private();
|
const priv = self.private();
|
||||||
if (priv.mouse_hover_url) |v| glib.free(@constCast(@ptrCast(v)));
|
if (priv.mouse_hover_url) |v| glib.free(@ptrCast(@constCast(v)));
|
||||||
priv.mouse_hover_url = null;
|
priv.mouse_hover_url = null;
|
||||||
if (url) |v| priv.mouse_hover_url = glib.ext.dupeZ(u8, v);
|
if (url) |v| priv.mouse_hover_url = glib.ext.dupeZ(u8, v);
|
||||||
self.as(gobject.Object).notifyByPspec(properties.@"mouse-hover-url".impl.param_spec);
|
self.as(gobject.Object).notifyByPspec(properties.@"mouse-hover-url".impl.param_spec);
|
||||||
|
@@ -136,7 +136,7 @@ pub const SurfaceTitleDialog = extern struct {
|
|||||||
fn finalize(self: *Self) callconv(.c) void {
|
fn finalize(self: *Self) callconv(.c) void {
|
||||||
const priv = self.private();
|
const priv = self.private();
|
||||||
if (priv.initial_value) |v| {
|
if (priv.initial_value) |v| {
|
||||||
glib.free(@constCast(@ptrCast(v)));
|
glib.free(@ptrCast(@constCast(v)));
|
||||||
priv.initial_value = null;
|
priv.initial_value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -270,11 +270,11 @@ pub const Tab = extern struct {
|
|||||||
fn finalize(self: *Self) callconv(.c) void {
|
fn finalize(self: *Self) callconv(.c) void {
|
||||||
const priv = self.private();
|
const priv = self.private();
|
||||||
if (priv.tooltip) |v| {
|
if (priv.tooltip) |v| {
|
||||||
glib.free(@constCast(@ptrCast(v)));
|
glib.free(@ptrCast(@constCast(v)));
|
||||||
priv.tooltip = null;
|
priv.tooltip = null;
|
||||||
}
|
}
|
||||||
if (priv.title) |v| {
|
if (priv.title) |v| {
|
||||||
glib.free(@constCast(@ptrCast(v)));
|
glib.free(@ptrCast(@constCast(v)));
|
||||||
priv.title = null;
|
priv.title = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -477,7 +477,7 @@ pub fn addOptions(self: *const Config, step: *std.Build.Step.Options) !void {
|
|||||||
step.addOption(std.SemanticVersion, "app_version", self.version);
|
step.addOption(std.SemanticVersion, "app_version", self.version);
|
||||||
step.addOption([:0]const u8, "app_version_string", try std.fmt.bufPrintZ(
|
step.addOption([:0]const u8, "app_version_string", try std.fmt.bufPrintZ(
|
||||||
&buf,
|
&buf,
|
||||||
"{}",
|
"{f}",
|
||||||
.{self.version},
|
.{self.version},
|
||||||
));
|
));
|
||||||
step.addOption(
|
step.addOption(
|
||||||
|
@@ -11,8 +11,8 @@ pub fn init(
|
|||||||
b: *std.Build,
|
b: *std.Build,
|
||||||
deps: *const SharedDeps,
|
deps: *const SharedDeps,
|
||||||
) !GhosttyBench {
|
) !GhosttyBench {
|
||||||
var steps = std.ArrayList(*std.Build.Step.Compile).init(b.allocator);
|
var steps: std.ArrayList(*std.Build.Step.Compile) = .empty;
|
||||||
errdefer steps.deinit();
|
errdefer steps.deinit(b.allocator);
|
||||||
|
|
||||||
// Our synthetic data generator
|
// Our synthetic data generator
|
||||||
{
|
{
|
||||||
@@ -28,7 +28,7 @@ pub fn init(
|
|||||||
});
|
});
|
||||||
exe.linkLibC();
|
exe.linkLibC();
|
||||||
_ = try deps.add(exe);
|
_ = try deps.add(exe);
|
||||||
try steps.append(exe);
|
try steps.append(b.allocator, exe);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Our benchmarking application.
|
// Our benchmarking application.
|
||||||
@@ -44,7 +44,7 @@ pub fn init(
|
|||||||
});
|
});
|
||||||
exe.linkLibC();
|
exe.linkLibC();
|
||||||
_ = try deps.add(exe);
|
_ = try deps.add(exe);
|
||||||
try steps.append(exe);
|
try steps.append(b.allocator, exe);
|
||||||
}
|
}
|
||||||
|
|
||||||
return .{ .steps = steps.items };
|
return .{ .steps = steps.items };
|
||||||
|
@@ -38,10 +38,10 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyDist {
|
|||||||
|
|
||||||
// embed the Ghostty version in the tarball
|
// embed the Ghostty version in the tarball
|
||||||
{
|
{
|
||||||
const version = b.addWriteFiles().add("VERSION", b.fmt("{}", .{cfg.version}));
|
const version = b.addWriteFiles().add("VERSION", b.fmt("{f}", .{cfg.version}));
|
||||||
// --add-file uses the most recent --prefix to determine the path
|
// --add-file uses the most recent --prefix to determine the path
|
||||||
// in the archive to copy the file (the directory only).
|
// in the archive to copy the file (the directory only).
|
||||||
git_archive.addArg(b.fmt("--prefix=ghostty-{}/", .{
|
git_archive.addArg(b.fmt("--prefix=ghostty-{f}/", .{
|
||||||
cfg.version,
|
cfg.version,
|
||||||
}));
|
}));
|
||||||
git_archive.addPrefixedFileArg("--add-file=", version);
|
git_archive.addPrefixedFileArg("--add-file=", version);
|
||||||
@@ -60,7 +60,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyDist {
|
|||||||
|
|
||||||
// --add-file uses the most recent --prefix to determine the path
|
// --add-file uses the most recent --prefix to determine the path
|
||||||
// in the archive to copy the file (the directory only).
|
// in the archive to copy the file (the directory only).
|
||||||
git_archive.addArg(b.fmt("--prefix=ghostty-{}/{s}/", .{
|
git_archive.addArg(b.fmt("--prefix=ghostty-{f}/{s}/", .{
|
||||||
cfg.version,
|
cfg.version,
|
||||||
std.fs.path.dirname(resource.dist).?,
|
std.fs.path.dirname(resource.dist).?,
|
||||||
}));
|
}));
|
||||||
@@ -72,11 +72,11 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyDist {
|
|||||||
// This is important. Standard source tarballs extract into
|
// This is important. Standard source tarballs extract into
|
||||||
// a directory named `project-version`. This is expected by
|
// a directory named `project-version`. This is expected by
|
||||||
// standard tooling such as debhelper and rpmbuild.
|
// standard tooling such as debhelper and rpmbuild.
|
||||||
b.fmt("--prefix=ghostty-{}/", .{cfg.version}),
|
b.fmt("--prefix=ghostty-{f}/", .{cfg.version}),
|
||||||
"-o",
|
"-o",
|
||||||
});
|
});
|
||||||
const output = git_archive.addOutputFileArg(b.fmt(
|
const output = git_archive.addOutputFileArg(b.fmt(
|
||||||
"ghostty-{}.tar.gz",
|
"ghostty-{f}.tar.gz",
|
||||||
.{cfg.version},
|
.{cfg.version},
|
||||||
));
|
));
|
||||||
git_archive.addArg("HEAD");
|
git_archive.addArg("HEAD");
|
||||||
@@ -84,7 +84,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyDist {
|
|||||||
// The install step to put the dist into the build directory.
|
// The install step to put the dist into the build directory.
|
||||||
const install = b.addInstallFile(
|
const install = b.addInstallFile(
|
||||||
output,
|
output,
|
||||||
b.fmt("dist/ghostty-{}.tar.gz", .{cfg.version}),
|
b.fmt("dist/ghostty-{f}.tar.gz", .{cfg.version}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// The check step to ensure the archive works.
|
// The check step to ensure the archive works.
|
||||||
@@ -96,7 +96,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyDist {
|
|||||||
// i.e. this is way `build.zig` is.
|
// i.e. this is way `build.zig` is.
|
||||||
const extract_dir = check
|
const extract_dir = check
|
||||||
.addOutputDirectoryArg("ghostty")
|
.addOutputDirectoryArg("ghostty")
|
||||||
.path(b, b.fmt("ghostty-{}", .{cfg.version}));
|
.path(b, b.fmt("ghostty-{f}", .{cfg.version}));
|
||||||
|
|
||||||
// Check that tests pass within the extracted directory. This isn't
|
// Check that tests pass within the extracted directory. This isn't
|
||||||
// a fully hermetic test because we're sharing the Zig cache. In
|
// a fully hermetic test because we're sharing the Zig cache. In
|
||||||
|
@@ -12,8 +12,8 @@ pub fn init(
|
|||||||
b: *std.Build,
|
b: *std.Build,
|
||||||
deps: *const SharedDeps,
|
deps: *const SharedDeps,
|
||||||
) !GhosttyDocs {
|
) !GhosttyDocs {
|
||||||
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
|
var steps: std.ArrayList(*std.Build.Step) = .empty;
|
||||||
errdefer steps.deinit();
|
errdefer steps.deinit(b.allocator);
|
||||||
|
|
||||||
const manpages = [_]struct {
|
const manpages = [_]struct {
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
@@ -52,7 +52,7 @@ pub fn init(
|
|||||||
const generate_markdown_step = b.addRunArtifact(generate_markdown);
|
const generate_markdown_step = b.addRunArtifact(generate_markdown);
|
||||||
const markdown_output = generate_markdown_step.captureStdOut();
|
const markdown_output = generate_markdown_step.captureStdOut();
|
||||||
|
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
markdown_output,
|
markdown_output,
|
||||||
"share/ghostty/doc/" ++ manpage.name ++ "." ++ manpage.section ++ ".md",
|
"share/ghostty/doc/" ++ manpage.name ++ "." ++ manpage.section ++ ".md",
|
||||||
).step);
|
).step);
|
||||||
@@ -67,7 +67,7 @@ pub fn init(
|
|||||||
});
|
});
|
||||||
generate_html.addFileArg(markdown_output);
|
generate_html.addFileArg(markdown_output);
|
||||||
|
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
generate_html.captureStdOut(),
|
generate_html.captureStdOut(),
|
||||||
"share/ghostty/doc/" ++ manpage.name ++ "." ++ manpage.section ++ ".html",
|
"share/ghostty/doc/" ++ manpage.name ++ "." ++ manpage.section ++ ".html",
|
||||||
).step);
|
).step);
|
||||||
@@ -82,7 +82,7 @@ pub fn init(
|
|||||||
});
|
});
|
||||||
generate_manpage.addFileArg(markdown_output);
|
generate_manpage.addFileArg(markdown_output);
|
||||||
|
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
generate_manpage.captureStdOut(),
|
generate_manpage.captureStdOut(),
|
||||||
"share/man/man" ++ manpage.section ++ "/" ++ manpage.name ++ "." ++ manpage.section,
|
"share/man/man" ++ manpage.section ++ "/" ++ manpage.name ++ "." ++ manpage.section,
|
||||||
).step);
|
).step);
|
||||||
|
@@ -18,8 +18,8 @@ update_step: *std.Build.Step,
|
|||||||
pub fn init(b: *std.Build, cfg: *const Config) !GhosttyI18n {
|
pub fn init(b: *std.Build, cfg: *const Config) !GhosttyI18n {
|
||||||
_ = cfg;
|
_ = cfg;
|
||||||
|
|
||||||
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
|
var steps: std.ArrayList(*std.Build.Step) = .empty;
|
||||||
defer steps.deinit();
|
defer steps.deinit(b.allocator);
|
||||||
|
|
||||||
inline for (locales) |locale| {
|
inline for (locales) |locale| {
|
||||||
// There is no encoding suffix in the LC_MESSAGES path on FreeBSD,
|
// There is no encoding suffix in the LC_MESSAGES path on FreeBSD,
|
||||||
@@ -33,7 +33,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyI18n {
|
|||||||
const msgfmt = b.addSystemCommand(&.{ "msgfmt", "-o", "-" });
|
const msgfmt = b.addSystemCommand(&.{ "msgfmt", "-o", "-" });
|
||||||
msgfmt.addFileArg(b.path("po/" ++ locale ++ ".po"));
|
msgfmt.addFileArg(b.path("po/" ++ locale ++ ".po"));
|
||||||
|
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
msgfmt.captureStdOut(),
|
msgfmt.captureStdOut(),
|
||||||
std.fmt.comptimePrint(
|
std.fmt.comptimePrint(
|
||||||
"share/locale/{s}/LC_MESSAGES/{s}.mo",
|
"share/locale/{s}/LC_MESSAGES/{s}.mo",
|
||||||
@@ -45,7 +45,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyI18n {
|
|||||||
return .{
|
return .{
|
||||||
.owner = b,
|
.owner = b,
|
||||||
.update_step = try createUpdateStep(b),
|
.update_step = try createUpdateStep(b),
|
||||||
.steps = try steps.toOwnedSlice(),
|
.steps = try steps.toOwnedSlice(b.allocator),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -40,7 +40,7 @@ pub fn initStatic(
|
|||||||
// Add our dependencies. Get the list of all static deps so we can
|
// Add our dependencies. Get the list of all static deps so we can
|
||||||
// build a combined archive if necessary.
|
// build a combined archive if necessary.
|
||||||
var lib_list = try deps.add(lib);
|
var lib_list = try deps.add(lib);
|
||||||
try lib_list.append(lib.getEmittedBin());
|
try lib_list.append(b.allocator, lib.getEmittedBin());
|
||||||
|
|
||||||
if (!deps.config.target.result.os.tag.isDarwin()) return .{
|
if (!deps.config.target.result.os.tag.isDarwin()) return .{
|
||||||
.step = &lib.step,
|
.step = &lib.step,
|
||||||
@@ -69,8 +69,9 @@ pub fn initShared(
|
|||||||
b: *std.Build,
|
b: *std.Build,
|
||||||
deps: *const SharedDeps,
|
deps: *const SharedDeps,
|
||||||
) !GhosttyLib {
|
) !GhosttyLib {
|
||||||
const lib = b.addSharedLibrary(.{
|
const lib = b.addLibrary(.{
|
||||||
.name = "ghostty",
|
.name = "ghostty",
|
||||||
|
.linkage = .dynamic,
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/main_c.zig"),
|
.root_source_file = b.path("src/main_c.zig"),
|
||||||
.target = deps.config.target,
|
.target = deps.config.target,
|
||||||
|
@@ -24,8 +24,9 @@ pub fn initShared(
|
|||||||
zig: *const GhosttyZig,
|
zig: *const GhosttyZig,
|
||||||
) !GhosttyLibVt {
|
) !GhosttyLibVt {
|
||||||
const target = zig.vt.resolved_target.?;
|
const target = zig.vt.resolved_target.?;
|
||||||
const lib = b.addSharedLibrary(.{
|
const lib = b.addLibrary(.{
|
||||||
.name = "ghostty-vt",
|
.name = "ghostty-vt",
|
||||||
|
.linkage = .dynamic,
|
||||||
.root_module = zig.vt_c,
|
.root_module = zig.vt_c,
|
||||||
.version = std.SemanticVersion{ .major = 0, .minor = 1, .patch = 0 },
|
.version = std.SemanticVersion{ .major = 0, .minor = 1, .patch = 0 },
|
||||||
});
|
});
|
||||||
|
@@ -10,8 +10,8 @@ const RunStep = std.Build.Step.Run;
|
|||||||
steps: []*std.Build.Step,
|
steps: []*std.Build.Step,
|
||||||
|
|
||||||
pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||||
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
|
var steps: std.ArrayList(*std.Build.Step) = .empty;
|
||||||
errdefer steps.deinit();
|
errdefer steps.deinit(b.allocator);
|
||||||
|
|
||||||
// This is the exe used to generate some build data.
|
// This is the exe used to generate some build data.
|
||||||
const build_data_exe = b.addExecutable(.{
|
const build_data_exe = b.addExecutable(.{
|
||||||
@@ -49,7 +49,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
"share/terminfo/ghostty.terminfo",
|
"share/terminfo/ghostty.terminfo",
|
||||||
);
|
);
|
||||||
|
|
||||||
try steps.append(&source_install.step);
|
try steps.append(b.allocator, &source_install.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Windows doesn't have the binaries below.
|
// Windows doesn't have the binaries below.
|
||||||
@@ -73,7 +73,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
"share/terminfo/ghostty.termcap",
|
"share/terminfo/ghostty.termcap",
|
||||||
);
|
);
|
||||||
|
|
||||||
try steps.append(&cap_install.step);
|
try steps.append(b.allocator, &cap_install.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile the terminfo source into a terminfo database
|
// Compile the terminfo source into a terminfo database
|
||||||
@@ -99,7 +99,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
.{ b.install_path, terminfo_share_dir },
|
.{ b.install_path, terminfo_share_dir },
|
||||||
));
|
));
|
||||||
|
|
||||||
try steps.append(&mkdir_step.step);
|
try steps.append(b.allocator, &mkdir_step.step);
|
||||||
|
|
||||||
// Use cp -R instead of Step.InstallDir because we need to preserve
|
// Use cp -R instead of Step.InstallDir because we need to preserve
|
||||||
// symlinks in the terminfo database. Zig's InstallDir step doesn't
|
// symlinks in the terminfo database. Zig's InstallDir step doesn't
|
||||||
@@ -109,7 +109,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
copy_step.addFileArg(path);
|
copy_step.addFileArg(path);
|
||||||
copy_step.addArg(b.fmt("{s}/share", .{b.install_path}));
|
copy_step.addArg(b.fmt("{s}/share", .{b.install_path}));
|
||||||
copy_step.step.dependOn(&mkdir_step.step);
|
copy_step.step.dependOn(&mkdir_step.step);
|
||||||
try steps.append(©_step.step);
|
try steps.append(b.allocator, ©_step.step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
.install_subdir = b.pathJoin(&.{ "ghostty", "shell-integration" }),
|
.install_subdir = b.pathJoin(&.{ "ghostty", "shell-integration" }),
|
||||||
.exclude_extensions = &.{".md"},
|
.exclude_extensions = &.{".md"},
|
||||||
});
|
});
|
||||||
try steps.append(&install_step.step);
|
try steps.append(b.allocator, &install_step.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Themes
|
// Themes
|
||||||
@@ -132,7 +132,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
.install_subdir = b.pathJoin(&.{ "ghostty", "themes" }),
|
.install_subdir = b.pathJoin(&.{ "ghostty", "themes" }),
|
||||||
.exclude_extensions = &.{".md"},
|
.exclude_extensions = &.{".md"},
|
||||||
});
|
});
|
||||||
try steps.append(&install_step.step);
|
try steps.append(b.allocator, &install_step.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fish shell completions
|
// Fish shell completions
|
||||||
@@ -147,7 +147,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
.install_dir = .prefix,
|
.install_dir = .prefix,
|
||||||
.install_subdir = "share/fish/vendor_completions.d",
|
.install_subdir = "share/fish/vendor_completions.d",
|
||||||
});
|
});
|
||||||
try steps.append(&install_step.step);
|
try steps.append(b.allocator, &install_step.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// zsh shell completions
|
// zsh shell completions
|
||||||
@@ -162,7 +162,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
.install_dir = .prefix,
|
.install_dir = .prefix,
|
||||||
.install_subdir = "share/zsh/site-functions",
|
.install_subdir = "share/zsh/site-functions",
|
||||||
});
|
});
|
||||||
try steps.append(&install_step.step);
|
try steps.append(b.allocator, &install_step.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bash shell completions
|
// bash shell completions
|
||||||
@@ -177,7 +177,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
.install_dir = .prefix,
|
.install_dir = .prefix,
|
||||||
.install_subdir = "share/bash-completion/completions",
|
.install_subdir = "share/bash-completion/completions",
|
||||||
});
|
});
|
||||||
try steps.append(&install_step.step);
|
try steps.append(b.allocator, &install_step.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vim and Neovim plugin
|
// Vim and Neovim plugin
|
||||||
@@ -210,14 +210,14 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
.install_dir = .prefix,
|
.install_dir = .prefix,
|
||||||
.install_subdir = "share/vim/vimfiles",
|
.install_subdir = "share/vim/vimfiles",
|
||||||
});
|
});
|
||||||
try steps.append(&vim_step.step);
|
try steps.append(b.allocator, &vim_step.step);
|
||||||
|
|
||||||
const neovim_step = b.addInstallDirectory(.{
|
const neovim_step = b.addInstallDirectory(.{
|
||||||
.source_dir = wf.getDirectory(),
|
.source_dir = wf.getDirectory(),
|
||||||
.install_dir = .prefix,
|
.install_dir = .prefix,
|
||||||
.install_subdir = "share/nvim/site",
|
.install_subdir = "share/nvim/site",
|
||||||
});
|
});
|
||||||
try steps.append(&neovim_step.step);
|
try steps.append(b.allocator, &neovim_step.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sublime syntax highlighting for bat cli tool
|
// Sublime syntax highlighting for bat cli tool
|
||||||
@@ -237,7 +237,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||||||
.install_dir = .prefix,
|
.install_dir = .prefix,
|
||||||
.install_subdir = "share/bat/syntaxes",
|
.install_subdir = "share/bat/syntaxes",
|
||||||
});
|
});
|
||||||
try steps.append(&install_step.step);
|
try steps.append(b.allocator, &install_step.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// App (Linux)
|
// App (Linux)
|
||||||
@@ -286,16 +286,17 @@ fn addLinuxAppResources(
|
|||||||
// second element of the tuple.
|
// second element of the tuple.
|
||||||
const Template = struct { std.Build.LazyPath, []const u8 };
|
const Template = struct { std.Build.LazyPath, []const u8 };
|
||||||
const templates: []const Template = templates: {
|
const templates: []const Template = templates: {
|
||||||
var ts: std.ArrayList(Template) = .init(b.allocator);
|
var ts: std.ArrayList(Template) = .empty;
|
||||||
|
defer ts.deinit(b.allocator);
|
||||||
|
|
||||||
// Desktop file so that we have an icon and other metadata
|
// Desktop file so that we have an icon and other metadata
|
||||||
try ts.append(.{
|
try ts.append(b.allocator, .{
|
||||||
b.path("dist/linux/app.desktop.in"),
|
b.path("dist/linux/app.desktop.in"),
|
||||||
b.fmt("share/applications/{s}.desktop", .{app_id}),
|
b.fmt("share/applications/{s}.desktop", .{app_id}),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Service for DBus activation.
|
// Service for DBus activation.
|
||||||
try ts.append(.{
|
try ts.append(b.allocator, .{
|
||||||
if (cfg.flatpak)
|
if (cfg.flatpak)
|
||||||
b.path("dist/linux/dbus.service.flatpak.in")
|
b.path("dist/linux/dbus.service.flatpak.in")
|
||||||
else
|
else
|
||||||
@@ -320,7 +321,7 @@ fn addLinuxAppResources(
|
|||||||
// See the following code:
|
// See the following code:
|
||||||
//
|
//
|
||||||
// https://github.com/flatpak/xdg-desktop-portal/blob/7d4d48cf079147c8887da17ec6c3954acd5a285c/src/xdp-utils.c#L152-L220
|
// https://github.com/flatpak/xdg-desktop-portal/blob/7d4d48cf079147c8887da17ec6c3954acd5a285c/src/xdp-utils.c#L152-L220
|
||||||
if (!cfg.flatpak) try ts.append(.{
|
if (!cfg.flatpak) try ts.append(b.allocator, .{
|
||||||
b.path("dist/linux/systemd.service.in"),
|
b.path("dist/linux/systemd.service.in"),
|
||||||
b.fmt(
|
b.fmt(
|
||||||
"{s}/systemd/user/app-{s}.service",
|
"{s}/systemd/user/app-{s}.service",
|
||||||
@@ -333,12 +334,12 @@ fn addLinuxAppResources(
|
|||||||
|
|
||||||
// AppStream metainfo so that application has rich metadata
|
// AppStream metainfo so that application has rich metadata
|
||||||
// within app stores
|
// within app stores
|
||||||
try ts.append(.{
|
try ts.append(b.allocator, .{
|
||||||
b.path("dist/linux/com.mitchellh.ghostty.metainfo.xml.in"),
|
b.path("dist/linux/com.mitchellh.ghostty.metainfo.xml.in"),
|
||||||
b.fmt("share/metainfo/{s}.metainfo.xml", .{app_id}),
|
b.fmt("share/metainfo/{s}.metainfo.xml", .{app_id}),
|
||||||
});
|
});
|
||||||
|
|
||||||
break :templates ts.items;
|
break :templates try ts.toOwnedSlice(b.allocator);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Process all our templates
|
// Process all our templates
|
||||||
@@ -361,65 +362,65 @@ fn addLinuxAppResources(
|
|||||||
template[1],
|
template[1],
|
||||||
);
|
);
|
||||||
|
|
||||||
try steps.append(©.step);
|
try steps.append(b.allocator, ©.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right click menu action for Plasma desktop
|
// Right click menu action for Plasma desktop
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
b.path("dist/linux/ghostty_dolphin.desktop"),
|
b.path("dist/linux/ghostty_dolphin.desktop"),
|
||||||
"share/kio/servicemenus/com.mitchellh.ghostty.desktop",
|
"share/kio/servicemenus/com.mitchellh.ghostty.desktop",
|
||||||
).step);
|
).step);
|
||||||
|
|
||||||
// Right click menu action for Nautilus. Note that this _must_ be named
|
// Right click menu action for Nautilus. Note that this _must_ be named
|
||||||
// `ghostty.py`. Using the full app id causes problems (see #5468).
|
// `ghostty.py`. Using the full app id causes problems (see #5468).
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
b.path("dist/linux/ghostty_nautilus.py"),
|
b.path("dist/linux/ghostty_nautilus.py"),
|
||||||
"share/nautilus-python/extensions/ghostty.py",
|
"share/nautilus-python/extensions/ghostty.py",
|
||||||
).step);
|
).step);
|
||||||
|
|
||||||
// Various icons that our application can use, including the icon
|
// Various icons that our application can use, including the icon
|
||||||
// that will be used for the desktop.
|
// that will be used for the desktop.
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
b.path("images/gnome/16.png"),
|
b.path("images/gnome/16.png"),
|
||||||
"share/icons/hicolor/16x16/apps/com.mitchellh.ghostty.png",
|
"share/icons/hicolor/16x16/apps/com.mitchellh.ghostty.png",
|
||||||
).step);
|
).step);
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
b.path("images/gnome/32.png"),
|
b.path("images/gnome/32.png"),
|
||||||
"share/icons/hicolor/32x32/apps/com.mitchellh.ghostty.png",
|
"share/icons/hicolor/32x32/apps/com.mitchellh.ghostty.png",
|
||||||
).step);
|
).step);
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
b.path("images/gnome/128.png"),
|
b.path("images/gnome/128.png"),
|
||||||
"share/icons/hicolor/128x128/apps/com.mitchellh.ghostty.png",
|
"share/icons/hicolor/128x128/apps/com.mitchellh.ghostty.png",
|
||||||
).step);
|
).step);
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
b.path("images/gnome/256.png"),
|
b.path("images/gnome/256.png"),
|
||||||
"share/icons/hicolor/256x256/apps/com.mitchellh.ghostty.png",
|
"share/icons/hicolor/256x256/apps/com.mitchellh.ghostty.png",
|
||||||
).step);
|
).step);
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
b.path("images/gnome/512.png"),
|
b.path("images/gnome/512.png"),
|
||||||
"share/icons/hicolor/512x512/apps/com.mitchellh.ghostty.png",
|
"share/icons/hicolor/512x512/apps/com.mitchellh.ghostty.png",
|
||||||
).step);
|
).step);
|
||||||
// Flatpaks only support icons up to 512x512.
|
// Flatpaks only support icons up to 512x512.
|
||||||
if (!cfg.flatpak) {
|
if (!cfg.flatpak) {
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
b.path("images/gnome/1024.png"),
|
b.path("images/gnome/1024.png"),
|
||||||
"share/icons/hicolor/1024x1024/apps/com.mitchellh.ghostty.png",
|
"share/icons/hicolor/1024x1024/apps/com.mitchellh.ghostty.png",
|
||||||
).step);
|
).step);
|
||||||
}
|
}
|
||||||
|
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
b.path("images/gnome/32.png"),
|
b.path("images/gnome/32.png"),
|
||||||
"share/icons/hicolor/16x16@2/apps/com.mitchellh.ghostty.png",
|
"share/icons/hicolor/16x16@2/apps/com.mitchellh.ghostty.png",
|
||||||
).step);
|
).step);
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
b.path("images/gnome/64.png"),
|
b.path("images/gnome/64.png"),
|
||||||
"share/icons/hicolor/32x32@2/apps/com.mitchellh.ghostty.png",
|
"share/icons/hicolor/32x32@2/apps/com.mitchellh.ghostty.png",
|
||||||
).step);
|
).step);
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
b.path("images/gnome/256.png"),
|
b.path("images/gnome/256.png"),
|
||||||
"share/icons/hicolor/128x128@2/apps/com.mitchellh.ghostty.png",
|
"share/icons/hicolor/128x128@2/apps/com.mitchellh.ghostty.png",
|
||||||
).step);
|
).step);
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
b.path("images/gnome/512.png"),
|
b.path("images/gnome/512.png"),
|
||||||
"share/icons/hicolor/256x256@2/apps/com.mitchellh.ghostty.png",
|
"share/icons/hicolor/256x256@2/apps/com.mitchellh.ghostty.png",
|
||||||
).step);
|
).step);
|
||||||
|
@@ -12,8 +12,8 @@ pub fn init(
|
|||||||
b: *std.Build,
|
b: *std.Build,
|
||||||
deps: *const SharedDeps,
|
deps: *const SharedDeps,
|
||||||
) !GhosttyWebdata {
|
) !GhosttyWebdata {
|
||||||
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
|
var steps: std.ArrayList(*std.Build.Step) = .empty;
|
||||||
errdefer steps.deinit();
|
errdefer steps.deinit(b.allocator);
|
||||||
|
|
||||||
{
|
{
|
||||||
const webgen_config = b.addExecutable(.{
|
const webgen_config = b.addExecutable(.{
|
||||||
@@ -43,7 +43,7 @@ pub fn init(
|
|||||||
const webgen_config_step = b.addRunArtifact(webgen_config);
|
const webgen_config_step = b.addRunArtifact(webgen_config);
|
||||||
const webgen_config_out = webgen_config_step.captureStdOut();
|
const webgen_config_out = webgen_config_step.captureStdOut();
|
||||||
|
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
webgen_config_out,
|
webgen_config_out,
|
||||||
"share/ghostty/webdata/config.mdx",
|
"share/ghostty/webdata/config.mdx",
|
||||||
).step);
|
).step);
|
||||||
@@ -52,8 +52,10 @@ pub fn init(
|
|||||||
{
|
{
|
||||||
const webgen_actions = b.addExecutable(.{
|
const webgen_actions = b.addExecutable(.{
|
||||||
.name = "webgen_actions",
|
.name = "webgen_actions",
|
||||||
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.root_source_file = b.path("src/main.zig"),
|
||||||
.target = b.graph.host,
|
.target = b.graph.host,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
deps.help_strings.addImport(webgen_actions);
|
deps.help_strings.addImport(webgen_actions);
|
||||||
|
|
||||||
@@ -72,7 +74,7 @@ pub fn init(
|
|||||||
const webgen_actions_step = b.addRunArtifact(webgen_actions);
|
const webgen_actions_step = b.addRunArtifact(webgen_actions);
|
||||||
const webgen_actions_out = webgen_actions_step.captureStdOut();
|
const webgen_actions_out = webgen_actions_step.captureStdOut();
|
||||||
|
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
webgen_actions_out,
|
webgen_actions_out,
|
||||||
"share/ghostty/webdata/actions.mdx",
|
"share/ghostty/webdata/actions.mdx",
|
||||||
).step);
|
).step);
|
||||||
@@ -81,8 +83,10 @@ pub fn init(
|
|||||||
{
|
{
|
||||||
const webgen_commands = b.addExecutable(.{
|
const webgen_commands = b.addExecutable(.{
|
||||||
.name = "webgen_commands",
|
.name = "webgen_commands",
|
||||||
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.root_source_file = b.path("src/main.zig"),
|
||||||
.target = b.graph.host,
|
.target = b.graph.host,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
deps.help_strings.addImport(webgen_commands);
|
deps.help_strings.addImport(webgen_commands);
|
||||||
|
|
||||||
@@ -101,7 +105,7 @@ pub fn init(
|
|||||||
const webgen_commands_step = b.addRunArtifact(webgen_commands);
|
const webgen_commands_step = b.addRunArtifact(webgen_commands);
|
||||||
const webgen_commands_out = webgen_commands_step.captureStdOut();
|
const webgen_commands_out = webgen_commands_step.captureStdOut();
|
||||||
|
|
||||||
try steps.append(&b.addInstallFile(
|
try steps.append(b.allocator, &b.addInstallFile(
|
||||||
webgen_commands_out,
|
webgen_commands_out,
|
||||||
"share/ghostty/webdata/commands.mdx",
|
"share/ghostty/webdata/commands.mdx",
|
||||||
).step);
|
).step);
|
||||||
|
@@ -44,7 +44,7 @@ pub fn create(b: *std.Build, opts: Options) ?*MetallibStep {
|
|||||||
const self = b.allocator.create(MetallibStep) catch @panic("OOM");
|
const self = b.allocator.create(MetallibStep) catch @panic("OOM");
|
||||||
|
|
||||||
const min_version = if (opts.target.query.os_version_min) |v|
|
const min_version = if (opts.target.query.os_version_min) |v|
|
||||||
b.fmt("{}", .{v.semver})
|
b.fmt("{f}", .{v.semver})
|
||||||
else switch (opts.target.result.os.tag) {
|
else switch (opts.target.result.os.tag) {
|
||||||
.macos => "10.14",
|
.macos => "10.14",
|
||||||
.ios => "11.0",
|
.ios => "11.0",
|
||||||
|
@@ -113,8 +113,8 @@ pub fn add(
|
|||||||
|
|
||||||
// We maintain a list of our static libraries and return it so that
|
// We maintain a list of our static libraries and return it so that
|
||||||
// we can build a single fat static library for the final app.
|
// we can build a single fat static library for the final app.
|
||||||
var static_libs = LazyPathList.init(b.allocator);
|
var static_libs: LazyPathList = .empty;
|
||||||
errdefer static_libs.deinit();
|
errdefer static_libs.deinit(b.allocator);
|
||||||
|
|
||||||
// WARNING: This is a hack!
|
// WARNING: This is a hack!
|
||||||
// If we're cross-compiling to Darwin then we don't add any deps.
|
// If we're cross-compiling to Darwin then we don't add any deps.
|
||||||
@@ -154,6 +154,7 @@ pub fn add(
|
|||||||
} else {
|
} else {
|
||||||
step.linkLibrary(freetype_dep.artifact("freetype"));
|
step.linkLibrary(freetype_dep.artifact("freetype"));
|
||||||
try static_libs.append(
|
try static_libs.append(
|
||||||
|
b.allocator,
|
||||||
freetype_dep.artifact("freetype").getEmittedBin(),
|
freetype_dep.artifact("freetype").getEmittedBin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -178,6 +179,7 @@ pub fn add(
|
|||||||
} else {
|
} else {
|
||||||
step.linkLibrary(harfbuzz_dep.artifact("harfbuzz"));
|
step.linkLibrary(harfbuzz_dep.artifact("harfbuzz"));
|
||||||
try static_libs.append(
|
try static_libs.append(
|
||||||
|
b.allocator,
|
||||||
harfbuzz_dep.artifact("harfbuzz").getEmittedBin(),
|
harfbuzz_dep.artifact("harfbuzz").getEmittedBin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -201,6 +203,7 @@ pub fn add(
|
|||||||
} else {
|
} else {
|
||||||
step.linkLibrary(fontconfig_dep.artifact("fontconfig"));
|
step.linkLibrary(fontconfig_dep.artifact("fontconfig"));
|
||||||
try static_libs.append(
|
try static_libs.append(
|
||||||
|
b.allocator,
|
||||||
fontconfig_dep.artifact("fontconfig").getEmittedBin(),
|
fontconfig_dep.artifact("fontconfig").getEmittedBin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -218,6 +221,7 @@ pub fn add(
|
|||||||
})) |libpng_dep| {
|
})) |libpng_dep| {
|
||||||
step.linkLibrary(libpng_dep.artifact("png"));
|
step.linkLibrary(libpng_dep.artifact("png"));
|
||||||
try static_libs.append(
|
try static_libs.append(
|
||||||
|
b.allocator,
|
||||||
libpng_dep.artifact("png").getEmittedBin(),
|
libpng_dep.artifact("png").getEmittedBin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -231,6 +235,7 @@ pub fn add(
|
|||||||
})) |zlib_dep| {
|
})) |zlib_dep| {
|
||||||
step.linkLibrary(zlib_dep.artifact("z"));
|
step.linkLibrary(zlib_dep.artifact("z"));
|
||||||
try static_libs.append(
|
try static_libs.append(
|
||||||
|
b.allocator,
|
||||||
zlib_dep.artifact("z").getEmittedBin(),
|
zlib_dep.artifact("z").getEmittedBin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -250,6 +255,7 @@ pub fn add(
|
|||||||
} else {
|
} else {
|
||||||
step.linkLibrary(oniguruma_dep.artifact("oniguruma"));
|
step.linkLibrary(oniguruma_dep.artifact("oniguruma"));
|
||||||
try static_libs.append(
|
try static_libs.append(
|
||||||
|
b.allocator,
|
||||||
oniguruma_dep.artifact("oniguruma").getEmittedBin(),
|
oniguruma_dep.artifact("oniguruma").getEmittedBin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -270,6 +276,7 @@ pub fn add(
|
|||||||
} else {
|
} else {
|
||||||
step.linkLibrary(glslang_dep.artifact("glslang"));
|
step.linkLibrary(glslang_dep.artifact("glslang"));
|
||||||
try static_libs.append(
|
try static_libs.append(
|
||||||
|
b.allocator,
|
||||||
glslang_dep.artifact("glslang").getEmittedBin(),
|
glslang_dep.artifact("glslang").getEmittedBin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -289,6 +296,7 @@ pub fn add(
|
|||||||
} else {
|
} else {
|
||||||
step.linkLibrary(spirv_cross_dep.artifact("spirv_cross"));
|
step.linkLibrary(spirv_cross_dep.artifact("spirv_cross"));
|
||||||
try static_libs.append(
|
try static_libs.append(
|
||||||
|
b.allocator,
|
||||||
spirv_cross_dep.artifact("spirv_cross").getEmittedBin(),
|
spirv_cross_dep.artifact("spirv_cross").getEmittedBin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -307,6 +315,7 @@ pub fn add(
|
|||||||
);
|
);
|
||||||
step.linkLibrary(sentry_dep.artifact("sentry"));
|
step.linkLibrary(sentry_dep.artifact("sentry"));
|
||||||
try static_libs.append(
|
try static_libs.append(
|
||||||
|
b.allocator,
|
||||||
sentry_dep.artifact("sentry").getEmittedBin(),
|
sentry_dep.artifact("sentry").getEmittedBin(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -316,6 +325,7 @@ pub fn add(
|
|||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
})) |breakpad_dep| {
|
})) |breakpad_dep| {
|
||||||
try static_libs.append(
|
try static_libs.append(
|
||||||
|
b.allocator,
|
||||||
breakpad_dep.artifact("breakpad").getEmittedBin(),
|
breakpad_dep.artifact("breakpad").getEmittedBin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -443,6 +453,7 @@ pub fn add(
|
|||||||
macos_dep.artifact("macos"),
|
macos_dep.artifact("macos"),
|
||||||
);
|
);
|
||||||
try static_libs.append(
|
try static_libs.append(
|
||||||
|
b.allocator,
|
||||||
macos_dep.artifact("macos").getEmittedBin(),
|
macos_dep.artifact("macos").getEmittedBin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -461,6 +472,7 @@ pub fn add(
|
|||||||
})) |libintl_dep| {
|
})) |libintl_dep| {
|
||||||
step.linkLibrary(libintl_dep.artifact("intl"));
|
step.linkLibrary(libintl_dep.artifact("intl"));
|
||||||
try static_libs.append(
|
try static_libs.append(
|
||||||
|
b.allocator,
|
||||||
libintl_dep.artifact("intl").getEmittedBin(),
|
libintl_dep.artifact("intl").getEmittedBin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -473,7 +485,10 @@ pub fn add(
|
|||||||
})) |cimgui_dep| {
|
})) |cimgui_dep| {
|
||||||
step.root_module.addImport("cimgui", cimgui_dep.module("cimgui"));
|
step.root_module.addImport("cimgui", cimgui_dep.module("cimgui"));
|
||||||
step.linkLibrary(cimgui_dep.artifact("cimgui"));
|
step.linkLibrary(cimgui_dep.artifact("cimgui"));
|
||||||
try static_libs.append(cimgui_dep.artifact("cimgui").getEmittedBin());
|
try static_libs.append(
|
||||||
|
b.allocator,
|
||||||
|
cimgui_dep.artifact("cimgui").getEmittedBin(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fonts
|
// Fonts
|
||||||
@@ -697,6 +712,7 @@ pub fn addSimd(
|
|||||||
})) |simdutf_dep| {
|
})) |simdutf_dep| {
|
||||||
m.linkLibrary(simdutf_dep.artifact("simdutf"));
|
m.linkLibrary(simdutf_dep.artifact("simdutf"));
|
||||||
if (static_libs) |v| try v.append(
|
if (static_libs) |v| try v.append(
|
||||||
|
b.allocator,
|
||||||
simdutf_dep.artifact("simdutf").getEmittedBin(),
|
simdutf_dep.artifact("simdutf").getEmittedBin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -708,7 +724,10 @@ pub fn addSimd(
|
|||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
})) |highway_dep| {
|
})) |highway_dep| {
|
||||||
m.linkLibrary(highway_dep.artifact("highway"));
|
m.linkLibrary(highway_dep.artifact("highway"));
|
||||||
if (static_libs) |v| try v.append(highway_dep.artifact("highway").getEmittedBin());
|
if (static_libs) |v| try v.append(
|
||||||
|
b.allocator,
|
||||||
|
highway_dep.artifact("highway").getEmittedBin(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// utfcpp - This is used as a dependency on our hand-written C++ code
|
// utfcpp - This is used as a dependency on our hand-written C++ code
|
||||||
@@ -717,7 +736,10 @@ pub fn addSimd(
|
|||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
})) |utfcpp_dep| {
|
})) |utfcpp_dep| {
|
||||||
m.linkLibrary(utfcpp_dep.artifact("utfcpp"));
|
m.linkLibrary(utfcpp_dep.artifact("utfcpp"));
|
||||||
if (static_libs) |v| try v.append(utfcpp_dep.artifact("utfcpp").getEmittedBin());
|
if (static_libs) |v| try v.append(
|
||||||
|
b.allocator,
|
||||||
|
utfcpp_dep.artifact("utfcpp").getEmittedBin(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SIMD C++ files
|
// SIMD C++ files
|
||||||
@@ -761,16 +783,20 @@ pub fn gtkNgDistResources(
|
|||||||
const gresource_xml = gresource_xml: {
|
const gresource_xml = gresource_xml: {
|
||||||
const xml_exe = b.addExecutable(.{
|
const xml_exe = b.addExecutable(.{
|
||||||
.name = "generate_gresource_xml",
|
.name = "generate_gresource_xml",
|
||||||
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/apprt/gtk/build/gresource.zig"),
|
.root_source_file = b.path("src/apprt/gtk/build/gresource.zig"),
|
||||||
.target = b.graph.host,
|
.target = b.graph.host,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
const xml_run = b.addRunArtifact(xml_exe);
|
const xml_run = b.addRunArtifact(xml_exe);
|
||||||
|
|
||||||
// Run our blueprint compiler across all of our blueprint files.
|
// Run our blueprint compiler across all of our blueprint files.
|
||||||
const blueprint_exe = b.addExecutable(.{
|
const blueprint_exe = b.addExecutable(.{
|
||||||
.name = "gtk_blueprint_compiler",
|
.name = "gtk_blueprint_compiler",
|
||||||
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/apprt/gtk/build/blueprint.zig"),
|
.root_source_file = b.path("src/apprt/gtk/build/blueprint.zig"),
|
||||||
.target = b.graph.host,
|
.target = b.graph.host,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
blueprint_exe.linkLibC();
|
blueprint_exe.linkLibC();
|
||||||
blueprint_exe.linkSystemLibrary2("gtk4", dynamic_link_opts);
|
blueprint_exe.linkSystemLibrary2("gtk4", dynamic_link_opts);
|
||||||
|
@@ -21,6 +21,9 @@ pub fn init(b: *std.Build, uucode_tables: std.Build.LazyPath) !UnicodeTables {
|
|||||||
.omit_frame_pointer = false,
|
.omit_frame_pointer = false,
|
||||||
.unwind_tables = .sync,
|
.unwind_tables = .sync,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
// TODO: x86_64 self-hosted crashes
|
||||||
|
.use_llvm = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const symbols_exe = b.addExecutable(.{
|
const symbols_exe = b.addExecutable(.{
|
||||||
@@ -32,6 +35,9 @@ pub fn init(b: *std.Build, uucode_tables: std.Build.LazyPath) !UnicodeTables {
|
|||||||
.omit_frame_pointer = false,
|
.omit_frame_pointer = false,
|
||||||
.unwind_tables = .sync,
|
.unwind_tables = .sync,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
// TODO: x86_64 self-hosted crashes
|
||||||
|
.use_llvm = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (b.lazyDependency("uucode", .{
|
if (b.lazyDependency("uucode", .{
|
||||||
|
@@ -324,7 +324,7 @@ pub fn parseIntoField(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const raw = field.default_value_ptr orelse break :default;
|
const raw = field.default_value_ptr orelse break :default;
|
||||||
const ptr: *const field.type = @alignCast(@ptrCast(raw));
|
const ptr: *const field.type = @ptrCast(@alignCast(raw));
|
||||||
@field(dst, field.name) = ptr.*;
|
@field(dst, field.name) = ptr.*;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -586,7 +586,7 @@ pub fn parseAutoStruct(
|
|||||||
break :default @field(default, field.name);
|
break :default @field(default, field.name);
|
||||||
} else {
|
} else {
|
||||||
const default_ptr = field.default_value_ptr orelse return error.InvalidValue;
|
const default_ptr = field.default_value_ptr orelse return error.InvalidValue;
|
||||||
const typed_ptr: *const field.type = @alignCast(@ptrCast(default_ptr));
|
const typed_ptr: *const field.type = @ptrCast(@alignCast(default_ptr));
|
||||||
break :default typed_ptr.*;
|
break :default typed_ptr.*;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -33,8 +33,13 @@ pub fn HashMap(
|
|||||||
) type {
|
) type {
|
||||||
return struct {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
const Map = std.HashMapUnmanaged(K, *Queue.Node, Context, max_load_percentage);
|
const Queue = std.DoublyLinkedList;
|
||||||
const Queue = std.DoublyLinkedList(KV);
|
const Map = std.HashMapUnmanaged(
|
||||||
|
K,
|
||||||
|
*Entry,
|
||||||
|
Context,
|
||||||
|
max_load_percentage,
|
||||||
|
);
|
||||||
|
|
||||||
/// Map to maintain our entries.
|
/// Map to maintain our entries.
|
||||||
map: Map,
|
map: Map,
|
||||||
@@ -46,6 +51,15 @@ pub fn HashMap(
|
|||||||
/// misses will begin evicting entries.
|
/// misses will begin evicting entries.
|
||||||
capacity: Map.Size,
|
capacity: Map.Size,
|
||||||
|
|
||||||
|
const Entry = struct {
|
||||||
|
data: KV,
|
||||||
|
node: Queue.Node,
|
||||||
|
|
||||||
|
fn fromNode(node: *Queue.Node) *Entry {
|
||||||
|
return @fieldParentPtr("node", node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub const KV = struct {
|
pub const KV = struct {
|
||||||
key: K,
|
key: K,
|
||||||
value: V,
|
value: V,
|
||||||
@@ -82,7 +96,7 @@ pub fn HashMap(
|
|||||||
var it = self.queue.first;
|
var it = self.queue.first;
|
||||||
while (it) |node| {
|
while (it) |node| {
|
||||||
it = node.next;
|
it = node.next;
|
||||||
alloc.destroy(node);
|
alloc.destroy(Entry.fromNode(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.map.deinit(alloc);
|
self.map.deinit(alloc);
|
||||||
@@ -108,8 +122,8 @@ pub fn HashMap(
|
|||||||
const map_gop = try self.map.getOrPutContext(alloc, key, ctx);
|
const map_gop = try self.map.getOrPutContext(alloc, key, ctx);
|
||||||
if (map_gop.found_existing) {
|
if (map_gop.found_existing) {
|
||||||
// Move to end to mark as most recently used
|
// Move to end to mark as most recently used
|
||||||
self.queue.remove(map_gop.value_ptr.*);
|
self.queue.remove(&map_gop.value_ptr.*.node);
|
||||||
self.queue.append(map_gop.value_ptr.*);
|
self.queue.append(&map_gop.value_ptr.*.node);
|
||||||
|
|
||||||
return GetOrPutResult{
|
return GetOrPutResult{
|
||||||
.found_existing = true,
|
.found_existing = true,
|
||||||
@@ -122,37 +136,34 @@ pub fn HashMap(
|
|||||||
// We're evicting if our map insertion increased our capacity.
|
// We're evicting if our map insertion increased our capacity.
|
||||||
const evict = self.map.count() > self.capacity;
|
const evict = self.map.count() > self.capacity;
|
||||||
|
|
||||||
// Get our node. If we're not evicting then we allocate a new
|
// Get our entry. If we're not evicting then we allocate a new
|
||||||
// node. If we are evicting then we avoid allocation by just
|
// entry. If we are evicting then we avoid allocation by just
|
||||||
// reusing the node we would've evicted.
|
// reusing the entry we would've evicted.
|
||||||
var node = if (!evict) try alloc.create(Queue.Node) else node: {
|
const entry: *Entry = if (!evict) try alloc.create(Entry) else entry: {
|
||||||
// Our first node is the least recently used.
|
// Our first node is the least recently used.
|
||||||
const least_used = self.queue.first.?;
|
const least_used_node = self.queue.popFirst().?;
|
||||||
|
const least_used_entry: *Entry = .fromNode(least_used_node);
|
||||||
// Move our least recently used to the end to make
|
|
||||||
// it the most recently used.
|
|
||||||
self.queue.remove(least_used);
|
|
||||||
|
|
||||||
// Remove the least used from the map
|
// Remove the least used from the map
|
||||||
_ = self.map.remove(least_used.data.key);
|
_ = self.map.remove(least_used_entry.data.key);
|
||||||
|
|
||||||
break :node least_used;
|
break :entry least_used_entry;
|
||||||
};
|
};
|
||||||
errdefer if (!evict) alloc.destroy(node);
|
errdefer if (!evict) alloc.destroy(entry);
|
||||||
|
|
||||||
// Store our node in the map.
|
// Store our entry in the map.
|
||||||
map_gop.value_ptr.* = node;
|
map_gop.value_ptr.* = entry;
|
||||||
|
|
||||||
// Mark the node as most recently used
|
// Mark the entry as most recently used
|
||||||
self.queue.append(node);
|
self.queue.append(&entry.node);
|
||||||
|
|
||||||
// Set our key
|
// Set our key
|
||||||
node.data.key = key;
|
entry.data.key = key;
|
||||||
|
|
||||||
return GetOrPutResult{
|
return .{
|
||||||
.found_existing = map_gop.found_existing,
|
.found_existing = map_gop.found_existing,
|
||||||
.value_ptr = &node.data.value,
|
.value_ptr = &entry.data.value,
|
||||||
.evicted = if (!evict) null else node.data,
|
.evicted = if (!evict) null else entry.data,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,11 +204,12 @@ pub fn HashMap(
|
|||||||
|
|
||||||
var i: Map.Size = 0;
|
var i: Map.Size = 0;
|
||||||
while (i < delta) : (i += 1) {
|
while (i < delta) : (i += 1) {
|
||||||
const node = self.queue.first.?;
|
const node = self.queue.popFirst().?;
|
||||||
evicted[i] = node.data.value;
|
const entry: *Entry = .fromNode(node);
|
||||||
|
evicted[i] = entry.data.value;
|
||||||
self.queue.remove(node);
|
self.queue.remove(node);
|
||||||
_ = self.map.remove(node.data.key);
|
_ = self.map.remove(entry.data.key);
|
||||||
alloc.destroy(node);
|
alloc.destroy(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.capacity = capacity;
|
self.capacity = capacity;
|
||||||
|
@@ -14,7 +14,7 @@ pub const CacheTable = cache_table.CacheTable;
|
|||||||
pub const CircBuf = circ_buf.CircBuf;
|
pub const CircBuf = circ_buf.CircBuf;
|
||||||
pub const IntrusiveDoublyLinkedList = intrusive_linked_list.DoublyLinkedList;
|
pub const IntrusiveDoublyLinkedList = intrusive_linked_list.DoublyLinkedList;
|
||||||
pub const SegmentedPool = segmented_pool.SegmentedPool;
|
pub const SegmentedPool = segmented_pool.SegmentedPool;
|
||||||
pub const SplitTree = split_tree.SplitTree;
|
//pub const SplitTree = split_tree.SplitTree;
|
||||||
|
|
||||||
test {
|
test {
|
||||||
@import("std").testing.refAllDecls(@This());
|
@import("std").testing.refAllDecls(@This());
|
||||||
|
@@ -149,7 +149,7 @@ pub fn setup() void {
|
|||||||
font_config.FontDataOwnedByAtlas = false;
|
font_config.FontDataOwnedByAtlas = false;
|
||||||
_ = cimgui.c.ImFontAtlas_AddFontFromMemoryTTF(
|
_ = cimgui.c.ImFontAtlas_AddFontFromMemoryTTF(
|
||||||
io.Fonts,
|
io.Fonts,
|
||||||
@constCast(@ptrCast(font.embedded.regular)),
|
@ptrCast(@constCast(font.embedded.regular)),
|
||||||
font.embedded.regular.len,
|
font.embedded.regular.len,
|
||||||
font_size,
|
font_size,
|
||||||
font_config,
|
font_config,
|
||||||
|
@@ -56,7 +56,7 @@ const std_size = Page.layout(std_capacity).total_size;
|
|||||||
/// allocator because we need memory that is zero-initialized and page-aligned.
|
/// allocator because we need memory that is zero-initialized and page-aligned.
|
||||||
const PagePool = std.heap.MemoryPoolAligned(
|
const PagePool = std.heap.MemoryPoolAligned(
|
||||||
[std_size]u8,
|
[std_size]u8,
|
||||||
std.heap.page_size_min,
|
.fromByteUnits(std.heap.page_size_min),
|
||||||
);
|
);
|
||||||
|
|
||||||
/// List of pins, known as "tracked" pins. These are pins that are kept
|
/// List of pins, known as "tracked" pins. These are pins that are kept
|
||||||
@@ -388,11 +388,18 @@ pub fn reset(self: *PageList) void {
|
|||||||
const page_arena = &self.pool.pages.arena;
|
const page_arena = &self.pool.pages.arena;
|
||||||
var it = page_arena.state.buffer_list.first;
|
var it = page_arena.state.buffer_list.first;
|
||||||
while (it) |node| : (it = node.next) {
|
while (it) |node| : (it = node.next) {
|
||||||
// The fully allocated buffer
|
// WARN: Since HeapAllocator's BufNode is not public API,
|
||||||
const alloc_buf = @as([*]u8, @ptrCast(node))[0..node.data];
|
// we have to hardcode its layout here. We do a comptime assert
|
||||||
|
// on Zig version to verify we check it on every bump.
|
||||||
|
const BufNode = struct {
|
||||||
|
data: usize,
|
||||||
|
node: std.SinglyLinkedList.Node,
|
||||||
|
};
|
||||||
|
const buf_node: *BufNode = @fieldParentPtr("node", node);
|
||||||
|
|
||||||
|
// The fully allocated buffer
|
||||||
|
const alloc_buf = @as([*]u8, @ptrCast(buf_node))[0..buf_node.data];
|
||||||
// The buffer minus our header
|
// The buffer minus our header
|
||||||
const BufNode = @TypeOf(page_arena.state.buffer_list).Node;
|
|
||||||
const data_buf = alloc_buf[@sizeOf(BufNode)..];
|
const data_buf = alloc_buf[@sizeOf(BufNode)..];
|
||||||
@memset(data_buf, 0);
|
@memset(data_buf, 0);
|
||||||
}
|
}
|
||||||
@@ -2075,7 +2082,7 @@ inline fn createPageExt(
|
|||||||
else
|
else
|
||||||
try page_alloc.alignedAlloc(
|
try page_alloc.alignedAlloc(
|
||||||
u8,
|
u8,
|
||||||
std.heap.page_size_min,
|
.fromByteUnits(std.heap.page_size_min),
|
||||||
layout.total_size,
|
layout.total_size,
|
||||||
);
|
);
|
||||||
errdefer if (pooled)
|
errdefer if (pooled)
|
||||||
@@ -2676,7 +2683,7 @@ pub const EncodeUtf8Options = struct {
|
|||||||
/// predates this and is a thin wrapper around it so the tests all live there.
|
/// predates this and is a thin wrapper around it so the tests all live there.
|
||||||
pub fn encodeUtf8(
|
pub fn encodeUtf8(
|
||||||
self: *const PageList,
|
self: *const PageList,
|
||||||
writer: anytype,
|
writer: *std.Io.Writer,
|
||||||
opts: EncodeUtf8Options,
|
opts: EncodeUtf8Options,
|
||||||
) anyerror!void {
|
) anyerror!void {
|
||||||
// We don't currently use self at all. There is an argument that this
|
// We don't currently use self at all. There is an argument that this
|
||||||
|
@@ -97,13 +97,9 @@ pub const Action = union(enum) {
|
|||||||
// Implement formatter for logging
|
// Implement formatter for logging
|
||||||
pub fn format(
|
pub fn format(
|
||||||
self: CSI,
|
self: CSI,
|
||||||
comptime layout: []const u8,
|
writer: *std.Io.Writer,
|
||||||
opts: std.fmt.FormatOptions,
|
|
||||||
writer: anytype,
|
|
||||||
) !void {
|
) !void {
|
||||||
_ = layout;
|
try writer.print("ESC [ {s} {any} {c}", .{
|
||||||
_ = opts;
|
|
||||||
try std.fmt.format(writer, "ESC [ {s} {any} {c}", .{
|
|
||||||
self.intermediates,
|
self.intermediates,
|
||||||
self.params,
|
self.params,
|
||||||
self.final,
|
self.final,
|
||||||
@@ -118,13 +114,9 @@ pub const Action = union(enum) {
|
|||||||
// Implement formatter for logging
|
// Implement formatter for logging
|
||||||
pub fn format(
|
pub fn format(
|
||||||
self: ESC,
|
self: ESC,
|
||||||
comptime layout: []const u8,
|
writer: *std.Io.Writer,
|
||||||
opts: std.fmt.FormatOptions,
|
|
||||||
writer: anytype,
|
|
||||||
) !void {
|
) !void {
|
||||||
_ = layout;
|
try writer.print("ESC {s} {c}", .{
|
||||||
_ = opts;
|
|
||||||
try std.fmt.format(writer, "ESC {s} {c}", .{
|
|
||||||
self.intermediates,
|
self.intermediates,
|
||||||
self.final,
|
self.final,
|
||||||
});
|
});
|
||||||
@@ -142,11 +134,8 @@ pub const Action = union(enum) {
|
|||||||
// print out custom formats for some of our primitives.
|
// print out custom formats for some of our primitives.
|
||||||
pub fn format(
|
pub fn format(
|
||||||
self: Action,
|
self: Action,
|
||||||
comptime layout: []const u8,
|
writer: *std.Io.Writer,
|
||||||
opts: std.fmt.FormatOptions,
|
|
||||||
writer: anytype,
|
|
||||||
) !void {
|
) !void {
|
||||||
_ = layout;
|
|
||||||
const T = Action;
|
const T = Action;
|
||||||
const info = @typeInfo(T).@"union";
|
const info = @typeInfo(T).@"union";
|
||||||
|
|
||||||
@@ -162,21 +151,20 @@ pub const Action = union(enum) {
|
|||||||
const value = @field(self, u_field.name);
|
const value = @field(self, u_field.name);
|
||||||
switch (@TypeOf(value)) {
|
switch (@TypeOf(value)) {
|
||||||
// Unicode
|
// Unicode
|
||||||
u21 => try std.fmt.format(writer, "'{u}' (U+{X})", .{ value, value }),
|
u21 => try writer.print("'{u}' (U+{X})", .{ value, value }),
|
||||||
|
|
||||||
// Byte
|
// Byte
|
||||||
u8 => try std.fmt.format(writer, "0x{x}", .{value}),
|
u8 => try writer.print("0x{x}", .{value}),
|
||||||
|
|
||||||
// Note: we don't do ASCII (u8) because there are a lot
|
// Note: we don't do ASCII (u8) because there are a lot
|
||||||
// of invisible characters we don't want to handle right
|
// of invisible characters we don't want to handle right
|
||||||
// now.
|
// now.
|
||||||
|
|
||||||
// All others do the default behavior
|
// All others do the default behavior
|
||||||
else => try std.fmt.formatType(
|
else => try writer.printValue(
|
||||||
@field(self, u_field.name),
|
|
||||||
"any",
|
"any",
|
||||||
opts,
|
.{},
|
||||||
writer,
|
@field(self, u_field.name),
|
||||||
3,
|
3,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@@ -391,7 +379,7 @@ inline fn doAction(self: *Parser, action: TransitionAction, c: u8) ?Action {
|
|||||||
// We only allow colon or mixed separators for the 'm' command.
|
// We only allow colon or mixed separators for the 'm' command.
|
||||||
if (c != 'm' and self.params_sep.count() > 0) {
|
if (c != 'm' and self.params_sep.count() > 0) {
|
||||||
log.warn(
|
log.warn(
|
||||||
"CSI colon or mixed separators only allowed for 'm' command, got: {}",
|
"CSI colon or mixed separators only allowed for 'm' command, got: {f}",
|
||||||
.{result},
|
.{result},
|
||||||
);
|
);
|
||||||
break :csi_dispatch null;
|
break :csi_dispatch null;
|
||||||
|
@@ -2168,17 +2168,21 @@ pub const SelectionString = struct {
|
|||||||
/// Returns the raw text associated with a selection. This will unwrap
|
/// Returns the raw text associated with a selection. This will unwrap
|
||||||
/// soft-wrapped edges. The returned slice is owned by the caller and allocated
|
/// soft-wrapped edges. The returned slice is owned by the caller and allocated
|
||||||
/// using alloc, not the allocator associated with the screen (unless they match).
|
/// using alloc, not the allocator associated with the screen (unless they match).
|
||||||
pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) ![:0]const u8 {
|
pub fn selectionString(
|
||||||
|
self: *Screen,
|
||||||
|
alloc: Allocator,
|
||||||
|
opts: SelectionString,
|
||||||
|
) ![:0]const u8 {
|
||||||
// Use an ArrayList so that we can grow the array as we go. We
|
// Use an ArrayList so that we can grow the array as we go. We
|
||||||
// build an initial capacity of just our rows in our selection times
|
// build an initial capacity of just our rows in our selection times
|
||||||
// columns. It can be more or less based on graphemes, newlines, etc.
|
// columns. It can be more or less based on graphemes, newlines, etc.
|
||||||
var strbuilder = std.ArrayList(u8).init(alloc);
|
var strbuilder: std.ArrayList(u8) = .empty;
|
||||||
defer strbuilder.deinit();
|
defer strbuilder.deinit(alloc);
|
||||||
|
|
||||||
// If we're building a stringmap, create our builder for the pins.
|
// If we're building a stringmap, create our builder for the pins.
|
||||||
const MapBuilder = std.ArrayList(Pin);
|
const MapBuilder = std.ArrayList(Pin);
|
||||||
var mapbuilder: ?MapBuilder = if (opts.map != null) MapBuilder.init(alloc) else null;
|
var mapbuilder: ?MapBuilder = if (opts.map != null) .empty else null;
|
||||||
defer if (mapbuilder) |*b| b.deinit();
|
defer if (mapbuilder) |*b| b.deinit(alloc);
|
||||||
|
|
||||||
const sel_ordered = opts.sel.ordered(self, .forward);
|
const sel_ordered = opts.sel.ordered(self, .forward);
|
||||||
const sel_start: Pin = start: {
|
const sel_start: Pin = start: {
|
||||||
@@ -2235,9 +2239,9 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) !
|
|||||||
const raw: u21 = if (cell.hasText()) cell.content.codepoint else 0;
|
const raw: u21 = if (cell.hasText()) cell.content.codepoint else 0;
|
||||||
const char = if (raw > 0) raw else ' ';
|
const char = if (raw > 0) raw else ' ';
|
||||||
const encode_len = try std.unicode.utf8Encode(char, &buf);
|
const encode_len = try std.unicode.utf8Encode(char, &buf);
|
||||||
try strbuilder.appendSlice(buf[0..encode_len]);
|
try strbuilder.appendSlice(alloc, buf[0..encode_len]);
|
||||||
if (mapbuilder) |*b| {
|
if (mapbuilder) |*b| {
|
||||||
for (0..encode_len) |_| try b.append(.{
|
for (0..encode_len) |_| try b.append(alloc, .{
|
||||||
.node = chunk.node,
|
.node = chunk.node,
|
||||||
.y = @intCast(y),
|
.y = @intCast(y),
|
||||||
.x = @intCast(x),
|
.x = @intCast(x),
|
||||||
@@ -2248,9 +2252,9 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) !
|
|||||||
const cps = chunk.node.data.lookupGrapheme(cell).?;
|
const cps = chunk.node.data.lookupGrapheme(cell).?;
|
||||||
for (cps) |cp| {
|
for (cps) |cp| {
|
||||||
const encode_len = try std.unicode.utf8Encode(cp, &buf);
|
const encode_len = try std.unicode.utf8Encode(cp, &buf);
|
||||||
try strbuilder.appendSlice(buf[0..encode_len]);
|
try strbuilder.appendSlice(alloc, buf[0..encode_len]);
|
||||||
if (mapbuilder) |*b| {
|
if (mapbuilder) |*b| {
|
||||||
for (0..encode_len) |_| try b.append(.{
|
for (0..encode_len) |_| try b.append(alloc, .{
|
||||||
.node = chunk.node,
|
.node = chunk.node,
|
||||||
.y = @intCast(y),
|
.y = @intCast(y),
|
||||||
.x = @intCast(x),
|
.x = @intCast(x),
|
||||||
@@ -2265,8 +2269,8 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) !
|
|||||||
if (!is_final_row and
|
if (!is_final_row and
|
||||||
(!row.wrap or sel_ordered.rectangle))
|
(!row.wrap or sel_ordered.rectangle))
|
||||||
{
|
{
|
||||||
try strbuilder.append('\n');
|
try strbuilder.append(alloc, '\n');
|
||||||
if (mapbuilder) |*b| try b.append(.{
|
if (mapbuilder) |*b| try b.append(alloc, .{
|
||||||
.node = chunk.node,
|
.node = chunk.node,
|
||||||
.y = @intCast(y),
|
.y = @intCast(y),
|
||||||
.x = chunk.node.data.size.cols - 1,
|
.x = chunk.node.data.size.cols - 1,
|
||||||
@@ -2281,11 +2285,11 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) !
|
|||||||
|
|
||||||
// If we have a mapbuilder, we need to setup our string map.
|
// If we have a mapbuilder, we need to setup our string map.
|
||||||
if (mapbuilder) |*b| {
|
if (mapbuilder) |*b| {
|
||||||
var strclone = try strbuilder.clone();
|
var strclone = try strbuilder.clone(alloc);
|
||||||
defer strclone.deinit();
|
defer strclone.deinit(alloc);
|
||||||
const str = try strclone.toOwnedSliceSentinel(0);
|
const str = try strclone.toOwnedSliceSentinel(alloc, 0);
|
||||||
errdefer alloc.free(str);
|
errdefer alloc.free(str);
|
||||||
const map = try b.toOwnedSlice();
|
const map = try b.toOwnedSlice(alloc);
|
||||||
errdefer alloc.free(map);
|
errdefer alloc.free(map);
|
||||||
opts.map.?.* = .{ .string = str, .map = map };
|
opts.map.?.* = .{ .string = str, .map = map };
|
||||||
}
|
}
|
||||||
@@ -2306,7 +2310,7 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) !
|
|||||||
const i = strbuilder.items.len;
|
const i = strbuilder.items.len;
|
||||||
strbuilder.items.len += trimmed.len;
|
strbuilder.items.len += trimmed.len;
|
||||||
std.mem.copyForwards(u8, strbuilder.items[i..], trimmed);
|
std.mem.copyForwards(u8, strbuilder.items[i..], trimmed);
|
||||||
try strbuilder.append('\n');
|
try strbuilder.append(alloc, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all trailing newlines
|
// Remove all trailing newlines
|
||||||
@@ -2317,7 +2321,7 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) !
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get our final string
|
// Get our final string
|
||||||
const string = try strbuilder.toOwnedSliceSentinel(0);
|
const string = try strbuilder.toOwnedSliceSentinel(alloc, 0);
|
||||||
errdefer alloc.free(string);
|
errdefer alloc.free(string);
|
||||||
|
|
||||||
return string;
|
return string;
|
||||||
@@ -2902,7 +2906,7 @@ pub fn promptPath(
|
|||||||
/// one byte at a time.
|
/// one byte at a time.
|
||||||
pub fn dumpString(
|
pub fn dumpString(
|
||||||
self: *const Screen,
|
self: *const Screen,
|
||||||
writer: anytype,
|
writer: *std.Io.Writer,
|
||||||
opts: PageList.EncodeUtf8Options,
|
opts: PageList.EncodeUtf8Options,
|
||||||
) anyerror!void {
|
) anyerror!void {
|
||||||
try self.pages.encodeUtf8(writer, opts);
|
try self.pages.encodeUtf8(writer, opts);
|
||||||
@@ -2915,10 +2919,10 @@ pub fn dumpStringAlloc(
|
|||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
tl: point.Point,
|
tl: point.Point,
|
||||||
) ![]const u8 {
|
) ![]const u8 {
|
||||||
var builder = std.ArrayList(u8).init(alloc);
|
var builder: std.Io.Writer.Allocating = .init(alloc);
|
||||||
defer builder.deinit();
|
defer builder.deinit();
|
||||||
|
|
||||||
try self.dumpString(builder.writer(), .{
|
try self.dumpString(&builder.writer, .{
|
||||||
.tl = self.pages.getTopLeft(tl),
|
.tl = self.pages.getTopLeft(tl),
|
||||||
.br = self.pages.getBottomRight(tl) orelse return error.UnknownPoint,
|
.br = self.pages.getBottomRight(tl) orelse return error.UnknownPoint,
|
||||||
.unwrap = false,
|
.unwrap = false,
|
||||||
@@ -2934,10 +2938,10 @@ pub fn dumpStringAllocUnwrapped(
|
|||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
tl: point.Point,
|
tl: point.Point,
|
||||||
) ![]const u8 {
|
) ![]const u8 {
|
||||||
var builder = std.ArrayList(u8).init(alloc);
|
var builder: std.Io.Writer.Allocating = .init(alloc);
|
||||||
defer builder.deinit();
|
defer builder.deinit();
|
||||||
|
|
||||||
try self.dumpString(builder.writer(), .{
|
try self.dumpString(&builder.writer, .{
|
||||||
.tl = self.pages.getTopLeft(tl),
|
.tl = self.pages.getTopLeft(tl),
|
||||||
.br = self.pages.getBottomRight(tl) orelse return error.UnknownPoint,
|
.br = self.pages.getBottomRight(tl) orelse return error.UnknownPoint,
|
||||||
.unwrap = true,
|
.unwrap = true,
|
||||||
@@ -9030,33 +9034,33 @@ test "Screen UTF8 cell map with newlines" {
|
|||||||
|
|
||||||
var cell_map = Page.CellMap.init(alloc);
|
var cell_map = Page.CellMap.init(alloc);
|
||||||
defer cell_map.deinit();
|
defer cell_map.deinit();
|
||||||
var builder = std.ArrayList(u8).init(alloc);
|
var builder: std.Io.Writer.Allocating = .init(alloc);
|
||||||
defer builder.deinit();
|
defer builder.deinit();
|
||||||
try s.dumpString(builder.writer(), .{
|
try s.dumpString(&builder.writer, .{
|
||||||
.tl = s.pages.getTopLeft(.screen),
|
.tl = s.pages.getTopLeft(.screen),
|
||||||
.br = s.pages.getBottomRight(.screen),
|
.br = s.pages.getBottomRight(.screen),
|
||||||
.cell_map = &cell_map,
|
.cell_map = &cell_map,
|
||||||
});
|
});
|
||||||
|
|
||||||
try testing.expectEqual(7, builder.items.len);
|
try testing.expectEqual(7, builder.written().len);
|
||||||
try testing.expectEqualStrings("A\n\nB\n\nC", builder.items);
|
try testing.expectEqualStrings("A\n\nB\n\nC", builder.written());
|
||||||
try testing.expectEqual(builder.items.len, cell_map.items.len);
|
try testing.expectEqual(builder.written().len, cell_map.map.items.len);
|
||||||
try testing.expectEqual(Page.CellMapEntry{
|
try testing.expectEqual(Page.CellMapEntry{
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
}, cell_map.items[0]);
|
}, cell_map.map.items[0]);
|
||||||
try testing.expectEqual(Page.CellMapEntry{
|
try testing.expectEqual(Page.CellMapEntry{
|
||||||
.x = 1,
|
.x = 1,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
}, cell_map.items[1]);
|
}, cell_map.map.items[1]);
|
||||||
try testing.expectEqual(Page.CellMapEntry{
|
try testing.expectEqual(Page.CellMapEntry{
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 1,
|
.y = 1,
|
||||||
}, cell_map.items[2]);
|
}, cell_map.map.items[2]);
|
||||||
try testing.expectEqual(Page.CellMapEntry{
|
try testing.expectEqual(Page.CellMapEntry{
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 2,
|
.y = 2,
|
||||||
}, cell_map.items[3]);
|
}, cell_map.map.items[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Screen UTF8 cell map with blank prefix" {
|
test "Screen UTF8 cell map with blank prefix" {
|
||||||
@@ -9068,32 +9072,32 @@ test "Screen UTF8 cell map with blank prefix" {
|
|||||||
s.cursorAbsolute(2, 1);
|
s.cursorAbsolute(2, 1);
|
||||||
try s.testWriteString("B");
|
try s.testWriteString("B");
|
||||||
|
|
||||||
var cell_map = Page.CellMap.init(alloc);
|
var cell_map: Page.CellMap = .init(alloc);
|
||||||
defer cell_map.deinit();
|
defer cell_map.deinit();
|
||||||
var builder = std.ArrayList(u8).init(alloc);
|
var builder: std.Io.Writer.Allocating = .init(alloc);
|
||||||
defer builder.deinit();
|
defer builder.deinit();
|
||||||
try s.dumpString(builder.writer(), .{
|
try s.dumpString(&builder.writer, .{
|
||||||
.tl = s.pages.getTopLeft(.screen),
|
.tl = s.pages.getTopLeft(.screen),
|
||||||
.br = s.pages.getBottomRight(.screen),
|
.br = s.pages.getBottomRight(.screen),
|
||||||
.cell_map = &cell_map,
|
.cell_map = &cell_map,
|
||||||
});
|
});
|
||||||
|
|
||||||
try testing.expectEqualStrings("\n B", builder.items);
|
try testing.expectEqualStrings("\n B", builder.written());
|
||||||
try testing.expectEqual(builder.items.len, cell_map.items.len);
|
try testing.expectEqual(builder.written().len, cell_map.map.items.len);
|
||||||
try testing.expectEqual(Page.CellMapEntry{
|
try testing.expectEqual(Page.CellMapEntry{
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
}, cell_map.items[0]);
|
}, cell_map.map.items[0]);
|
||||||
try testing.expectEqual(Page.CellMapEntry{
|
try testing.expectEqual(Page.CellMapEntry{
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 1,
|
.y = 1,
|
||||||
}, cell_map.items[1]);
|
}, cell_map.map.items[1]);
|
||||||
try testing.expectEqual(Page.CellMapEntry{
|
try testing.expectEqual(Page.CellMapEntry{
|
||||||
.x = 1,
|
.x = 1,
|
||||||
.y = 1,
|
.y = 1,
|
||||||
}, cell_map.items[2]);
|
}, cell_map.map.items[2]);
|
||||||
try testing.expectEqual(Page.CellMapEntry{
|
try testing.expectEqual(Page.CellMapEntry{
|
||||||
.x = 2,
|
.x = 2,
|
||||||
.y = 1,
|
.y = 1,
|
||||||
}, cell_map.items[3]);
|
}, cell_map.map.items[3]);
|
||||||
}
|
}
|
||||||
|
@@ -223,7 +223,7 @@ pub fn init(
|
|||||||
.left = 0,
|
.left = 0,
|
||||||
.right = cols - 1,
|
.right = cols - 1,
|
||||||
},
|
},
|
||||||
.pwd = std.ArrayList(u8).init(alloc),
|
.pwd = .empty,
|
||||||
.modes = .{
|
.modes = .{
|
||||||
.values = opts.default_modes,
|
.values = opts.default_modes,
|
||||||
.default = opts.default_modes,
|
.default = opts.default_modes,
|
||||||
@@ -235,7 +235,7 @@ pub fn deinit(self: *Terminal, alloc: Allocator) void {
|
|||||||
self.tabstops.deinit(alloc);
|
self.tabstops.deinit(alloc);
|
||||||
self.screen.deinit();
|
self.screen.deinit();
|
||||||
self.secondary_screen.deinit();
|
self.secondary_screen.deinit();
|
||||||
self.pwd.deinit();
|
self.pwd.deinit(alloc);
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,7 +34,7 @@ pub fn BitmapAllocator(comptime chunk_size: comptime_int) type {
|
|||||||
assert(std.math.isPowerOfTwo(chunk_size));
|
assert(std.math.isPowerOfTwo(chunk_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const base_align = @alignOf(u64);
|
pub const base_align: std.mem.Alignment = .fromByteUnits(@alignOf(u64));
|
||||||
pub const bitmap_bit_size = @bitSizeOf(u64);
|
pub const bitmap_bit_size = @bitSizeOf(u64);
|
||||||
|
|
||||||
/// The bitmap of available chunks. Each bit represents a chunk. A
|
/// The bitmap of available chunks. Each bit represents a chunk. A
|
||||||
@@ -49,7 +49,7 @@ pub fn BitmapAllocator(comptime chunk_size: comptime_int) type {
|
|||||||
|
|
||||||
/// Initialize the allocator map with a given buf and memory layout.
|
/// Initialize the allocator map with a given buf and memory layout.
|
||||||
pub fn init(buf: OffsetBuf, l: Layout) Self {
|
pub fn init(buf: OffsetBuf, l: Layout) Self {
|
||||||
assert(@intFromPtr(buf.start()) % base_align == 0);
|
assert(base_align.check(@intFromPtr(buf.start())));
|
||||||
|
|
||||||
// Initialize our bitmaps to all 1s to note that all chunks are free.
|
// Initialize our bitmaps to all 1s to note that all chunks are free.
|
||||||
const bitmap = buf.member(u64, l.bitmap_start);
|
const bitmap = buf.member(u64, l.bitmap_start);
|
||||||
@@ -92,7 +92,7 @@ pub fn BitmapAllocator(comptime chunk_size: comptime_int) type {
|
|||||||
return error.OutOfMemory;
|
return error.OutOfMemory;
|
||||||
|
|
||||||
const chunks = self.chunks.ptr(base);
|
const chunks = self.chunks.ptr(base);
|
||||||
const ptr: [*]T = @alignCast(@ptrCast(&chunks[idx * chunk_size]));
|
const ptr: [*]T = @ptrCast(@alignCast(&chunks[idx * chunk_size]));
|
||||||
return ptr[0..n];
|
return ptr[0..n];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -83,7 +83,7 @@ pub const Handler = struct {
|
|||||||
// https://github.com/mitchellh/ghostty/issues/517
|
// https://github.com/mitchellh/ghostty/issues/517
|
||||||
'q' => .{
|
'q' => .{
|
||||||
.state = .{
|
.state = .{
|
||||||
.xtgettcap = try std.ArrayList(u8).initCapacity(
|
.xtgettcap = try .initCapacity(
|
||||||
alloc,
|
alloc,
|
||||||
128, // Arbitrary choice
|
128, // Arbitrary choice
|
||||||
),
|
),
|
||||||
@@ -134,11 +134,11 @@ pub const Handler = struct {
|
|||||||
} else unreachable,
|
} else unreachable,
|
||||||
|
|
||||||
.xtgettcap => |*list| {
|
.xtgettcap => |*list| {
|
||||||
if (list.items.len >= self.max_bytes) {
|
if (list.written().len >= self.max_bytes) {
|
||||||
return error.OutOfMemory;
|
return error.OutOfMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
try list.append(byte);
|
try list.writer.writeByte(byte);
|
||||||
},
|
},
|
||||||
|
|
||||||
.decrqss => |*buffer| {
|
.decrqss => |*buffer| {
|
||||||
@@ -170,11 +170,12 @@ pub const Handler = struct {
|
|||||||
break :tmux .{ .tmux = .{ .exit = {} } };
|
break :tmux .{ .tmux = .{ .exit = {} } };
|
||||||
} else unreachable,
|
} else unreachable,
|
||||||
|
|
||||||
.xtgettcap => |list| xtgettcap: {
|
.xtgettcap => |*list| xtgettcap: {
|
||||||
for (list.items, 0..) |b, i| {
|
// Note: purposely do not deinit our state here because
|
||||||
list.items[i] = std.ascii.toUpper(b);
|
// we copy it into the resulting command.
|
||||||
}
|
const items = list.written();
|
||||||
break :xtgettcap .{ .xtgettcap = .{ .data = list } };
|
for (items, 0..) |b, i| items[i] = std.ascii.toUpper(b);
|
||||||
|
break :xtgettcap .{ .xtgettcap = .{ .data = list.* } };
|
||||||
},
|
},
|
||||||
|
|
||||||
.decrqss => |buffer| .{ .decrqss = switch (buffer.len) {
|
.decrqss => |buffer| .{ .decrqss = switch (buffer.len) {
|
||||||
@@ -216,8 +217,8 @@ pub const Command = union(enum) {
|
|||||||
else
|
else
|
||||||
void,
|
void,
|
||||||
|
|
||||||
pub fn deinit(self: Command) void {
|
pub fn deinit(self: *Command) void {
|
||||||
switch (self) {
|
switch (self.*) {
|
||||||
.xtgettcap => |*v| v.data.deinit(),
|
.xtgettcap => |*v| v.data.deinit(),
|
||||||
.decrqss => {},
|
.decrqss => {},
|
||||||
.tmux => {},
|
.tmux => {},
|
||||||
@@ -225,16 +226,16 @@ pub const Command = union(enum) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const XTGETTCAP = struct {
|
pub const XTGETTCAP = struct {
|
||||||
data: std.ArrayList(u8),
|
data: std.Io.Writer.Allocating,
|
||||||
i: usize = 0,
|
i: usize = 0,
|
||||||
|
|
||||||
/// Returns the next terminfo key being requested and null
|
/// Returns the next terminfo key being requested and null
|
||||||
/// when there are no more keys. The returned value is NOT hex-decoded
|
/// when there are no more keys. The returned value is NOT hex-decoded
|
||||||
/// because we expect to use a comptime lookup table.
|
/// because we expect to use a comptime lookup table.
|
||||||
pub fn next(self: *XTGETTCAP) ?[]const u8 {
|
pub fn next(self: *XTGETTCAP) ?[]const u8 {
|
||||||
if (self.i >= self.data.items.len) return null;
|
const items = self.data.written();
|
||||||
|
if (self.i >= items.len) return null;
|
||||||
var rem = self.data.items[self.i..];
|
var rem = items[self.i..];
|
||||||
const idx = std.mem.indexOf(u8, rem, ";") orelse rem.len;
|
const idx = std.mem.indexOf(u8, rem, ";") orelse rem.len;
|
||||||
|
|
||||||
// Note that if we're at the end, idx + 1 is len + 1 so we're over
|
// Note that if we're at the end, idx + 1 is len + 1 so we're over
|
||||||
@@ -271,7 +272,7 @@ const State = union(enum) {
|
|||||||
ignore: void,
|
ignore: void,
|
||||||
|
|
||||||
/// XTGETTCAP
|
/// XTGETTCAP
|
||||||
xtgettcap: std.ArrayList(u8),
|
xtgettcap: std.Io.Writer.Allocating,
|
||||||
|
|
||||||
/// DECRQSS
|
/// DECRQSS
|
||||||
decrqss: struct {
|
decrqss: struct {
|
||||||
|
@@ -88,7 +88,7 @@ pub fn OffsetHashMap(
|
|||||||
/// Initialize a new HashMap with the given capacity and backing
|
/// Initialize a new HashMap with the given capacity and backing
|
||||||
/// memory. The backing memory must be aligned to base_align.
|
/// memory. The backing memory must be aligned to base_align.
|
||||||
pub fn init(buf: OffsetBuf, l: Layout) Self {
|
pub fn init(buf: OffsetBuf, l: Layout) Self {
|
||||||
assert(@intFromPtr(buf.start()) % base_align == 0);
|
assert(base_align.check(@intFromPtr(buf.start())));
|
||||||
|
|
||||||
const m = Unmanaged.init(buf, l);
|
const m = Unmanaged.init(buf, l);
|
||||||
return .{ .metadata = getOffset(
|
return .{ .metadata = getOffset(
|
||||||
@@ -124,7 +124,11 @@ fn HashMapUnmanaged(
|
|||||||
const header_align = @alignOf(Header);
|
const header_align = @alignOf(Header);
|
||||||
const key_align = if (@sizeOf(K) == 0) 1 else @alignOf(K);
|
const key_align = if (@sizeOf(K) == 0) 1 else @alignOf(K);
|
||||||
const val_align = if (@sizeOf(V) == 0) 1 else @alignOf(V);
|
const val_align = if (@sizeOf(V) == 0) 1 else @alignOf(V);
|
||||||
const base_align = @max(header_align, key_align, val_align);
|
const base_align: mem.Alignment = .fromByteUnits(@max(
|
||||||
|
header_align,
|
||||||
|
key_align,
|
||||||
|
val_align,
|
||||||
|
));
|
||||||
|
|
||||||
// This is actually a midway pointer to the single buffer containing
|
// This is actually a midway pointer to the single buffer containing
|
||||||
// a `Header` field, the `Metadata`s and `Entry`s.
|
// a `Header` field, the `Metadata`s and `Entry`s.
|
||||||
@@ -287,7 +291,7 @@ fn HashMapUnmanaged(
|
|||||||
/// Initialize a hash map with a given capacity and a buffer. The
|
/// Initialize a hash map with a given capacity and a buffer. The
|
||||||
/// buffer must fit within the size defined by `layoutForCapacity`.
|
/// buffer must fit within the size defined by `layoutForCapacity`.
|
||||||
pub fn init(buf: OffsetBuf, layout: Layout) Self {
|
pub fn init(buf: OffsetBuf, layout: Layout) Self {
|
||||||
assert(@intFromPtr(buf.start()) % base_align == 0);
|
assert(base_align.check(@intFromPtr(buf.start())));
|
||||||
|
|
||||||
// Get all our main pointers
|
// Get all our main pointers
|
||||||
const metadata_buf = buf.rebase(@sizeOf(Header));
|
const metadata_buf = buf.rebase(@sizeOf(Header));
|
||||||
@@ -862,7 +866,11 @@ fn HashMapUnmanaged(
|
|||||||
|
|
||||||
// Our total memory size required is the end of our values
|
// Our total memory size required is the end of our values
|
||||||
// aligned to the base required alignment.
|
// aligned to the base required alignment.
|
||||||
const total_size = std.mem.alignForward(usize, vals_end, base_align);
|
const total_size = std.mem.alignForward(
|
||||||
|
usize,
|
||||||
|
vals_end,
|
||||||
|
base_align.toByteUnits(),
|
||||||
|
);
|
||||||
|
|
||||||
// The offsets we actually store in the map are from the
|
// The offsets we actually store in the map are from the
|
||||||
// metadata pointer so that we can use self.metadata as
|
// metadata pointer so that we can use self.metadata as
|
||||||
@@ -1126,15 +1134,15 @@ test "HashMap put and remove loop in random order" {
|
|||||||
defer alloc.free(buf);
|
defer alloc.free(buf);
|
||||||
var map = Map.init(.init(buf), layout);
|
var map = Map.init(.init(buf), layout);
|
||||||
|
|
||||||
var keys = std.ArrayList(u32).init(alloc);
|
var keys: std.ArrayList(u32) = .empty;
|
||||||
defer keys.deinit();
|
defer keys.deinit(alloc);
|
||||||
|
|
||||||
const size = 32;
|
const size = 32;
|
||||||
const iterations = 100;
|
const iterations = 100;
|
||||||
|
|
||||||
var i: u32 = 0;
|
var i: u32 = 0;
|
||||||
while (i < size) : (i += 1) {
|
while (i < size) : (i += 1) {
|
||||||
try keys.append(i);
|
try keys.append(alloc, i);
|
||||||
}
|
}
|
||||||
var prng = std.Random.DefaultPrng.init(0);
|
var prng = std.Random.DefaultPrng.init(0);
|
||||||
const random = prng.random();
|
const random = prng.random();
|
||||||
|
@@ -42,13 +42,8 @@ pub const Kind = union(enum) {
|
|||||||
|
|
||||||
pub fn format(
|
pub fn format(
|
||||||
self: Kind,
|
self: Kind,
|
||||||
comptime layout: []const u8,
|
writer: *std.Io.Writer,
|
||||||
opts: std.fmt.FormatOptions,
|
|
||||||
writer: anytype,
|
|
||||||
) !void {
|
) !void {
|
||||||
_ = layout;
|
|
||||||
_ = opts;
|
|
||||||
|
|
||||||
switch (self) {
|
switch (self) {
|
||||||
.palette => |p| try writer.print("{d}", .{p}),
|
.palette => |p| try writer.print("{d}", .{p}),
|
||||||
.special => |s| try writer.print("{s}", .{@tagName(s)}),
|
.special => |s| try writer.print("{s}", .{@tagName(s)}),
|
||||||
@@ -61,11 +56,11 @@ test "OSC: kitty color protocol kind string" {
|
|||||||
|
|
||||||
var buf: [256]u8 = undefined;
|
var buf: [256]u8 = undefined;
|
||||||
{
|
{
|
||||||
const actual = try std.fmt.bufPrint(&buf, "{}", .{Kind{ .special = .foreground }});
|
const actual = try std.fmt.bufPrint(&buf, "{f}", .{Kind{ .special = .foreground }});
|
||||||
try testing.expectEqualStrings("foreground", actual);
|
try testing.expectEqualStrings("foreground", actual);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const actual = try std.fmt.bufPrint(&buf, "{}", .{Kind{ .palette = 42 }});
|
const actual = try std.fmt.bufPrint(&buf, "{f}", .{Kind{ .palette = 42 }});
|
||||||
try testing.expectEqualStrings("42", actual);
|
try testing.expectEqualStrings("42", actual);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -475,7 +475,7 @@ pub const Parser = struct {
|
|||||||
|
|
||||||
// Some commands have their own memory management we need to clear.
|
// Some commands have their own memory management we need to clear.
|
||||||
switch (self.command) {
|
switch (self.command) {
|
||||||
.kitty_color_protocol => |*v| v.list.deinit(),
|
.kitty_color_protocol => |*v| v.list.deinit(self.alloc.?),
|
||||||
.color_operation => |*v| v.requests.deinit(self.alloc.?),
|
.color_operation => |*v| v.requests.deinit(self.alloc.?),
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
@@ -821,15 +821,15 @@ pub const Parser = struct {
|
|||||||
|
|
||||||
.@"21" => switch (c) {
|
.@"21" => switch (c) {
|
||||||
';' => kitty: {
|
';' => kitty: {
|
||||||
const alloc = self.alloc orelse {
|
if (self.alloc == null) {
|
||||||
log.info("OSC 21 requires an allocator, but none was provided", .{});
|
log.info("OSC 21 requires an allocator, but none was provided", .{});
|
||||||
self.state = .invalid;
|
self.state = .invalid;
|
||||||
break :kitty;
|
break :kitty;
|
||||||
};
|
}
|
||||||
|
|
||||||
self.command = .{
|
self.command = .{
|
||||||
.kitty_color_protocol = .{
|
.kitty_color_protocol = .{
|
||||||
.list = std.ArrayList(kitty_color.OSC.Request).init(alloc),
|
.list = .empty,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1553,18 +1553,22 @@ pub const Parser = struct {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Asserted when the command is set to kitty_color_protocol
|
||||||
|
// that we have an allocator.
|
||||||
|
const alloc = self.alloc.?;
|
||||||
|
|
||||||
if (kind == .key_only or value.len == 0) {
|
if (kind == .key_only or value.len == 0) {
|
||||||
v.list.append(.{ .reset = key }) catch |err| {
|
v.list.append(alloc, .{ .reset = key }) catch |err| {
|
||||||
log.warn("unable to append kitty color protocol option: {}", .{err});
|
log.warn("unable to append kitty color protocol option: {}", .{err});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
} else if (mem.eql(u8, "?", value)) {
|
} else if (mem.eql(u8, "?", value)) {
|
||||||
v.list.append(.{ .query = key }) catch |err| {
|
v.list.append(alloc, .{ .query = key }) catch |err| {
|
||||||
log.warn("unable to append kitty color protocol option: {}", .{err});
|
log.warn("unable to append kitty color protocol option: {}", .{err});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
v.list.append(.{
|
v.list.append(alloc, .{
|
||||||
.set = .{
|
.set = .{
|
||||||
.key = key,
|
.key = key,
|
||||||
.color = RGB.parse(value) catch |err| switch (err) {
|
.color = RGB.parse(value) catch |err| switch (err) {
|
||||||
|
@@ -86,7 +86,7 @@ pub const Page = struct {
|
|||||||
assert(std.heap.page_size_min % @max(
|
assert(std.heap.page_size_min % @max(
|
||||||
@alignOf(Row),
|
@alignOf(Row),
|
||||||
@alignOf(Cell),
|
@alignOf(Cell),
|
||||||
style.Set.base_align,
|
style.Set.base_align.toByteUnits(),
|
||||||
) == 0);
|
) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1528,7 +1528,21 @@ pub const Page = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// See cell_map
|
/// See cell_map
|
||||||
pub const CellMap = std.ArrayList(CellMapEntry);
|
pub const CellMap = struct {
|
||||||
|
alloc: Allocator,
|
||||||
|
map: std.ArrayList(CellMapEntry),
|
||||||
|
|
||||||
|
pub fn init(alloc: Allocator) CellMap {
|
||||||
|
return .{
|
||||||
|
.alloc = alloc,
|
||||||
|
.map = .empty,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *CellMap) void {
|
||||||
|
self.map.deinit(self.alloc);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// The x/y coordinate of a single cell in the cell map.
|
/// The x/y coordinate of a single cell in the cell map.
|
||||||
pub const CellMapEntry = struct {
|
pub const CellMapEntry = struct {
|
||||||
@@ -1547,7 +1561,7 @@ pub const Page = struct {
|
|||||||
/// it makes it easier to test input contents.
|
/// it makes it easier to test input contents.
|
||||||
pub fn encodeUtf8(
|
pub fn encodeUtf8(
|
||||||
self: *const Page,
|
self: *const Page,
|
||||||
writer: anytype,
|
writer: *std.Io.Writer,
|
||||||
opts: EncodeUtf8Options,
|
opts: EncodeUtf8Options,
|
||||||
) anyerror!EncodeUtf8Options.TrailingUtf8State {
|
) anyerror!EncodeUtf8Options.TrailingUtf8State {
|
||||||
var blank_rows: usize = opts.preceding.rows;
|
var blank_rows: usize = opts.preceding.rows;
|
||||||
@@ -1583,7 +1597,7 @@ pub const Page = struct {
|
|||||||
// This is tested in Screen.zig, i.e. one test is
|
// This is tested in Screen.zig, i.e. one test is
|
||||||
// "cell map with newlines"
|
// "cell map with newlines"
|
||||||
if (opts.cell_map) |cell_map| {
|
if (opts.cell_map) |cell_map| {
|
||||||
try cell_map.append(.{
|
try cell_map.map.append(cell_map.alloc, .{
|
||||||
.x = last_x,
|
.x = last_x,
|
||||||
.y = @intCast(y - blank_rows + i - 1),
|
.y = @intCast(y - blank_rows + i - 1),
|
||||||
});
|
});
|
||||||
@@ -1618,9 +1632,9 @@ pub const Page = struct {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (blank_cells > 0) {
|
if (blank_cells > 0) {
|
||||||
try writer.writeByteNTimes(' ', blank_cells);
|
try writer.splatByteAll(' ', blank_cells);
|
||||||
if (opts.cell_map) |cell_map| {
|
if (opts.cell_map) |cell_map| {
|
||||||
for (0..blank_cells) |i| try cell_map.append(.{
|
for (0..blank_cells) |i| try cell_map.map.append(cell_map.alloc, .{
|
||||||
.x = @intCast(x - blank_cells + i),
|
.x = @intCast(x - blank_cells + i),
|
||||||
.y = y,
|
.y = y,
|
||||||
});
|
});
|
||||||
@@ -1634,7 +1648,7 @@ pub const Page = struct {
|
|||||||
try writer.print("{u}", .{cell.content.codepoint});
|
try writer.print("{u}", .{cell.content.codepoint});
|
||||||
if (opts.cell_map) |cell_map| {
|
if (opts.cell_map) |cell_map| {
|
||||||
last_x = x + 1;
|
last_x = x + 1;
|
||||||
try cell_map.append(.{
|
try cell_map.map.append(cell_map.alloc, .{
|
||||||
.x = x,
|
.x = x,
|
||||||
.y = y,
|
.y = y,
|
||||||
});
|
});
|
||||||
@@ -1645,7 +1659,7 @@ pub const Page = struct {
|
|||||||
try writer.print("{u}", .{cell.content.codepoint});
|
try writer.print("{u}", .{cell.content.codepoint});
|
||||||
if (opts.cell_map) |cell_map| {
|
if (opts.cell_map) |cell_map| {
|
||||||
last_x = x + 1;
|
last_x = x + 1;
|
||||||
try cell_map.append(.{
|
try cell_map.map.append(cell_map.alloc, .{
|
||||||
.x = x,
|
.x = x,
|
||||||
.y = y,
|
.y = y,
|
||||||
});
|
});
|
||||||
@@ -1653,7 +1667,7 @@ pub const Page = struct {
|
|||||||
|
|
||||||
for (self.lookupGrapheme(cell).?) |cp| {
|
for (self.lookupGrapheme(cell).?) |cp| {
|
||||||
try writer.print("{u}", .{cp});
|
try writer.print("{u}", .{cp});
|
||||||
if (opts.cell_map) |cell_map| try cell_map.append(.{
|
if (opts.cell_map) |cell_map| try cell_map.map.append(cell_map.alloc, .{
|
||||||
.x = x,
|
.x = x,
|
||||||
.y = y,
|
.y = y,
|
||||||
});
|
});
|
||||||
@@ -1743,25 +1757,25 @@ pub const Page = struct {
|
|||||||
const dirty_end: usize = dirty_start + (dirty_usize_length * @sizeOf(usize));
|
const dirty_end: usize = dirty_start + (dirty_usize_length * @sizeOf(usize));
|
||||||
|
|
||||||
const styles_layout: style.Set.Layout = .init(cap.styles);
|
const styles_layout: style.Set.Layout = .init(cap.styles);
|
||||||
const styles_start = alignForward(usize, dirty_end, style.Set.base_align);
|
const styles_start = alignForward(usize, dirty_end, style.Set.base_align.toByteUnits());
|
||||||
const styles_end = styles_start + styles_layout.total_size;
|
const styles_end = styles_start + styles_layout.total_size;
|
||||||
|
|
||||||
const grapheme_alloc_layout = GraphemeAlloc.layout(cap.grapheme_bytes);
|
const grapheme_alloc_layout = GraphemeAlloc.layout(cap.grapheme_bytes);
|
||||||
const grapheme_alloc_start = alignForward(usize, styles_end, GraphemeAlloc.base_align);
|
const grapheme_alloc_start = alignForward(usize, styles_end, GraphemeAlloc.base_align.toByteUnits());
|
||||||
const grapheme_alloc_end = grapheme_alloc_start + grapheme_alloc_layout.total_size;
|
const grapheme_alloc_end = grapheme_alloc_start + grapheme_alloc_layout.total_size;
|
||||||
|
|
||||||
const grapheme_count = @divFloor(cap.grapheme_bytes, grapheme_chunk);
|
const grapheme_count = @divFloor(cap.grapheme_bytes, grapheme_chunk);
|
||||||
const grapheme_map_layout = GraphemeMap.layout(@intCast(grapheme_count));
|
const grapheme_map_layout = GraphemeMap.layout(@intCast(grapheme_count));
|
||||||
const grapheme_map_start = alignForward(usize, grapheme_alloc_end, GraphemeMap.base_align);
|
const grapheme_map_start = alignForward(usize, grapheme_alloc_end, GraphemeMap.base_align.toByteUnits());
|
||||||
const grapheme_map_end = grapheme_map_start + grapheme_map_layout.total_size;
|
const grapheme_map_end = grapheme_map_start + grapheme_map_layout.total_size;
|
||||||
|
|
||||||
const string_layout = StringAlloc.layout(cap.string_bytes);
|
const string_layout = StringAlloc.layout(cap.string_bytes);
|
||||||
const string_start = alignForward(usize, grapheme_map_end, StringAlloc.base_align);
|
const string_start = alignForward(usize, grapheme_map_end, StringAlloc.base_align.toByteUnits());
|
||||||
const string_end = string_start + string_layout.total_size;
|
const string_end = string_start + string_layout.total_size;
|
||||||
|
|
||||||
const hyperlink_count = @divFloor(cap.hyperlink_bytes, @sizeOf(hyperlink.Set.Item));
|
const hyperlink_count = @divFloor(cap.hyperlink_bytes, @sizeOf(hyperlink.Set.Item));
|
||||||
const hyperlink_set_layout: hyperlink.Set.Layout = .init(@intCast(hyperlink_count));
|
const hyperlink_set_layout: hyperlink.Set.Layout = .init(@intCast(hyperlink_count));
|
||||||
const hyperlink_set_start = alignForward(usize, string_end, hyperlink.Set.base_align);
|
const hyperlink_set_start = alignForward(usize, string_end, hyperlink.Set.base_align.toByteUnits());
|
||||||
const hyperlink_set_end = hyperlink_set_start + hyperlink_set_layout.total_size;
|
const hyperlink_set_end = hyperlink_set_start + hyperlink_set_layout.total_size;
|
||||||
|
|
||||||
const hyperlink_map_count: u32 = count: {
|
const hyperlink_map_count: u32 = count: {
|
||||||
@@ -1773,7 +1787,7 @@ pub const Page = struct {
|
|||||||
break :count std.math.ceilPowerOfTwoAssert(u32, mult);
|
break :count std.math.ceilPowerOfTwoAssert(u32, mult);
|
||||||
};
|
};
|
||||||
const hyperlink_map_layout = hyperlink.Map.layout(hyperlink_map_count);
|
const hyperlink_map_layout = hyperlink.Map.layout(hyperlink_map_count);
|
||||||
const hyperlink_map_start = alignForward(usize, hyperlink_set_end, hyperlink.Map.base_align);
|
const hyperlink_map_start = alignForward(usize, hyperlink_set_end, hyperlink.Map.base_align.toByteUnits());
|
||||||
const hyperlink_map_end = hyperlink_map_start + hyperlink_map_layout.total_size;
|
const hyperlink_map_end = hyperlink_map_start + hyperlink_map_layout.total_size;
|
||||||
|
|
||||||
const total_size = alignForward(usize, hyperlink_map_end, std.heap.page_size_min);
|
const total_size = alignForward(usize, hyperlink_map_end, std.heap.page_size_min);
|
||||||
@@ -1867,12 +1881,12 @@ pub const Capacity = struct {
|
|||||||
// for rows & cells (which will allow us to calculate the number of
|
// for rows & cells (which will allow us to calculate the number of
|
||||||
// rows we can fit at a certain column width) we need to layout the
|
// rows we can fit at a certain column width) we need to layout the
|
||||||
// "meta" members of the page (i.e. everything else) from the end.
|
// "meta" members of the page (i.e. everything else) from the end.
|
||||||
const hyperlink_map_start = alignBackward(usize, layout.total_size - layout.hyperlink_map_layout.total_size, hyperlink.Map.base_align);
|
const hyperlink_map_start = alignBackward(usize, layout.total_size - layout.hyperlink_map_layout.total_size, hyperlink.Map.base_align.toByteUnits());
|
||||||
const hyperlink_set_start = alignBackward(usize, hyperlink_map_start - layout.hyperlink_set_layout.total_size, hyperlink.Set.base_align);
|
const hyperlink_set_start = alignBackward(usize, hyperlink_map_start - layout.hyperlink_set_layout.total_size, hyperlink.Set.base_align.toByteUnits());
|
||||||
const string_alloc_start = alignBackward(usize, hyperlink_set_start - layout.string_alloc_layout.total_size, StringAlloc.base_align);
|
const string_alloc_start = alignBackward(usize, hyperlink_set_start - layout.string_alloc_layout.total_size, StringAlloc.base_align.toByteUnits());
|
||||||
const grapheme_map_start = alignBackward(usize, string_alloc_start - layout.grapheme_map_layout.total_size, GraphemeMap.base_align);
|
const grapheme_map_start = alignBackward(usize, string_alloc_start - layout.grapheme_map_layout.total_size, GraphemeMap.base_align.toByteUnits());
|
||||||
const grapheme_alloc_start = alignBackward(usize, grapheme_map_start - layout.grapheme_alloc_layout.total_size, GraphemeAlloc.base_align);
|
const grapheme_alloc_start = alignBackward(usize, grapheme_map_start - layout.grapheme_alloc_layout.total_size, GraphemeAlloc.base_align.toByteUnits());
|
||||||
const styles_start = alignBackward(usize, grapheme_alloc_start - layout.styles_layout.total_size, style.Set.base_align);
|
const styles_start = alignBackward(usize, grapheme_alloc_start - layout.styles_layout.total_size, style.Set.base_align.toByteUnits());
|
||||||
|
|
||||||
// The size per row is:
|
// The size per row is:
|
||||||
// - The row metadata itself
|
// - The row metadata itself
|
||||||
|
@@ -59,12 +59,12 @@ pub fn RefCountedSet(
|
|||||||
return struct {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
pub const base_align = @max(
|
pub const base_align: std.mem.Alignment = .fromByteUnits(@max(
|
||||||
@alignOf(Context),
|
@alignOf(Context),
|
||||||
@alignOf(Layout),
|
@alignOf(Layout),
|
||||||
@alignOf(Item),
|
@alignOf(Item),
|
||||||
@alignOf(Id),
|
@alignOf(Id),
|
||||||
);
|
));
|
||||||
|
|
||||||
/// Set item
|
/// Set item
|
||||||
pub const Item = struct {
|
pub const Item = struct {
|
||||||
|
@@ -55,7 +55,7 @@ pub const PageListSearch = struct {
|
|||||||
needle: []const u8,
|
needle: []const u8,
|
||||||
) Allocator.Error!PageListSearch {
|
) Allocator.Error!PageListSearch {
|
||||||
var window = try SlidingWindow.init(alloc, needle);
|
var window = try SlidingWindow.init(alloc, needle);
|
||||||
errdefer window.deinit(alloc);
|
errdefer window.deinit();
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.list = list,
|
.list = list,
|
||||||
@@ -63,16 +63,13 @@ pub const PageListSearch = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *PageListSearch, alloc: Allocator) void {
|
pub fn deinit(self: *PageListSearch) void {
|
||||||
self.window.deinit(alloc);
|
self.window.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the next match for the needle in the pagelist. This returns
|
/// Find the next match for the needle in the pagelist. This returns
|
||||||
/// null when there are no more matches.
|
/// null when there are no more matches.
|
||||||
pub fn next(
|
pub fn next(self: *PageListSearch) Allocator.Error!?Selection {
|
||||||
self: *PageListSearch,
|
|
||||||
alloc: Allocator,
|
|
||||||
) Allocator.Error!?Selection {
|
|
||||||
// Try to search for the needle in the window. If we find a match
|
// Try to search for the needle in the window. If we find a match
|
||||||
// then we can return that and we're done.
|
// then we can return that and we're done.
|
||||||
if (self.window.next()) |sel| return sel;
|
if (self.window.next()) |sel| return sel;
|
||||||
@@ -89,7 +86,7 @@ pub const PageListSearch = struct {
|
|||||||
// until we find a match or we reach the end of the pagelist.
|
// until we find a match or we reach the end of the pagelist.
|
||||||
// This append then next pattern limits memory usage of the window.
|
// This append then next pattern limits memory usage of the window.
|
||||||
while (node_) |node| : (node_ = node.next) {
|
while (node_) |node| : (node_ = node.next) {
|
||||||
try self.window.append(alloc, node);
|
try self.window.append(node);
|
||||||
if (self.window.next()) |sel| return sel;
|
if (self.window.next()) |sel| return sel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,6 +112,14 @@ pub const PageListSearch = struct {
|
|||||||
/// and repeat the process. This will always maintain the minimum
|
/// and repeat the process. This will always maintain the minimum
|
||||||
/// required memory to search for the needle.
|
/// required memory to search for the needle.
|
||||||
const SlidingWindow = struct {
|
const SlidingWindow = struct {
|
||||||
|
/// The allocator to use for all the data within this window. We
|
||||||
|
/// store this rather than passing it around because its already
|
||||||
|
/// part of multiple elements (eg. Meta's CellMap) and we want to
|
||||||
|
/// ensure we always use a consistent allocator. Additionally, only
|
||||||
|
/// a small amount of sliding windows are expected to be in use
|
||||||
|
/// at any one time so the memory overhead isn't that large.
|
||||||
|
alloc: Allocator,
|
||||||
|
|
||||||
/// The data buffer is a circular buffer of u8 that contains the
|
/// The data buffer is a circular buffer of u8 that contains the
|
||||||
/// encoded page text that we can use to search for the needle.
|
/// encoded page text that we can use to search for the needle.
|
||||||
data: DataBuf,
|
data: DataBuf,
|
||||||
@@ -163,6 +168,7 @@ const SlidingWindow = struct {
|
|||||||
errdefer alloc.free(overlap_buf);
|
errdefer alloc.free(overlap_buf);
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
|
.alloc = alloc,
|
||||||
.data = data,
|
.data = data,
|
||||||
.meta = meta,
|
.meta = meta,
|
||||||
.needle = needle,
|
.needle = needle,
|
||||||
@@ -170,13 +176,13 @@ const SlidingWindow = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *SlidingWindow, alloc: Allocator) void {
|
pub fn deinit(self: *SlidingWindow) void {
|
||||||
alloc.free(self.overlap_buf);
|
self.alloc.free(self.overlap_buf);
|
||||||
self.data.deinit(alloc);
|
self.data.deinit(self.alloc);
|
||||||
|
|
||||||
var meta_it = self.meta.iterator(.forward);
|
var meta_it = self.meta.iterator(.forward);
|
||||||
while (meta_it.next()) |meta| meta.deinit();
|
while (meta_it.next()) |meta| meta.deinit();
|
||||||
self.meta.deinit(alloc);
|
self.meta.deinit(self.alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear all data but retain allocated capacity.
|
/// Clear all data but retain allocated capacity.
|
||||||
@@ -206,7 +212,10 @@ const SlidingWindow = struct {
|
|||||||
|
|
||||||
// Search the first slice for the needle.
|
// Search the first slice for the needle.
|
||||||
if (std.mem.indexOf(u8, slices[0], self.needle)) |idx| {
|
if (std.mem.indexOf(u8, slices[0], self.needle)) |idx| {
|
||||||
return self.selection(idx, self.needle.len);
|
return self.selection(
|
||||||
|
idx,
|
||||||
|
self.needle.len,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search the overlap buffer for the needle.
|
// Search the overlap buffer for the needle.
|
||||||
@@ -244,7 +253,10 @@ const SlidingWindow = struct {
|
|||||||
|
|
||||||
// Search the last slice for the needle.
|
// Search the last slice for the needle.
|
||||||
if (std.mem.indexOf(u8, slices[1], self.needle)) |idx| {
|
if (std.mem.indexOf(u8, slices[1], self.needle)) |idx| {
|
||||||
return self.selection(slices[0].len + idx, self.needle.len);
|
return self.selection(
|
||||||
|
slices[0].len + idx,
|
||||||
|
self.needle.len,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No match. We keep `needle.len - 1` bytes available to
|
// No match. We keep `needle.len - 1` bytes available to
|
||||||
@@ -254,15 +266,15 @@ const SlidingWindow = struct {
|
|||||||
var saved: usize = 0;
|
var saved: usize = 0;
|
||||||
while (meta_it.next()) |meta| {
|
while (meta_it.next()) |meta| {
|
||||||
const needed = self.needle.len - 1 - saved;
|
const needed = self.needle.len - 1 - saved;
|
||||||
if (meta.cell_map.items.len >= needed) {
|
if (meta.cell_map.map.items.len >= needed) {
|
||||||
// We save up to this meta. We set our data offset
|
// We save up to this meta. We set our data offset
|
||||||
// to exactly where it needs to be to continue
|
// to exactly where it needs to be to continue
|
||||||
// searching.
|
// searching.
|
||||||
self.data_offset = meta.cell_map.items.len - needed;
|
self.data_offset = meta.cell_map.map.items.len - needed;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
saved += meta.cell_map.items.len;
|
saved += meta.cell_map.map.items.len;
|
||||||
} else {
|
} else {
|
||||||
// If we exited the while loop naturally then we
|
// If we exited the while loop naturally then we
|
||||||
// never got the amount we needed and so there is
|
// never got the amount we needed and so there is
|
||||||
@@ -284,7 +296,7 @@ const SlidingWindow = struct {
|
|||||||
var prune_data_len: usize = 0;
|
var prune_data_len: usize = 0;
|
||||||
for (0..prune_count) |_| {
|
for (0..prune_count) |_| {
|
||||||
const meta = meta_it.next().?;
|
const meta = meta_it.next().?;
|
||||||
prune_data_len += meta.cell_map.items.len;
|
prune_data_len += meta.cell_map.map.items.len;
|
||||||
meta.deinit();
|
meta.deinit();
|
||||||
}
|
}
|
||||||
self.meta.deleteOldest(prune_count);
|
self.meta.deleteOldest(prune_count);
|
||||||
@@ -384,16 +396,16 @@ const SlidingWindow = struct {
|
|||||||
// meta_i is the index we expect to find the match in the
|
// meta_i is the index we expect to find the match in the
|
||||||
// cell map within this meta if it contains it.
|
// cell map within this meta if it contains it.
|
||||||
const meta_i = idx - offset.*;
|
const meta_i = idx - offset.*;
|
||||||
if (meta_i >= meta.cell_map.items.len) {
|
if (meta_i >= meta.cell_map.map.items.len) {
|
||||||
// This meta doesn't contain the match. This means we
|
// This meta doesn't contain the match. This means we
|
||||||
// can also prune this set of data because we only look
|
// can also prune this set of data because we only look
|
||||||
// forward.
|
// forward.
|
||||||
offset.* += meta.cell_map.items.len;
|
offset.* += meta.cell_map.map.items.len;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We found the meta that contains the start of the match.
|
// We found the meta that contains the start of the match.
|
||||||
const map = meta.cell_map.items[meta_i];
|
const map = meta.cell_map.map.items[meta_i];
|
||||||
return .{
|
return .{
|
||||||
.node = meta.node,
|
.node = meta.node,
|
||||||
.y = map.y,
|
.y = map.y,
|
||||||
@@ -411,13 +423,15 @@ const SlidingWindow = struct {
|
|||||||
/// via a search (via next()).
|
/// via a search (via next()).
|
||||||
pub fn append(
|
pub fn append(
|
||||||
self: *SlidingWindow,
|
self: *SlidingWindow,
|
||||||
alloc: Allocator,
|
|
||||||
node: *PageList.List.Node,
|
node: *PageList.List.Node,
|
||||||
) Allocator.Error!void {
|
) Allocator.Error!void {
|
||||||
// Initialize our metadata for the node.
|
// Initialize our metadata for the node.
|
||||||
var meta: Meta = .{
|
var meta: Meta = .{
|
||||||
.node = node,
|
.node = node,
|
||||||
.cell_map = .init(alloc),
|
.cell_map = .{
|
||||||
|
.alloc = self.alloc,
|
||||||
|
.map = .empty,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
errdefer meta.deinit();
|
errdefer meta.deinit();
|
||||||
|
|
||||||
@@ -425,27 +439,27 @@ const SlidingWindow = struct {
|
|||||||
// temporary memory, and then copy it into our circular buffer.
|
// temporary memory, and then copy it into our circular buffer.
|
||||||
// In the future, we should benchmark and see if we can encode
|
// In the future, we should benchmark and see if we can encode
|
||||||
// directly into the circular buffer.
|
// directly into the circular buffer.
|
||||||
var encoded: std.ArrayListUnmanaged(u8) = .{};
|
var encoded: std.Io.Writer.Allocating = .init(self.alloc);
|
||||||
defer encoded.deinit(alloc);
|
defer encoded.deinit();
|
||||||
|
|
||||||
// Encode the page into the buffer.
|
// Encode the page into the buffer.
|
||||||
const page: *const Page = &meta.node.data;
|
const page: *const Page = &meta.node.data;
|
||||||
_ = page.encodeUtf8(
|
_ = page.encodeUtf8(
|
||||||
encoded.writer(alloc),
|
&encoded.writer,
|
||||||
.{ .cell_map = &meta.cell_map },
|
.{ .cell_map = &meta.cell_map },
|
||||||
) catch {
|
) catch {
|
||||||
// writer uses anyerror but the only realistic error on
|
// writer uses anyerror but the only realistic error on
|
||||||
// an ArrayList is out of memory.
|
// an ArrayList is out of memory.
|
||||||
return error.OutOfMemory;
|
return error.OutOfMemory;
|
||||||
};
|
};
|
||||||
assert(meta.cell_map.items.len == encoded.items.len);
|
assert(meta.cell_map.map.items.len == encoded.written().len);
|
||||||
|
|
||||||
// Ensure our buffers are big enough to store what we need.
|
// Ensure our buffers are big enough to store what we need.
|
||||||
try self.data.ensureUnusedCapacity(alloc, encoded.items.len);
|
try self.data.ensureUnusedCapacity(self.alloc, encoded.written().len);
|
||||||
try self.meta.ensureUnusedCapacity(alloc, 1);
|
try self.meta.ensureUnusedCapacity(self.alloc, 1);
|
||||||
|
|
||||||
// Append our new node to the circular buffer.
|
// Append our new node to the circular buffer.
|
||||||
try self.data.appendSlice(encoded.items);
|
try self.data.appendSlice(encoded.written());
|
||||||
try self.meta.append(meta);
|
try self.meta.append(meta);
|
||||||
|
|
||||||
self.assertIntegrity();
|
self.assertIntegrity();
|
||||||
@@ -462,7 +476,7 @@ const SlidingWindow = struct {
|
|||||||
// Integrity check: verify our data matches our metadata exactly.
|
// Integrity check: verify our data matches our metadata exactly.
|
||||||
var meta_it = self.meta.iterator(.forward);
|
var meta_it = self.meta.iterator(.forward);
|
||||||
var data_len: usize = 0;
|
var data_len: usize = 0;
|
||||||
while (meta_it.next()) |m| data_len += m.cell_map.items.len;
|
while (meta_it.next()) |m| data_len += m.cell_map.map.items.len;
|
||||||
assert(data_len == self.data.len());
|
assert(data_len == self.data.len());
|
||||||
|
|
||||||
// Integrity check: verify our data offset is within bounds.
|
// Integrity check: verify our data offset is within bounds.
|
||||||
@@ -480,11 +494,11 @@ test "PageListSearch single page" {
|
|||||||
try testing.expect(s.pages.pages.first == s.pages.pages.last);
|
try testing.expect(s.pages.pages.first == s.pages.pages.last);
|
||||||
|
|
||||||
var search = try PageListSearch.init(alloc, &s.pages, "boo!");
|
var search = try PageListSearch.init(alloc, &s.pages, "boo!");
|
||||||
defer search.deinit(alloc);
|
defer search.deinit();
|
||||||
|
|
||||||
// We should be able to find two matches.
|
// We should be able to find two matches.
|
||||||
{
|
{
|
||||||
const sel = (try search.next(alloc)).?;
|
const sel = (try search.next()).?;
|
||||||
try testing.expectEqual(point.Point{ .active = .{
|
try testing.expectEqual(point.Point{ .active = .{
|
||||||
.x = 7,
|
.x = 7,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
@@ -495,7 +509,7 @@ test "PageListSearch single page" {
|
|||||||
} }, s.pages.pointFromPin(.active, sel.end()).?);
|
} }, s.pages.pointFromPin(.active, sel.end()).?);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const sel = (try search.next(alloc)).?;
|
const sel = (try search.next()).?;
|
||||||
try testing.expectEqual(point.Point{ .active = .{
|
try testing.expectEqual(point.Point{ .active = .{
|
||||||
.x = 19,
|
.x = 19,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
@@ -505,8 +519,8 @@ test "PageListSearch single page" {
|
|||||||
.y = 0,
|
.y = 0,
|
||||||
} }, s.pages.pointFromPin(.active, sel.end()).?);
|
} }, s.pages.pointFromPin(.active, sel.end()).?);
|
||||||
}
|
}
|
||||||
try testing.expect((try search.next(alloc)) == null);
|
try testing.expect((try search.next()) == null);
|
||||||
try testing.expect((try search.next(alloc)) == null);
|
try testing.expect((try search.next()) == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "SlidingWindow empty on init" {
|
test "SlidingWindow empty on init" {
|
||||||
@@ -514,7 +528,7 @@ test "SlidingWindow empty on init" {
|
|||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
var w = try SlidingWindow.init(alloc, "boo!");
|
var w = try SlidingWindow.init(alloc, "boo!");
|
||||||
defer w.deinit(alloc);
|
defer w.deinit();
|
||||||
try testing.expectEqual(0, w.data.len());
|
try testing.expectEqual(0, w.data.len());
|
||||||
try testing.expectEqual(0, w.meta.len());
|
try testing.expectEqual(0, w.meta.len());
|
||||||
}
|
}
|
||||||
@@ -524,7 +538,7 @@ test "SlidingWindow single append" {
|
|||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
var w = try SlidingWindow.init(alloc, "boo!");
|
var w = try SlidingWindow.init(alloc, "boo!");
|
||||||
defer w.deinit(alloc);
|
defer w.deinit();
|
||||||
|
|
||||||
var s = try Screen.init(alloc, 80, 24, 0);
|
var s = try Screen.init(alloc, 80, 24, 0);
|
||||||
defer s.deinit();
|
defer s.deinit();
|
||||||
@@ -533,7 +547,7 @@ test "SlidingWindow single append" {
|
|||||||
// We want to test single-page cases.
|
// We want to test single-page cases.
|
||||||
try testing.expect(s.pages.pages.first == s.pages.pages.last);
|
try testing.expect(s.pages.pages.first == s.pages.pages.last);
|
||||||
const node: *PageList.List.Node = s.pages.pages.first.?;
|
const node: *PageList.List.Node = s.pages.pages.first.?;
|
||||||
try w.append(alloc, node);
|
try w.append(node);
|
||||||
|
|
||||||
// We should be able to find two matches.
|
// We should be able to find two matches.
|
||||||
{
|
{
|
||||||
@@ -567,7 +581,7 @@ test "SlidingWindow single append no match" {
|
|||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
var w = try SlidingWindow.init(alloc, "nope!");
|
var w = try SlidingWindow.init(alloc, "nope!");
|
||||||
defer w.deinit(alloc);
|
defer w.deinit();
|
||||||
|
|
||||||
var s = try Screen.init(alloc, 80, 24, 0);
|
var s = try Screen.init(alloc, 80, 24, 0);
|
||||||
defer s.deinit();
|
defer s.deinit();
|
||||||
@@ -576,7 +590,7 @@ test "SlidingWindow single append no match" {
|
|||||||
// We want to test single-page cases.
|
// We want to test single-page cases.
|
||||||
try testing.expect(s.pages.pages.first == s.pages.pages.last);
|
try testing.expect(s.pages.pages.first == s.pages.pages.last);
|
||||||
const node: *PageList.List.Node = s.pages.pages.first.?;
|
const node: *PageList.List.Node = s.pages.pages.first.?;
|
||||||
try w.append(alloc, node);
|
try w.append(node);
|
||||||
|
|
||||||
// No matches
|
// No matches
|
||||||
try testing.expect(w.next() == null);
|
try testing.expect(w.next() == null);
|
||||||
@@ -591,7 +605,7 @@ test "SlidingWindow two pages" {
|
|||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
var w = try SlidingWindow.init(alloc, "boo!");
|
var w = try SlidingWindow.init(alloc, "boo!");
|
||||||
defer w.deinit(alloc);
|
defer w.deinit();
|
||||||
|
|
||||||
var s = try Screen.init(alloc, 80, 24, 1000);
|
var s = try Screen.init(alloc, 80, 24, 1000);
|
||||||
defer s.deinit();
|
defer s.deinit();
|
||||||
@@ -609,8 +623,8 @@ test "SlidingWindow two pages" {
|
|||||||
|
|
||||||
// Add both pages
|
// Add both pages
|
||||||
const node: *PageList.List.Node = s.pages.pages.first.?;
|
const node: *PageList.List.Node = s.pages.pages.first.?;
|
||||||
try w.append(alloc, node);
|
try w.append(node);
|
||||||
try w.append(alloc, node.next.?);
|
try w.append(node.next.?);
|
||||||
|
|
||||||
// Search should find two matches
|
// Search should find two matches
|
||||||
{
|
{
|
||||||
@@ -644,7 +658,7 @@ test "SlidingWindow two pages match across boundary" {
|
|||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
var w = try SlidingWindow.init(alloc, "hello, world");
|
var w = try SlidingWindow.init(alloc, "hello, world");
|
||||||
defer w.deinit(alloc);
|
defer w.deinit();
|
||||||
|
|
||||||
var s = try Screen.init(alloc, 80, 24, 1000);
|
var s = try Screen.init(alloc, 80, 24, 1000);
|
||||||
defer s.deinit();
|
defer s.deinit();
|
||||||
@@ -661,8 +675,8 @@ test "SlidingWindow two pages match across boundary" {
|
|||||||
|
|
||||||
// Add both pages
|
// Add both pages
|
||||||
const node: *PageList.List.Node = s.pages.pages.first.?;
|
const node: *PageList.List.Node = s.pages.pages.first.?;
|
||||||
try w.append(alloc, node);
|
try w.append(node);
|
||||||
try w.append(alloc, node.next.?);
|
try w.append(node.next.?);
|
||||||
|
|
||||||
// Search should find a match
|
// Search should find a match
|
||||||
{
|
{
|
||||||
@@ -688,7 +702,7 @@ test "SlidingWindow two pages no match prunes first page" {
|
|||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
var w = try SlidingWindow.init(alloc, "nope!");
|
var w = try SlidingWindow.init(alloc, "nope!");
|
||||||
defer w.deinit(alloc);
|
defer w.deinit();
|
||||||
|
|
||||||
var s = try Screen.init(alloc, 80, 24, 1000);
|
var s = try Screen.init(alloc, 80, 24, 1000);
|
||||||
defer s.deinit();
|
defer s.deinit();
|
||||||
@@ -706,8 +720,8 @@ test "SlidingWindow two pages no match prunes first page" {
|
|||||||
|
|
||||||
// Add both pages
|
// Add both pages
|
||||||
const node: *PageList.List.Node = s.pages.pages.first.?;
|
const node: *PageList.List.Node = s.pages.pages.first.?;
|
||||||
try w.append(alloc, node);
|
try w.append(node);
|
||||||
try w.append(alloc, node.next.?);
|
try w.append(node.next.?);
|
||||||
|
|
||||||
// Search should find nothing
|
// Search should find nothing
|
||||||
try testing.expect(w.next() == null);
|
try testing.expect(w.next() == null);
|
||||||
@@ -737,18 +751,18 @@ test "SlidingWindow two pages no match keeps both pages" {
|
|||||||
try s.testWriteString("hello. boo!");
|
try s.testWriteString("hello. boo!");
|
||||||
|
|
||||||
// Imaginary needle for search. Doesn't match!
|
// Imaginary needle for search. Doesn't match!
|
||||||
var needle_list = std.ArrayList(u8).init(alloc);
|
var needle_list: std.ArrayList(u8) = .empty;
|
||||||
defer needle_list.deinit();
|
defer needle_list.deinit(alloc);
|
||||||
try needle_list.appendNTimes('x', first_page_rows * s.pages.cols);
|
try needle_list.appendNTimes(alloc, 'x', first_page_rows * s.pages.cols);
|
||||||
const needle: []const u8 = needle_list.items;
|
const needle: []const u8 = needle_list.items;
|
||||||
|
|
||||||
var w = try SlidingWindow.init(alloc, needle);
|
var w = try SlidingWindow.init(alloc, needle);
|
||||||
defer w.deinit(alloc);
|
defer w.deinit();
|
||||||
|
|
||||||
// Add both pages
|
// Add both pages
|
||||||
const node: *PageList.List.Node = s.pages.pages.first.?;
|
const node: *PageList.List.Node = s.pages.pages.first.?;
|
||||||
try w.append(alloc, node);
|
try w.append(node);
|
||||||
try w.append(alloc, node.next.?);
|
try w.append(node.next.?);
|
||||||
|
|
||||||
// Search should find nothing
|
// Search should find nothing
|
||||||
try testing.expect(w.next() == null);
|
try testing.expect(w.next() == null);
|
||||||
@@ -763,7 +777,7 @@ test "SlidingWindow single append across circular buffer boundary" {
|
|||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
var w = try SlidingWindow.init(alloc, "abc");
|
var w = try SlidingWindow.init(alloc, "abc");
|
||||||
defer w.deinit(alloc);
|
defer w.deinit();
|
||||||
|
|
||||||
var s = try Screen.init(alloc, 80, 24, 0);
|
var s = try Screen.init(alloc, 80, 24, 0);
|
||||||
defer s.deinit();
|
defer s.deinit();
|
||||||
@@ -776,8 +790,8 @@ test "SlidingWindow single append across circular buffer boundary" {
|
|||||||
// our implementation changes our test will fail.
|
// our implementation changes our test will fail.
|
||||||
try testing.expect(s.pages.pages.first == s.pages.pages.last);
|
try testing.expect(s.pages.pages.first == s.pages.pages.last);
|
||||||
const node: *PageList.List.Node = s.pages.pages.first.?;
|
const node: *PageList.List.Node = s.pages.pages.first.?;
|
||||||
try w.append(alloc, node);
|
try w.append(node);
|
||||||
try w.append(alloc, node);
|
try w.append(node);
|
||||||
{
|
{
|
||||||
// No wrap around yet
|
// No wrap around yet
|
||||||
const slices = w.data.getPtrSlice(0, w.data.len());
|
const slices = w.data.getPtrSlice(0, w.data.len());
|
||||||
@@ -793,7 +807,7 @@ test "SlidingWindow single append across circular buffer boundary" {
|
|||||||
w.needle = "boo";
|
w.needle = "boo";
|
||||||
|
|
||||||
// Add new page, now wraps
|
// Add new page, now wraps
|
||||||
try w.append(alloc, node);
|
try w.append(node);
|
||||||
{
|
{
|
||||||
const slices = w.data.getPtrSlice(0, w.data.len());
|
const slices = w.data.getPtrSlice(0, w.data.len());
|
||||||
try testing.expect(slices[0].len > 0);
|
try testing.expect(slices[0].len > 0);
|
||||||
@@ -818,7 +832,7 @@ test "SlidingWindow single append match on boundary" {
|
|||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
var w = try SlidingWindow.init(alloc, "abcd");
|
var w = try SlidingWindow.init(alloc, "abcd");
|
||||||
defer w.deinit(alloc);
|
defer w.deinit();
|
||||||
|
|
||||||
var s = try Screen.init(alloc, 80, 24, 0);
|
var s = try Screen.init(alloc, 80, 24, 0);
|
||||||
defer s.deinit();
|
defer s.deinit();
|
||||||
@@ -831,8 +845,8 @@ test "SlidingWindow single append match on boundary" {
|
|||||||
// our implementation changes our test will fail.
|
// our implementation changes our test will fail.
|
||||||
try testing.expect(s.pages.pages.first == s.pages.pages.last);
|
try testing.expect(s.pages.pages.first == s.pages.pages.last);
|
||||||
const node: *PageList.List.Node = s.pages.pages.first.?;
|
const node: *PageList.List.Node = s.pages.pages.first.?;
|
||||||
try w.append(alloc, node);
|
try w.append(node);
|
||||||
try w.append(alloc, node);
|
try w.append(node);
|
||||||
{
|
{
|
||||||
// No wrap around yet
|
// No wrap around yet
|
||||||
const slices = w.data.getPtrSlice(0, w.data.len());
|
const slices = w.data.getPtrSlice(0, w.data.len());
|
||||||
@@ -848,7 +862,7 @@ test "SlidingWindow single append match on boundary" {
|
|||||||
w.needle = "boo!";
|
w.needle = "boo!";
|
||||||
|
|
||||||
// Add new page, now wraps
|
// Add new page, now wraps
|
||||||
try w.append(alloc, node);
|
try w.append(node);
|
||||||
{
|
{
|
||||||
const slices = w.data.getPtrSlice(0, w.data.len());
|
const slices = w.data.getPtrSlice(0, w.data.len());
|
||||||
try testing.expect(slices[0].len > 0);
|
try testing.expect(slices[0].len > 0);
|
||||||
|
@@ -288,13 +288,13 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
|
|
||||||
for (actions) |action_opt| {
|
for (actions) |action_opt| {
|
||||||
const action = action_opt orelse continue;
|
const action = action_opt orelse continue;
|
||||||
if (comptime debug) log.info("action: {}", .{action});
|
if (comptime debug) log.info("action: {f}", .{action});
|
||||||
|
|
||||||
// If this handler handles everything manually then we do nothing
|
// If this handler handles everything manually then we do nothing
|
||||||
// if it can be processed.
|
// if it can be processed.
|
||||||
if (@hasDecl(T, "handleManually")) {
|
if (@hasDecl(T, "handleManually")) {
|
||||||
const processed = self.handler.handleManually(action) catch |err| err: {
|
const processed = self.handler.handleManually(action) catch |err| err: {
|
||||||
log.warn("error handling action manually err={} action={}", .{
|
log.warn("error handling action manually err={} action={f}", .{
|
||||||
err,
|
err,
|
||||||
action,
|
action,
|
||||||
});
|
});
|
||||||
@@ -341,7 +341,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
|
|
||||||
pub inline fn execute(self: *Self, c: u8) !void {
|
pub inline fn execute(self: *Self, c: u8) !void {
|
||||||
const c0: ansi.C0 = @enumFromInt(c);
|
const c0: ansi.C0 = @enumFromInt(c);
|
||||||
if (comptime debug) log.info("execute: {}", .{c0});
|
if (comptime debug) log.info("execute: {f}", .{c0});
|
||||||
switch (c0) {
|
switch (c0) {
|
||||||
// We ignore SOH/STX: https://github.com/microsoft/terminal/issues/10786
|
// We ignore SOH/STX: https://github.com/microsoft/terminal/issues/10786
|
||||||
.NUL, .SOH, .STX => {},
|
.NUL, .SOH, .STX => {},
|
||||||
@@ -399,12 +399,12 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid cursor up command: {}", .{input});
|
log.warn("invalid cursor up command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI A with intermediates: {s}",
|
"ignoring unimplemented CSI A with intermediates: {s}",
|
||||||
@@ -419,12 +419,12 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid cursor down command: {}", .{input});
|
log.warn("invalid cursor down command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI B with intermediates: {s}",
|
"ignoring unimplemented CSI B with intermediates: {s}",
|
||||||
@@ -439,11 +439,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid cursor right command: {}", .{input});
|
log.warn("invalid cursor right command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI C with intermediates: {s}",
|
"ignoring unimplemented CSI C with intermediates: {s}",
|
||||||
@@ -458,11 +458,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid cursor left command: {}", .{input});
|
log.warn("invalid cursor left command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI D with intermediates: {s}",
|
"ignoring unimplemented CSI D with intermediates: {s}",
|
||||||
@@ -477,12 +477,12 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid cursor up command: {}", .{input});
|
log.warn("invalid cursor up command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI E with intermediates: {s}",
|
"ignoring unimplemented CSI E with intermediates: {s}",
|
||||||
@@ -497,12 +497,12 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid cursor down command: {}", .{input});
|
log.warn("invalid cursor down command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI F with intermediates: {s}",
|
"ignoring unimplemented CSI F with intermediates: {s}",
|
||||||
@@ -516,8 +516,8 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => if (@hasDecl(T, "setCursorCol")) switch (input.params.len) {
|
0 => if (@hasDecl(T, "setCursorCol")) switch (input.params.len) {
|
||||||
0 => try self.handler.setCursorCol(1),
|
0 => try self.handler.setCursorCol(1),
|
||||||
1 => try self.handler.setCursorCol(input.params[0]),
|
1 => try self.handler.setCursorCol(input.params[0]),
|
||||||
else => log.warn("invalid HPA command: {}", .{input}),
|
else => log.warn("invalid HPA command: {f}", .{input}),
|
||||||
} else log.warn("unimplemented CSI callback: {}", .{input}),
|
} else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI G with intermediates: {s}",
|
"ignoring unimplemented CSI G with intermediates: {s}",
|
||||||
@@ -532,8 +532,8 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => try self.handler.setCursorPos(1, 1),
|
0 => try self.handler.setCursorPos(1, 1),
|
||||||
1 => try self.handler.setCursorPos(input.params[0], 1),
|
1 => try self.handler.setCursorPos(input.params[0], 1),
|
||||||
2 => try self.handler.setCursorPos(input.params[0], input.params[1]),
|
2 => try self.handler.setCursorPos(input.params[0], input.params[1]),
|
||||||
else => log.warn("invalid CUP command: {}", .{input}),
|
else => log.warn("invalid CUP command: {f}", .{input}),
|
||||||
} else log.warn("unimplemented CSI callback: {}", .{input}),
|
} else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI H with intermediates: {s}",
|
"ignoring unimplemented CSI H with intermediates: {s}",
|
||||||
@@ -548,11 +548,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid horizontal tab command: {}", .{input});
|
log.warn("invalid horizontal tab command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI I with intermediates: {s}",
|
"ignoring unimplemented CSI I with intermediates: {s}",
|
||||||
@@ -569,7 +569,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const protected = protected_ orelse {
|
const protected = protected_ orelse {
|
||||||
log.warn("invalid erase display command: {}", .{input});
|
log.warn("invalid erase display command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -580,12 +580,12 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const mode = mode_ orelse {
|
const mode = mode_ orelse {
|
||||||
log.warn("invalid erase display command: {}", .{input});
|
log.warn("invalid erase display command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
try self.handler.eraseDisplay(mode, protected);
|
try self.handler.eraseDisplay(mode, protected);
|
||||||
} else log.warn("unimplemented CSI callback: {}", .{input}),
|
} else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
// Erase Line
|
// Erase Line
|
||||||
'K' => if (@hasDecl(T, "eraseLine")) {
|
'K' => if (@hasDecl(T, "eraseLine")) {
|
||||||
@@ -596,7 +596,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const protected = protected_ orelse {
|
const protected = protected_ orelse {
|
||||||
log.warn("invalid erase line command: {}", .{input});
|
log.warn("invalid erase line command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -607,12 +607,12 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const mode = mode_ orelse {
|
const mode = mode_ orelse {
|
||||||
log.warn("invalid erase line command: {}", .{input});
|
log.warn("invalid erase line command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
try self.handler.eraseLine(mode, protected);
|
try self.handler.eraseLine(mode, protected);
|
||||||
} else log.warn("unimplemented CSI callback: {}", .{input}),
|
} else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
// IL - Insert Lines
|
// IL - Insert Lines
|
||||||
// TODO: test
|
// TODO: test
|
||||||
@@ -620,8 +620,8 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => if (@hasDecl(T, "insertLines")) switch (input.params.len) {
|
0 => if (@hasDecl(T, "insertLines")) switch (input.params.len) {
|
||||||
0 => try self.handler.insertLines(1),
|
0 => try self.handler.insertLines(1),
|
||||||
1 => try self.handler.insertLines(input.params[0]),
|
1 => try self.handler.insertLines(input.params[0]),
|
||||||
else => log.warn("invalid IL command: {}", .{input}),
|
else => log.warn("invalid IL command: {f}", .{input}),
|
||||||
} else log.warn("unimplemented CSI callback: {}", .{input}),
|
} else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI L with intermediates: {s}",
|
"ignoring unimplemented CSI L with intermediates: {s}",
|
||||||
@@ -635,8 +635,8 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => if (@hasDecl(T, "deleteLines")) switch (input.params.len) {
|
0 => if (@hasDecl(T, "deleteLines")) switch (input.params.len) {
|
||||||
0 => try self.handler.deleteLines(1),
|
0 => try self.handler.deleteLines(1),
|
||||||
1 => try self.handler.deleteLines(input.params[0]),
|
1 => try self.handler.deleteLines(input.params[0]),
|
||||||
else => log.warn("invalid DL command: {}", .{input}),
|
else => log.warn("invalid DL command: {f}", .{input}),
|
||||||
} else log.warn("unimplemented CSI callback: {}", .{input}),
|
} else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI M with intermediates: {s}",
|
"ignoring unimplemented CSI M with intermediates: {s}",
|
||||||
@@ -651,11 +651,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid delete characters command: {}", .{input});
|
log.warn("invalid delete characters command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI P with intermediates: {s}",
|
"ignoring unimplemented CSI P with intermediates: {s}",
|
||||||
@@ -671,11 +671,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid scroll up command: {}", .{input});
|
log.warn("invalid scroll up command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI S with intermediates: {s}",
|
"ignoring unimplemented CSI S with intermediates: {s}",
|
||||||
@@ -690,11 +690,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid scroll down command: {}", .{input});
|
log.warn("invalid scroll down command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI T with intermediates: {s}",
|
"ignoring unimplemented CSI T with intermediates: {s}",
|
||||||
@@ -711,7 +711,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
if (@hasDecl(T, "tabSet"))
|
if (@hasDecl(T, "tabSet"))
|
||||||
try self.handler.tabSet()
|
try self.handler.tabSet()
|
||||||
else
|
else
|
||||||
log.warn("unimplemented tab set callback: {}", .{input});
|
log.warn("unimplemented tab set callback: {f}", .{input});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -725,12 +725,12 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
2 => if (@hasDecl(T, "tabClear"))
|
2 => if (@hasDecl(T, "tabClear"))
|
||||||
try self.handler.tabClear(.current)
|
try self.handler.tabClear(.current)
|
||||||
else
|
else
|
||||||
log.warn("unimplemented tab clear callback: {}", .{input}),
|
log.warn("unimplemented tab clear callback: {f}", .{input}),
|
||||||
|
|
||||||
5 => if (@hasDecl(T, "tabClear"))
|
5 => if (@hasDecl(T, "tabClear"))
|
||||||
try self.handler.tabClear(.all)
|
try self.handler.tabClear(.all)
|
||||||
else
|
else
|
||||||
log.warn("unimplemented tab clear callback: {}", .{input}),
|
log.warn("unimplemented tab clear callback: {f}", .{input}),
|
||||||
|
|
||||||
else => {},
|
else => {},
|
||||||
},
|
},
|
||||||
@@ -738,7 +738,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
log.warn("invalid cursor tabulation control: {}", .{input});
|
log.warn("invalid cursor tabulation control: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -746,8 +746,8 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
if (@hasDecl(T, "tabReset"))
|
if (@hasDecl(T, "tabReset"))
|
||||||
try self.handler.tabReset()
|
try self.handler.tabReset()
|
||||||
else
|
else
|
||||||
log.warn("unimplemented tab reset callback: {}", .{input});
|
log.warn("unimplemented tab reset callback: {f}", .{input});
|
||||||
} else log.warn("invalid cursor tabulation control: {}", .{input}),
|
} else log.warn("invalid cursor tabulation control: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI W with intermediates: {s}",
|
"ignoring unimplemented CSI W with intermediates: {s}",
|
||||||
@@ -762,11 +762,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid erase characters command: {}", .{input});
|
log.warn("invalid erase characters command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI X with intermediates: {s}",
|
"ignoring unimplemented CSI X with intermediates: {s}",
|
||||||
@@ -781,11 +781,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid horizontal tab back command: {}", .{input});
|
log.warn("invalid horizontal tab back command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI Z with intermediates: {s}",
|
"ignoring unimplemented CSI Z with intermediates: {s}",
|
||||||
@@ -800,11 +800,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid HPR command: {}", .{input});
|
log.warn("invalid HPR command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI a with intermediates: {s}",
|
"ignoring unimplemented CSI a with intermediates: {s}",
|
||||||
@@ -819,11 +819,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid print repeat command: {}", .{input});
|
log.warn("invalid print repeat command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI b with intermediates: {s}",
|
"ignoring unimplemented CSI b with intermediates: {s}",
|
||||||
@@ -842,12 +842,12 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
},
|
},
|
||||||
else => @as(?ansi.DeviceAttributeReq, null),
|
else => @as(?ansi.DeviceAttributeReq, null),
|
||||||
} orelse {
|
} orelse {
|
||||||
log.warn("invalid device attributes command: {}", .{input});
|
log.warn("invalid device attributes command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
try self.handler.deviceAttributes(req, input.params);
|
try self.handler.deviceAttributes(req, input.params);
|
||||||
} else log.warn("unimplemented CSI callback: {}", .{input}),
|
} else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
// VPA - Cursor Vertical Position Absolute
|
// VPA - Cursor Vertical Position Absolute
|
||||||
'd' => switch (input.intermediates.len) {
|
'd' => switch (input.intermediates.len) {
|
||||||
@@ -856,11 +856,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid VPA command: {}", .{input});
|
log.warn("invalid VPA command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI d with intermediates: {s}",
|
"ignoring unimplemented CSI d with intermediates: {s}",
|
||||||
@@ -875,11 +875,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => 1,
|
0 => 1,
|
||||||
1 => input.params[0],
|
1 => input.params[0],
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid VPR command: {}", .{input});
|
log.warn("invalid VPR command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI e with intermediates: {s}",
|
"ignoring unimplemented CSI e with intermediates: {s}",
|
||||||
@@ -894,11 +894,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
switch (input.params.len) {
|
switch (input.params.len) {
|
||||||
1 => @enumFromInt(input.params[0]),
|
1 => @enumFromInt(input.params[0]),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid tab clear command: {}", .{input});
|
log.warn("invalid tab clear command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input}),
|
) else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI g with intermediates: {s}",
|
"ignoring unimplemented CSI g with intermediates: {s}",
|
||||||
@@ -913,7 +913,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
if (input.intermediates.len == 1 and
|
if (input.intermediates.len == 1 and
|
||||||
input.intermediates[0] == '?') break :ansi false;
|
input.intermediates[0] == '?') break :ansi false;
|
||||||
|
|
||||||
log.warn("invalid set mode command: {}", .{input});
|
log.warn("invalid set mode command: {f}", .{input});
|
||||||
break :mode;
|
break :mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -924,7 +924,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
log.warn("unimplemented mode: {}", .{mode_int});
|
log.warn("unimplemented mode: {}", .{mode_int});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else log.warn("unimplemented CSI callback: {}", .{input}),
|
} else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
// RM - Reset Mode
|
// RM - Reset Mode
|
||||||
'l' => if (@hasDecl(T, "setMode")) mode: {
|
'l' => if (@hasDecl(T, "setMode")) mode: {
|
||||||
@@ -933,7 +933,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
if (input.intermediates.len == 1 and
|
if (input.intermediates.len == 1 and
|
||||||
input.intermediates[0] == '?') break :ansi false;
|
input.intermediates[0] == '?') break :ansi false;
|
||||||
|
|
||||||
log.warn("invalid set mode command: {}", .{input});
|
log.warn("invalid set mode command: {f}", .{input});
|
||||||
break :mode;
|
break :mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -944,7 +944,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
log.warn("unimplemented mode: {}", .{mode_int});
|
log.warn("unimplemented mode: {}", .{mode_int});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else log.warn("unimplemented CSI callback: {}", .{input}),
|
} else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
// SGR - Select Graphic Rendition
|
// SGR - Select Graphic Rendition
|
||||||
'm' => switch (input.intermediates.len) {
|
'm' => switch (input.intermediates.len) {
|
||||||
@@ -958,7 +958,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
// log.info("SGR attribute: {}", .{attr});
|
// log.info("SGR attribute: {}", .{attr});
|
||||||
try self.handler.setAttribute(attr);
|
try self.handler.setAttribute(attr);
|
||||||
}
|
}
|
||||||
} else log.warn("unimplemented CSI callback: {}", .{input}),
|
} else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
1 => switch (input.intermediates[0]) {
|
1 => switch (input.intermediates[0]) {
|
||||||
'>' => if (@hasDecl(T, "setModifyKeyFormat")) blk: {
|
'>' => if (@hasDecl(T, "setModifyKeyFormat")) blk: {
|
||||||
@@ -974,13 +974,13 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
2 => .{ .function_keys = {} },
|
2 => .{ .function_keys = {} },
|
||||||
4 => .{ .other_keys = .none },
|
4 => .{ .other_keys = .none },
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid setModifyKeyFormat: {}", .{input});
|
log.warn("invalid setModifyKeyFormat: {f}", .{input});
|
||||||
break :blk;
|
break :blk;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (input.params.len > 2) {
|
if (input.params.len > 2) {
|
||||||
log.warn("invalid setModifyKeyFormat: {}", .{input});
|
log.warn("invalid setModifyKeyFormat: {f}", .{input});
|
||||||
break :blk;
|
break :blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1000,7 +1000,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try self.handler.setModifyKeyFormat(format);
|
try self.handler.setModifyKeyFormat(format);
|
||||||
} else log.warn("unimplemented setModifyKeyFormat: {}", .{input}),
|
} else log.warn("unimplemented setModifyKeyFormat: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"unknown CSI m with intermediate: {}",
|
"unknown CSI m with intermediate: {}",
|
||||||
@@ -1029,12 +1029,12 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
input.intermediates[0] == '?')
|
input.intermediates[0] == '?')
|
||||||
{
|
{
|
||||||
if (!@hasDecl(T, "deviceStatusReport")) {
|
if (!@hasDecl(T, "deviceStatusReport")) {
|
||||||
log.warn("unimplemented CSI callback: {}", .{input});
|
log.warn("unimplemented CSI callback: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.params.len != 1) {
|
if (input.params.len != 1) {
|
||||||
log.warn("invalid device status report command: {}", .{input});
|
log.warn("invalid device status report command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1043,12 +1043,12 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
if (input.intermediates.len == 1 and
|
if (input.intermediates.len == 1 and
|
||||||
input.intermediates[0] == '?') break :question true;
|
input.intermediates[0] == '?') break :question true;
|
||||||
|
|
||||||
log.warn("invalid set mode command: {}", .{input});
|
log.warn("invalid set mode command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
const req = device_status.reqFromInt(input.params[0], question) orelse {
|
const req = device_status.reqFromInt(input.params[0], question) orelse {
|
||||||
log.warn("invalid device status report command: {}", .{input});
|
log.warn("invalid device status report command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1067,7 +1067,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
// only support reverting back to modify other keys in
|
// only support reverting back to modify other keys in
|
||||||
// numeric except format.
|
// numeric except format.
|
||||||
try self.handler.setModifyKeyFormat(.{ .other_keys = .numeric_except });
|
try self.handler.setModifyKeyFormat(.{ .other_keys = .numeric_except });
|
||||||
} else log.warn("unimplemented setModifyKeyFormat: {}", .{input}),
|
} else log.warn("unimplemented setModifyKeyFormat: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"unknown CSI n with intermediate: {}",
|
"unknown CSI n with intermediate: {}",
|
||||||
@@ -1101,13 +1101,13 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (input.params.len != 1) {
|
if (input.params.len != 1) {
|
||||||
log.warn("invalid DECRQM command: {}", .{input});
|
log.warn("invalid DECRQM command: {f}", .{input});
|
||||||
break :decrqm;
|
break :decrqm;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (@hasDecl(T, "requestMode")) {
|
if (@hasDecl(T, "requestMode")) {
|
||||||
try self.handler.requestMode(input.params[0], ansi_mode);
|
try self.handler.requestMode(input.params[0], ansi_mode);
|
||||||
} else log.warn("unimplemented DECRQM callback: {}", .{input});
|
} else log.warn("unimplemented DECRQM callback: {f}", .{input});
|
||||||
},
|
},
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
@@ -1126,11 +1126,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => ansi.CursorStyle.default,
|
0 => ansi.CursorStyle.default,
|
||||||
1 => @enumFromInt(input.params[0]),
|
1 => @enumFromInt(input.params[0]),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid set curor style command: {}", .{input});
|
log.warn("invalid set curor style command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
) else log.warn("unimplemented CSI callback: {}", .{input});
|
) else log.warn("unimplemented CSI callback: {f}", .{input});
|
||||||
},
|
},
|
||||||
|
|
||||||
// DECSCA
|
// DECSCA
|
||||||
@@ -1147,12 +1147,12 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const mode = mode_ orelse {
|
const mode = mode_ orelse {
|
||||||
log.warn("invalid set protected mode command: {}", .{input});
|
log.warn("invalid set protected mode command: {f}", .{input});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
try self.handler.setProtectedMode(mode);
|
try self.handler.setProtectedMode(mode);
|
||||||
} else log.warn("unimplemented CSI callback: {}", .{input});
|
} else log.warn("unimplemented CSI callback: {f}", .{input});
|
||||||
},
|
},
|
||||||
|
|
||||||
// XTVERSION
|
// XTVERSION
|
||||||
@@ -1180,10 +1180,10 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => try self.handler.setTopAndBottomMargin(0, 0),
|
0 => try self.handler.setTopAndBottomMargin(0, 0),
|
||||||
1 => try self.handler.setTopAndBottomMargin(input.params[0], 0),
|
1 => try self.handler.setTopAndBottomMargin(input.params[0], 0),
|
||||||
2 => try self.handler.setTopAndBottomMargin(input.params[0], input.params[1]),
|
2 => try self.handler.setTopAndBottomMargin(input.params[0], input.params[1]),
|
||||||
else => log.warn("invalid DECSTBM command: {}", .{input}),
|
else => log.warn("invalid DECSTBM command: {f}", .{input}),
|
||||||
}
|
}
|
||||||
} else log.warn(
|
} else log.warn(
|
||||||
"unimplemented CSI callback: {}",
|
"unimplemented CSI callback: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
|
|
||||||
@@ -1203,13 +1203,13 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
},
|
},
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"unknown CSI s with intermediate: {}",
|
"unknown CSI s with intermediate: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI s with intermediates: {s}",
|
"ignoring unimplemented CSI s with intermediates: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -1225,10 +1225,10 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => try self.handler.setLeftAndRightMarginAmbiguous(),
|
0 => try self.handler.setLeftAndRightMarginAmbiguous(),
|
||||||
1 => try self.handler.setLeftAndRightMargin(input.params[0], 0),
|
1 => try self.handler.setLeftAndRightMargin(input.params[0], 0),
|
||||||
2 => try self.handler.setLeftAndRightMargin(input.params[0], input.params[1]),
|
2 => try self.handler.setLeftAndRightMargin(input.params[0], input.params[1]),
|
||||||
else => log.warn("invalid DECSLRM command: {}", .{input}),
|
else => log.warn("invalid DECSLRM command: {f}", .{input}),
|
||||||
}
|
}
|
||||||
} else log.warn(
|
} else log.warn(
|
||||||
"unimplemented CSI callback: {}",
|
"unimplemented CSI callback: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
|
|
||||||
@@ -1254,30 +1254,30 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => false,
|
0 => false,
|
||||||
1 => true,
|
1 => true,
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid XTSHIFTESCAPE command: {}", .{input});
|
log.warn("invalid XTSHIFTESCAPE command: {f}", .{input});
|
||||||
break :capture;
|
break :capture;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid XTSHIFTESCAPE command: {}", .{input});
|
log.warn("invalid XTSHIFTESCAPE command: {f}", .{input});
|
||||||
break :capture;
|
break :capture;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
try self.handler.setMouseShiftCapture(capture);
|
try self.handler.setMouseShiftCapture(capture);
|
||||||
} else log.warn(
|
} else log.warn(
|
||||||
"unimplemented CSI callback: {}",
|
"unimplemented CSI callback: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"unknown CSI s with intermediate: {}",
|
"unknown CSI s with intermediate: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI s with intermediates: {s}",
|
"ignoring unimplemented CSI s with intermediates: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -1296,7 +1296,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
} else log.warn(
|
} else log.warn(
|
||||||
"ignoring CSI 14 t with extra parameters: {}",
|
"ignoring CSI 14 t with extra parameters: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
16 => if (input.params.len == 1) {
|
16 => if (input.params.len == 1) {
|
||||||
@@ -1308,7 +1308,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
} else log.warn(
|
} else log.warn(
|
||||||
"ignoring CSI 16 t with extra parameters: {s}",
|
"ignoring CSI 16 t with extra parameters: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
18 => if (input.params.len == 1) {
|
18 => if (input.params.len == 1) {
|
||||||
@@ -1320,7 +1320,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
} else log.warn(
|
} else log.warn(
|
||||||
"ignoring CSI 18 t with extra parameters: {s}",
|
"ignoring CSI 18 t with extra parameters: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
21 => if (input.params.len == 1) {
|
21 => if (input.params.len == 1) {
|
||||||
@@ -1332,7 +1332,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
} else log.warn(
|
} else log.warn(
|
||||||
"ignoring CSI 21 t with extra parameters: {s}",
|
"ignoring CSI 21 t with extra parameters: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
inline 22, 23 => |number| if ((input.params.len == 2 or
|
inline 22, 23 => |number| if ((input.params.len == 2 or
|
||||||
@@ -1359,21 +1359,21 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
} else log.warn(
|
} else log.warn(
|
||||||
"ignoring CSI 22/23 t with extra parameters: {s}",
|
"ignoring CSI 22/23 t with extra parameters: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring CSI t with unimplemented parameter: {s}",
|
"ignoring CSI t with unimplemented parameter: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
} else log.err(
|
} else log.err(
|
||||||
"ignoring CSI t with no parameters: {s}",
|
"ignoring CSI t with no parameters: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI t with intermediates: {s}",
|
"ignoring unimplemented CSI t with intermediates: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -1382,7 +1382,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => if (@hasDecl(T, "restoreCursor"))
|
0 => if (@hasDecl(T, "restoreCursor"))
|
||||||
try self.handler.restoreCursor()
|
try self.handler.restoreCursor()
|
||||||
else
|
else
|
||||||
log.warn("unimplemented CSI callback: {}", .{input}),
|
log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
// Kitty keyboard protocol
|
// Kitty keyboard protocol
|
||||||
1 => switch (input.intermediates[0]) {
|
1 => switch (input.intermediates[0]) {
|
||||||
@@ -1393,7 +1393,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
'>' => if (@hasDecl(T, "pushKittyKeyboard")) push: {
|
'>' => if (@hasDecl(T, "pushKittyKeyboard")) push: {
|
||||||
const flags: u5 = if (input.params.len == 1)
|
const flags: u5 = if (input.params.len == 1)
|
||||||
std.math.cast(u5, input.params[0]) orelse {
|
std.math.cast(u5, input.params[0]) orelse {
|
||||||
log.warn("invalid pushKittyKeyboard command: {}", .{input});
|
log.warn("invalid pushKittyKeyboard command: {f}", .{input});
|
||||||
break :push;
|
break :push;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1414,7 +1414,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
'=' => if (@hasDecl(T, "setKittyKeyboard")) set: {
|
'=' => if (@hasDecl(T, "setKittyKeyboard")) set: {
|
||||||
const flags: u5 = if (input.params.len >= 1)
|
const flags: u5 = if (input.params.len >= 1)
|
||||||
std.math.cast(u5, input.params[0]) orelse {
|
std.math.cast(u5, input.params[0]) orelse {
|
||||||
log.warn("invalid setKittyKeyboard command: {}", .{input});
|
log.warn("invalid setKittyKeyboard command: {f}", .{input});
|
||||||
break :set;
|
break :set;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1430,7 +1430,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
2 => .@"or",
|
2 => .@"or",
|
||||||
3 => .not,
|
3 => .not,
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid setKittyKeyboard command: {}", .{input});
|
log.warn("invalid setKittyKeyboard command: {f}", .{input});
|
||||||
break :set;
|
break :set;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -1442,13 +1442,13 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
},
|
},
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"unknown CSI s with intermediate: {}",
|
"unknown CSI s with intermediate: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI u: {}",
|
"ignoring unimplemented CSI u: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -1458,11 +1458,11 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => if (@hasDecl(T, "insertBlanks")) switch (input.params.len) {
|
0 => if (@hasDecl(T, "insertBlanks")) switch (input.params.len) {
|
||||||
0 => try self.handler.insertBlanks(1),
|
0 => try self.handler.insertBlanks(1),
|
||||||
1 => try self.handler.insertBlanks(input.params[0]),
|
1 => try self.handler.insertBlanks(input.params[0]),
|
||||||
else => log.warn("invalid ICH command: {}", .{input}),
|
else => log.warn("invalid ICH command: {f}", .{input}),
|
||||||
} else log.warn("unimplemented CSI callback: {}", .{input}),
|
} else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||||
|
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring unimplemented CSI @: {}",
|
"ignoring unimplemented CSI @: {f}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -1487,13 +1487,13 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
break :decsasd true;
|
break :decsasd true;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!success) log.warn("unimplemented CSI callback: {}", .{input});
|
if (!success) log.warn("unimplemented CSI callback: {f}", .{input});
|
||||||
},
|
},
|
||||||
|
|
||||||
else => if (@hasDecl(T, "csiUnimplemented"))
|
else => if (@hasDecl(T, "csiUnimplemented"))
|
||||||
try self.handler.csiUnimplemented(input)
|
try self.handler.csiUnimplemented(input)
|
||||||
else
|
else
|
||||||
log.warn("unimplemented CSI action: {}", .{input}),
|
log.warn("unimplemented CSI action: {f}", .{input}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1690,10 +1690,10 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
'7' => if (@hasDecl(T, "saveCursor")) switch (action.intermediates.len) {
|
'7' => if (@hasDecl(T, "saveCursor")) switch (action.intermediates.len) {
|
||||||
0 => try self.handler.saveCursor(),
|
0 => try self.handler.saveCursor(),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid command: {}", .{action});
|
log.warn("invalid command: {f}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
} else log.warn("unimplemented ESC callback: {}", .{action}),
|
} else log.warn("unimplemented ESC callback: {f}", .{action}),
|
||||||
|
|
||||||
'8' => blk: {
|
'8' => blk: {
|
||||||
switch (action.intermediates.len) {
|
switch (action.intermediates.len) {
|
||||||
@@ -1701,14 +1701,14 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
0 => if (@hasDecl(T, "restoreCursor")) {
|
0 => if (@hasDecl(T, "restoreCursor")) {
|
||||||
try self.handler.restoreCursor();
|
try self.handler.restoreCursor();
|
||||||
break :blk {};
|
break :blk {};
|
||||||
} else log.warn("unimplemented restore cursor callback: {}", .{action}),
|
} else log.warn("unimplemented restore cursor callback: {f}", .{action}),
|
||||||
|
|
||||||
1 => switch (action.intermediates[0]) {
|
1 => switch (action.intermediates[0]) {
|
||||||
// DECALN - Fill Screen with E
|
// DECALN - Fill Screen with E
|
||||||
'#' => if (@hasDecl(T, "decaln")) {
|
'#' => if (@hasDecl(T, "decaln")) {
|
||||||
try self.handler.decaln();
|
try self.handler.decaln();
|
||||||
break :blk {};
|
break :blk {};
|
||||||
} else log.warn("unimplemented ESC callback: {}", .{action}),
|
} else log.warn("unimplemented ESC callback: {f}", .{action}),
|
||||||
|
|
||||||
else => {},
|
else => {},
|
||||||
},
|
},
|
||||||
@@ -1716,146 +1716,146 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
else => {}, // fall through
|
else => {}, // fall through
|
||||||
}
|
}
|
||||||
|
|
||||||
log.warn("unimplemented ESC action: {}", .{action});
|
log.warn("unimplemented ESC action: {f}", .{action});
|
||||||
},
|
},
|
||||||
|
|
||||||
// IND - Index
|
// IND - Index
|
||||||
'D' => if (@hasDecl(T, "index")) switch (action.intermediates.len) {
|
'D' => if (@hasDecl(T, "index")) switch (action.intermediates.len) {
|
||||||
0 => try self.handler.index(),
|
0 => try self.handler.index(),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid index command: {}", .{action});
|
log.warn("invalid index command: {f}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
} else log.warn("unimplemented ESC callback: {}", .{action}),
|
} else log.warn("unimplemented ESC callback: {f}", .{action}),
|
||||||
|
|
||||||
// NEL - Next Line
|
// NEL - Next Line
|
||||||
'E' => if (@hasDecl(T, "nextLine")) switch (action.intermediates.len) {
|
'E' => if (@hasDecl(T, "nextLine")) switch (action.intermediates.len) {
|
||||||
0 => try self.handler.nextLine(),
|
0 => try self.handler.nextLine(),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid next line command: {}", .{action});
|
log.warn("invalid next line command: {f}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
} else log.warn("unimplemented ESC callback: {}", .{action}),
|
} else log.warn("unimplemented ESC callback: {f}", .{action}),
|
||||||
|
|
||||||
// HTS - Horizontal Tab Set
|
// HTS - Horizontal Tab Set
|
||||||
'H' => if (@hasDecl(T, "tabSet")) switch (action.intermediates.len) {
|
'H' => if (@hasDecl(T, "tabSet")) switch (action.intermediates.len) {
|
||||||
0 => try self.handler.tabSet(),
|
0 => try self.handler.tabSet(),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid tab set command: {}", .{action});
|
log.warn("invalid tab set command: {f}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
} else log.warn("unimplemented tab set callback: {}", .{action}),
|
} else log.warn("unimplemented tab set callback: {f}", .{action}),
|
||||||
|
|
||||||
// RI - Reverse Index
|
// RI - Reverse Index
|
||||||
'M' => if (@hasDecl(T, "reverseIndex")) switch (action.intermediates.len) {
|
'M' => if (@hasDecl(T, "reverseIndex")) switch (action.intermediates.len) {
|
||||||
0 => try self.handler.reverseIndex(),
|
0 => try self.handler.reverseIndex(),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid reverse index command: {}", .{action});
|
log.warn("invalid reverse index command: {f}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
} else log.warn("unimplemented ESC callback: {}", .{action}),
|
} else log.warn("unimplemented ESC callback: {f}", .{action}),
|
||||||
|
|
||||||
// SS2 - Single Shift 2
|
// SS2 - Single Shift 2
|
||||||
'N' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
'N' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
||||||
0 => try self.handler.invokeCharset(.GL, .G2, true),
|
0 => try self.handler.invokeCharset(.GL, .G2, true),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid single shift 2 command: {}", .{action});
|
log.warn("invalid single shift 2 command: {f}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
} else log.warn("unimplemented invokeCharset: {}", .{action}),
|
} else log.warn("unimplemented invokeCharset: {f}", .{action}),
|
||||||
|
|
||||||
// SS3 - Single Shift 3
|
// SS3 - Single Shift 3
|
||||||
'O' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
'O' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
||||||
0 => try self.handler.invokeCharset(.GL, .G3, true),
|
0 => try self.handler.invokeCharset(.GL, .G3, true),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid single shift 3 command: {}", .{action});
|
log.warn("invalid single shift 3 command: {f}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
} else log.warn("unimplemented invokeCharset: {}", .{action}),
|
} else log.warn("unimplemented invokeCharset: {f}", .{action}),
|
||||||
|
|
||||||
// SPA - Start of Guarded Area
|
// SPA - Start of Guarded Area
|
||||||
'V' => if (@hasDecl(T, "setProtectedMode") and action.intermediates.len == 0) {
|
'V' => if (@hasDecl(T, "setProtectedMode") and action.intermediates.len == 0) {
|
||||||
try self.handler.setProtectedMode(ansi.ProtectedMode.iso);
|
try self.handler.setProtectedMode(ansi.ProtectedMode.iso);
|
||||||
} else log.warn("unimplemented ESC callback: {}", .{action}),
|
} else log.warn("unimplemented ESC callback: {f}", .{action}),
|
||||||
|
|
||||||
// EPA - End of Guarded Area
|
// EPA - End of Guarded Area
|
||||||
'W' => if (@hasDecl(T, "setProtectedMode") and action.intermediates.len == 0) {
|
'W' => if (@hasDecl(T, "setProtectedMode") and action.intermediates.len == 0) {
|
||||||
try self.handler.setProtectedMode(ansi.ProtectedMode.off);
|
try self.handler.setProtectedMode(ansi.ProtectedMode.off);
|
||||||
} else log.warn("unimplemented ESC callback: {}", .{action}),
|
} else log.warn("unimplemented ESC callback: {f}", .{action}),
|
||||||
|
|
||||||
// DECID
|
// DECID
|
||||||
'Z' => if (@hasDecl(T, "deviceAttributes") and action.intermediates.len == 0) {
|
'Z' => if (@hasDecl(T, "deviceAttributes") and action.intermediates.len == 0) {
|
||||||
try self.handler.deviceAttributes(.primary, &.{});
|
try self.handler.deviceAttributes(.primary, &.{});
|
||||||
} else log.warn("unimplemented ESC callback: {}", .{action}),
|
} else log.warn("unimplemented ESC callback: {f}", .{action}),
|
||||||
|
|
||||||
// RIS - Full Reset
|
// RIS - Full Reset
|
||||||
'c' => if (@hasDecl(T, "fullReset")) switch (action.intermediates.len) {
|
'c' => if (@hasDecl(T, "fullReset")) switch (action.intermediates.len) {
|
||||||
0 => try self.handler.fullReset(),
|
0 => try self.handler.fullReset(),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid full reset command: {}", .{action});
|
log.warn("invalid full reset command: {f}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
} else log.warn("unimplemented ESC callback: {}", .{action}),
|
} else log.warn("unimplemented ESC callback: {f}", .{action}),
|
||||||
|
|
||||||
// LS2 - Locking Shift 2
|
// LS2 - Locking Shift 2
|
||||||
'n' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
'n' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
||||||
0 => try self.handler.invokeCharset(.GL, .G2, false),
|
0 => try self.handler.invokeCharset(.GL, .G2, false),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid single shift 2 command: {}", .{action});
|
log.warn("invalid single shift 2 command: {f}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
} else log.warn("unimplemented invokeCharset: {}", .{action}),
|
} else log.warn("unimplemented invokeCharset: {f}", .{action}),
|
||||||
|
|
||||||
// LS3 - Locking Shift 3
|
// LS3 - Locking Shift 3
|
||||||
'o' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
'o' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
||||||
0 => try self.handler.invokeCharset(.GL, .G3, false),
|
0 => try self.handler.invokeCharset(.GL, .G3, false),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid single shift 3 command: {}", .{action});
|
log.warn("invalid single shift 3 command: {f}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
} else log.warn("unimplemented invokeCharset: {}", .{action}),
|
} else log.warn("unimplemented invokeCharset: {f}", .{action}),
|
||||||
|
|
||||||
// LS1R - Locking Shift 1 Right
|
// LS1R - Locking Shift 1 Right
|
||||||
'~' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
'~' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
||||||
0 => try self.handler.invokeCharset(.GR, .G1, false),
|
0 => try self.handler.invokeCharset(.GR, .G1, false),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid locking shift 1 right command: {}", .{action});
|
log.warn("invalid locking shift 1 right command: {f}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
} else log.warn("unimplemented invokeCharset: {}", .{action}),
|
} else log.warn("unimplemented invokeCharset: {f}", .{action}),
|
||||||
|
|
||||||
// LS2R - Locking Shift 2 Right
|
// LS2R - Locking Shift 2 Right
|
||||||
'}' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
'}' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
||||||
0 => try self.handler.invokeCharset(.GR, .G2, false),
|
0 => try self.handler.invokeCharset(.GR, .G2, false),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid locking shift 2 right command: {}", .{action});
|
log.warn("invalid locking shift 2 right command: {f}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
} else log.warn("unimplemented invokeCharset: {}", .{action}),
|
} else log.warn("unimplemented invokeCharset: {f}", .{action}),
|
||||||
|
|
||||||
// LS3R - Locking Shift 3 Right
|
// LS3R - Locking Shift 3 Right
|
||||||
'|' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
'|' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
||||||
0 => try self.handler.invokeCharset(.GR, .G3, false),
|
0 => try self.handler.invokeCharset(.GR, .G3, false),
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid locking shift 3 right command: {}", .{action});
|
log.warn("invalid locking shift 3 right command: {f}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
} else log.warn("unimplemented invokeCharset: {}", .{action}),
|
} else log.warn("unimplemented invokeCharset: {f}", .{action}),
|
||||||
|
|
||||||
// Set application keypad mode
|
// Set application keypad mode
|
||||||
'=' => if (@hasDecl(T, "setMode") and action.intermediates.len == 0) {
|
'=' => if (@hasDecl(T, "setMode") and action.intermediates.len == 0) {
|
||||||
try self.handler.setMode(.keypad_keys, true);
|
try self.handler.setMode(.keypad_keys, true);
|
||||||
} else log.warn("unimplemented setMode: {}", .{action}),
|
} else log.warn("unimplemented setMode: {f}", .{action}),
|
||||||
|
|
||||||
// Reset application keypad mode
|
// Reset application keypad mode
|
||||||
'>' => if (@hasDecl(T, "setMode") and action.intermediates.len == 0) {
|
'>' => if (@hasDecl(T, "setMode") and action.intermediates.len == 0) {
|
||||||
try self.handler.setMode(.keypad_keys, false);
|
try self.handler.setMode(.keypad_keys, false);
|
||||||
} else log.warn("unimplemented setMode: {}", .{action}),
|
} else log.warn("unimplemented setMode: {f}", .{action}),
|
||||||
|
|
||||||
else => if (@hasDecl(T, "escUnimplemented"))
|
else => if (@hasDecl(T, "escUnimplemented"))
|
||||||
try self.handler.escUnimplemented(action)
|
try self.handler.escUnimplemented(action)
|
||||||
else
|
else
|
||||||
log.warn("unimplemented ESC action: {}", .{action}),
|
log.warn("unimplemented ESC action: {f}", .{action}),
|
||||||
|
|
||||||
// Sets ST (string terminator). We don't have to do anything
|
// Sets ST (string terminator). We don't have to do anything
|
||||||
// because our parser always accepts ST.
|
// because our parser always accepts ST.
|
||||||
|
@@ -24,13 +24,9 @@ pub fn eql(a: Properties, b: Properties) bool {
|
|||||||
// Needed for lut.Generator
|
// Needed for lut.Generator
|
||||||
pub fn format(
|
pub fn format(
|
||||||
self: Properties,
|
self: Properties,
|
||||||
comptime layout: []const u8,
|
writer: *std.Io.Writer,
|
||||||
opts: std.fmt.FormatOptions,
|
|
||||||
writer: anytype,
|
|
||||||
) !void {
|
) !void {
|
||||||
_ = layout;
|
try writer.print(
|
||||||
_ = opts;
|
|
||||||
try std.fmt.format(writer,
|
|
||||||
\\.{{
|
\\.{{
|
||||||
\\ .width= {},
|
\\ .width= {},
|
||||||
\\ .grapheme_boundary_class= .{s},
|
\\ .grapheme_boundary_class= .{s},
|
||||||
|
@@ -54,12 +54,14 @@ pub fn Generator(
|
|||||||
defer blocks_map.deinit();
|
defer blocks_map.deinit();
|
||||||
|
|
||||||
// Our stages
|
// Our stages
|
||||||
var stage1 = std.ArrayList(u16).init(alloc);
|
var stage1: std.ArrayList(u16) = .empty;
|
||||||
defer stage1.deinit();
|
var stage2: std.ArrayList(u16) = .empty;
|
||||||
var stage2 = std.ArrayList(u16).init(alloc);
|
var stage3: std.ArrayList(Elem) = .empty;
|
||||||
defer stage2.deinit();
|
defer {
|
||||||
var stage3 = std.ArrayList(Elem).init(alloc);
|
stage1.deinit(alloc);
|
||||||
defer stage3.deinit();
|
stage2.deinit(alloc);
|
||||||
|
stage3.deinit(alloc);
|
||||||
|
}
|
||||||
|
|
||||||
var block: Block = undefined;
|
var block: Block = undefined;
|
||||||
var block_len: u16 = 0;
|
var block_len: u16 = 0;
|
||||||
@@ -74,7 +76,7 @@ pub fn Generator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const idx = stage3.items.len;
|
const idx = stage3.items.len;
|
||||||
try stage3.append(elem);
|
try stage3.append(alloc, elem);
|
||||||
break :block_idx idx;
|
break :block_idx idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -96,11 +98,11 @@ pub fn Generator(
|
|||||||
u16,
|
u16,
|
||||||
stage2.items.len,
|
stage2.items.len,
|
||||||
) orelse return error.Stage2TooLarge;
|
) orelse return error.Stage2TooLarge;
|
||||||
for (block[0..block_len]) |entry| try stage2.append(entry);
|
for (block[0..block_len]) |entry| try stage2.append(alloc, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map stage1 => stage2 and reset our block
|
// Map stage1 => stage2 and reset our block
|
||||||
try stage1.append(gop.value_ptr.*);
|
try stage1.append(alloc, gop.value_ptr.*);
|
||||||
block_len = 0;
|
block_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,11 +111,11 @@ pub fn Generator(
|
|||||||
assert(stage2.items.len <= std.math.maxInt(u16));
|
assert(stage2.items.len <= std.math.maxInt(u16));
|
||||||
assert(stage3.items.len <= std.math.maxInt(u16));
|
assert(stage3.items.len <= std.math.maxInt(u16));
|
||||||
|
|
||||||
const stage1_owned = try stage1.toOwnedSlice();
|
const stage1_owned = try stage1.toOwnedSlice(alloc);
|
||||||
errdefer alloc.free(stage1_owned);
|
errdefer alloc.free(stage1_owned);
|
||||||
const stage2_owned = try stage2.toOwnedSlice();
|
const stage2_owned = try stage2.toOwnedSlice(alloc);
|
||||||
errdefer alloc.free(stage2_owned);
|
errdefer alloc.free(stage2_owned);
|
||||||
const stage3_owned = try stage3.toOwnedSlice();
|
const stage3_owned = try stage3.toOwnedSlice(alloc);
|
||||||
errdefer alloc.free(stage3_owned);
|
errdefer alloc.free(stage3_owned);
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
@@ -145,7 +147,7 @@ pub fn Tables(comptime Elem: type) type {
|
|||||||
/// Writes the lookup table as Zig to the given writer. The
|
/// Writes the lookup table as Zig to the given writer. The
|
||||||
/// written file exports three constants: stage1, stage2, and
|
/// written file exports three constants: stage1, stage2, and
|
||||||
/// stage3. These can be used to rebuild the lookup table in Zig.
|
/// stage3. These can be used to rebuild the lookup table in Zig.
|
||||||
pub fn writeZig(self: *const Self, writer: anytype) !void {
|
pub fn writeZig(self: *const Self, writer: *std.Io.Writer) !void {
|
||||||
try writer.print(
|
try writer.print(
|
||||||
\\//! This file is auto-generated. Do not edit.
|
\\//! This file is auto-generated. Do not edit.
|
||||||
\\
|
\\
|
||||||
@@ -168,7 +170,13 @@ pub fn Tables(comptime Elem: type) type {
|
|||||||
\\
|
\\
|
||||||
\\pub const stage3: [{}]Elem = .{{
|
\\pub const stage3: [{}]Elem = .{{
|
||||||
, .{self.stage3.len});
|
, .{self.stage3.len});
|
||||||
for (self.stage3) |entry| try writer.print("{},", .{entry});
|
for (self.stage3) |entry| {
|
||||||
|
if (@typeInfo(@TypeOf(entry)) == .@"struct" and
|
||||||
|
@hasDecl(@TypeOf(entry), "format"))
|
||||||
|
try writer.print("{f},", .{entry})
|
||||||
|
else
|
||||||
|
try writer.print("{},", .{entry});
|
||||||
|
}
|
||||||
try writer.writeAll(
|
try writer.writeAll(
|
||||||
\\};
|
\\};
|
||||||
\\ };
|
\\ };
|
||||||
|
@@ -84,7 +84,11 @@ pub fn main() !void {
|
|||||||
defer alloc.free(t.stage1);
|
defer alloc.free(t.stage1);
|
||||||
defer alloc.free(t.stage2);
|
defer alloc.free(t.stage2);
|
||||||
defer alloc.free(t.stage3);
|
defer alloc.free(t.stage3);
|
||||||
try t.writeZig(std.io.getStdOut().writer());
|
|
||||||
|
var buf: [4096]u8 = undefined;
|
||||||
|
var stdout = std.fs.File.stdout().writer(&buf);
|
||||||
|
try t.writeZig(&stdout.interface);
|
||||||
|
try stdout.end();
|
||||||
|
|
||||||
// Uncomment when manually debugging to see our table sizes.
|
// Uncomment when manually debugging to see our table sizes.
|
||||||
// std.log.warn("stage1={} stage2={} stage3={}", .{
|
// std.log.warn("stage1={} stage2={} stage3={}", .{
|
||||||
|
@@ -30,7 +30,11 @@ pub fn main() !void {
|
|||||||
defer alloc.free(t.stage1);
|
defer alloc.free(t.stage1);
|
||||||
defer alloc.free(t.stage2);
|
defer alloc.free(t.stage2);
|
||||||
defer alloc.free(t.stage3);
|
defer alloc.free(t.stage3);
|
||||||
try t.writeZig(std.io.getStdOut().writer());
|
|
||||||
|
var buf: [4096]u8 = undefined;
|
||||||
|
var stdout = std.fs.File.stdout().writer(&buf);
|
||||||
|
try t.writeZig(&stdout.interface);
|
||||||
|
try stdout.end();
|
||||||
|
|
||||||
// Uncomment when manually debugging to see our table sizes.
|
// Uncomment when manually debugging to see our table sizes.
|
||||||
// std.log.warn("stage1={} stage2={} stage3={}", .{
|
// std.log.warn("stage1={} stage2={} stage3={}", .{
|
||||||
|
Reference in New Issue
Block a user