diff --git a/README.md b/README.md index eff2ee2..d4e1889 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Or check your favorite local system package repository. Make sure your system meets the requirements listed above. -Flow builds with zig 0.13 at this time. Build with: +Flow builds with zig 0.14.0 at this time. Build with: ```shell zig build -Doptimize=ReleaseSafe diff --git a/build.zig b/build.zig index 2a364df..a2735ec 100644 --- a/build.zig +++ b/build.zig @@ -89,7 +89,7 @@ fn build_release( .{ .cpu_arch = .x86_64, .os_tag = .windows }, .{ .cpu_arch = .aarch64, .os_tag = .windows }, }; - const optimize = .ReleaseSafe; + const optimize = .ReleaseFast; var version = std.ArrayList(u8).init(b.allocator); defer version.deinit(); @@ -583,7 +583,7 @@ pub fn build_exe( }); lint_step.dependOn(&lints.step); - // b.default_step.dependOn(lint_step); + b.default_step.dependOn(lint_step); } fn gen_version_info( diff --git a/build.zig.version b/build.zig.version index 54d1a4f..a803cc2 100644 --- a/build.zig.version +++ b/build.zig.version @@ -1 +1 @@ -0.13.0 +0.14.0 diff --git a/build.zig.zon b/build.zig.zon index ed19001..d61e402 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,41 +1,42 @@ .{ - .name = "flow", + .name = .flow, .version = "0.2.0", - .minimum_zig_version = "0.13.0", + .minimum_zig_version = "0.14.0", + .fingerprint = 0x52c0d670590aa80f, .dependencies = .{ .syntax = .{ .path = "src/syntax" }, .flags = .{ - .url = "https://github.com/n0s4/flags/archive/b3905aa990719ff567f1c5a2f89e6dd3292d8533.tar.gz", - .hash = "1220930a42f8da3fb7f723e3ad3f6dcc6db76327dd8d26274566423192d53e91b2bb", + .url = "https://github.com/n0s4/flags/archive/372501d1576b5723829bcba98e41361132c7b618.tar.gz", + .hash = "1220ae181067a549c7a99cc0868193a7889b151381410419191ab1a79304f914336e", }, .dizzy = .{ .url = "https://github.com/neurocyte/dizzy/archive/455d18369cbb2a0458ba70be919cd378338d695e.tar.gz", .hash = "1220220dbc7fe91c1c54438193ca765cebbcb7d58f35cdcaee404a9d2245a42a4362", }, .thespian = .{ - .url = "https://github.com/neurocyte/thespian/archive/9ca04ddfc715e0f7d29d3f6b39269ad9bf174230.tar.gz", - .hash = "1220b05b5949454bf155a802d5034c060431b8bf59f9d4d2d5241397e9fd201d78d9", + .url = "https://github.com/neurocyte/thespian/archive/78c9c1292c683478d8ac98d8318bc098442cc0b9.tar.gz", + .hash = "thespian-0.0.1-owFOjsnnBgBCsKhYw9XeHnQw0Um9SJQECEZ0aqomc04m", }, .themes = .{ .url = "https://github.com/neurocyte/flow-themes/releases/download/master-59bf204551bcb238faddd06779063570e7e6d431/flow-themes.tar.gz", .hash = "12209a213a392ea80ea5c7dde125e7161bb0278ac4b99db9df2b7af783710bcb09f7", }, .fuzzig = .{ - .url = "https://github.com/fjebaker/fuzzig/archive/0fd156d5097365151e85a85eef9d8cf0eebe7b00.tar.gz", - .hash = "122019f077d09686b1ec47928ca2b4bf264422f3a27afc5b49dafb0129a4ceca0d01", + .url = "https://github.com/fjebaker/fuzzig/archive/44c04733c7c0fee3db83672aaaaf4ed03e943156.tar.gz", + .hash = "1220666c7afe30f6a51ae477f7755e9b6a5341723bfcb5de349817b5d0912b96f9ad", }, .vaxis = .{ - .url = "https://github.com/neurocyte/libvaxis/archive/e518e139417a9773f59624961b02e05b8fffff35.tar.gz", - .hash = "122045fec2cedf3f68c20f961c42f3ca1e901238aec5a0c7b3b632cd21ce3b621f76", + .url = "https://github.com/neurocyte/libvaxis/archive/da7d26fa0e86c721414bdcb82ea46cf0b4da5b68.tar.gz", + .hash = "1220fe019c2901695c959873ef9b1736bd04197d377ad1c520eff8affd5204dd2bc2", }, .zeit = .{ .url = "https://github.com/rockorager/zeit/archive/8fd203f85f597f16e0a525c1f1ca1e0bffded809.tar.gz", .hash = "122022233835adc719535a8e7cefdd2902a67bbfb7ef198441ca9ce89c0593f488c2", }, .win32 = .{ - .url = "https://github.com/marlersoft/zigwin32/archive/259b6f353a48968d7e3171573db4fd898b046188.tar.gz", - .hash = "1220925614447b54ccc9894bbba8b202c6a8b750267890edab7732064867e46f3217", + .url = "https://github.com/marlersoft/zigwin32/archive/e8739b32a33ce48a3286aba31918b26a9dfc6ef0.tar.gz", + .hash = "1220219ca4acfa5804ca39945f92554e93507b077c03605b7a4c1c0401f0c7121339", .lazy = true, }, }, diff --git a/src/EventHandler.zig b/src/EventHandler.zig index 37b6bf1..879ba12 100644 --- a/src/EventHandler.zig +++ b/src/EventHandler.zig @@ -16,7 +16,7 @@ pub const VTable = struct { pub fn to_owned(pimpl: anytype) Self { const impl = @typeInfo(@TypeOf(pimpl)); - const child: type = impl.Pointer.child; + const child: type = impl.pointer.child; return .{ .ptr = pimpl, .vtable = comptime &.{ @@ -56,7 +56,7 @@ var none = {}; pub fn to_unowned(pimpl: anytype) Self { const impl = @typeInfo(@TypeOf(pimpl)); - const child: type = impl.Pointer.child; + const child: type = impl.pointer.child; return .{ .ptr = pimpl, .vtable = comptime &.{ @@ -79,7 +79,7 @@ pub fn to_unowned(pimpl: anytype) Self { pub fn bind(pimpl: anytype, comptime f: *const fn (ctx: @TypeOf(pimpl), from: tp.pid_ref, m: tp.message) tp.result) Self { const impl = @typeInfo(@TypeOf(pimpl)); - const child: type = impl.Pointer.child; + const child: type = impl.pointer.child; return .{ .ptr = pimpl, .vtable = comptime &.{ diff --git a/src/LSP.zig b/src/LSP.zig index b14c5a5..61bc845 100644 --- a/src/LSP.zig +++ b/src/LSP.zig @@ -172,9 +172,9 @@ const Process = struct { const frame = tracy.initZone(@src(), .{ .name = module_name }); defer frame.deinit(); errdefer self.deinit(); - var method: []u8 = ""; - var bytes: []u8 = ""; - var err: []u8 = ""; + var method: []const u8 = ""; + var bytes: []const u8 = ""; + var err: []const u8 = ""; var code: u32 = 0; var cbor_id: []const u8 = ""; @@ -259,7 +259,7 @@ const Process = struct { } } - fn handle_output(self: *Process, bytes: []u8) Error!void { + fn handle_output(self: *Process, bytes: []const u8) Error!void { try self.recv_buf.appendSlice(bytes); self.write_log("### RECV:\n{s}\n###\n", .{bytes}); self.frame_message_recv() catch |e| { diff --git a/src/buffer/Buffer.zig b/src/buffer/Buffer.zig index e2ed666..cb1de28 100644 --- a/src/buffer/Buffer.zig +++ b/src/buffer/Buffer.zig @@ -55,7 +55,7 @@ file_type_icon: ?[]const u8 = null, file_type_color: ?u24 = null, pub const EolMode = enum { lf, crlf }; -pub const EolModeTag = @typeInfo(EolMode).Enum.tag_type; +pub const EolModeTag = @typeInfo(EolMode).@"enum".tag_type; const UndoNode = struct { root: Root, @@ -71,26 +71,26 @@ const UndoBranch = struct { }; pub const WalkerMut = struct { - keep_walking: bool = false, - found: bool = false, + keep_walking_: bool = false, + found_: bool = false, replace: ?Root = null, err: ?anyerror = null, - pub const keep_walking = WalkerMut{ .keep_walking = true }; - pub const stop = WalkerMut{ .keep_walking = false }; - pub const found = WalkerMut{ .found = true }; + pub const keep_walking = WalkerMut{ .keep_walking_ = true }; + pub const stop = WalkerMut{ .keep_walking_ = false }; + pub const found = WalkerMut{ .found_ = true }; const F = *const fn (ctx: *anyopaque, leaf: *const Leaf, metrics: Metrics) WalkerMut; }; pub const Walker = struct { - keep_walking: bool = false, - found: bool = false, + keep_walking_: bool = false, + found_: bool = false, err: ?anyerror = null, - pub const keep_walking = Walker{ .keep_walking = true }; - pub const stop = Walker{ .keep_walking = false }; - pub const found = Walker{ .found = true }; + pub const keep_walking = Walker{ .keep_walking_ = true }; + pub const stop = Walker{ .keep_walking_ = false }; + pub const found = Walker{ .found_ = true }; const F = *const fn (ctx: *anyopaque, leaf: *const Leaf, metrics: Metrics) Walker; }; @@ -126,8 +126,8 @@ pub const Branch = struct { fn merge_results_const(_: *const Branch, left: Walker, right: Walker) Walker { var result = Walker{}; result.err = if (left.err) |_| left.err else right.err; - result.keep_walking = left.keep_walking and right.keep_walking; - result.found = left.found or right.found; + result.keep_walking_ = left.keep_walking_ and right.keep_walking_; + result.found_ = left.found_ or right.found_; return result; } @@ -144,8 +144,8 @@ pub const Branch = struct { else Node.new(allocator, new_left, new_right) catch |e| return .{ .err = e }; } - result.keep_walking = left.keep_walking and right.keep_walking; - result.found = left.found or right.found; + result.keep_walking_ = left.keep_walking_ and right.keep_walking_; + result.found_ = left.found_ or right.found_; return result; } }; @@ -350,10 +350,10 @@ const Node = union(enum) { switch (self.*) { .node => |*node| { const left = node.left.walk_const(f, ctx, metrics); - if (!left.keep_walking) { + if (!left.keep_walking_) { var result = Walker{}; result.err = left.err; - result.found = left.found; + result.found_ = left.found_; return result; } const right = node.right.walk_const(f, ctx, metrics); @@ -367,10 +367,10 @@ const Node = union(enum) { switch (self.*) { .node => |*node| { const left = node.left.walk(allocator, f, ctx, metrics); - if (!left.keep_walking) { + if (!left.keep_walking_) { var result = WalkerMut{}; result.err = left.err; - result.found = left.found; + result.found_ = left.found_; if (left.replace) |p| { result.replace = Node.new(allocator, p, node.right) catch |e| return .{ .err = e }; } @@ -390,14 +390,14 @@ const Node = union(enum) { if (line >= left_bols) return node.right.walk_from_line_begin_const_internal(line - left_bols, f, ctx, metrics); const left_result = node.left.walk_from_line_begin_const_internal(line, f, ctx, metrics); - const right_result = if (left_result.found and left_result.keep_walking) node.right.walk_const(f, ctx, metrics) else Walker{}; + const right_result = if (left_result.found_ and left_result.keep_walking_) node.right.walk_const(f, ctx, metrics) else Walker{}; return node.merge_results_const(left_result, right_result); }, .leaf => |*l| { if (line == 0) { var result = f(ctx, l, metrics); if (result.err) |_| return result; - result.found = true; + result.found_ = true; return result; } return Walker.keep_walking; @@ -408,7 +408,7 @@ const Node = union(enum) { pub fn walk_from_line_begin_const(self: *const Node, line: usize, f: Walker.F, ctx: *anyopaque, metrics: Metrics) !bool { const result = self.walk_from_line_begin_const_internal(line, f, ctx, metrics); if (result.err) |e| return e; - return result.found; + return result.found_; } fn walk_from_line_begin_internal(self: *const Node, allocator: Allocator, line: usize, f: WalkerMut.F, ctx: *anyopaque, metrics: Metrics) WalkerMut { @@ -420,8 +420,8 @@ const Node = union(enum) { if (right_result.replace) |p| { var result = WalkerMut{}; result.err = right_result.err; - result.found = right_result.found; - result.keep_walking = right_result.keep_walking; + result.found_ = right_result.found_; + result.keep_walking_ = right_result.keep_walking_; result.replace = if (p.is_empty()) node.left else @@ -432,7 +432,7 @@ const Node = union(enum) { } } const left_result = node.left.walk_from_line_begin_internal(allocator, line, f, ctx, metrics); - const right_result = if (left_result.found and left_result.keep_walking) node.right.walk(allocator, f, ctx, metrics) else WalkerMut{}; + const right_result = if (left_result.found_ and left_result.keep_walking_) node.right.walk(allocator, f, ctx, metrics) else WalkerMut{}; return node.merge_results(allocator, left_result, right_result); }, .leaf => |*l| { @@ -442,7 +442,7 @@ const Node = union(enum) { result.replace = null; return result; } - result.found = true; + result.found_ = true; return result; } return WalkerMut.keep_walking; @@ -453,7 +453,7 @@ const Node = union(enum) { pub fn walk_from_line_begin(self: *const Node, allocator: Allocator, line: usize, f: WalkerMut.F, ctx: *anyopaque, metrics: Metrics) !struct { bool, ?Root } { const result = self.walk_from_line_begin_internal(allocator, line, f, ctx, metrics); if (result.err) |e| return e; - return .{ result.found, result.replace }; + return .{ result.found_, result.replace }; } fn find_line_node(self: *const Node, line: usize) ?*const Node { @@ -508,12 +508,12 @@ const Node = union(enum) { if (ret.err) |e| return .{ .err = e }; buf = buf[bytes..]; ctx.abs_col += @intCast(cols); - if (!ret.keep_walking) return Walker.stop; + if (!ret.keep_walking_) return Walker.stop; } if (leaf.eol) { const ret = ctx.walker_f(ctx.walker_ctx, "\n", 1, metrics); if (ret.err) |e| return .{ .err = e }; - if (!ret.keep_walking) return Walker.stop; + if (!ret.keep_walking_) return Walker.stop; ctx.abs_col = 0; } return Walker.keep_walking; @@ -670,7 +670,7 @@ const Node = union(enum) { var result = WalkerMut.keep_walking; if (ctx.delete_next_bol and ctx.bytes == 0) { result.replace = Leaf.new(ctx.allocator, leaf.buf, false, leaf.eol) catch |e| return .{ .err = e }; - result.keep_walking = false; + result.keep_walking_ = false; ctx.delete_next_bol = false; return result; } @@ -724,7 +724,7 @@ const Node = union(enum) { } } if (ctx.bytes == 0 and !ctx.delete_next_bol) - result.keep_walking = false; + result.keep_walking_ = false; } return result; } @@ -1211,6 +1211,9 @@ pub const LoadFromFileError = error{ DanglingSurrogateHalf, ExpectedSecondSurrogateHalf, UnexpectedSecondSurrogateHalf, + LockViolation, + ProcessNotFound, + Canceled, }; pub fn load_from_file( @@ -1302,6 +1305,7 @@ pub const StoreToFileError = error{ PathAlreadyExists, PipeBusy, ProcessFdQuotaExceeded, + ProcessNotFound, ReadOnlyFileSystem, RenameAcrossMountPoints, SharingViolation, diff --git a/src/command.zig b/src/command.zig index 44de9e6..b3b0bf6 100644 --- a/src/command.zig +++ b/src/command.zig @@ -216,7 +216,7 @@ fn getTargetType(comptime Namespace: type) type { fn getCommands(comptime Namespace: type) []const CmdDef(*getTargetType(Namespace)) { @setEvalBranchQuota(10_000); comptime switch (@typeInfo(Namespace)) { - .Struct => |info| { + .@"struct" => |info| { var count = 0; const Target = getTargetType(Namespace); // @compileLog(Namespace, Target); @@ -257,14 +257,14 @@ pub fn Collection(comptime Namespace: type) type { fields_var[i] = .{ .name = cmd.name, .type = Clsr, - .default_value = null, + .default_value_ptr = null, .is_comptime = false, .alignment = if (@sizeOf(Clsr) > 0) @alignOf(Clsr) else 0, }; } const fields: [cmds.len]std.builtin.Type.StructField = fields_var; const Fields = @Type(.{ - .Struct = .{ + .@"struct" = .{ .is_tuple = false, .layout = .auto, .decls = &.{}, diff --git a/src/keybind/parse_flow.zig b/src/keybind/parse_flow.zig index 792aa26..4fe04c9 100644 --- a/src/keybind/parse_flow.zig +++ b/src/keybind/parse_flow.zig @@ -29,7 +29,7 @@ pub fn parse_key_events(allocator: std.mem.Allocator, str: []const u8) ParseErro var iter = std.mem.tokenizeScalar(u8, item, '+'); loop: while (iter.next()) |part| { if (part.len == 0) return parse_error("empty part in '{s}'", .{str}); - const modsInfo = @typeInfo(input.ModSet).Struct; + const modsInfo = @typeInfo(input.ModSet).@"struct"; inline for (modsInfo.fields) |field| { if (std.mem.eql(u8, part, field.name)) { if (@field(mods, field.name)) return parse_error("duplicate modifier '{s}' in '{s}'", .{ part, str }); diff --git a/src/location_history.zig b/src/location_history.zig index c64c43f..98d5864 100644 --- a/src/location_history.zig +++ b/src/location_history.zig @@ -123,13 +123,13 @@ const Process = struct { if (isdupe(self.backwards.getLastOrNull(), entry)) { if (self.current) |current| self.forwards.append(current) catch {}; - const top = self.backwards.pop(); - self.allocator.free(top.file_path); + if (self.backwards.pop()) |top| + self.allocator.free(top.file_path); tp.trace(tp.channel.all, tp.message.fmt(.{ "location", "back", entry.file_path, entry.cursor.row, entry.cursor.col, self.backwards.items.len, self.forwards.items.len })); } else if (isdupe(self.forwards.getLastOrNull(), entry)) { if (self.current) |current| self.backwards.append(current) catch {}; - const top = self.forwards.pop(); - self.allocator.free(top.file_path); + if (self.forwards.pop()) |top| + self.allocator.free(top.file_path); tp.trace(tp.channel.all, tp.message.fmt(.{ "location", "forward", entry.file_path, entry.cursor.row, entry.cursor.col, self.backwards.items.len, self.forwards.items.len })); } else if (self.current) |current| { try self.backwards.append(current); diff --git a/src/log.zig b/src/log.zig index c0df56a..71d3521 100644 --- a/src/log.zig +++ b/src/log.zig @@ -1,8 +1,6 @@ const std = @import("std"); const tp = @import("thespian"); -const fba = std.heap.FixedBufferAllocator; - const Self = @This(); pub const max_log_message = tp.max_message_size - 128; @@ -11,7 +9,7 @@ allocator: std.mem.Allocator, receiver: Receiver, subscriber: ?tp.pid, heap: [32 + 1024]u8, -fba: fba, +fba: std.heap.FixedBufferAllocator, msg_store: MsgStoreT, const MsgStoreT = std.DoublyLinkedList([]u8); @@ -39,7 +37,7 @@ fn init(args: StartArgs) !*Self { .receiver = Receiver.init(Self.receive, p), .subscriber = null, .heap = undefined, - .fba = fba.init(&p.heap), + .fba = std.heap.FixedBufferAllocator.init(&p.heap), .msg_store = MsgStoreT{}, }; return p; diff --git a/src/main.zig b/src/main.zig index 74d298b..18c4ee9 100644 --- a/src/main.zig +++ b/src/main.zig @@ -25,7 +25,7 @@ pub const application_title = "Flow Control"; pub const application_subtext = "a programmer's text editor"; pub const application_description = application_title ++ ": " ++ application_subtext; -pub const std_options = .{ +pub const std_options: std.Options = .{ // .log_level = if (builtin.mode == .Debug) .debug else .warn, .log_level = if (builtin.mode == .Debug) .info else .warn, .logFn = log.std_log_function, @@ -33,7 +33,11 @@ pub const std_options = .{ const renderer = @import("renderer"); -pub const panic = if (@hasDecl(renderer, "panic")) renderer.panic else std.builtin.default_panic; +pub const panic = if (@hasDecl(renderer, "panic")) renderer.panic else default_panic; + +fn default_panic(msg: []const u8, _: ?*std.builtin.StackTrace, ret_addr: ?usize) noreturn { + return std.debug.defaultPanic(msg, ret_addr); +} pub fn main() anyerror!void { if (builtin.os.tag == .linux) { @@ -52,7 +56,7 @@ pub fn main() anyerror!void { \\ \\Pass in file names to be opened with an optional :LINE or :LINE:COL appended to the \\file name to specify a specific location, or pass + separately to set the line. - ; + ; pub const descriptions = .{ .project = "Set project directory (default: cwd)", @@ -506,7 +510,7 @@ fn read_cbor_config( else => return e, }) { var known = false; - inline for (@typeInfo(T).Struct.fields) |field_info| + inline for (@typeInfo(T).@"struct".fields) |field_info| if (comptime std.mem.eql(u8, "include_files", field_info.name)) { if (std.mem.eql(u8, field_name, field_info.name)) { known = true; @@ -565,7 +569,7 @@ fn write_text_config_file(comptime T: type, data: T, file_name: []const u8) !voi pub fn write_config_to_writer(comptime T: type, data: T, writer: anytype) !void { const default: T = .{}; - inline for (@typeInfo(T).Struct.fields) |field_info| { + inline for (@typeInfo(T).@"struct".fields) |field_info| { if (config_eql( field_info.type, @field(data, field_info.name), @@ -587,8 +591,8 @@ fn config_eql(comptime T: type, a: T, b: T) bool { else => {}, } switch (@typeInfo(T)) { - .Bool, .Int, .Float, .Enum => return a == b, - .Optional => |info| { + .bool, .int, .float, .@"enum" => return a == b, + .optional => |info| { if (a == null and b == null) return true; if (a == null or b == null) diff --git a/src/project_manager.zig b/src/project_manager.zig index e077023..cdf536f 100644 --- a/src/project_manager.zig +++ b/src/project_manager.zig @@ -924,10 +924,11 @@ const FilteredWalker = struct { var containing = top; var dirname_len = top.dirname_len; if (top.iter.next() catch { - var item = self.stack.pop(); - if (self.stack.items.len != 0) { - item.iter.dir.close(); - } + var item_ = self.stack.pop(); + if (item_) |*item| + if (self.stack.items.len != 0) { + item.iter.dir.close(); + }; continue; }) |base| { self.name_buffer.shrinkRetainingCapacity(dirname_len); @@ -958,10 +959,11 @@ const FilteredWalker = struct { else => continue, } } else { - var item = self.stack.pop(); - if (self.stack.items.len != 0) { - item.iter.dir.close(); - } + var item_ = self.stack.pop(); + if (item_) |*item| + if (self.stack.items.len != 0) { + item.iter.dir.close(); + }; } } return null; diff --git a/src/renderer/vaxis/Plane.zig b/src/renderer/vaxis/Plane.zig index e1dd9d3..a3a5c23 100644 --- a/src/renderer/vaxis/Plane.zig +++ b/src/renderer/vaxis/Plane.zig @@ -37,7 +37,7 @@ pub const option = enum { }; pub fn init(nopts: *const Options, parent_: Plane) !Plane { - const opts = .{ + const opts: vaxis.Window.ChildOptions = .{ .x_off = @as(i17, @intCast(nopts.x)), .y_off = @as(i17, @intCast(nopts.y)), .width = @as(u16, @intCast(nopts.cols)), diff --git a/src/renderer/vaxis/input.zig b/src/renderer/vaxis/input.zig index ea4c8ea..15aaed9 100644 --- a/src/renderer/vaxis/input.zig +++ b/src/renderer/vaxis/input.zig @@ -8,7 +8,7 @@ pub const key = vaxis.Key; pub const Key = u21; pub const Mouse = vaxis.Mouse.Button; -pub const MouseType = @typeInfo(Mouse).Enum.tag_type; +pub const MouseType = @typeInfo(Mouse).@"enum".tag_type; pub const mouse = struct { pub const MOTION: Mouse = vaxis.Mouse.Button.none; diff --git a/src/renderer/vaxis/renderer.zig b/src/renderer/vaxis/renderer.zig index f768d07..adea572 100644 --- a/src/renderer/vaxis/renderer.zig +++ b/src/renderer/vaxis/renderer.zig @@ -12,6 +12,7 @@ pub const Cell = @import("Cell.zig"); pub const CursorShape = vaxis.Cell.CursorShape; pub const style = @import("style.zig").StyleBits; +pub const styles = @import("style.zig"); const Self = @This(); pub const log_name = "vaxis"; @@ -25,6 +26,7 @@ no_alternate: bool, event_buffer: std.ArrayList(u8), input_buffer: std.ArrayList(u8), mods: vaxis.Key.Modifiers = .{}, +queries_done: bool, bracketed_paste: bool = false, bracketed_paste_buffer: std.ArrayList(u8), @@ -61,6 +63,7 @@ pub fn init(allocator: std.mem.Allocator, handler_ctx: *anyopaque, no_alternate: .handler_ctx = handler_ctx, .logger = log.logger(log_name), .loop = undefined, + .queries_done = false, }; } @@ -80,13 +83,14 @@ var panic_cleanup: ?struct { vx: *vaxis.Vaxis, } = null; pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, ret_addr: ?usize) noreturn { + _ = error_return_trace; // TODO: what to do with this in zig-0.14? const cleanup = panic_cleanup; panic_cleanup = null; if (cleanup) |self| { self.vx.deinit(self.allocator, self.tty.anyWriter()); self.tty.deinit(); } - return std.builtin.default_panic(msg, error_return_trace, ret_addr orelse @returnAddress()); + return std.debug.defaultPanic(msg, ret_addr orelse @returnAddress()); } pub fn run(self: *Self) !void { @@ -152,6 +156,15 @@ pub fn process_renderer_event(self: *Self, msg: []const u8) !void { const event = std.mem.bytesAsValue(vaxis.Event, input_); switch (event.*) { .key_press => |key__| { + // Check for a cursor position response for our explicity width query. This will + // always be an F3 key with shift = true, and we must be looking for queries + if (key__.codepoint == vaxis.Key.f3 and key__.mods.shift and !self.queries_done) { + self.logger.print("explicit width capability detected", .{}); + self.vx.caps.explicit_width = true; + self.vx.caps.unicode = .unicode; + self.vx.screen.width_method = .unicode; + return; + } const key_ = filter_mods(normalize_shifted_alphas(key__)); try self.sync_mod_state(key_.codepoint, key_.mods); const cbor_msg = try self.fmtmsg(.{ @@ -253,6 +266,7 @@ pub fn process_renderer_event(self: *Self, msg: []const u8) !void { self.vx.caps.sgr_pixels = true; }, .cap_da1 => { + self.queries_done = true; self.vx.enableDetectedFeatures(self.tty.anyWriter()) catch |e| self.logger.err("enable features", e); try self.vx.setMouseMode(self.tty.anyWriter(), true); }, diff --git a/src/renderer/vaxis/style.zig b/src/renderer/vaxis/style.zig index 4420bd5..589fa44 100644 --- a/src/renderer/vaxis/style.zig +++ b/src/renderer/vaxis/style.zig @@ -4,11 +4,11 @@ pub const StyleBits = packed struct(u5) { undercurl: bool = false, underline: bool = false, italic: bool = false, - - pub const struck: StyleBits = .{ .struck = true }; - pub const bold: StyleBits = .{ .bold = true }; - pub const undercurl: StyleBits = .{ .undercurl = true }; - pub const underline: StyleBits = .{ .underline = true }; - pub const italic: StyleBits = .{ .italic = true }; - pub const normal: StyleBits = .{}; }; + +pub const struck: StyleBits = .{ .struck = true }; +pub const bold: StyleBits = .{ .bold = true }; +pub const undercurl: StyleBits = .{ .undercurl = true }; +pub const underline: StyleBits = .{ .underline = true }; +pub const italic: StyleBits = .{ .italic = true }; +pub const normal: StyleBits = .{}; diff --git a/src/renderer/win32/renderer.zig b/src/renderer/win32/renderer.zig index 6c63388..192f279 100644 --- a/src/renderer/win32/renderer.zig +++ b/src/renderer/win32/renderer.zig @@ -18,8 +18,38 @@ pub const StyleBits = @import("tuirenderer").style; const gui = @import("gui"); const DropWriter = gui.DropWriter; pub const style = StyleBits; +pub const styles = @import("tuirenderer").styles; -pub const panic = win32.messageBoxThenPanic(.{ .title = "Flow Panic" }); +pub const panic = messageBoxThenPanic(.{ .title = "Flow Panic" }); + +threadlocal var thread_is_panicing = false; +fn messageBoxThenPanic( + opt: struct { + title: [:0]const u8, + style: win32.MESSAGEBOX_STYLE = .{ .ICONASTERISK = 1 }, + // TODO: add option/logic to include the stacktrace in the messagebox + }, +) std.builtin.PanicFn { + return struct { + pub fn panic( + msg: []const u8, + _: ?*std.builtin.StackTrace, + ret_addr: ?usize, + ) noreturn { + if (!thread_is_panicing) { + thread_is_panicing = true; + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + const msg_z: [:0]const u8 = if (std.fmt.allocPrintZ( + arena.allocator(), + "{s}", + .{msg}, + )) |msg_z| msg_z else |_| "failed allocate error message"; + _ = win32.MessageBoxA(null, msg_z, opt.title, opt.style); + } + std.debug.defaultPanic(msg, ret_addr); + } + }.panic; +} allocator: std.mem.Allocator, vx: vaxis.Vaxis, @@ -35,7 +65,7 @@ thread: ?std.Thread = null, hwnd: ?win32.HWND = null, title_buf: std.ArrayList(u16), -style: ?Style = null, +style_: ?Style = null, const global = struct { var init_called: bool = false; @@ -344,12 +374,12 @@ fn update_window_title(self: *Self) void { } pub fn set_terminal_style(self: *Self, style_: Style) void { - self.style = style_; + self.style_ = style_; self.update_window_style(); } fn update_window_style(self: *Self) void { const hwnd = self.hwnd orelse return; - if (self.style) |style_| { + if (self.style_) |style_| { if (style_.bg) |color| gui.set_window_background(hwnd, @intCast(color.color)); } } diff --git a/src/ripgrep.zig b/src/ripgrep.zig index 3b86f2a..219c4d4 100644 --- a/src/ripgrep.zig +++ b/src/ripgrep.zig @@ -134,7 +134,7 @@ const Process = struct { fn receive(self: *Process, _: tp.pid_ref, m: tp.message) tp.result { errdefer self.deinit(); - var bytes: []u8 = ""; + var bytes: []const u8 = ""; if (try m.match(.{ "input", tp.extract(&bytes) })) { const sp = self.sp orelse return tp.exit_error(error.Closed, null); @@ -155,7 +155,7 @@ const Process = struct { } } - fn handle_output(self: *Process, bytes: []u8) !void { + fn handle_output(self: *Process, bytes: []const u8) !void { try self.output.appendSlice(bytes); } diff --git a/src/shell.zig b/src/shell.zig index 04f6217..05aa4d9 100644 --- a/src/shell.zig +++ b/src/shell.zig @@ -187,7 +187,7 @@ const Process = struct { fn receive(self: *Process, _: tp.pid_ref, m: tp.message) tp.result { errdefer self.deinit(); - var bytes: []u8 = ""; + var bytes: []const u8 = ""; if (try m.match(.{ "input", tp.extract(&bytes) })) { const sp = self.sp orelse return tp.exit_error(error.Closed, null); diff --git a/src/syntax/build.zig b/src/syntax/build.zig index c74f15f..f9a3105 100644 --- a/src/syntax/build.zig +++ b/src/syntax/build.zig @@ -9,7 +9,7 @@ pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const tree_sitter_dep = b.dependency("tree-sitter", .{ + const tree_sitter_dep = b.dependency("tree_sitter", .{ .target = target, .optimize = optimize, }); diff --git a/src/syntax/build.zig.zon b/src/syntax/build.zig.zon index 0f161c8..eb592e2 100644 --- a/src/syntax/build.zig.zon +++ b/src/syntax/build.zig.zon @@ -1,11 +1,13 @@ .{ - .name = "flow-syntax", - .version = "0.0.1", + .name = .flow_syntax, + .version = "0.1.0", + .fingerprint = 0x3ba2584ea1cec85f, + .minimum_zig_version = "0.14.0-dev.3451+d8d2aa9af", .dependencies = .{ - .@"tree-sitter" = .{ + .tree_sitter = .{ .url = "https://github.com/neurocyte/tree-sitter/releases/download/master-86dd4d2536f2748c5b4ea0e1e70678039a569aac/source.tar.gz", - .hash = "1220e9fba96c468283129e977767472dee00b16f356e5912431cec8f1a009b6691a2", + .hash = "N-V-__8AACablCbp-6lsRoKDEp6Xd2dHLe4AsW81blkSQxzs", }, }, .paths = .{ diff --git a/src/syntax/src/file_type.zig b/src/syntax/src/file_type.zig index dfecb1b..d6c4445 100644 --- a/src/syntax/src/file_type.zig +++ b/src/syntax/src/file_type.zig @@ -88,7 +88,7 @@ fn ft_func_name(comptime lang: []const u8) []const u8 { const LangFn = *const fn () callconv(.C) ?*const treez.Language; -const FirstLineMatch = struct { +pub const FirstLineMatch = struct { prefix: ?[]const u8 = null, content: ?[]const u8 = null, }; @@ -105,7 +105,7 @@ fn vec(comptime args: anytype) []const []const u8 { fn load_file_types(comptime Namespace: type) []const FileType { comptime switch (@typeInfo(Namespace)) { - .Struct => |info| { + .@"struct" => |info| { var count = 0; for (info.decls) |_| { // @compileLog(decl.name, @TypeOf(@field(Namespace, decl.name))); diff --git a/src/syntax/src/file_types.zig b/src/syntax/src/file_types.zig index b33100a..870c6b7 100644 --- a/src/syntax/src/file_types.zig +++ b/src/syntax/src/file_types.zig @@ -1,3 +1,6 @@ +const file_type = @import("file_type.zig"); +const FirstLineMatch = file_type.FirstLineMatch; + pub const agda = .{ .description = "Agda", .extensions = .{"agda"}, @@ -18,7 +21,7 @@ pub const bash = .{ .icon = "󱆃", .extensions = .{ "sh", "bash", ".profile" }, .comment = "#", - .first_line_matches = .{ .prefix = "#!", .content = "sh" }, + .first_line_matches = FirstLineMatch{ .prefix = "#!", .content = "sh" }, .formatter = .{ "shfmt", "--indent", "4" }, .language_server = .{ "bash-language-server", "start" }, }; @@ -253,7 +256,7 @@ pub const lua = .{ .extensions = .{"lua"}, .comment = "--", .injections = "tree-sitter-lua/queries/injections.scm", - .first_line_matches = .{ .prefix = "--", .content = "lua" }, + .first_line_matches = FirstLineMatch{ .prefix = "--", .content = "lua" }, .language_server = .{"lua-lsp"}, }; @@ -263,7 +266,7 @@ pub const mail = .{ .extensions = .{ "eml", "mbox" }, .comment = ">", .highlights = "tree-sitter-mail/queries/mail/highlights.scm", - .first_line_matches = .{ .prefix = "From" }, + .first_line_matches = FirstLineMatch{ .prefix = "From" }, }; pub const make = .{ @@ -407,7 +410,7 @@ pub const python = .{ .icon = "󰌠", .extensions = .{ "py", "pyi" }, .comment = "#", - .first_line_matches = .{ .prefix = "#!", .content = "python" }, + .first_line_matches = FirstLineMatch{ .prefix = "#!", .content = "python" }, .language_server = .{"pylsp"}, }; @@ -520,7 +523,7 @@ pub const xml = .{ .extensions = .{"xml"}, .comment = "