diff --git a/src/syntax/src/QueryCache.zig b/src/syntax/src/QueryCache.zig deleted file mode 100644 index 21870c8..0000000 --- a/src/syntax/src/QueryCache.zig +++ /dev/null @@ -1,125 +0,0 @@ -const std = @import("std"); -const build_options = @import("build_options"); - -const treez = if (build_options.use_tree_sitter) - @import("treez") -else - @import("treez_dummy.zig"); - -const Self = @This(); - -pub const FileType = @import("file_type.zig"); -const Query = treez.Query; - -allocator: std.mem.Allocator, -mutex: ?std.Thread.Mutex, -highlights: std.StringHashMapUnmanaged(*Query) = .{}, -injections: std.StringHashMapUnmanaged(*Query) = .{}, -ref_count: usize = 1, - -pub const QueryType = enum { - highlights, - injections, -}; - -pub const QueryParseError = error{ - InvalidSyntax, - InvalidNodeType, - InvalidField, - InvalidCapture, - InvalidStructure, - InvalidLanguage, -}; - -pub const Error = (error{ - NotFound, - OutOfMemory, -} || QueryParseError); - -pub fn create(allocator: std.mem.Allocator, opts: struct { lock: bool = false }) !*Self { - const self = try allocator.create(Self); - self.* = .{ - .allocator = allocator, - .mutex = if (opts.lock) .{} else null, - }; - return self; -} - -pub fn deinit(self: *Self) void { - self.release_ref_unlocked_and_maybe_destroy(); -} - -fn add_ref_locked(self: *Self) void { - std.debug.assert(self.ref_count > 0); - self.ref_count += 1; -} - -fn release_ref_unlocked_and_maybe_destroy(self: *Self) void { - { - if (self.mutex) |*mtx| mtx.lock(); - defer if (self.mutex) |*mtx| mtx.unlock(); - self.ref_count -= 1; - if (self.ref_count > 0) return; - } - - var iter_highlights = self.highlights.iterator(); - while (iter_highlights.next()) |p| { - self.allocator.free(p.key_ptr.*); - p.value_ptr.*.destroy(); - } - var iter_injections = self.injections.iterator(); - while (iter_injections.next()) |p| { - self.allocator.free(p.key_ptr.*); - p.value_ptr.*.destroy(); - } - self.highlights.deinit(self.allocator); - self.injections.deinit(self.allocator); - self.allocator.destroy(self); -} - -fn ReturnType(comptime query_type: QueryType) type { - return switch (query_type) { - .highlights => *Query, - .injections => ?*Query, - }; -} - -fn get_or_add_internal(self: *Self, file_type: *const FileType, comptime query_type: QueryType) Error!ReturnType(query_type) { - const hash = switch (query_type) { - .highlights => &self.highlights, - .injections => &self.injections, - }; - - return if (hash.get(file_type.name)) |query| query else blk: { - const lang = file_type.lang_fn() orelse std.debug.panic("tree-sitter parser function failed for language: {s}", .{file_type.name}); - const query = try Query.create(lang, switch (query_type) { - .highlights => file_type.highlights, - .injections => if (file_type.injections) |injections| injections else return null, - }); - errdefer query.destroy(); - try hash.put(self.allocator, try self.allocator.dupe(u8, file_type.name), query); - break :blk query; - }; -} - -pub fn pre_load(self: *Self, lang_name: []const u8) Error!void { - if (self.mutex) |*mtx| mtx.lock(); - defer if (self.mutex) |*mtx| mtx.unlock(); - const file_type = FileType.get_by_name(lang_name) orelse return; - _ = try self.get_or_add_internal(file_type, .highlights); - _ = try self.get_or_add_internal(file_type, .injections); -} - -pub fn get(self: *Self, file_type: *const FileType, comptime query_type: QueryType) Error!ReturnType(query_type) { - if (self.mutex) |*mtx| mtx.lock(); - defer if (self.mutex) |*mtx| mtx.unlock(); - const query = try self.get_or_add_internal(file_type, query_type); - self.add_ref_locked(); - return query; -} - -pub fn release(self: *Self, query: *Query, comptime query_type: QueryType) void { - _ = query; - _ = query_type; - self.release_ref_unlocked_and_maybe_destroy(); -} diff --git a/src/syntax/src/syntax.zig b/src/syntax/src/syntax.zig index 20f9b8e..0f8ff97 100644 --- a/src/syntax/src/syntax.zig +++ b/src/syntax/src/syntax.zig @@ -10,7 +10,6 @@ const Self = @This(); pub const Edit = treez.InputEdit; pub const FileType = @import("file_type.zig"); -pub const QueryCache = @import("QueryCache.zig"); pub const Range = treez.Range; pub const Point = treez.Point; const Input = treez.Input; @@ -24,40 +23,37 @@ lang: *const Language, file_type: *const FileType, parser: *Parser, query: *Query, -injections: ?*Query, +injections: *Query, tree: ?*treez.Tree = null, -pub fn create(file_type: *const FileType, allocator: std.mem.Allocator, query_cache: *QueryCache) !*Self { - const query = try query_cache.get(file_type, .highlights); - const injections = try query_cache.get(file_type, .injections); +pub fn create(file_type: *const FileType, allocator: std.mem.Allocator) !*Self { const self = try allocator.create(Self); self.* = .{ .allocator = allocator, .lang = file_type.lang_fn() orelse std.debug.panic("tree-sitter parser function failed for language: {s}", .{file_type.name}), .file_type = file_type, .parser = try Parser.create(), - .query = query, - .injections = injections, + .query = try Query.create(self.lang, file_type.highlights), + .injections = try Query.create(self.lang, file_type.highlights), }; - errdefer self.destroy(query_cache); + errdefer self.destroy(); try self.parser.setLanguage(self.lang); return self; } -pub fn create_file_type(allocator: std.mem.Allocator, lang_name: []const u8, query_cache: *QueryCache) !*Self { +pub fn create_file_type(allocator: std.mem.Allocator, lang_name: []const u8) !*Self { const file_type = FileType.get_by_name(lang_name) orelse return error.NotFound; - return create(file_type, allocator, query_cache); + return create(file_type, allocator); } -pub fn create_guess_file_type(allocator: std.mem.Allocator, content: []const u8, file_path: ?[]const u8, query_cache: *QueryCache) !*Self { +pub fn create_guess_file_type(allocator: std.mem.Allocator, content: []const u8, file_path: ?[]const u8) !*Self { const file_type = FileType.guess(file_path, content) orelse return error.NotFound; - return create(file_type, allocator, query_cache); + return create(file_type, allocator); } -pub fn destroy(self: *Self, query_cache: *QueryCache) void { +pub fn destroy(self: *Self) void { if (self.tree) |tree| tree.destroy(); - query_cache.release(self.query, .highlights); - if (self.injections) |injections| query_cache.release(injections, .injections); + self.query.destroy(); self.parser.destroy(); self.allocator.destroy(self); } diff --git a/src/tui/editor.zig b/src/tui/editor.zig index c0061ad..2f75a45 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -464,7 +464,7 @@ pub const Editor = struct { if (self.buffer) |_| self.write_state(meta.writer()) catch {}; for (self.diagnostics.items) |*d| d.deinit(self.diagnostics.allocator); self.diagnostics.deinit(); - if (self.syntax) |syn| syn.destroy(tui.query_cache()); + if (self.syntax) |syn| syn.destroy(); self.cursels.deinit(); self.matches.deinit(); self.handlers.deinit(); @@ -588,7 +588,7 @@ pub const Editor = struct { const frame_ = tracy.initZone(@src(), .{ .name = "create" }); defer frame_.deinit(); break :blk if (syn_file_type) |ft| - syntax.create(ft, self.allocator, tui.query_cache()) catch null + syntax.create(ft, self.allocator) catch null else null; }; @@ -4301,7 +4301,7 @@ pub const Editor = struct { var content = std.ArrayList(u8).init(self.allocator); defer content.deinit(); try root.store(content.writer(), eol_mode); - self.syntax = syntax.create_guess_file_type(self.allocator, content.items, self.file_path, tui.query_cache()) catch |e| switch (e) { + self.syntax = syntax.create_guess_file_type(self.allocator, content.items, self.file_path) catch |e| switch (e) { error.NotFound => null, else => return e, }; @@ -5447,7 +5447,7 @@ pub const Editor = struct { if (!try ctx.args.match(.{tp.extract(&file_type)})) return error.InvalidSetFileTypeArgument; - if (self.syntax) |syn| syn.destroy(tui.query_cache()); + if (self.syntax) |syn| syn.destroy(); self.syntax_last_rendered_root = null; self.syntax_refresh_full = true; self.syntax_incremental_reparse = false; @@ -5457,7 +5457,7 @@ pub const Editor = struct { defer content.deinit(); const root = try self.buf_root(); try root.store(content.writer(), try self.buf_eol_mode()); - const syn = syntax.create_file_type(self.allocator, file_type, tui.query_cache()) catch null; + const syn = syntax.create_file_type(self.allocator, file_type) catch null; if (syn) |syn_| if (self.file_path) |file_path| project_manager.did_open( file_path, diff --git a/src/tui/tui.zig b/src/tui/tui.zig index 51386b3..a3850dd 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -12,7 +12,6 @@ pub const renderer = @import("renderer"); const command = @import("command"); const EventHandler = @import("EventHandler"); const keybind = @import("keybind"); -const syntax = @import("syntax"); const Widget = @import("Widget.zig"); const MessageFilter = @import("MessageFilter.zig"); @@ -57,7 +56,6 @@ default_cursor: keybind.CursorShape = .default, fontface_: []const u8 = "", fontfaces_: std.ArrayListUnmanaged([]const u8) = .{}, enable_mouse_idle_timer: bool = false, -query_cache_: *syntax.QueryCache, const keepalive = std.time.us_per_day * 365; // one year const idle_frames = 0; @@ -122,7 +120,6 @@ fn init(allocator: Allocator) !*Self { )), .theme_ = theme_, .no_sleep = tp.env.get().is("no-sleep"), - .query_cache_ = try syntax.QueryCache.create(allocator, .{}), }; instance_ = self; defer instance_ = null; @@ -214,7 +211,6 @@ fn deinit(self: *Self) void { self.rdr_.stop(); self.rdr_.deinit(); self.logger.deinit(); - self.query_cache_.deinit(); self.allocator.destroy(self); } @@ -1056,10 +1052,6 @@ pub fn mini_mode() ?*MiniMode { return if (current().mini_mode_) |*p| p else null; } -pub fn query_cache() *syntax.QueryCache { - return current().query_cache_; -} - pub fn config() *const @import("config") { return ¤t().config_; }