diff --git a/build.zig b/build.zig index 16046a8..8dfec44 100644 --- a/build.zig +++ b/build.zig @@ -414,10 +414,6 @@ pub fn build_exe( .root_source_file = b.path("src/bin_path.zig"), }); - const snippet_mod = b.createModule(.{ - .root_source_file = b.path("src/snippet.zig"), - }); - const Buffer_mod = b.createModule(.{ .root_source_file = b.path("src/buffer/Buffer.zig"), .imports = &.{ @@ -634,7 +630,6 @@ pub fn build_exe( .{ .name = "zeit", .module = zeit_mod }, .{ .name = "VcsStatus", .module = VcsStatus_mod }, .{ .name = "bin_path", .module = bin_path_mod }, - .{ .name = "snippet", .module = snippet_mod }, }, }); diff --git a/src/snippet.zig b/src/snippet.zig deleted file mode 100644 index 2f6f8e0..0000000 --- a/src/snippet.zig +++ /dev/null @@ -1,162 +0,0 @@ -text: []const u8, -tabstops: [][]Range, - -const Snippet = @This(); -const Range = struct { begin: Position, end: ?Position = null }; -const Position = struct { usize }; - -const Tabstop = struct { - id: usize, - range: Range, -}; - -pub fn deinit(self: *const Snippet, allocator: std.mem.Allocator) void { - for (self.tabstops) |tabstop| allocator.free(tabstop); - allocator.free(self.tabstops); - allocator.free(self.text); -} - -pub fn parse(allocator: std.mem.Allocator, snippet: []const u8) Error!Snippet { - var tabstops: std.ArrayList(struct { id: usize, range: Range }) = .empty; - defer tabstops.deinit(allocator); - var id: ?usize = null; - var content_begin: ?Position = null; - var max_id: usize = 0; - var text: std.Io.Writer.Allocating = .init(allocator); - defer text.deinit(); - - var state: enum { - initial, - escape, - tabstop, - placeholder, - content, - content_escape, - } = .initial; - - var iter = snippet; - while (iter.len > 0) : (iter = iter[1..]) { - const c = iter[0]; - fsm: switch (state) { - .initial => switch (c) { - '\\' => { - state = .escape; - }, - '$' => { - state = .tabstop; - }, - else => try text.writer.writeByte(c), - }, - .escape => { - try text.writer.writeByte(c); - state = .initial; - }, - .tabstop => switch (c) { - '{' => { - state = .placeholder; - }, - '0'...'9' => { - const digit: usize = @intCast(c - '0'); - id = if (id) |id_| (id_ * 10) + digit else digit; - }, - else => { - const pos = snippet.len - iter.len; - if (id == null) - return invalid(snippet, pos, error.InvalidIdValue); - (try tabstops.addOne(allocator)).* = .{ - .id = id orelse unreachable, - .range = .{ .begin = .{text.written().len} }, - }; - max_id = @max(id orelse unreachable, max_id); - id = null; - state = .initial; - break :fsm; - }, - }, - .placeholder => switch (c) { - '0'...'9' => { - const digit: usize = @intCast(c - '0'); - id = if (id) |id_| (id_ * 10) + digit else digit; - }, - ':' => { - const pos = snippet.len - iter.len; - if (id == null) - return invalid(snippet, pos, error.InvalidIdValue); - content_begin = .{text.written().len}; - state = .content; - }, - else => { - const pos = snippet.len - iter.len; - return invalid(snippet, pos, error.InvalidIdValue); - }, - }, - .content => switch (c) { - '\\' => { - state = .content_escape; - }, - '}' => { - const pos = snippet.len - iter.len; - if (id == null) - return invalid(snippet, pos, error.InvalidIdValue); - if (content_begin == null) - return invalid(snippet, pos, error.InvalidPlaceholderValue); - (try tabstops.addOne(allocator)).* = .{ - .id = id orelse unreachable, - .range = .{ - .begin = content_begin orelse unreachable, - .end = .{text.written().len}, - }, - }; - max_id = @max(id orelse unreachable, max_id); - id = null; - content_begin = null; - state = .initial; - }, - else => try text.writer.writeByte(c), - }, - .content_escape => { - try text.writer.writeByte(c); - state = .content; - }, - } - } - - if (state != .initial) { - const pos = snippet.len - iter.len; - if (id == null) - return invalid(snippet, pos, error.UnexpectedEndOfDocument); - } - - var result: std.ArrayList([]Range) = .empty; - defer result.deinit(allocator); - var n: usize = 1; - while (n <= max_id) : (n += 1) { - var tabstop: std.ArrayList(Range) = .empty; - errdefer tabstop.deinit(allocator); - for (tabstops.items) |item| if (item.id == n) { - (try tabstop.addOne(allocator)).* = item.range; - }; - (try result.addOne(allocator)).* = try tabstop.toOwnedSlice(allocator); - } - return .{ - .text = try text.toOwnedSlice(), - .tabstops = try result.toOwnedSlice(allocator), - }; -} - -fn invalid(snippet: []const u8, pos: usize, e: Error) Error { - log.err("invalid snippet: {s}", .{snippet}); - log.err("{t} at pos {d}", .{ e, pos }); - return e; -} - -pub const Error = error{ - WriteFailed, - OutOfMemory, - InvalidIdValue, - InvalidPlaceholderValue, - UnexpectedEndOfDocument, -}; - -const log = std.log.scoped(.snippet); -const std = @import("std"); diff --git a/src/tui/mode/overlay/completion_palette.zig b/src/tui/mode/overlay/completion_palette.zig index 5b141c5..1af71a6 100644 --- a/src/tui/mode/overlay/completion_palette.zig +++ b/src/tui/mode/overlay/completion_palette.zig @@ -45,18 +45,18 @@ pub fn load_entries(palette: *Type) !usize { max_description = 0; var max_label_len: usize = 0; for (palette.entries.items) |*item| { - const values = get_values(item.cbor); - if (get_replace_selection(values.replace)) |replace| { + const label_, const sort_text, _, const maybe_replace, _, const label_detail, const label_description, _, _ = get_values(item.cbor); + if (get_replace_selection(maybe_replace)) |replace| { if (palette.value.replace == null) palette.value.replace = replace; } - item.label = values.label; - item.sort_text = values.sort_text; + item.label = label_; + item.sort_text = sort_text; - var lines = std.mem.splitScalar(u8, values.label_description, '\n'); - const label_description_len = if (lines.next()) |desc| desc.len else values.label_description.len; + var lines = std.mem.splitScalar(u8, label_description, '\n'); + const label_description_len = if (lines.next()) |desc| desc.len else label_description.len; max_label_len = @max(max_label_len, item.label.len); - max_description = @max(max_description, label_description_len + values.label_detail.len); + max_description = @max(max_description, label_description_len + label_detail.len); } const less_fn = struct { @@ -102,17 +102,17 @@ pub fn on_render_menu(_: *Type, button: *Type.ButtonType, theme: *const Widget.T if (!(cbor.matchValue(&iter, cbor.extract_cbor(&item_cbor)) catch false)) return false; if (!(cbor.matchValue(&iter, cbor.extract_cbor(&matches_cbor)) catch false)) return false; - const values = get_values(item_cbor); - const icon_: []const u8 = kind_icon(@enumFromInt(values.kind)); + const label_, _, const kind, _, _, const label_detail, const label_description, _, _ = get_values(item_cbor); + const icon_: []const u8 = kind_icon(@enumFromInt(kind)); const color: u24 = 0x0; return tui.render_symbol( &button.plane, - values.label, + label_, icon_, color, - values.label_detail, - values.label_description, + label_detail, + label_description, matches_cbor, button.active, selected, @@ -121,21 +121,7 @@ pub fn on_render_menu(_: *Type, button: *Type.ButtonType, theme: *const Widget.T ); } -const Values = struct { - label: []const u8, - sort_text: []const u8, - kind: u8, - replace: Buffer.Selection, - additionalTextEdits: []const u8, - label_detail: []const u8, - label_description: []const u8, - detail: []const u8, - documentation: []const u8, - insertTextFormat: usize, - textEdit_newText: []const u8, -}; - -fn get_values(item_cbor: []const u8) Values { +fn get_values(item_cbor: []const u8) struct { []const u8, []const u8, u8, Buffer.Selection, []const u8, []const u8, []const u8, []const u8, []const u8 } { var label_: []const u8 = ""; var label_detail: []const u8 = ""; var label_description: []const u8 = ""; @@ -172,19 +158,7 @@ fn get_values(item_cbor: []const u8) Values { cbor.extract(&replace.end.col), // replace.end.col cbor.extract_cbor(&additionalTextEdits), }) catch false; - return .{ - .label = label_, - .sort_text = sort_text, - .kind = kind, - .replace = replace, - .additionalTextEdits = additionalTextEdits, - .label_detail = label_detail, - .label_description = label_description, - .detail = detail, - .documentation = documentation, - .insertTextFormat = insertTextFormat, - .textEdit_newText = textEdit_newText, - }; + return .{ label_, sort_text, kind, replace, additionalTextEdits, label_detail, label_description, detail, documentation }; } const TextEdit = struct { newText: []const u8 = &.{}, insert: ?Range = null, replace: ?Range = null }; @@ -201,35 +175,25 @@ fn get_replace_selection(replace: Buffer.Selection) ?Buffer.Selection { } fn select(menu: **Type.MenuType, button: *Type.ButtonType, _: Type.Pos) void { - const values = get_values(button.opts.label); - switch (values.insertTextFormat) { - 2 => { - const snippet = @import("snippet").parse(menu.*.opts.ctx.allocator, values.textEdit_newText) catch return; - defer snippet.deinit(menu.*.opts.ctx.allocator); - tp.self_pid().send(.{ "cmd", "insert_chars", .{snippet.text} }) catch |e| menu.*.opts.ctx.logger.err(module_name, e); - }, - else => { - tp.self_pid().send(.{ "cmd", "insert_chars", .{values.label} }) catch |e| menu.*.opts.ctx.logger.err(module_name, e); - }, - } + const label_, _, _, _, _, _, _, _, _ = get_values(button.opts.label); + tp.self_pid().send(.{ "cmd", "exit_overlay_mode" }) catch |e| menu.*.opts.ctx.logger.err(module_name, e); + tp.self_pid().send(.{ "cmd", "insert_chars", .{label_} }) catch |e| menu.*.opts.ctx.logger.err(module_name, e); const mv = tui.mainview() orelse return; mv.cancel_info_content() catch {}; - tp.self_pid().send(.{ "cmd", "exit_overlay_mode" }) catch |e| menu.*.opts.ctx.logger.err(module_name, e); } pub fn updated(palette: *Type, button_: ?*Type.ButtonType) !void { const button = button_ orelse return cancel(palette); - const values = get_values(button.opts.label); + const label_, _, _, const replace, _, _, _, const detail, const documentation = get_values(button.opts.label); const editor = tui.get_active_editor() orelse return error.NotFound; - editor.get_primary().selection = get_replace_selection(values.replace); + editor.get_primary().selection = get_replace_selection(replace); const mv = tui.mainview() orelse return; - try mv.set_info_content(values.label, .replace); + try mv.set_info_content(label_, .replace); try mv.set_info_content(" ", .append); // blank line - try mv.set_info_content(values.detail, .append); - // try mv.set_info_content(values.textEdit_newText, .append); + try mv.set_info_content(detail, .append); try mv.set_info_content(" ", .append); // blank line - try mv.set_info_content(values.documentation, .append); + try mv.set_info_content(documentation, .append); } pub fn cancel(palette: *Type) !void {