summaryrefslogtreecommitdiff
path: root/src/locations.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-15 18:41:15 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commit02ea4db25f9802e76112f3b4e69aa75e5a9464dc (patch)
treedaa17ec75135e055a60eff982d97057dcd109c25 /src/locations.zig
parent505dedb2459e7b51cbdb0c066698c6e5596d19dd (diff)
downloadpardes-02ea4db25f9802e76112f3b4e69aa75e5a9464dc.tar.gz
pardes-02ea4db25f9802e76112f3b4e69aa75e5a9464dc.zip
Default location results to stacked addresses and source previews
Diffstat (limited to 'src/locations.zig')
-rw-r--r--src/locations.zig121
1 files changed, 83 insertions, 38 deletions
diff --git a/src/locations.zig b/src/locations.zig
index 0f580e34..97caf1d9 100644
--- a/src/locations.zig
+++ b/src/locations.zig
@@ -15,7 +15,7 @@ pub fn isContextLine(line: []const u8) bool {
}
pub const Row = struct {
- kind: enum { match, context },
+ kind: enum { match, context, preview },
declaration: bool = false,
path: []u8,
at: look.Spot,
@@ -44,15 +44,16 @@ pub fn equalRows(a: []const Row, b: []const Row) bool {
/// Compare native producer rows with an already formatted, context-free view.
/// Identical refreshes retain allocations, syntax and selection state.
-pub fn sameInput(input: []const u8, rendered: []const u8, rows: []const Row) bool {
+pub fn sameInput(input: []const u8, rendered: []const u8, rows: []const Row, layout: Config.Layout) bool {
if (rows.len == 0) return std.mem.eql(u8, input, rendered);
- if (std.mem.endsWith(u8, input, "\n") != std.mem.endsWith(u8, rendered, "\n")) return false;
var raw_lines = std.mem.splitScalar(u8, input, '\n');
var shown_lines = std.mem.splitScalar(u8, rendered, '\n');
var width: usize = 0;
- for (rows, 0..) |row, index| {
+ var index: usize = 0;
+ while (index < rows.len) {
+ const row = rows[index];
if (row.kind != .match) return false;
- if (index % alignment_entries == 0) {
+ if (layout == .@"inline" and index % alignment_entries == 0) {
width = 0;
var chunk = raw_lines;
for (0..alignment_entries) |_| {
@@ -64,9 +65,19 @@ pub fn sameInput(input: []const u8, rendered: []const u8, rows: []const Row) boo
const raw = raw_lines.next() orelse return false;
const shown = shown_lines.next() orelse return false;
const target = parseRaw(raw);
- if (target.end != row.location_end or row.code_start > shown.len or
- !std.mem.eql(u8, raw[0..target.end], shown[0..row.location_end]) or
- !std.mem.eql(u8, raw[target.code_start..], shown[row.code_start..])) return false;
+ if (target.end != row.location_end or row.location_end > shown.len or row.code_start > shown.len or
+ !std.mem.eql(u8, raw[0..target.end], shown[0..row.location_end])) return false;
+ if (layout == .stacked) {
+ if (shown.len != row.location_end or row.code_start != shown.len or index + 1 >= rows.len) return false;
+ const preview = rows[index + 1];
+ if (preview.kind != .preview or preview.location_end != 0 or preview.code_start != 0 or
+ !std.meta.eql(row.at, preview.at) or !std.mem.eql(u8, row.path, preview.path)) return false;
+ const code = shown_lines.next() orelse return false;
+ if (!std.mem.eql(u8, raw[target.code_start..], code)) return false;
+ index += 2;
+ continue;
+ }
+ if (!std.mem.eql(u8, raw[target.code_start..], shown[row.code_start..])) return false;
// A restored result may still have the old pane-wide padding. Do not
// let the identical-input shortcut retain that layout when rerun.
if (row.code_start <= row.location_end) return false;
@@ -74,9 +85,14 @@ pub fn sameInput(input: []const u8, rendered: []const u8, rows: []const Row) boo
if (padding.len != width - pardes.panes.File.displayWidth(raw[0..target.end]) + 1 or
padding[padding.len - 1] != '\t') return false;
for (padding[0 .. padding.len - 1]) |byte| if (byte != ' ') return false;
+ index += 1;
}
- if (raw_lines.next()) |tail| if (tail.len != 0) return false;
- return raw_lines.next() == null;
+ const raw_tail = raw_lines.next();
+ const shown_tail = shown_lines.next();
+ if ((raw_tail == null) != (shown_tail == null)) return false;
+ if (raw_tail) |tail| if (tail.len != 0) return false;
+ if (shown_tail) |tail| if (tail.len != 0) return false;
+ return raw_lines.next() == null and shown_lines.next() == null;
}
pub const Parsed = struct {
@@ -246,44 +262,73 @@ pub fn format(p: *pardes.Pardes, dir: []const u8, input: []const u8, anchor: ?us
rows.deinit(p.gpa);
}
var mapped = anchor;
- first = 0;
- while (first < pending.items.len) {
- const end = alignmentEnd(pending.items, first);
- var width: usize = 0;
- for (pending.items[first..end]) |row| width = @max(width, labelWidth(row));
- for (pending.items[first..end], first..) |row, index| {
- const before = out.written().len;
+ if (p.locations_config.layout == .stacked) {
+ for (pending.items, 0..) |row, index| {
const context = row.original == null;
- try out.writer.writeAll(row.label);
- const location_end = if (row.hidden) 0 else out.written().len - before;
- if (row.depth > 0) {
- try out.writer.writeByte(' ');
- try out.writer.splatByteAll('*', row.depth);
- }
- try out.writer.splatByteAll(' ', width - labelWidth(row));
- try out.writer.writeByte('\t');
- const code_start = out.written().len - before;
- try out.writer.writeAll(row.code);
- if (row.declaration and index + 1 < pending.items.len) {
- const next = pending.items[index + 1];
- if (std.mem.eql(u8, row.path, next.path) and next.at.line -| row.at.line > 1)
- try out.writer.writeAll(" ...");
+ if (anchor != null and row.original == anchor) mapped = rows.items.len;
+ if (!row.hidden) {
+ const before = out.written().len;
+ try out.writer.writeAll(row.label);
+ if (row.depth > 0) {
+ try out.writer.writeByte(' ');
+ try out.writer.splatByteAll('*', row.depth);
+ }
+ try appendMetadata(p.gpa, &rows, row, if (context) .context else .match, row.label.len, out.written().len - before, false);
+ try out.writer.writeByte('\n');
}
+ try writeCode(&out.writer, pending.items, index);
+ try appendMetadata(p.gpa, &rows, row, if (context) .context else .preview, 0, 0, true);
if (index + 1 < pending.items.len or std.mem.endsWith(u8, input, "\n")) try out.writer.writeByte('\n');
- const owned_path = try p.gpa.dupe(u8, row.path);
- errdefer p.gpa.free(owned_path);
- const owned_colors = try p.gpa.dupe(u8, row.colors);
- errdefer p.gpa.free(owned_colors);
- try rows.append(p.gpa, .{ .kind = if (context) .context else .match, .declaration = row.declaration, .path = owned_path, .at = row.at, .location_end = location_end, .code_start = code_start, .colors = owned_colors });
- if (anchor != null and row.original == anchor) mapped = index;
}
- first = end;
+ } else {
+ first = 0;
+ while (first < pending.items.len) {
+ const end = alignmentEnd(pending.items, first);
+ var width: usize = 0;
+ for (pending.items[first..end]) |row| width = @max(width, labelWidth(row));
+ for (pending.items[first..end], first..) |row, index| {
+ const before = out.written().len;
+ const context = row.original == null;
+ try out.writer.writeAll(row.label);
+ const location_end = if (row.hidden) 0 else out.written().len - before;
+ if (row.depth > 0) {
+ try out.writer.writeByte(' ');
+ try out.writer.splatByteAll('*', row.depth);
+ }
+ try out.writer.splatByteAll(' ', width - labelWidth(row));
+ try out.writer.writeByte('\t');
+ const code_start = out.written().len - before;
+ try writeCode(&out.writer, pending.items, index);
+ if (index + 1 < pending.items.len or std.mem.endsWith(u8, input, "\n")) try out.writer.writeByte('\n');
+ try appendMetadata(p.gpa, &rows, row, if (context) .context else .match, location_end, code_start, true);
+ if (anchor != null and row.original == anchor) mapped = index;
+ }
+ first = end;
+ }
}
const owned_rows = try rows.toOwnedSlice(p.gpa);
errdefer freeRows(p.gpa, owned_rows);
return .{ .content = try out.toOwnedSlice(), .rows = owned_rows, .anchor = mapped };
}
+fn writeCode(writer: *std.Io.Writer, rows: []const Pending, index: usize) !void {
+ const row = rows[index];
+ try writer.writeAll(row.code);
+ if (row.declaration and index + 1 < rows.len) {
+ const next = rows[index + 1];
+ if (std.mem.eql(u8, row.path, next.path) and next.at.line -| row.at.line > 1)
+ try writer.writeAll(" ...");
+ }
+}
+
+fn appendMetadata(gpa: std.mem.Allocator, rows: *std.ArrayList(Row), pending: Pending, kind: @FieldType(Row, "kind"), location_end: usize, code_start: usize, source: bool) !void {
+ const path = try gpa.dupe(u8, pending.path);
+ errdefer gpa.free(path);
+ const colors = try gpa.dupe(u8, if (source) pending.colors else &.{});
+ errdefer gpa.free(colors);
+ try rows.append(gpa, .{ .kind = kind, .declaration = pending.declaration, .path = path, .at = pending.at, .location_end = location_end, .code_start = code_start, .colors = colors });
+}
+
const alignment_entries = 8;
/// Keep neighboring context with the nearer match at a chunk boundary. Shared