diff --git a/src/terminal/ScreenSet.zig b/src/terminal/ScreenSet.zig --- a/src/terminal/ScreenSet.zig +++ b/src/terminal/ScreenSet.zig @@ -9,16 +9,13 @@ const std = @import("std"); const assert = @import("../quirks.zig").inlineAssert; -const build_options = @import("terminal_options"); -const lib = @import("../lib/main.zig"); +const lib = @import("lib.zig"); const testing = std.testing; const Allocator = std.mem.Allocator; const Screen = @import("Screen.zig"); -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; - /// The possible keys for screens in the screen set. -pub const Key = lib.Enum(lib_target, &.{ +pub const Key = lib.Enum(lib.target, &.{ "primary", "alternate", }); diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -5,7 +5,7 @@ const std = @import("std"); const build_options = @import("terminal_options"); -const lib = @import("../lib/main.zig"); +const lib = @import("lib.zig"); const assert = @import("../quirks.zig").inlineAssert; const testing = std.testing; const Allocator = std.mem.Allocator; @@ -34,8 +34,6 @@ const Page = pagepkg.Page; const Cell = pagepkg.Cell; const Row = pagepkg.Row; - -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; const log = std.log.scoped(.terminal); @@ -1706,14 +1704,14 @@ /// Scroll by some delta amount, up is negative. delta: isize, - pub const Tag = lib.Enum(lib_target, &.{ + pub const Tag = lib.Enum(lib.target, &.{ "top", "bottom", "delta", }); const c_union = lib.TaggedUnion( - lib_target, + lib.target, @This(), // Padding: largest variant is isize (8 bytes on 64-bit). // Use [2]u64 (16 bytes) for future expansion. diff --git a/src/terminal/ansi.zig b/src/terminal/ansi.zig --- a/src/terminal/ansi.zig +++ b/src/terminal/ansi.zig @@ -1,6 +1,4 @@ -const build_options = @import("terminal_options"); -const lib = @import("../lib/main.zig"); -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; +const lib = @import("lib.zig"); /// C0 (7-bit) control characters from ANSI. /// @@ -54,7 +52,7 @@ /// Possible cursor styles (ESC [ q) pub const CursorStyle = lib.Enum( - lib_target, + lib.target, &.{ "default", "blinking_block", @@ -78,7 +76,7 @@ /// The display to target for status updates (DECSASD). pub const StatusDisplay = lib.Enum( - lib_target, + lib.target, &.{ "main", "status_line", @@ -88,7 +86,7 @@ /// The possible modify key formats to ESC[>{a};{b}m /// Note: this is not complete, we should add more as we support more pub const ModifyKeyFormat = lib.Enum( - lib_target, + lib.target, &.{ "legacy", "cursor_keys", diff --git a/src/terminal/csi.zig b/src/terminal/csi.zig --- a/src/terminal/csi.zig +++ b/src/terminal/csi.zig @@ -1,6 +1,4 @@ -const build_options = @import("terminal_options"); -const lib = @import("../lib/main.zig"); -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; +const lib = @import("lib.zig"); /// Modes for the ED CSI command. pub const EraseDisplay = enum(u8) { @@ -38,7 +36,7 @@ /// Style formats for terminal size reports. pub const SizeReportStyle = lib.Enum( - lib_target, + lib.target, &.{ // XTWINOPS "csi_14_t", diff --git a/src/terminal/device_attributes.zig b/src/terminal/device_attributes.zig --- a/src/terminal/device_attributes.zig +++ b/src/terminal/device_attributes.zig @@ -1,11 +1,9 @@ const std = @import("std"); const testing = std.testing; -const build_options = @import("terminal_options"); -const lib = @import("../lib/main.zig"); -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; +const lib = @import("lib.zig"); /// The device attribute request type (CSI c). -pub const Req = lib.Enum(lib_target, &.{ +pub const Req = lib.Enum(lib.target, &.{ "primary", // Blank "secondary", // > "tertiary", // = diff --git a/src/terminal/device_status.zig b/src/terminal/device_status.zig --- a/src/terminal/device_status.zig +++ b/src/terminal/device_status.zig @@ -1,10 +1,8 @@ const std = @import("std"); -const build_options = @import("terminal_options"); -const lib = @import("../lib/main.zig"); -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; +const lib = @import("lib.zig"); /// The color scheme reported in response to a CSI ? 996 n query. -pub const ColorScheme = lib.Enum(lib_target, &.{ +pub const ColorScheme = lib.Enum(lib.target, &.{ "light", "dark", }); diff --git a/src/terminal/focus.zig b/src/terminal/focus.zig --- a/src/terminal/focus.zig +++ b/src/terminal/focus.zig @@ -1,7 +1,5 @@ const std = @import("std"); -const build_options = @import("terminal_options"); -const lib = @import("../lib/main.zig"); -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; +const lib = @import("lib.zig"); /// Maximum number of bytes that `encode` will write. Any users of this /// should be resilient to this changing, so this is always a specific @@ -10,7 +8,7 @@ /// A focus event that can be reported to the application running in the /// terminal when focus reporting mode (mode 1004) is enabled. -pub const Event = lib.Enum(lib_target, &.{ +pub const Event = lib.Enum(lib.target, &.{ "gained", "lost", }); diff --git a/src/terminal/formatter.zig b/src/terminal/formatter.zig --- a/src/terminal/formatter.zig +++ b/src/terminal/formatter.zig @@ -1,8 +1,6 @@ const std = @import("std"); -const build_options = @import("terminal_options"); const assert = @import("../quirks.zig").inlineAssert; -const lib = @import("../lib/main.zig"); -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; +const lib = @import("lib.zig"); const Allocator = std.mem.Allocator; const color = @import("color.zig"); const size = @import("size.zig"); @@ -22,7 +20,7 @@ const Style = @import("style.zig").Style; /// Formats available. -pub const Format = lib.Enum(lib_target, &.{ +pub const Format = lib.Enum(lib.target, &.{ // Plain text. "plain", diff --git a/src/terminal/lib.zig b/src/terminal/lib.zig new file mode 100644 --- /dev/null +++ b/src/terminal/lib.zig @@ -0,0 +1,23 @@ +const std = @import("std"); +const build_options = @import("terminal_options"); +const lib = @import("../lib/main.zig"); + +/// The target for the terminal lib in particular. +pub const target: lib.Target = if (build_options.c_abi) .c else .zig; + +/// The calling convention to use for C APIs. If we're not building for +/// C ABI then we use auto which allows our C APIs to be cleanly called +/// by Zig. This is required because we modify our struct layouts based +/// on C ABI too. +pub const calling_conv: std.builtin.CallingConvention = if (build_options.c_abi) + .c +else + .auto; + +/// Forwarded decls from lib that are used. +pub const Enum = lib.Enum; +pub const TaggedUnion = lib.TaggedUnion; +pub const Struct = lib.Struct; +pub const String = lib.String; +pub const checkGhosttyHEnum = lib.checkGhosttyHEnum; +pub const structSizedFieldFits = lib.structSizedFieldFits; diff --git a/src/terminal/mouse.zig b/src/terminal/mouse.zig --- a/src/terminal/mouse.zig +++ b/src/terminal/mouse.zig @@ -1,11 +1,10 @@ const std = @import("std"); const build_options = @import("terminal_options"); -const lib = @import("../lib/main.zig"); -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; +const lib = @import("lib.zig"); /// The event types that can be reported for mouse-related activities. /// These are all mutually exclusive (hence in a single enum). -pub const Event = lib.Enum(lib_target, &.{ +pub const Event = lib.Enum(lib.target, &.{ "none", "x10", // 9 "normal", // 1000 @@ -20,7 +19,7 @@ /// The format of mouse events when enabled. /// These are all mutually exclusive (hence in a single enum). -pub const Format = lib.Enum(lib_target, &.{ +pub const Format = lib.Enum(lib.target, &.{ "x10", "utf8", // 1005 "sgr", // 1006 diff --git a/src/terminal/osc.zig b/src/terminal/osc.zig --- a/src/terminal/osc.zig +++ b/src/terminal/osc.zig @@ -11,11 +11,11 @@ const mem = std.mem; const assert = @import("../quirks.zig").inlineAssert; const Allocator = mem.Allocator; -const LibEnum = @import("../lib/enum.zig").Enum; +const lib = @import("lib.zig"); +const LibEnum = lib.Enum; const kitty_color = @import("kitty/color.zig"); const parsers = @import("osc/parsers.zig"); const encoding = @import("osc/encoding.zig"); -const lib = @import("../lib/main.zig"); pub const color = parsers.color; pub const semantic_prompt = parsers.semantic_prompt; @@ -165,7 +165,7 @@ pub const KittyClipboardProtocol = parsers.kitty_clipboard_protocol.OSC; pub const Key = LibEnum( - if (build_options.c_abi) .c else .zig, + lib.target, // NOTE: Order matters, see LibEnum documentation. &.{ "invalid", diff --git a/src/terminal/point.zig b/src/terminal/point.zig --- a/src/terminal/point.zig +++ b/src/terminal/point.zig @@ -1,10 +1,7 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const build_options = @import("terminal_options"); -const lib = @import("../lib/main.zig"); +const lib = @import("lib.zig"); const size = @import("size.zig"); - -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; /// The possible reference locations for a point. When someone says "(42, 80)" /// in the context of a terminal, that could mean multiple things: it is in the @@ -12,7 +9,7 @@ /// cursor is? the entire scrollback history? etc. /// /// This tag is used to differentiate those cases. -pub const Tag = lib.Enum(lib_target, &.{ +pub const Tag = lib.Enum(lib.target, &.{ // Top-left is part of the active area where a running program can // jump the cursor and make changes. The active area is the "editable" // part of the screen. @@ -70,7 +67,7 @@ } const c_union = lib.TaggedUnion( - lib_target, + lib.target, @This(), // Padding: largest variant is Coordinate (u16 + u32 = 6 bytes). // Use [2]u64 (16 bytes) for future expansion. diff --git a/src/terminal/render.zig b/src/terminal/render.zig --- a/src/terminal/render.zig +++ b/src/terminal/render.zig @@ -1,11 +1,9 @@ const std = @import("std"); -const build_options = @import("terminal_options"); const assert = @import("../quirks.zig").inlineAssert; const Allocator = std.mem.Allocator; const ArenaAllocator = std.heap.ArenaAllocator; const fastmem = @import("../fastmem.zig"); -const lib = @import("../lib/main.zig"); -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; +const lib = @import("lib.zig"); const color = @import("color.zig"); const cursor = @import("cursor.zig"); const highlight = @import("highlight.zig"); @@ -226,7 +224,7 @@ }; // Dirty state. - pub const Dirty = lib.Enum(lib_target, &.{ + pub const Dirty = lib.Enum(lib.target, &.{ // Not dirty at all. Can skip rendering if prior state was // already rendered. "false", diff --git a/src/terminal/sgr.zig b/src/terminal/sgr.zig --- a/src/terminal/sgr.zig +++ b/src/terminal/sgr.zig @@ -1,14 +1,11 @@ //! SGR (Select Graphic Rendition) attrinvbute parsing and types. const std = @import("std"); -const build_options = @import("terminal_options"); const assert = @import("../quirks.zig").inlineAssert; const testing = std.testing; -const lib = @import("../lib/main.zig"); +const lib = @import("lib.zig"); const color = @import("color.zig"); const SepList = @import("Parser.zig").Action.CSI.SepList; - -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; /// Attribute type for SGR pub const Attribute = union(Tag) { @@ -81,7 +78,7 @@ @"256_fg": u8, pub const Tag = lib.Enum( - lib_target, + lib.target, &.{ "unset", "unknown", @@ -158,7 +155,7 @@ /// C ABI functions. const c_union = lib.TaggedUnion( - lib_target, + lib.target, @This(), // Padding size for C ABI compatibility. // Largest variant is Unknown.C: 2 pointers + 2 usize = 32 bytes on 64-bit. diff --git a/src/terminal/size_report.zig b/src/terminal/size_report.zig --- a/src/terminal/size_report.zig +++ b/src/terminal/size_report.zig @@ -1,11 +1,9 @@ const std = @import("std"); -const build_options = @import("terminal_options"); -const lib = @import("../lib/main.zig"); -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; +const lib = @import("lib.zig"); const CellCountInt = @import("size.zig").CellCountInt; /// Output formats for terminal size reports written to the PTY. -pub const Style = lib.Enum(lib_target, &.{ +pub const Style = lib.Enum(lib.target, &.{ // In-band size reports (mode 2048) "mode_2048", // XTWINOPS: report text area size in pixels @@ -17,7 +15,7 @@ }); /// Runtime size values used to encode terminal size reports. -pub const Size = lib.Struct(lib_target, struct { +pub const Size = lib.Struct(lib.target, struct { /// Terminal row count in cells. rows: CellCountInt, diff --git a/src/terminal/stream.zig b/src/terminal/stream.zig --- a/src/terminal/stream.zig +++ b/src/terminal/stream.zig @@ -5,7 +5,7 @@ const testing = std.testing; const Allocator = std.mem.Allocator; const simd = @import("../simd/main.zig"); -const lib = @import("../lib/main.zig"); +const lib = @import("lib.zig"); const Parser = @import("Parser.zig"); const ansi = @import("ansi.zig"); const charsets = @import("charsets.zig"); @@ -28,8 +28,6 @@ /// debugging an issue in the SIMD code then you'll need to /// do something else. const debug = false; - -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; /// The possible actions that can be emitted by the Stream /// function for handling. @@ -129,7 +127,7 @@ semantic_prompt: SemanticPrompt, pub const Key = lib.Enum( - lib_target, + lib.target, &.{ "print", "print_repeat", @@ -229,7 +227,7 @@ /// C ABI functions. const c_union = lib.TaggedUnion( - lib_target, + lib.target, @This(), // TODO: Before shipping an ABI-compatible libghostty, verify this. // This was just arbitrarily chosen for now. @@ -254,7 +252,7 @@ } }; - pub const InvokeCharset = lib.Struct(lib_target, struct { + pub const InvokeCharset = lib.Struct(lib.target, struct { bank: charsets.ActiveSlot, charset: charsets.Slots, locking: bool, @@ -384,7 +382,7 @@ } }; - pub const ConfigureCharset = lib.Struct(lib_target, struct { + pub const ConfigureCharset = lib.Struct(lib.target, struct { slot: charsets.Slots, charset: charsets.Charset, }); diff --git a/src/terminal/c/render.zig b/src/terminal/c/render.zig --- a/src/terminal/c/render.zig +++ b/src/terminal/c/render.zig @@ -1,7 +1,7 @@ const std = @import("std"); const testing = std.testing; const Allocator = std.mem.Allocator; -const lib = @import("../../lib/main.zig"); +const lib = @import("../lib.zig"); const lib_alloc = @import("../../lib/allocator.zig"); const CAllocator = lib_alloc.Allocator; const colorpkg = @import("../color.zig"); diff --git a/src/terminal/c/terminal.zig b/src/terminal/c/terminal.zig --- a/src/terminal/c/terminal.zig +++ b/src/terminal/c/terminal.zig @@ -1,6 +1,6 @@ const std = @import("std"); const testing = std.testing; -const lib = @import("../../lib/main.zig"); +const lib = @import("../lib.zig"); const lib_alloc = @import("../../lib/allocator.zig"); const CAllocator = lib_alloc.Allocator; const ZigTerminal = @import("../Terminal.zig"); diff --git a/src/terminal/osc/parsers/kitty_text_sizing.zig b/src/terminal/osc/parsers/kitty_text_sizing.zig --- a/src/terminal/osc/parsers/kitty_text_sizing.zig +++ b/src/terminal/osc/parsers/kitty_text_sizing.zig @@ -2,27 +2,25 @@ //! Specification: https://sw.kovidgoyal.net/kitty/text-sizing-protocol/ const std = @import("std"); -const build_options = @import("terminal_options"); const assert = @import("../../../quirks.zig").inlineAssert; const Parser = @import("../../osc.zig").Parser; const Command = @import("../../osc.zig").Command; const encoding = @import("../encoding.zig"); -const lib = @import("../../../lib/main.zig"); -const lib_target: lib.Target = if (build_options.c_abi) .c else .zig; +const lib = @import("../../lib.zig"); const log = std.log.scoped(.kitty_text_sizing); pub const max_payload_length = 4096; -pub const VAlign = lib.Enum(lib_target, &.{ +pub const VAlign = lib.Enum(lib.target, &.{ "top", "bottom", "center", }); -pub const HAlign = lib.Enum(lib_target, &.{ +pub const HAlign = lib.Enum(lib.target, &.{ "left", "right", "center",