diff options
Diffstat (limited to 'src/locations.zig')
| -rw-r--r-- | src/locations.zig | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/src/locations.zig b/src/locations.zig index 97caf1d9..b34f7a6f 100644 --- a/src/locations.zig +++ b/src/locations.zig @@ -158,17 +158,19 @@ const Pending = struct { } }; -fn sourceText(p: *pardes.Pardes, arena: std.mem.Allocator, dir: []const u8, path: []const u8) ?[]const u8 { +const Source = struct { path: []const u8, bytes: []const u8 }; + +fn sourceText(p: *pardes.Pardes, arena: std.mem.Allocator, dir: []const u8, path: []const u8) ?Source { if (std.ascii.eqlIgnoreCase(std.fs.path.extension(path), ".pdf")) return null; const lexical = std.fs.path.resolvePosix(arena, &.{ dir, path }) catch return null; var pathbuf: [4096]u8 = undefined; const full = if (filesystem.resolve(p, path, dir, &pathbuf)) |resolved| resolved.path else lexical; for (p.panes) |slot| if (slot) |pane| { - if (pane.file) |file| if (file.output == null and (std.mem.eql(u8, file.path, full) or std.mem.eql(u8, file.path, lexical))) return file.content; + if (pane.file) |file| if (file.output == null and (std.mem.eql(u8, file.path, full) or std.mem.eql(u8, file.path, lexical))) return .{ .path = lexical, .bytes = file.content }; }; const bytes = filesystem.read(p, full) catch return null; defer p.gpa.free(bytes); - return arena.dupe(u8, bytes) catch null; + return .{ .path = lexical, .bytes = arena.dupe(u8, bytes) catch return null }; } /// Inputs are sorted results. Expand each source group, merge context with @@ -193,18 +195,22 @@ pub fn format(p: *pardes.Pardes, dir: []const u8, input: []const u8, anchor: ?us const group_start = pending.items.len; try pending.appendSlice(arena, matches.items[first..end]); if (expand and (p.locations_config.context > 0 or p.locations_config.tscontext)) { - if (sourceText(p, arena, dir, path)) |source| { + if (sourceText(p, arena, dir, path)) |text| { + const source = text.bytes; var source_lines: std.ArrayList([]const u8) = .empty; var source_split = std.mem.splitScalar(u8, source, '\n'); while (source_split.next()) |line| try source_lines.append(arena, line); const count = source_lines.items.len; const wanted = try arena.alloc(u8, count); @memset(wanted, 0); - const source_colors = syntax.highlightFileRange(arena, path, source, 0, source.len) catch &.{}; - const declarations = if (p.locations_config.tscontext) - syntax.contextDeclarations(arena, path, source) catch &.{} - else - &.{}; + // Muted declaration headers do not need a source-color pass. + // Exact bytes include unsaved edits and virtual/remote sources. + var cached = p.locations_cache.get(p.tree_sitter_gpa, text.path, source, p.locations_config.tscontext, p.locations_config.context > 0) catch + @import("locations_cache.zig").Result{ .analysis = syntax.analyzeSource(arena, text.path, source, p.locations_config.tscontext, p.locations_config.context > 0) catch .{} }; + defer cached.deinit(p.tree_sitter_gpa); + const analysis = cached.analysis; + const source_colors = analysis.colors; + const declarations = if (p.locations_config.tscontext) analysis.declarations else &.{}; for (pending.items[group_start..]) |*match| { const row = match.at.line -| 1; if (row >= count) continue; @@ -235,7 +241,8 @@ pub fn format(p: *pardes.Pardes, dir: []const u8, input: []const u8, anchor: ?us const declaration = kind & declaration_context != 0; const colors = if (!declaration and offset + line.len <= source_colors.len) source_colors[offset..][0..line.len] else &.{}; const hidden = !declaration or !p.locations_config.tslocations or kind & declaration_start == 0; - try appendContext(arena, &pending, path, line, row, declaration, hidden, colors); + // Later source groups may evict this analysis from the cache. + try appendContext(arena, &pending, path, line, row, declaration, hidden, try arena.dupe(u8, colors)); } } } |
