summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-15 15:29:52 -0300
committerGabriel Schneider <[email protected]>2026-09-15 17:24:42 -0300
commitc1787ff868ee723629c1d500098d36dc419f77c3 (patch)
treea8ed559daf246f18c6d07b6053f750d8cfc808c6
parent95f41f0eccd27d2823ffd49bc6cd9bf01fadcc4e (diff)
downloadpardes-c1787ff868ee723629c1d500098d36dc419f77c3.tar.gz
pardes-c1787ff868ee723629c1d500098d36dc419f77c3.zip
Hide redundant locations on neighboring result context
-rw-r--r--docs/config.md3
-rw-r--r--src/locations.zig2
-rw-r--r--test/panes.zig47
3 files changed, 45 insertions, 7 deletions
diff --git a/docs/config.md b/docs/config.md
index 3a6d00d2..b0065ad2 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -146,7 +146,8 @@ LocationsConfig context:5 tscontext:on tslocations:off
```
- `context` is the number of source lines above and below each match (default
- `0`). Overlapping context is shown once.
+ `0`). Overlapping context is shown once. These neighboring lines omit their
+ locations and keep their code aligned with the matching result.
- `tscontext` includes enclosing tree-sitter declaration headers in source
order (default `off`).
- `tslocations` shows locations beside those declaration headers (default
diff --git a/src/locations.zig b/src/locations.zig
index 5e588dbe..ebc87a2e 100644
--- a/src/locations.zig
+++ b/src/locations.zig
@@ -194,7 +194,7 @@ pub fn format(p: *pardes.Pardes, dir: []const u8, input: []const u8, anchor: ?us
const offset = @intFromPtr(line.ptr) - @intFromPtr(source.ptr);
const declaration = kind & 2 != 0;
const colors = if (!declaration and offset + line.len <= source_colors.len) source_colors[offset..][0..line.len] else &.{};
- try appendContext(arena, &pending, path, line, row, declaration, declaration and !p.locations_config.tslocations, colors);
+ try appendContext(arena, &pending, path, line, row, declaration, !declaration or !p.locations_config.tslocations, colors);
}
}
}
diff --git a/test/panes.zig b/test/panes.zig
index 9972df84..8c140001 100644
--- a/test/panes.zig
+++ b/test/panes.zig
@@ -1966,6 +1966,39 @@ const OutputTests = struct {
}
}
+ test "Locations neighboring context hides addresses without changing source alignment" {
+ for ([_]bool{ false, true }) |tslocations| {
+ const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true });
+ defer p.deinit();
+ const source = "\tbefore\n\tmatch\n after\n";
+ const pane = try TreeContextTests.setZigFile(p, source);
+ p.locations_config = .{ .context = 1, .tscontext = false, .tslocations = tslocations };
+ const path = pane.file.?.path;
+ try fillResults(p, 0, "/", .search, "neighbors", try std.fmt.allocPrint(p.gpa, "{s}:2:1 \tmatch\n", .{path}), 0);
+ const file = &p.panes[pane.search_pane.?].?.file.?;
+ try std.testing.expectEqual(@as(usize, 3), file.location_rows.len);
+ const match = file.location_rows[1];
+ const match_line = modal.lineSlice(file.content, 1);
+ const alignment = panes.File.displayWidth(match_line[0..match.code_start]);
+ try std.testing.expect(match.location_end > 0);
+ try std.testing.expect(std.mem.startsWith(u8, match_line, path));
+ for (file.location_rows, 0..) |row, index| {
+ const line = modal.lineSlice(file.content, index);
+ try std.testing.expectEqualStrings(path, row.path);
+ try std.testing.expectEqual(index + 1, row.at.line);
+ try std.testing.expect(!row.declaration);
+ try std.testing.expectEqual(alignment, panes.File.displayWidth(line[0..row.code_start]));
+ try std.testing.expectEqualStrings(modal.lineSlice(source, index), line[row.code_start..]);
+ if (index != 1) {
+ try std.testing.expectEqual(@as(usize, 0), row.location_end);
+ try std.testing.expectEqual(@as(usize, 0), std.mem.trim(u8, line[0..row.code_start], " \t").len);
+ try std.testing.expect(!panes.Output.isResultRow(file, index));
+ }
+ }
+ try std.testing.expectEqual(@as(usize, 1), panes.Output.nextResult(file.content, file.location_rows, path, .{}));
+ }
+ }
+
test "Locations context uses unsaved sources and navigation visits only matches" {
if (!syntax.enabled) return error.SkipZigTest;
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 100, .rows = 30 });
@@ -2001,7 +2034,7 @@ const OutputTests = struct {
matches[count] = i;
count += 1;
} else {
- if (row.location_end > 0) try std.testing.expect(std.mem.startsWith(u8, line, path));
+ try std.testing.expectEqual(@as(usize, 0), row.location_end);
try std.testing.expect(!panes.Output.isResultRow(file, i));
try std.testing.expectEqualStrings(modal.lineSlice(source, expected_line - 1), line[row.code_start..]);
}
@@ -2069,15 +2102,15 @@ const OutputTests = struct {
try std.testing.expect(pardes.test_api.searchStep(restored, 0, -1));
try std.testing.expectEqual(matches[0], restored_source.search_row.?);
- // Editing drops source metadata. Hidden declarations remain skipped,
- // while flush-left visible context becomes an ordinary location.
+ // Editing drops source metadata; hidden context padding still keeps
+ // those rows out of match navigation.
panes.File.setContent(p, file, try p.gpa.dupe(u8, file.content));
try std.testing.expectEqual(@as(usize, 0), file.location_rows.len);
pane.search_row = null;
try std.testing.expect(pardes.test_api.searchStep(p, 0, 1));
- try std.testing.expectEqual(@as(usize, 2), pane.search_row.?);
- try std.testing.expect(pardes.test_api.searchStep(p, 0, 1));
try std.testing.expectEqual(matches[0], pane.search_row.?);
+ try std.testing.expect(pardes.test_api.searchStep(p, 0, 1));
+ try std.testing.expectEqual(matches[1], pane.search_row.?);
}
test "Locations visible declarations are muted and stars count scopes rather than signature lines" {
@@ -2122,6 +2155,10 @@ const OutputTests = struct {
try std.testing.expect(row.location_end > 0);
try std.testing.expect(std.mem.startsWith(u8, line, path));
try std.testing.expectEqualStrings(path, panes.Output.location(line).path);
+ } else {
+ try std.testing.expect(!row.declaration);
+ try std.testing.expectEqual(@as(usize, 0), row.location_end);
+ try std.testing.expectEqualStrings(modal.lineSlice(source, row.at.line - 1), line[row.code_start..]);
}
}
try std.testing.expectEqual(@as(usize, 2), matches);